drivers/reset/reset-ti-sci.c

Source file repositories/reference/linux-study-clean/drivers/reset/reset-ti-sci.c

File Facts

System
Linux kernel
Corpus path
drivers/reset/reset-ti-sci.c
Extension
.c
Size
7925 bytes
Lines
260
Domain
Driver Families
Bucket
drivers/reset
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct ti_sci_reset_control {
	u32 dev_id;
	u32 reset_mask;
	struct mutex lock;
};

/**
 * 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 {
	struct reset_controller_dev rcdev;
	struct device *dev;
	const struct ti_sci_handle *sci;
	struct idr idr;
};

#define to_ti_sci_reset_data(p)	\
	container_of((p), struct ti_sci_reset_data, rcdev)

/**
 * 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)
{
	struct ti_sci_reset_data *data = to_ti_sci_reset_data(rcdev);
	const struct ti_sci_handle *sci = data->sci;
	const struct ti_sci_dev_ops *dev_ops = &sci->ops.dev_ops;
	struct ti_sci_reset_control *control;
	u32 reset_state;
	int ret;

	control = idr_find(&data->idr, id);
	if (!control)
		return -EINVAL;

	mutex_lock(&control->lock);

	ret = dev_ops->get_device_resets(sci, control->dev_id, &reset_state);
	if (ret)
		goto out;

	if (assert)
		reset_state |= control->reset_mask;
	else
		reset_state &= ~control->reset_mask;

	ret = dev_ops->set_device_resets(sci, control->dev_id, reset_state);
out:
	mutex_unlock(&control->lock);

	return ret;
}

/**
 * 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)
{
	return ti_sci_reset_set(rcdev, id, true);
}

/**

Annotation

Implementation Notes