[PATCH RESEND] watchdog: sbsa_gwdt: clamp WOR value to hw max
Juuso Rinta
juuso.rinta at nokia.com
Mon May 4 11:34:34 CEST 2026
The WOR register is 32 bits, so any tick count exceeding U32_MAX is
truncated by writel(). A large requested timeout can wrap to a small
value causing the watchdog to fire sooner than requested.
Clamp the calculated value to U32_MAX prior to writing the register so
over-large requests will be set to the maximum timeout value.
Found by code review.
Signed-off-by: Juuso Rinta <juuso.rinta at nokia.com>
---
drivers/watchdog/sbsa_gwdt.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c
index 807884c5bc7..3a924cb2b9a 100644
--- a/drivers/watchdog/sbsa_gwdt.c
+++ b/drivers/watchdog/sbsa_gwdt.c
@@ -50,6 +50,7 @@ static int sbsa_gwdt_start(struct udevice *dev, u64 timeout, ulong flags)
{
struct sbsa_gwdt_priv *priv = dev_get_priv(dev);
u32 clk;
+ u64 tout_wdog;
/*
* it work in the single stage mode in u-boot,
@@ -58,8 +59,13 @@ static int sbsa_gwdt_start(struct udevice *dev, u64 timeout, ulong flags)
* to half value of timeout.
*/
clk = get_tbclk();
- writel(clk / (2 * 1000) * timeout,
- priv->reg_control + SBSA_GWDT_WOR);
+
+ /* if requested timeout overflows, clamp it to u32_max */
+ tout_wdog = ((u64)clk * timeout) / (2 * 1000);
+ if (tout_wdog > U32_MAX)
+ tout_wdog = U32_MAX;
+
+ writel(tout_wdog, priv->reg_control + SBSA_GWDT_WOR);
/* writing WCS will cause an explicit watchdog refresh */
writel(SBSA_GWDT_WCS_EN, priv->reg_control + SBSA_GWDT_WCS);
---
base-commit: 4433253ecf2041f9362a763bb6cb79960921ac7e
change-id: 20260428-fix-sbsa-timeout-overflow-20cf84fa8a6b
Best regards,
--
Juuso Rinta <juuso.rinta at nokia.com>
--
Juuso Rinta <juuso.rinta at nokia.com>
More information about the U-Boot
mailing list