]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
watchdog: Automatically register device with sysreset
authorSamuel Holland <samuel@sholland.org>
Thu, 4 Nov 2021 03:55:14 +0000 (22:55 -0500)
committerStefan Roese <sr@denx.de>
Thu, 4 Nov 2021 07:57:19 +0000 (08:57 +0100)
Add an option to automatically register watchdog devices with the
wdt_reboot driver for use with sysreset. This allows sysreset to be a
drop-in replacement for platform-specific watchdog reset code, without
needing any device tree changes.

Signed-off-by: Samuel Holland <samuel@sholland.org>
Reviewed-by: Stefan Roese <sr@denx.de>
drivers/sysreset/Kconfig
drivers/sysreset/sysreset_watchdog.c
drivers/watchdog/wdt-uclass.c
include/sysreset.h

index de75c9cccc5069df947720de44bb02b6d5fa2297..f6d60038b897307cac940d87de82d6c3bf56c5e8 100644 (file)
@@ -131,6 +131,13 @@ config SYSRESET_WATCHDOG
        help
          Reboot support for generic watchdog reset.
 
+config SYSRESET_WATCHDOG_AUTO
+       bool "Automatically register first watchdog with sysreset"
+       depends on SYSRESET_WATCHDOG
+       help
+         If enabled, the first watchdog (as selected by the watchdog uclass)
+         will automatically be registered with the watchdog reboot driver.
+
 config SYSRESET_RESETCTL
        bool "Enable support for reset controller reboot driver"
        select DM_RESET
index b723f5647cd37280a6a0893b46733972d26c836a..35efcac59dda973387d3d92c7d06439b75ae25df 100644 (file)
@@ -5,7 +5,9 @@
 
 #include <common.h>
 #include <dm.h>
+#include <dm/device-internal.h>
 #include <errno.h>
+#include <malloc.h>
 #include <sysreset.h>
 #include <wdt.h>
 
@@ -57,3 +59,25 @@ U_BOOT_DRIVER(wdt_reboot) = {
        .plat_auto      = sizeof(struct wdt_reboot_plat),
        .ops = &wdt_reboot_ops,
 };
+
+#if IS_ENABLED(CONFIG_SYSRESET_WATCHDOG_AUTO)
+int sysreset_register_wdt(struct udevice *dev)
+{
+       struct wdt_reboot_plat *plat = malloc(sizeof(*plat));
+       int ret;
+
+       if (!plat)
+               return -ENOMEM;
+
+       plat->wdt = dev;
+
+       ret = device_bind(dev, DM_DRIVER_GET(wdt_reboot),
+                         dev->name, plat, ofnode_null(), NULL);
+       if (ret) {
+               free(plat);
+               return ret;
+       }
+
+       return 0;
+}
+#endif
index 7570710c4d91aa400af3243a92731a64d8c3bad5..6d0f4738676fdad152b9ceff297aa971cb4ca812 100644 (file)
@@ -10,6 +10,7 @@
 #include <errno.h>
 #include <hang.h>
 #include <log.h>
+#include <sysreset.h>
 #include <time.h>
 #include <wdt.h>
 #include <asm/global_data.h>
@@ -44,6 +45,13 @@ static void init_watchdog_dev(struct udevice *dev)
 
        priv = dev_get_uclass_priv(dev);
 
+       if (IS_ENABLED(CONFIG_SYSRESET_WATCHDOG_AUTO)) {
+               ret = sysreset_register_wdt(dev);
+               if (ret)
+                       printf("WDT:   Failed to register %s for sysreset\n",
+                              dev->name);
+       }
+
        if (!IS_ENABLED(CONFIG_WATCHDOG_AUTOSTART)) {
                printf("WDT:   Not starting %s\n", dev->name);
                return;
index 9d4ed87ceafbf41b8636a97f061ea770a597c921..ff20abdeed3cfd7d7dde8a3891ca156f04beb8b8 100644 (file)
@@ -133,4 +133,14 @@ void sysreset_walk_halt(enum sysreset_t type);
  */
 void reset_cpu(void);
 
+/**
+ * sysreset_register_wdt() - register a watchdog for use with sysreset
+ *
+ * This registers the given watchdog timer to be used to reset the system.
+ *
+ * @dev:       WDT device
+ * @return:    0 if OK, -errno if error
+ */
+int sysreset_register_wdt(struct udevice *dev);
+
 #endif