From: Antonio Borneo <antonio.borneo@foss.st.com>
To: Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Maxime Coquelin <mcoquelin.stm32@gmail.com>,
Alexandre Torgue <alexandre.torgue@foss.st.com>,
Russell King <linux@armlinux.org.uk>,
Wim Van Sebroeck <wim@linux-watchdog.org>,
Guenter Roeck <linux@roeck-us.net>, <devicetree@vger.kernel.org>,
<linux-stm32@st-md-mailman.stormreply.com>,
<linux-arm-kernel@lists.infradead.org>,
<linux-kernel@vger.kernel.org>
Cc: "Antonio Borneo" <antonio.borneo@foss.st.com>,
linux-watchdog@vger.kernel.org,
"Clément Le Goffic" <clement.legoffic@foss.st.com>,
"Amelie Delaunay" <amelie.delaunay@foss.st.com>
Subject: [PATCH v3 02/13] watchdog: stm32_iwdg: detect whether the watchdog is running
Date: Fri, 6 Nov 2026 17:34:18 +0100 [thread overview]
Message-ID: <20261106163429.618392-3-antonio.borneo@foss.st.com> (raw)
In-Reply-To: <20261106163429.618392-1-antonio.borneo@foss.st.com>
From: Clément Le Goffic <clement.legoffic@foss.st.com>
On STM32MP13x and STM32MP2xx platforms, the ONF bit in the IWDG
status register indicates whether the watchdog is running. This
feature was introduced with IWDG hardware version 3.1 and is not
available on older versions, such as the one used on STM32MP15x.
On older hardware versions, determine the watchdog state by
writing the current reload value back to the reload register,
then checking the RVU (Reload Value Update) bit in the status
register. The update completes only if the watchdog is already
running.
Use this state information to service only watchdogs that were
started by earlier boot stages.
Signed-off-by: Clément Le Goffic <clement.legoffic@foss.st.com>
Signed-off-by: Antonio Borneo <antonio.borneo@foss.st.com>
---
drivers/watchdog/stm32_iwdg.c | 45 +++++++++++++++++++++++------------
1 file changed, 30 insertions(+), 15 deletions(-)
diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c
index 30b4cbf20afa9..ce3e1f96ef50a 100644
--- a/drivers/watchdog/stm32_iwdg.c
+++ b/drivers/watchdog/stm32_iwdg.c
@@ -49,6 +49,7 @@
/* IWDG_SR register bit mask */
#define SR_PVU BIT(0) /* Watchdog prescaler value update */
#define SR_RVU BIT(1) /* Watchdog counter reload value update */
+#define SR_ONF BIT(8) /* Watchdog enable status bit */
#define EWCR_EWIT GENMASK(11, 0) /* Watchdog counter window value */
#define EWCR_EWIC BIT(14) /* Watchdog early interrupt acknowledge */
@@ -57,6 +58,9 @@
/* IWDG_VERR register mask */
#define VERR_MASK GENMASK(7, 0)
+/* IWDG Compatibility */
+#define ONF_MIN_VER 0x31
+
/* set timeout to 100000 us */
#define TIMEOUT_US 100000
#define SLEEP_US 1000
@@ -250,6 +254,31 @@ static int stm32_iwdg_clk_init(struct platform_device *pdev,
return 0;
}
+static bool stm32_iwdg_is_running(struct stm32_iwdg *wdt)
+{
+ bool running;
+ u32 rlr, sr;
+ int ret;
+
+ if (wdt->hw_version >= ONF_MIN_VER)
+ return (reg_read(wdt->regs, IWDG_SR) & SR_ONF) != 0;
+
+ /*
+ * Workaround for old versions without IWDG_SR_ONF bit:
+ * - write in IWDG_RLR_OFFSET
+ * - wait for sync
+ * - if sync succeeds, then iwdg is running
+ */
+ reg_write(wdt->regs, IWDG_KR, KR_KEY_EWA);
+ rlr = reg_read(wdt->regs, IWDG_RLR);
+ reg_write(wdt->regs, IWDG_RLR, rlr);
+ ret = readl_poll_timeout(wdt->regs + IWDG_SR, sr, !(sr & SR_RVU), SLEEP_US, TIMEOUT_US);
+ running = ret ? false : true;
+ reg_write(wdt->regs, IWDG_KR, KR_KEY_DWA);
+
+ return running;
+}
+
static const struct watchdog_info stm32_iwdg_info = {
.options = WDIOF_SETTIMEOUT |
WDIOF_MAGICCLOSE |
@@ -362,23 +391,9 @@ static int stm32_iwdg_probe(struct platform_device *pdev)
watchdog_set_nowayout(wdd, WATCHDOG_NOWAYOUT);
watchdog_init_timeout(wdd, 0, dev);
- /*
- * In case of CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED is set
- * (Means U-Boot/bootloaders leaves the watchdog running)
- * When we get here we should make a decision to prevent
- * any side effects before user space daemon will take care of it.
- * The best option, taking into consideration that there is no
- * way to read values back from hardware, is to enforce watchdog
- * being run with deterministic values.
- */
- if (IS_ENABLED(CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED)) {
- ret = stm32_iwdg_start(wdd);
- if (ret)
- return ret;
-
+ if (IS_ENABLED(CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED) && stm32_iwdg_is_running(wdt))
/* Make sure the watchdog is serviced */
set_bit(WDOG_HW_RUNNING, &wdd->status);
- }
ret = devm_watchdog_register_device(dev, wdd);
if (ret)
--
2.34.1
next prev parent reply other threads:[~2026-11-06 16:34 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-06 16:34 [PATCH v3 00/13] Update watchdogs support on STM32MP platforms Antonio Borneo
2026-11-06 16:34 ` [PATCH v3 01/13] watchdog: stm32_iwdg: get hardware version during probe Antonio Borneo
2026-11-06 16:34 ` Antonio Borneo [this message]
2026-11-06 16:34 ` [PATCH v3 03/13] watchdog: stm32_iwdg: add pretimeout support for iwdg v4.0 Antonio Borneo
2026-11-06 16:34 ` [PATCH v3 04/13] ARM: stm32: enable arm smc watchdog on stm32mp1xx Antonio Borneo
2026-11-06 16:34 ` [PATCH v3 05/13] ARM: dts: stm32: add iwdg1 node on stm32mp151 SoC Antonio Borneo
2026-11-06 16:34 ` [PATCH v3 06/13] ARM: dts: stm32: enable iwdg1 on stm32mp15x ST boards Antonio Borneo
2026-11-06 16:34 ` [PATCH v3 07/13] ARM: dts: stm32: move arm smc watchdog to stm32mp151 SoC Antonio Borneo
2026-11-06 16:34 ` [PATCH v3 08/13] ARM: dts: stm32: enable arm smc watchdog on stm32mp15x scmi boards Antonio Borneo
2026-11-06 16:34 ` [PATCH v3 09/13] ARM: dts: stm32: add watchdog0 alias on ST stm32mp1xx boards Antonio Borneo
2026-11-06 16:34 ` [PATCH v3 10/13] arm64: dts: st: add iwdg1 and iwdg2 support to stm32mp211 Antonio Borneo
2026-11-06 16:34 ` [PATCH v3 11/13] arm64: dts: st: add iwdg1 and iwdg2 support to stm32mp231 Antonio Borneo
2026-11-06 16:34 ` [PATCH v3 12/13] arm64: dts: st: add iwdg1 and iwdg2 support to stm32mp251 Antonio Borneo
2026-11-06 16:34 ` [PATCH v3 13/13] arm64: dts: st: enable iwdg2 on stm32mp2xx ST boards Antonio Borneo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261106163429.618392-3-antonio.borneo@foss.st.com \
--to=antonio.borneo@foss.st.com \
--cc=alexandre.torgue@foss.st.com \
--cc=amelie.delaunay@foss.st.com \
--cc=clement.legoffic@foss.st.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=krzk+dt@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-stm32@st-md-mailman.stormreply.com \
--cc=linux-watchdog@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=linux@roeck-us.net \
--cc=mcoquelin.stm32@gmail.com \
--cc=robh@kernel.org \
--cc=wim@linux-watchdog.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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®