diff options
| author | Michal Simek <[email protected]> | 2026-05-25 13:45:42 +0200 |
|---|---|---|
| committer | Michal Simek <[email protected]> | 2026-06-08 10:50:06 +0200 |
| commit | 19f7def2646f2ec2926e8a0fcff50d4b754eec92 (patch) | |
| tree | 4c2f6d7b1a04203930f44a71f3a5fdc2006f706d /drivers | |
| parent | 4706bd020886bc8fd583efb91aa227ed99c95c45 (diff) | |
reset: Add reset_reset() and reset_reset_bulk() API
Add reset_reset() and reset_reset_bulk() functions to the reset
controller API. These functions assert and then deassert reset signals
in a single call, providing a convenient way to pulse/toggle a reset
line.
This mimics the Linux kernel's reset_control_reset() and
reset_control_bulk_reset() APIs. The new functions are useful for
drivers that need to cycle a reset line during initialization or
error recovery but with also passing delay parameter.
If a driver implements the rst_reset op, it will be called directly
with the delay parameter. Otherwise, the reset core performs
reset_assert(), optional udelay(), and reset_deassert() as fallback.
Reviewed-by: Simon Glass <[email protected]>
Signed-off-by: Michal Simek <[email protected]>
Link: https://lore.kernel.org/r/55ddd313c9e7b2d4dc79ab36bdd0040f871610f6.1779709539.git.michal.simek@amd.com
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/reset/reset-uclass.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/reset/reset-uclass.c b/drivers/reset/reset-uclass.c index fe4cebf54f1..c199e3e5da7 100644 --- a/drivers/reset/reset-uclass.c +++ b/drivers/reset/reset-uclass.c @@ -13,6 +13,7 @@ #include <reset-uclass.h> #include <dm/devres.h> #include <dm/lists.h> +#include <linux/delay.h> static inline struct reset_ops *reset_dev_ops(struct udevice *dev) { @@ -225,6 +226,39 @@ int reset_deassert_bulk(struct reset_ctl_bulk *bulk) return 0; } +int reset_reset(struct reset_ctl *reset_ctl, ulong delay_us) +{ + struct reset_ops *ops = reset_dev_ops(reset_ctl->dev); + int ret; + + debug("%s(reset_ctl=%p, delay_us=%lu)\n", __func__, reset_ctl, + delay_us); + + if (ops->rst_reset) + return ops->rst_reset(reset_ctl, delay_us); + + ret = reset_assert(reset_ctl); + if (ret < 0) + return ret; + + udelay(delay_us); + + return reset_deassert(reset_ctl); +} + +int reset_reset_bulk(struct reset_ctl_bulk *bulk, ulong delay_us) +{ + int i, ret; + + for (i = 0; i < bulk->count; i++) { + ret = reset_reset(&bulk->resets[i], delay_us); + if (ret < 0) + return ret; + } + + return 0; +} + int reset_status(struct reset_ctl *reset_ctl) { struct reset_ops *ops = reset_dev_ops(reset_ctl->dev); |
