mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-13 15:03:58 +03:00
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 <sjg@chromium.org> Signed-off-by: Michal Simek <michal.simek@amd.com> Link: https://lore.kernel.org/r/55ddd313c9e7b2d4dc79ab36bdd0040f871610f6.1779709539.git.michal.simek@amd.com
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -76,6 +76,25 @@ struct reset_ops {
|
||||
* @return 0 if OK, or a negative error code.
|
||||
*/
|
||||
int (*rst_deassert)(struct reset_ctl *reset_ctl);
|
||||
/**
|
||||
* rst_reset - Reset a HW module.
|
||||
*
|
||||
* This optional function triggers a reset pulse on the reset line.
|
||||
* If not implemented, reset_reset() falls back to rst_assert(),
|
||||
* udelay(@delay_us), then rst_deassert(); that delay is therefore
|
||||
* observed only on the fallback path.
|
||||
*
|
||||
* When rst_reset is provided, @delay_us is controller-specific: the
|
||||
* implementation should honour it if the hardware needs a minimum
|
||||
* assertion time before release. It may ignore @delay_us when the
|
||||
* pulse shape is fixed elsewhere (for example a firmware pulse).
|
||||
*
|
||||
* @reset_ctl: The reset signal to pulse.
|
||||
* @delay_us: Minimum delay in microseconds between assert and
|
||||
* deassert where applicable; see above.
|
||||
* @return 0 if OK, or a negative error code.
|
||||
*/
|
||||
int (*rst_reset)(struct reset_ctl *reset_ctl, ulong delay_us);
|
||||
/**
|
||||
* rst_status - Check reset signal status.
|
||||
*
|
||||
|
||||
@@ -320,6 +320,45 @@ int reset_deassert(struct reset_ctl *reset_ctl);
|
||||
*/
|
||||
int reset_deassert_bulk(struct reset_ctl_bulk *bulk);
|
||||
|
||||
/**
|
||||
* reset_reset - Reset a HW module by asserting and deasserting a reset signal.
|
||||
*
|
||||
* This function will assert and then deassert the specified reset signal,
|
||||
* thus resetting the affected HW module. This is a convenience function
|
||||
* that combines reset_assert() and reset_deassert().
|
||||
*
|
||||
* If the controller implements struct reset_ops.rst_reset, that callback
|
||||
* is used and @delay_us is interpreted as documented there. Otherwise the
|
||||
* core performs reset_assert(), udelay(@delay_us), then reset_deassert().
|
||||
*
|
||||
* @reset_ctl: A reset control struct that was previously successfully
|
||||
* requested by reset_get_by_*().
|
||||
* @delay_us: Delay in microseconds between assert and deassert on the
|
||||
* fallback path; meaning is driver-specific when rst_reset is used.
|
||||
* Use 0 for no delay on the fallback path.
|
||||
* Return: 0 if OK, or a negative error code.
|
||||
*/
|
||||
int reset_reset(struct reset_ctl *reset_ctl, ulong delay_us);
|
||||
|
||||
/**
|
||||
* reset_reset_bulk - Reset all HW modules in a reset control bulk struct.
|
||||
*
|
||||
* This calls reset_reset() on each entry in order. Each line therefore
|
||||
* completes its own assert/delay/deassert (or controller rst_reset) before
|
||||
* the next entry starts. That matches Linux reset_control_bulk_reset().
|
||||
*
|
||||
* When several lines must stay asserted together for @delay_us (typical
|
||||
* multi-reset controllers), use reset_assert_bulk(), udelay(@delay_us),
|
||||
* and reset_deassert_bulk() instead.
|
||||
*
|
||||
* @bulk: A reset control bulk struct that was previously successfully
|
||||
* requested by reset_get_bulk().
|
||||
* @delay_us: Delay in microseconds passed to each reset_reset(); see
|
||||
* reset_reset() and struct reset_ops.rst_reset.
|
||||
* Return: 0 if OK, or a negative error code.
|
||||
*/
|
||||
int reset_reset_bulk(struct reset_ctl_bulk *bulk, ulong delay_us);
|
||||
|
||||
/**
|
||||
* rst_status - Check reset signal status.
|
||||
*
|
||||
@@ -443,6 +482,16 @@ static inline int reset_deassert_bulk(struct reset_ctl_bulk *bulk)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int reset_reset(struct reset_ctl *reset_ctl, ulong delay_us)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static inline int reset_reset_bulk(struct reset_ctl_bulk *bulk, ulong delay_us)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static inline int reset_status(struct reset_ctl *reset_ctl)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
|
||||
Reference in New Issue
Block a user