aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Vasut <marex@denx.de>2020-01-24 05:44:24 +0100
committerLokesh Vutla <lokeshvutla@ti.com>2020-02-04 09:07:24 +0530
commit11c1af60b5c779be780d105fd33232282d30b5b6 (patch)
tree0477ea40564ba1c42af9a41733aefab0bd20e925
parent8a9ec4dd5f0fe3f221721a94cdc45a2a6edb5927 (diff)
downloadu-boot-11c1af60b5c779be780d105fd33232282d30b5b6.zip
u-boot-11c1af60b5c779be780d105fd33232282d30b5b6.tar.gz
u-boot-11c1af60b5c779be780d105fd33232282d30b5b6.tar.bz2
watchdog: omap_wdt: Fix WDT reloading
The watchdog timer value was never updated in the hardware by this driver, so the watchdog triggered on some random stale value that was left in the hardware. The TI SPRUH37C says, quote: 20.4.3.9 Modifying Timer Count/Load Values and Prescaler Setting ... After a write access, the load register value and prescaler ratio registers are updated immediately, but new values are considered only after the next consecutive counter overflow or after a new trigger command (the WDT_WTGR register). This means at least one trigger must happen. The driver probably depended on someone calling it's .reset() callback, however that is not guaranteed e.g. if the WDT operates without servicing. Add this missing trigger. Signed-off-by: Marek Vasut <marex@denx.de> Cc: Grygorii Strashko <grygorii.strashko@ti.com> Cc: Sam Protsenko <semen.protsenko@linaro.org> Cc: Suniel Mahesh <sunil.m@techveda.org> Reviewed-by: Lokesh Vutla <lokeshvutla@ti.com> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
-rw-r--r--drivers/watchdog/omap_wdt.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index b9cdf70..85425ca 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -219,6 +219,16 @@ static int omap3_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
while ((readl(&priv->regs->wdtwwps)) & WDT_WWPS_PEND_WSPR)
;
+ /* Trigger the watchdog to actually reload the counter. */
+ while ((readl(&priv->regs->wdtwwps)) & WDT_WWPS_PEND_WTGR)
+ ;
+
+ priv->wdt_trgr_pattern = ~(priv->wdt_trgr_pattern);
+ writel(priv->wdt_trgr_pattern, &priv->regs->wdtwtgr);
+
+ while ((readl(&priv->regs->wdtwwps)) & WDT_WWPS_PEND_WTGR)
+ ;
+
return 0;
}