Re: [PATCH] clk: stm32: add support for reset_control_reset()

From: Gabriel FERNANDEZ

Date: Wed Oct 14 2026 - 05:47:52 EST


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@xxxxxxxxxxx>
---
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@xxxxxxxxxxx> 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