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:Yes. stm32-dma3 calls reset_control_reset() at probe time and the
The STM32 RCC reset controller currently implements only .assert(),Do you have specific consumer drivers in mind?
.deassert(), and .status().
As a result, reset_control_reset() returns -ENOTSUPP, forcing consumers
to open-code the assert / delay / deassert sequence.
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 avoidThe (documented) purpose of the .reset callback is to allow handling
duplicating this logic in consumers.
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>Is this delay enough for all possible consumers, on all platforms that
---
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
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.
Right, waiting for the line to be released is part of deassert, not of
+If polling is necessary after deassertion, doesn't this be have to be
+/* 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);
moved into stm32_reset_deassert()?
reset. I'll move it there in v2.
Best regards,
Gabriel
regards
Philipp