Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * Texas Instrument's System Control Interface (TI-SCI) reset driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (C) 2015-2017 Texas Instruments Incorporated - https://www.ti.com/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *	Andrew F. Davis <afd@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * This program is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * it under the terms of the GNU General Public License version 2 as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * published by the Free Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * kind, whether express or implied; without even the implied warranty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/idr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/reset-controller.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/soc/ti/ti_sci_protocol.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * struct ti_sci_reset_control - reset control structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * @dev_id: SoC-specific device identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * @reset_mask: reset mask to use for toggling reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * @lock: synchronize reset_mask read-modify-writes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) struct ti_sci_reset_control {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	u32 dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	u32 reset_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * struct ti_sci_reset_data - reset controller information structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * @rcdev: reset controller entity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  * @dev: reset controller device pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  * @sci: TI SCI handle used for communication with system controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  * @idr: idr structure for mapping ids to reset control structures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) struct ti_sci_reset_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	struct reset_controller_dev rcdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	const struct ti_sci_handle *sci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	struct idr idr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define to_ti_sci_reset_data(p)	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	container_of((p), struct ti_sci_reset_data, rcdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  * ti_sci_reset_set() - program a device's reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  * @rcdev: reset controller entity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  * @id: ID of the reset to toggle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  * @assert: boolean flag to indicate assert or deassert
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  * This is a common internal function used to assert or deassert a device's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  * reset using the TI SCI protocol. The device's reset is asserted if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  * @assert argument is true, or deasserted if @assert argument is false.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  * The mechanism itself is a read-modify-write procedure, the current device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  * reset register is read using a TI SCI device operation, the new value is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  * set or un-set using the reset's mask, and the new reset value written by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  * using another TI SCI device operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  * Return: 0 for successful request, else a corresponding error value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) static int ti_sci_reset_set(struct reset_controller_dev *rcdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 			    unsigned long id, bool assert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	struct ti_sci_reset_data *data = to_ti_sci_reset_data(rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	const struct ti_sci_handle *sci = data->sci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	const struct ti_sci_dev_ops *dev_ops = &sci->ops.dev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	struct ti_sci_reset_control *control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	u32 reset_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	control = idr_find(&data->idr, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	if (!control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	mutex_lock(&control->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	ret = dev_ops->get_device_resets(sci, control->dev_id, &reset_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	if (assert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		reset_state |= control->reset_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		reset_state &= ~control->reset_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	ret = dev_ops->set_device_resets(sci, control->dev_id, reset_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	mutex_unlock(&control->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  * ti_sci_reset_assert() - assert device reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)  * @rcdev: reset controller entity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)  * @id: ID of the reset to be asserted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)  * This function implements the reset driver op to assert a device's reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)  * using the TI SCI protocol. This invokes the function ti_sci_reset_set()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)  * with the corresponding parameters as passed in, but with the @assert
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)  * argument set to true for asserting the reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)  * Return: 0 for successful request, else a corresponding error value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static int ti_sci_reset_assert(struct reset_controller_dev *rcdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 			       unsigned long id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	return ti_sci_reset_set(rcdev, id, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)  * ti_sci_reset_deassert() - deassert device reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  * @rcdev: reset controller entity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  * @id: ID of the reset to be deasserted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  * This function implements the reset driver op to deassert a device's reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  * using the TI SCI protocol. This invokes the function ti_sci_reset_set()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  * with the corresponding parameters as passed in, but with the @assert
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)  * argument set to false for deasserting the reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)  * Return: 0 for successful request, else a corresponding error value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static int ti_sci_reset_deassert(struct reset_controller_dev *rcdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 				 unsigned long id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	return ti_sci_reset_set(rcdev, id, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)  * ti_sci_reset_status() - check device reset status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  * @rcdev: reset controller entity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  * @id: ID of reset to be checked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  * This function implements the reset driver op to return the status of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)  * device's reset using the TI SCI protocol. The reset register value is read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)  * by invoking the TI SCI device operation .get_device_resets(), and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)  * status of the specific reset is extracted and returned using this reset's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  * reset mask.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)  * Return: 0 if reset is deasserted, or a non-zero value if reset is asserted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static int ti_sci_reset_status(struct reset_controller_dev *rcdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 			       unsigned long id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	struct ti_sci_reset_data *data = to_ti_sci_reset_data(rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	const struct ti_sci_handle *sci = data->sci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	const struct ti_sci_dev_ops *dev_ops = &sci->ops.dev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	struct ti_sci_reset_control *control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	u32 reset_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	control = idr_find(&data->idr, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	if (!control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	ret = dev_ops->get_device_resets(sci, control->dev_id, &reset_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	return reset_state & control->reset_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static const struct reset_control_ops ti_sci_reset_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	.assert		= ti_sci_reset_assert,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	.deassert	= ti_sci_reset_deassert,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	.status		= ti_sci_reset_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)  * ti_sci_reset_of_xlate() - translate a set of OF arguments to a reset ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)  * @rcdev: reset controller entity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)  * @reset_spec: OF reset argument specifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)  * This function performs the translation of the reset argument specifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)  * values defined in a reset consumer device node. The function allocates a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)  * reset control structure for that device reset, and will be used by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)  * driver for performing any reset functions on that reset. An idr structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)  * is allocated and used to map to the reset control structure. This idr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)  * is used by the driver to do reset lookups.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)  * Return: 0 for successful request, else a corresponding error value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static int ti_sci_reset_of_xlate(struct reset_controller_dev *rcdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 				 const struct of_phandle_args *reset_spec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	struct ti_sci_reset_data *data = to_ti_sci_reset_data(rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	struct ti_sci_reset_control *control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	control = devm_kzalloc(data->dev, sizeof(*control), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	if (!control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	control->dev_id = reset_spec->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	control->reset_mask = reset_spec->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	mutex_init(&control->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	return idr_alloc(&data->idr, control, 0, 0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static const struct of_device_id ti_sci_reset_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	{ .compatible = "ti,sci-reset", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	{ /* sentinel */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) MODULE_DEVICE_TABLE(of, ti_sci_reset_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static int ti_sci_reset_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	struct ti_sci_reset_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	if (!pdev->dev.of_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	data->sci = devm_ti_sci_get_handle(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	if (IS_ERR(data->sci))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		return PTR_ERR(data->sci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	data->rcdev.ops = &ti_sci_reset_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	data->rcdev.owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	data->rcdev.of_node = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	data->rcdev.of_reset_n_cells = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	data->rcdev.of_xlate = ti_sci_reset_of_xlate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	data->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	idr_init(&data->idr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	platform_set_drvdata(pdev, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	return reset_controller_register(&data->rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static int ti_sci_reset_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	struct ti_sci_reset_data *data = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	reset_controller_unregister(&data->rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	idr_destroy(&data->idr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static struct platform_driver ti_sci_reset_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	.probe = ti_sci_reset_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	.remove = ti_sci_reset_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		.name = "ti-sci-reset",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		.of_match_table = ti_sci_reset_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) module_platform_driver(ti_sci_reset_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) MODULE_DESCRIPTION("TI System Control Interface (TI SCI) Reset driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) MODULE_LICENSE("GPL v2");