aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2021-11-04 09:14:19 -0400
committerTom Rini <trini@konsulko.com>2021-11-04 09:14:19 -0400
commit2a5ad542e6c238ff5c0b490b49354e780ab46d71 (patch)
tree52890055abf902ec90e4abdb0fe7adac441f7887
parentbc18582a1471384e3c4584dfd17f48a91c88445d (diff)
parent40edc320b16271a725876b1b6f875cbd342c6582 (diff)
downloadu-boot-2a5ad542e6c238ff5c0b490b49354e780ab46d71.zip
u-boot-2a5ad542e6c238ff5c0b490b49354e780ab46d71.tar.gz
u-boot-2a5ad542e6c238ff5c0b490b49354e780ab46d71.tar.bz2
Merge https://source.denx.de/u-boot/custodians/u-boot-marvellWIP/04Nov2021
- Improved sysreset/watchdog uclass integration (Samuel)
-rw-r--r--arch/arm/Kconfig3
-rw-r--r--arch/arm/mach-sunxi/board.c2
-rw-r--r--drivers/sysreset/Kconfig11
-rw-r--r--drivers/sysreset/sysreset_gpio.c2
-rw-r--r--drivers/sysreset/sysreset_resetctl.c2
-rw-r--r--drivers/sysreset/sysreset_syscon.c2
-rw-r--r--drivers/sysreset/sysreset_watchdog.c40
-rw-r--r--drivers/watchdog/wdt-uclass.c8
-rw-r--r--include/sysreset.h10
9 files changed, 67 insertions, 13 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b4808d4..ae911d6 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1084,6 +1084,9 @@ config ARCH_SUNXI
imply SPL_MMC if MMC
imply SPL_POWER
imply SPL_SERIAL
+ imply SYSRESET
+ imply SYSRESET_WATCHDOG
+ imply SYSRESET_WATCHDOG_AUTO
imply USB_GADGET
imply WDT
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index b4ba2a7..3ef1797 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -346,6 +346,7 @@ void board_init_f(ulong dummy)
}
#endif
+#if !CONFIG_IS_ENABLED(SYSRESET)
void reset_cpu(void)
{
#if defined(CONFIG_SUNXI_GEN_SUN4I) || defined(CONFIG_MACH_SUN8I_R40)
@@ -376,6 +377,7 @@ void reset_cpu(void)
while (1) { }
#endif
}
+#endif
#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) && !defined(CONFIG_ARM64)
void enable_caches(void)
diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig
index 43a948c..f6d6003 100644
--- a/drivers/sysreset/Kconfig
+++ b/drivers/sysreset/Kconfig
@@ -118,8 +118,6 @@ config SYSRESET_TI_SCI
This enables the system reset driver support over TI System Control
Interface available on some new TI's SoCs.
-endif
-
config SYSRESET_SYSCON
bool "Enable support for mfd syscon reboot driver"
select REGMAP
@@ -133,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
@@ -162,4 +167,6 @@ config SYSRESET_MPC83XX
help
Reboot support for NXP MPC83xx SoCs.
+endif
+
endmenu
diff --git a/drivers/sysreset/sysreset_gpio.c b/drivers/sysreset/sysreset_gpio.c
index 680b759..dfca10c 100644
--- a/drivers/sysreset/sysreset_gpio.c
+++ b/drivers/sysreset/sysreset_gpio.c
@@ -33,7 +33,7 @@ static struct sysreset_ops gpio_reboot_ops = {
.request = gpio_reboot_request,
};
-int gpio_reboot_probe(struct udevice *dev)
+static int gpio_reboot_probe(struct udevice *dev)
{
struct gpio_reboot_priv *priv = dev_get_priv(dev);
diff --git a/drivers/sysreset/sysreset_resetctl.c b/drivers/sysreset/sysreset_resetctl.c
index c039521..25bd5c9 100644
--- a/drivers/sysreset/sysreset_resetctl.c
+++ b/drivers/sysreset/sysreset_resetctl.c
@@ -26,7 +26,7 @@ static struct sysreset_ops resetctl_reboot_ops = {
.request = resetctl_reboot_request,
};
-int resetctl_reboot_probe(struct udevice *dev)
+static int resetctl_reboot_probe(struct udevice *dev)
{
struct resetctl_reboot_priv *priv = dev_get_priv(dev);
diff --git a/drivers/sysreset/sysreset_syscon.c b/drivers/sysreset/sysreset_syscon.c
index 28fdfb0..525faf2 100644
--- a/drivers/sysreset/sysreset_syscon.c
+++ b/drivers/sysreset/sysreset_syscon.c
@@ -39,7 +39,7 @@ static struct sysreset_ops syscon_reboot_ops = {
.request = syscon_reboot_request,
};
-int syscon_reboot_probe(struct udevice *dev)
+static int syscon_reboot_probe(struct udevice *dev)
{
struct syscon_reboot_priv *priv = dev_get_priv(dev);
int err;
diff --git a/drivers/sysreset/sysreset_watchdog.c b/drivers/sysreset/sysreset_watchdog.c
index 0dc2d8b..35efcac 100644
--- a/drivers/sysreset/sysreset_watchdog.c
+++ b/drivers/sysreset/sysreset_watchdog.c
@@ -5,20 +5,22 @@
#include <common.h>
#include <dm.h>
+#include <dm/device-internal.h>
#include <errno.h>
+#include <malloc.h>
#include <sysreset.h>
#include <wdt.h>
-struct wdt_reboot_priv {
+struct wdt_reboot_plat {
struct udevice *wdt;
};
static int wdt_reboot_request(struct udevice *dev, enum sysreset_t type)
{
- struct wdt_reboot_priv *priv = dev_get_priv(dev);
+ struct wdt_reboot_plat *plat = dev_get_plat(dev);
int ret;
- ret = wdt_expire_now(priv->wdt, 0);
+ ret = wdt_expire_now(plat->wdt, 0);
if (ret)
return ret;
@@ -29,13 +31,13 @@ static struct sysreset_ops wdt_reboot_ops = {
.request = wdt_reboot_request,
};
-int wdt_reboot_probe(struct udevice *dev)
+static int wdt_reboot_of_to_plat(struct udevice *dev)
{
- struct wdt_reboot_priv *priv = dev_get_priv(dev);
+ struct wdt_reboot_plat *plat = dev_get_plat(dev);
int err;
err = uclass_get_device_by_phandle(UCLASS_WDT, dev,
- "wdt", &priv->wdt);
+ "wdt", &plat->wdt);
if (err) {
pr_err("unable to find wdt device\n");
return err;
@@ -53,7 +55,29 @@ U_BOOT_DRIVER(wdt_reboot) = {
.name = "wdt_reboot",
.id = UCLASS_SYSRESET,
.of_match = wdt_reboot_ids,
+ .of_to_plat = wdt_reboot_of_to_plat,
+ .plat_auto = sizeof(struct wdt_reboot_plat),
.ops = &wdt_reboot_ops,
- .priv_auto = sizeof(struct wdt_reboot_priv),
- .probe = wdt_reboot_probe,
};
+
+#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 7570710..6d0f473 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 9d4ed87..ff20abd 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