summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAhmad Fatoum <a.fatoum@pengutronix.de>2021-05-31 09:13:19 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2021-06-09 14:34:11 +0200
commit0ed7bb09f2ef7b40ddcc4a8d269ad42f612c8438 (patch)
tree5a41a9a0b63daab873b2568b71df3533027141c4 /drivers
parent71c1671d27eb2e561f0b23b245925b2e27e67042 (diff)
downloadbarebox-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.c26
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),