summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAhmad Fatoum <a.fatoum@pengutronix.de>2020-06-22 17:15:25 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2020-06-23 10:23:54 +0200
commit2863db306e02b14c31dd7ea1fa4857bc3675e42c (patch)
treeb6cb1d3696ee2feeaba16a1d214ac58ded0ed2c6
parent0b944fce55f4750000a6a0df477034a9e4971b6f (diff)
downloadbarebox-2863db306e02b14c31dd7ea1fa4857bc3675e42c.tar.gz
barebox-2863db306e02b14c31dd7ea1fa4857bc3675e42c.tar.xz
startup: inhibit watchdogs on non-interactive autoboot abort
nv.autoboot=abort has been added as development aid to have barebox stop at the shell prompt automatically. It makes sense to inhibit all watchdogs in this mode, so the user can later use the shell in peace. This also applies to fastboot aborting the shell prompt. If this happens, watchdog will be automatically inhibited as well. Behavior on user aborting the shell prompt via keypad or uart input remains unchanged for backwards-compatibility. Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--common/startup.c4
-rw-r--r--drivers/watchdog/wd_core.c27
-rw-r--r--include/watchdog.h6
3 files changed, 37 insertions, 0 deletions
diff --git a/common/startup.c b/common/startup.c
index 511675ed55..fa66fe086e 100644
--- a/common/startup.c
+++ b/common/startup.c
@@ -43,6 +43,7 @@
#include <console_countdown.h>
#include <environment.h>
#include <linux/ctype.h>
+#include <watchdog.h>
extern initcall_t __barebox_initcalls_start[], __barebox_early_initcalls_end[],
__barebox_initcalls_end[];
@@ -351,6 +352,9 @@ static int run_init(void)
if (autoboot == AUTOBOOT_MENU)
run_command(MENUFILE);
+ if (autoboot == AUTOBOOT_ABORT && autoboot == global_autoboot_state)
+ watchdog_inhibit_all();
+
run_shell();
run_command(MENUFILE);
diff --git a/drivers/watchdog/wd_core.c b/drivers/watchdog/wd_core.c
index 377fd2378a..ab1dcaa40a 100644
--- a/drivers/watchdog/wd_core.c
+++ b/drivers/watchdog/wd_core.c
@@ -276,3 +276,30 @@ struct watchdog *watchdog_get_by_name(const char *name)
return NULL;
}
EXPORT_SYMBOL(watchdog_get_by_name);
+
+int watchdog_inhibit_all(void)
+{
+ struct watchdog *wd;
+ int ret = 0;
+
+ list_for_each_entry(wd, &watchdog_list, list) {
+ int err;
+ if (!wd->priority || watchdog_hw_running(wd) == false)
+ continue;
+
+ err = watchdog_set_timeout(wd, 0);
+ if (!err)
+ continue;
+
+ if (err != -ENOSYS || !IS_ENABLED(CONFIG_WATCHDOG_POLLER)) {
+ ret = err;
+ continue;
+ }
+
+ wd->poller_enable = true;
+ watchdog_poller_start(wd);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(watchdog_inhibit_all);
diff --git a/include/watchdog.h b/include/watchdog.h
index 419c1cdf46..81414ef8ec 100644
--- a/include/watchdog.h
+++ b/include/watchdog.h
@@ -45,6 +45,7 @@ int watchdog_deregister(struct watchdog *);
struct watchdog *watchdog_get_default(void);
struct watchdog *watchdog_get_by_name(const char *name);
int watchdog_set_timeout(struct watchdog*, unsigned);
+int watchdog_inhibit_all(void);
#else
static inline int watchdog_register(struct watchdog *w)
{
@@ -70,6 +71,11 @@ static inline int watchdog_set_timeout(struct watchdog*w, unsigned t)
{
return 0;
}
+
+static inline int watchdog_inhibit_all(void)
+{
+ return -ENOSYS;
+}
#endif
#define WATCHDOG_DEFAULT_PRIORITY 100