Re: [PATCH] reset-controller: ti: introduce a new reset handler
From: Philipp Zabel <p.zabel@pengutronix.de>
Date: 2026-03-10 09:44:53
Also in:
linux-mediatek, lkml
On Di, 2026-03-10 at 11:39 +0800, Zexin Wang wrote:
Introduce ti_syscon_reset() to integrate assert and deassert together. If some modules need do serialized assert and deassert operations to reset itself, reset_control_reset can be called for convenience.
With this change, reset_control_reset() would stop returning -ENOTSUPP on all existing platforms using ti,syscon-reset. But it wouldn't work correctly because no delays are specified. Note that reset_control_reset() was introduced to support hardware that is hard-wired to create reset pulses of a fixed length, with no individual control over assertion and deassertion. If the consumer driver does not need to work on such hardware, using reset_control_reset() over reset_control_assert()/deassert() is not necessary.
quoted hunk ↗ jump to hunk
Signed-off-by: Zexin Wang <redacted> --- drivers/reset/reset-ti-syscon.c | 34 +++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+)diff --git a/drivers/reset/reset-ti-syscon.c b/drivers/reset/reset-ti-syscon.c index 23f86ddb8668..f37685e32b0a 100644 --- a/drivers/reset/reset-ti-syscon.c +++ b/drivers/reset/reset-ti-syscon.c@@ -7,6 +7,7 @@ * Suman Anna <afd@ti.com> */ +#include <linux/delay.h> #include <linux/mfd/syscon.h> #include <linux/module.h> #include <linux/of.h>@@ -42,12 +43,14 @@ struct ti_syscon_reset_control { * @regmap: regmap handle containing the memory-mapped reset registers * @controls: array of reset controls * @nr_controls: number of controls in control array + * @reset_duration_us: time of controller assert reset */ struct ti_syscon_reset_data { struct reset_controller_dev rcdev; struct regmap *regmap; struct ti_syscon_reset_control *controls; unsigned int nr_controls; + unsigned int reset_duration_us; }; #define to_ti_syscon_reset_data(_rcdev) \@@ -150,9 +153,37 @@ static int ti_syscon_reset_status(struct reset_controller_dev *rcdev, !(control->flags & STATUS_SET); } +/** + * ti_syscon_reset() - perform a full reset cycle on a device + * @rcdev: reset controller entity + * @id: ID of the reset to be asserted and deasserted + * + * This function performs a full reset cycle by asserting and then + * deasserting the reset signal for a device. It ensures the device + * is properly reset and ready for operation. + * + * Return: 0 for successful request, else a corresponding error value + */ +static int ti_syscon_reset(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct ti_syscon_reset_data *data = to_ti_syscon_reset_data(rcdev); + int ret;
This should keep returning -ENOTSUPP for unspecified delays.
quoted hunk ↗ jump to hunk
+ ret = ti_syscon_reset_assert(rcdev, id); + if (ret) + return ret; + + if (data->reset_duration_us) + usleep_range(data->reset_duration_us, data->reset_duration_us * 2); + + return ti_syscon_reset_deassert(rcdev, id); +} + static const struct reset_control_ops ti_syscon_reset_ops = { .assert = ti_syscon_reset_assert, .deassert = ti_syscon_reset_deassert, + .reset = ti_syscon_reset, .status = ti_syscon_reset_status, };@@ -196,6 +227,9 @@ static int ti_syscon_reset_probe(struct platform_device *pdev) controls[i].flags = be32_to_cpup(list++); } + of_property_read_u32(pdev->dev.of_node, "reset-duration-us", + &data->reset_duration_us);
This OF property is missing documentation. At the very least ti_syscon_reset would need to be gated behind existence of this property or a new compatible. But, since there is one delay for all reset lines, this is the maximum of all per-consumer necessary delays. This is a fixed property of the SoC. So why specify it in the device tree at all? You could just derive it from a SoC specific compatible. regards Philipp