[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