summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/Kconfig10
-rw-r--r--common/boot.c16
-rw-r--r--common/oftree.c25
-rw-r--r--include/boot.h3
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,