Browse Source

Merge https://source.denx.de/u-boot/custodians/u-boot-marvell

- Improved sysreset/watchdog uclass integration (Samuel)
Tom Rini 2 years ago
parent
commit
2a5ad542e6

+ 3 - 0
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
 

+ 2 - 0
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)

+ 9 - 2
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

+ 1 - 1
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);
 

+ 1 - 1
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);
 

+ 1 - 1
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;

+ 32 - 8
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

+ 8 - 0
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;

+ 10 - 0
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