diff options
-rw-r--r-- | common/Kconfig | 10 | ||||
-rw-r--r-- | common/boot.c | 16 | ||||
-rw-r--r-- | common/oftree.c | 25 | ||||
-rw-r--r-- | include/boot.h | 3 |
4 files changed, 51 insertions, 3 deletions
diff --git a/common/Kconfig b/common/Kconfig index ffdce2f96c..d1baee60e6 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -1007,6 +1007,16 @@ config MACHINE_ID Note: if no hashable information is available no machine id will be passed to the kernel. +config SYSTEMD_OF_WATCHDOG + bool "inform devicetree-enabled kernel of used watchdog" + depends on WATCHDOG && OFTREE && FLEXIBLE_BOOTARGS + help + Sets the linux.bootargs.dyn.watchdog global variable with a value of + systemd.watchdog-device=/dev/WDOG if barebox succeeded in enabling + the watchdog WDOG prior to boot. WDOG is the alias of the watchdog + in the kernel device tree. If the kernel is booted without a device + tree or with one that lacks aliases, nothing is added. + menu "OP-TEE loading" config OPTEE_SIZE diff --git a/common/boot.c b/common/boot.c index c6ec22873d..1657608d33 100644 --- a/common/boot.c +++ b/common/boot.c @@ -116,6 +116,13 @@ void boot_set_watchdog_timeout(unsigned int timeout) boot_watchdog_timeout = timeout; } +static struct watchdog *boot_enabled_watchdog; + +struct watchdog *boot_get_enabled_watchdog(void) +{ + return boot_enabled_watchdog; +} + static char *global_boot_default; static char *global_user; @@ -143,10 +150,13 @@ int boot_entry(struct bootentry *be, int verbose, int dryrun) printf("Booting entry '%s'\n", be->title); if (IS_ENABLED(CONFIG_WATCHDOG) && boot_watchdog_timeout) { - ret = watchdog_set_timeout(watchdog_get_default(), - boot_watchdog_timeout); - if (ret) + boot_enabled_watchdog = watchdog_get_default(); + + ret = watchdog_set_timeout(boot_enabled_watchdog, boot_watchdog_timeout); + if (ret) { pr_warn("Failed to enable watchdog: %s\n", strerror(-ret)); + boot_enabled_watchdog = NULL; + } } ret = be->boot(be, verbose, dryrun); diff --git a/common/oftree.c b/common/oftree.c index 36906e86fc..075b9d6b8b 100644 --- a/common/oftree.c +++ b/common/oftree.c @@ -14,6 +14,8 @@ #include <bootsource.h> #include <i2c/i2c.h> #include <reset_source.h> +#include <watchdog.h> +#include <globalvar.h> #define MAX_LEVEL 32 /* how deeply nested we will go */ @@ -139,6 +141,26 @@ static int of_fixup_bootargs_bootsource(struct device_node *root, return ret; } +static void watchdog_build_bootargs(struct watchdog *watchdog, struct device_node *root) +{ + int alias_id; + char *buf; + + if (!watchdog) + return; + + alias_id = watchdog_get_alias_id_from(watchdog, root); + if (alias_id < 0) + return; + + buf = basprintf("systemd.watchdog-device=/dev/watchdog%d", alias_id); + if (!buf) + return; + + globalvar_add_simple("linux.bootargs.dyn.watchdog", buf); + free(buf); +} + static int of_fixup_bootargs(struct device_node *root, void *unused) { struct device_node *node; @@ -147,6 +169,9 @@ static int of_fixup_bootargs(struct device_node *root, void *unused) int instance = reset_source_get_instance(); struct device_d *dev; + if (IS_ENABLED(CONFIG_SYSTEMD_OF_WATCHDOG)) + watchdog_build_bootargs(boot_get_enabled_watchdog(), root); + str = linux_bootargs_get(); if (!str) return 0; diff --git a/include/boot.h b/include/boot.h index 4054c27d93..3d5dd1cb6e 100644 --- a/include/boot.h +++ b/include/boot.h @@ -42,7 +42,10 @@ int bootentry_register_provider(int (*fn)(struct bootentries *bootentries, const #define bootentries_for_each_entry(bootentries, entry) \ list_for_each_entry(entry, &bootentries->entries, list) +struct watchdog; + void boot_set_watchdog_timeout(unsigned int timeout); +struct watchdog *boot_get_enabled_watchdog(void); struct bootentries *bootentries_alloc(void); void bootentries_free(struct bootentries *bootentries); int bootentry_create_from_name(struct bootentries *bootentries, |