
On 04.11.21 04:55, Samuel Holland wrote:
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
Thanks, Stefan
Changes in v3:
- Move condition to wdt-uclass.c to fix build errors.
- Include watchdog name in error message.
Changes in v2:
- Rebase on top of 492ee6b8d0e7 (now handle all watchdogs).
drivers/sysreset/Kconfig | 7 +++++++ drivers/sysreset/sysreset_watchdog.c | 24 ++++++++++++++++++++++++ drivers/watchdog/wdt-uclass.c | 8 ++++++++ include/sysreset.h | 10 ++++++++++ 4 files changed, 49 insertions(+)
diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig index de75c9cccc..f6d60038b8 100644 --- a/drivers/sysreset/Kconfig +++ b/drivers/sysreset/Kconfig @@ -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
diff --git a/drivers/sysreset/sysreset_watchdog.c b/drivers/sysreset/sysreset_watchdog.c index b723f5647c..35efcac59d 100644 --- a/drivers/sysreset/sysreset_watchdog.c +++ b/drivers/sysreset/sysreset_watchdog.c @@ -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 diff --git a/drivers/watchdog/wdt-uclass.c b/drivers/watchdog/wdt-uclass.c index 7570710c4d..6d0f473867 100644 --- a/drivers/watchdog/wdt-uclass.c +++ b/drivers/watchdog/wdt-uclass.c @@ -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;
diff --git a/include/sysreset.h b/include/sysreset.h index 9d4ed87cea..ff20abdeed 100644 --- a/include/sysreset.h +++ b/include/sysreset.h @@ -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
Viele Grüße, Stefan