[PATCH] clk: stm32: add support for reset_control_reset()
Philipp Zabel
p.zabel at pengutronix.de
Tue Oct 13 08:38:16 PDT 2026
On Di, 2026-10-13 at 16:52 +0200, Gabriel Fernandez wrote:
> The STM32 RCC reset controller currently implements only .assert(),
> .deassert(), and .status().
> As a result, reset_control_reset() returns -ENOTSUPP, forcing consumers
> to open-code the assert / delay / deassert sequence.
Do you have specific consumer drivers in mind?
> Implement .reset() to provide the standard reset operation and avoid
> duplicating this logic in consumers.
The (documented) purpose of the .reset callback is to allow handling
self-deasserting resets, not convenience. I try pushing back on
unnecessary .reset implementations in reset controller drivers.
There are a few drivers with direct level control that implement .reset
like this, but those are mostly for the benefit of consumer drivers
that can be paired with different reset controllers, some of which are
self-deasserting.
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
> ---
> drivers/clk/stm32/reset-stm32.c | 45 +++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 45 insertions(+)
>
> diff --git a/drivers/clk/stm32/reset-stm32.c b/drivers/clk/stm32/reset-stm32.c
> index fc237fccae68..9b853417e9c5 100644
> --- a/drivers/clk/stm32/reset-stm32.c
> +++ b/drivers/clk/stm32/reset-stm32.c
> @@ -4,6 +4,8 @@
> * Author: Gabriel Fernandez <gabriel.fernandez at foss.st.com> for STMicroelectronics.
> */
>
> +#include <linux/delay.h>
> +#include <linux/iopoll.h>
> #include <linux/of.h>
> #include <linux/platform_device.h>
> #include <linux/regmap.h>
> @@ -13,6 +15,13 @@
>
> #include "reset-stm32.h"
>
> +/* Hold time between reset assertion and deassertion */
> +#define STM32_RESET_ASSERT_DELAY_US 2
Is this delay enough for all possible consumers, on all platforms that
reset-stm32 supports?
> +
> +/* Polling of the reset status bit after deassertion */
> +#define STM32_RESET_DEASSERT_POLL_US 10
> +#define STM32_RESET_DEASSERT_TIMEOUT_US (10 * USEC_PER_MSEC)
> +
> struct stm32_reset_data {
> /* reset lock */
> spinlock_t lock;
> @@ -119,9 +128,45 @@ static int stm32_reset_status(struct reset_controller_dev *rcdev,
> return !!(reg & BIT(ptr_line->bit_idx));
> }
>
> +static int stm32_check_deassert(struct reset_controller_dev *rcdev,
> + unsigned long id)
> +{
> + struct stm32_reset_data *data = to_stm32_reset_data(rcdev);
> + struct stm32_reset_cfg line_reset;
> + const struct stm32_reset_cfg *ptr_line;
> + u32 reg;
> +
> + ptr_line = stm32_get_reset_line(rcdev, id, &line_reset);
> + if (!ptr_line)
> + return -EPERM;
> +
> + return readl_poll_timeout(data->membase + ptr_line->offset, reg,
> + !(reg & BIT(ptr_line->bit_idx)),
> + STM32_RESET_DEASSERT_POLL_US,
> + STM32_RESET_DEASSERT_TIMEOUT_US);
> +}
> +
> +static int stm32_reset(struct reset_controller_dev *rcdev, unsigned long id)
> +{
> + int ret;
> +
> + ret = stm32_reset_assert(rcdev, id);
> + if (ret)
> + return ret;
> +
> + fsleep(STM32_RESET_ASSERT_DELAY_US);
> +
> + ret = stm32_reset_deassert(rcdev, id);
> + if (ret)
> + return ret;
> +
> + return stm32_check_deassert(rcdev, id);
If polling is necessary after deassertion, doesn't this be have to be
moved into stm32_reset_deassert()?
regards
Philipp
More information about the linux-arm-kernel
mailing list