[PATCH 1/6] watchdog: wdt-uclass: add get_timeout operation and helper
Juuso Rinta
juuso.rinta at nokia.com
Fri Jul 10 06:51:17 CEST 2026
The wdt_start function may be called with a timeout greater
than the hardware-supported maximum. This in turn can result
to bogus print, e.g.
Started <watchdog@> with servicing every 1000ms (60s timeout)
Add a uclass get_timeout operation and helper so drivers can
report the effective timeout. When available, the startup
print now shows both actual and requested timeout values, e.g.
Started <watchdog@> with servicing every 1000ms (10s timeout, requested 60s)
Signed-off-by: Juuso Rinta <juuso.rinta at nokia.com>
---
drivers/watchdog/wdt-uclass.c | 35 +++++++++++++++++++++++++++++++++--
include/wdt.h | 22 ++++++++++++++++++++++
2 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/drivers/watchdog/wdt-uclass.c b/drivers/watchdog/wdt-uclass.c
index 438833b2245..c9ce5c07afd 100644
--- a/drivers/watchdog/wdt-uclass.c
+++ b/drivers/watchdog/wdt-uclass.c
@@ -116,10 +116,28 @@ int initr_watchdog(void)
return 0;
}
+int wdt_get_timeout(struct udevice *dev, u64 *timeout_ms)
+{
+ const struct wdt_ops *ops = device_get_ops(dev);
+ u64 tout_val;
+ int ret;
+
+ if (!ops->get_timeout)
+ return -ENOSYS;
+
+ ret = ops->get_timeout(dev, &tout_val);
+ if (ret == 0)
+ *timeout_ms = tout_val;
+
+ return ret;
+}
+
int wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
{
const struct wdt_ops *ops = device_get_ops(dev);
int ret;
+ u64 effective_timeout = timeout_ms;
+ char requested_timeout[32];
if (!ops->start)
return -ENOSYS;
@@ -143,9 +161,22 @@ int wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
}
priv->running = true;
- printf("WDT: Started %s with%s servicing %s (%ds timeout)\n",
+
+ /* Get the effective timeout from driver if supported */
+ memset(requested_timeout, 0, 32);
+ if (wdt_get_timeout(dev, &effective_timeout) == 0) {
+ u32 effective_s = (u32)lldiv(effective_timeout, 1000);
+ u32 requested_s = (u32)lldiv(timeout_ms, 1000);
+
+ if (effective_s != requested_s) {
+ snprintf(requested_timeout, 32, ", requested %ds",
+ requested_s);
+ }
+ }
+
+ printf("WDT: Started %s with%s servicing %s (%ds timeout%s)\n",
dev->name, IS_ENABLED(CONFIG_WATCHDOG) ? "" : "out",
- str, (u32)lldiv(timeout_ms, 1000));
+ str, (u32)lldiv(effective_timeout, 1000), requested_timeout);
}
return ret;
diff --git a/include/wdt.h b/include/wdt.h
index 1ef656585c4..5c38eba3a5a 100644
--- a/include/wdt.h
+++ b/include/wdt.h
@@ -74,6 +74,19 @@ int wdt_reset(struct udevice *dev);
*/
int wdt_expire_now(struct udevice *dev, ulong flags);
+/*
+ * Get the effective timeout in milliseconds.
+ *
+ * The effective value may differ from the value passed to wdt_start()
+ * if the hardware has rounded and/or clamped it.
+ *
+ * @dev: WDT device
+ * @timeout_ms: A pointer where the effective timeout in milliseconds
+ * is returned to. On error, the value is left unchanged.
+ * @return 0 if OK -ve on error
+ */
+int wdt_get_timeout(struct udevice *dev, u64 *timeout_ms);
+
/*
* struct wdt_ops - Driver model wdt operations
*
@@ -120,6 +133,15 @@ struct wdt_ops {
* @return 0 if OK -ve on error. May not return.
*/
int (*expire_now)(struct udevice *dev, ulong flags);
+ /*
+ * Get the effective timeout in milliseconds (optional)
+ *
+ * @dev: WDT device
+ * @timeout_ms: Location to store timeout in milliseconds,
+ * written only on success
+ * @return 0 if OK -ve on error
+ */
+ int (*get_timeout)(struct udevice *dev, u64 *timeout_ms);
};
int initr_watchdog(void);
--
2.39.2
More information about the U-Boot
mailing list