* [PATCH] clk: stm32: add support for reset_control_reset()
@ 2026-10-13 14:52 Gabriel Fernandez
2026-10-13 15:38 ` Philipp Zabel
0 siblings, 1 reply; 3+ messages in thread
From: Gabriel Fernandez @ 2026-10-13 14:52 UTC (permalink / raw)
To: Stephen Boyd, Brian Masney, Jerome Brunet, Maxime Coquelin,
Alexandre Torgue, Philipp Zabel
Cc: linux-clk, linux-stm32, linux-arm-kernel, linux-kernel,
Gabriel Fernandez
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.
Implement .reset() to provide the standard reset operation and avoid
duplicating this logic in consumers.
Signed-off-by: Gabriel Fernandez <gabriel.fernandez@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@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
+
+/* 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);
+}
+
static const struct reset_control_ops stm32_reset_ops = {
.assert = stm32_reset_assert,
.deassert = stm32_reset_deassert,
+ .reset = stm32_reset,
.status = stm32_reset_status,
};
---
base-commit: a90ee4305c4a5df72c11b31dacfdc76e00fcf78a
change-id: 20261013-ups_reset_control_reset-4c2f1b08ddf1
Best regards,
--
Gabriel Fernandez <gabriel.fernandez@foss.st.com>
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] clk: stm32: add support for reset_control_reset()
2026-10-13 14:52 [PATCH] clk: stm32: add support for reset_control_reset() Gabriel Fernandez
@ 2026-10-13 15:38 ` Philipp Zabel
2026-10-14 9:38 ` Gabriel FERNANDEZ
0 siblings, 1 reply; 3+ messages in thread
From: Philipp Zabel @ 2026-10-13 15:38 UTC (permalink / raw)
To: Gabriel Fernandez, Stephen Boyd, Brian Masney, Jerome Brunet,
Maxime Coquelin, Alexandre Torgue
Cc: linux-clk, linux-stm32, linux-arm-kernel, linux-kernel
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@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@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
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] clk: stm32: add support for reset_control_reset()
2026-10-13 15:38 ` Philipp Zabel
@ 2026-10-14 9:38 ` Gabriel FERNANDEZ
0 siblings, 0 replies; 3+ messages in thread
From: Gabriel FERNANDEZ @ 2026-10-14 9:38 UTC (permalink / raw)
To: Philipp Zabel, Stephen Boyd, Brian Masney, Jerome Brunet,
Maxime Coquelin, Alexandre Torgue
Cc: linux-clk, linux-stm32, linux-arm-kernel, linux-kernel
Hi Philipp,
Thanks for the review.
On 10/13/26 17:38, Philipp Zabel wrote:
> 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?
Yes. stm32-dma3 calls reset_control_reset() at probe time and the
STM32MP25 hantro glue (stm32mp25_venc_reset()) does as well. Today both
get -ENOTSUPP from the RCC, so the reset is silently skipped.
>
>> 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.
OK, I see. We do have some IPs, such as the GPU, that use a self-deasserting
reset. The corresponding driver has not been upstreamed yet.
>> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@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@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?
Yes, you are right. Even if 2 us should cover a good part of the IPs,
I'll re-checkagainst STM32MP13/MP15/MP25 and use a conservative value in v2.
>
>> +
>> +/* 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()?
Right, waiting for the line to be released is part of deassert, not of
reset. I'll move it there in v2.
Best regards,
Gabriel
> regards
> Philipp
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-14 9:39 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-13 14:52 [PATCH] clk: stm32: add support for reset_control_reset() Gabriel Fernandez
2026-10-13 15:38 ` Philipp Zabel
2026-10-14 9:38 ` Gabriel FERNANDEZ
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®