diff options
author | Ahmad Fatoum <a.fatoum@pengutronix.de> | 2021-05-31 09:13:19 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2021-06-09 14:34:11 +0200 |
commit | 0ed7bb09f2ef7b40ddcc4a8d269ad42f612c8438 (patch) | |
tree | 5a41a9a0b63daab873b2568b71df3533027141c4 /drivers | |
parent | 71c1671d27eb2e561f0b23b245925b2e27e67042 (diff) | |
download | barebox-0ed7bb09f2ef7b40ddcc4a8d269ad42f612c8438.tar.gz barebox-0ed7bb09f2ef7b40ddcc4a8d269ad42f612c8438.tar.xz |
watchdog: add option to provide fall-back restart handler
Some barebox ports may have a watchdog, but no restart handler, e.g.
reset happens via PMIC, which has no driver yet, but watchdog controls
reset line going to PMIC. Accommodate such setups by allowing
registration of watchdog as fall back restart handler.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Link: https://lore.barebox.org/20210531071319.32459-1-a.fatoum@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/watchdog/wd_core.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/watchdog/wd_core.c b/drivers/watchdog/wd_core.c index 4b0ee31d5b..2e2814a8f2 100644 --- a/drivers/watchdog/wd_core.c +++ b/drivers/watchdog/wd_core.c @@ -18,6 +18,7 @@ #include <errno.h> #include <linux/ctype.h> #include <watchdog.h> +#include <restart.h> static LIST_HEAD(watchdog_list); @@ -177,6 +178,24 @@ static int seconds_to_expire_get(struct param_d *p, void *priv) return 0; } +static void __noreturn watchdog_restart_handle(struct restart_handler *this) +{ + struct watchdog *wd = watchdog_get_default(); + int ret = -ENODEV; + + if (wd) + ret = watchdog_set_timeout(wd, 1); + + BUG_ON(ret); + mdelay(2000); + __builtin_unreachable(); +} + +static struct restart_handler restart_handler = { + .restart = watchdog_restart_handle, + .name = "watchdog-restart", +}; + int watchdog_register(struct watchdog *wd) { struct param_d *p; @@ -247,6 +266,13 @@ int watchdog_register(struct watchdog *wd) goto error_unregister; } + if (!restart_handler.priority) { + restart_handler.priority = 10; /* don't override others */ + ret = restart_handler_register(&restart_handler); + if (ret) + dev_warn(&wd->dev, "failed to register restart handler\n"); + } + list_add_tail(&wd->list, &watchdog_list); pr_debug("registering watchdog %s with priority %d\n", watchdog_name(wd), |