// SPDX-License-Identifier: GPL-2.0-only /* * Texas Instrument's System Control Interface (TI-SCI) reset driver * * Copyright (C) 2015-2017 Texas Instruments Incorporated - https://www.ti.com/ * Andrew F. Davis <[email protected]> */ #include <linux/idr.h> #include <linux/module.h> #include <linux/mutex.h> #include <linux/of.h> #include <linux/platform_device.h> #include <linux/reset-controller.h> #include <linux/soc/ti/ti_sci_protocol.h> /** * struct ti_sci_reset_control - reset control structure * @dev_id: SoC-specific device identifier * @reset_mask: reset mask to use for toggling reset * @lock: synchronize reset_mask read-modify-writes */ struct ti_sci_reset_control { … }; /** * struct ti_sci_reset_data - reset controller information structure * @rcdev: reset controller entity * @dev: reset controller device pointer * @sci: TI SCI handle used for communication with system controller * @idr: idr structure for mapping ids to reset control structures */ struct ti_sci_reset_data { … }; #define to_ti_sci_reset_data(p) … /** * ti_sci_reset_set() - program a device's reset * @rcdev: reset controller entity * @id: ID of the reset to toggle * @assert: boolean flag to indicate assert or deassert * * This is a common internal function used to assert or deassert a device's * reset using the TI SCI protocol. The device's reset is asserted if the * @assert argument is true, or deasserted if @assert argument is false. * The mechanism itself is a read-modify-write procedure, the current device * reset register is read using a TI SCI device operation, the new value is * set or un-set using the reset's mask, and the new reset value written by * using another TI SCI device operation. * * Return: 0 for successful request, else a corresponding error value */ static int ti_sci_reset_set(struct reset_controller_dev *rcdev, unsigned long id, bool assert) { … } /** * ti_sci_reset_assert() - assert device reset * @rcdev: reset controller entity * @id: ID of the reset to be asserted * * This function implements the reset driver op to assert a device's reset * using the TI SCI protocol. This invokes the function ti_sci_reset_set() * with the corresponding parameters as passed in, but with the @assert * argument set to true for asserting the reset. * * Return: 0 for successful request, else a corresponding error value */ static int ti_sci_reset_assert(struct reset_controller_dev *rcdev, unsigned long id) { … } /** * ti_sci_reset_deassert() - deassert device reset * @rcdev: reset controller entity * @id: ID of the reset to be deasserted * * This function implements the reset driver op to deassert a device's reset * using the TI SCI protocol. This invokes the function ti_sci_reset_set() * with the corresponding parameters as passed in, but with the @assert * argument set to false for deasserting the reset. * * Return: 0 for successful request, else a corresponding error value */ static int ti_sci_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id) { … } /** * ti_sci_reset_status() - check device reset status * @rcdev: reset controller entity * @id: ID of reset to be checked * * This function implements the reset driver op to return the status of a * device's reset using the TI SCI protocol. The reset register value is read * by invoking the TI SCI device operation .get_device_resets(), and the * status of the specific reset is extracted and returned using this reset's * reset mask. * * Return: 0 if reset is deasserted, or a non-zero value if reset is asserted */ static int ti_sci_reset_status(struct reset_controller_dev *rcdev, unsigned long id) { … } static const struct reset_control_ops ti_sci_reset_ops = …; /** * ti_sci_reset_of_xlate() - translate a set of OF arguments to a reset ID * @rcdev: reset controller entity * @reset_spec: OF reset argument specifier * * This function performs the translation of the reset argument specifier * values defined in a reset consumer device node. The function allocates a * reset control structure for that device reset, and will be used by the * driver for performing any reset functions on that reset. An idr structure * is allocated and used to map to the reset control structure. This idr * is used by the driver to do reset lookups. * * Return: 0 for successful request, else a corresponding error value */ static int ti_sci_reset_of_xlate(struct reset_controller_dev *rcdev, const struct of_phandle_args *reset_spec) { … } static const struct of_device_id ti_sci_reset_of_match[] = …; MODULE_DEVICE_TABLE(of, ti_sci_reset_of_match); static int ti_sci_reset_probe(struct platform_device *pdev) { … } static void ti_sci_reset_remove(struct platform_device *pdev) { … } static struct platform_driver ti_sci_reset_driver = …; module_platform_driver(…) …; MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …;