[PATCH] watchdog: allow overriding the rate-limiting logic

Rasmus Villemoes rasmus.villemoes at prevas.dk
Thu Mar 12 12:40:34 CET 2020


On the MPC8309-derived board I'm currently working on, the current
rate-limiting logic in the generic watchdog_reset function poses two
problems:

First, the hard-coded limit of 1000ms is too large for the
external GPIO-triggered watchdog we have.

Second, in the SPL, the decrementer interrupt is not enabled, so the
get_timer() call calls always returns 0, so wdt_reset() is never
actually called. Enabling that interrupt (i.e. calling
interrupt_init() somewhere in my early board code) is a bit
problematic, since U-Boot proper gets loaded to address 0, hence
overwriting exception vectors - and the reason I even need to care
about the watchdog in the SPL is that the signature verification takes
a rather long time, so just disabling interrupts before loading U-Boot
proper doesn't work.

Both problems can be solved by allowing the board to override the
rate-limiting logic. For example, in my case I will implement the
function in terms of get_ticks() (i.e. the time base registers on
PPC) which do not depend on interrupts, and use a threshold of
gd->bus_clk / (4*16) ticks (~62ms).

Signed-off-by: Rasmus Villemoes <rasmus.villemoes at prevas.dk>
---

This is on top of https://patchwork.ozlabs.org/patch/1242772/, but
it's obviously trivial to do on master instead.

 drivers/watchdog/wdt-uclass.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/watchdog/wdt-uclass.c b/drivers/watchdog/wdt-uclass.c
index 309a0e9c5b..ad53e86b80 100644
--- a/drivers/watchdog/wdt-uclass.c
+++ b/drivers/watchdog/wdt-uclass.c
@@ -67,6 +67,19 @@ int wdt_expire_now(struct udevice *dev, ulong flags)
 }
 
 #if defined(CONFIG_WATCHDOG)
+__weak int watchdog_reset_ratelimit(void)
+{
+	static ulong next_reset;
+	ulong now;
+
+	now = get_timer(0);
+	if (time_after(now, next_reset)) {
+		next_reset = now + 1000;	/* reset every 1000ms */
+		return 1;
+	}
+	return 0;
+}
+
 /*
  * Called by macro WATCHDOG_RESET. This function be called *very* early,
  * so we need to make sure, that the watchdog driver is ready before using
@@ -74,19 +87,13 @@ int wdt_expire_now(struct udevice *dev, ulong flags)
  */
 void watchdog_reset(void)
 {
-	static ulong next_reset;
-	ulong now;
-
 	/* Exit if GD is not ready or watchdog is not initialized yet */
 	if (!gd || !(gd->flags & GD_FLG_WDT_READY))
 		return;
 
 	/* Do not reset the watchdog too often */
-	now = get_timer(0);
-	if (time_after(now, next_reset)) {
-		next_reset = now + 1000;	/* reset every 1000ms */
+	if (watchdog_reset_ratelimit())
 		wdt_reset(gd->watchdog_dev);
-	}
 }
 #endif
 
-- 
2.23.0



More information about the U-Boot mailing list