[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