- Improved sysreset/watchdog uclass integration (Samuel)
This commit is contained in:
Tom Rini 2021-11-04 09:14:19 -04:00
commit 2a5ad542e6
9 changed files with 67 additions and 13 deletions

View File

@ -1084,6 +1084,9 @@ config ARCH_SUNXI
imply SPL_MMC if MMC imply SPL_MMC if MMC
imply SPL_POWER imply SPL_POWER
imply SPL_SERIAL imply SPL_SERIAL
imply SYSRESET
imply SYSRESET_WATCHDOG
imply SYSRESET_WATCHDOG_AUTO
imply USB_GADGET imply USB_GADGET
imply WDT imply WDT

View File

@ -346,6 +346,7 @@ void board_init_f(ulong dummy)
} }
#endif #endif
#if !CONFIG_IS_ENABLED(SYSRESET)
void reset_cpu(void) void reset_cpu(void)
{ {
#if defined(CONFIG_SUNXI_GEN_SUN4I) || defined(CONFIG_MACH_SUN8I_R40) #if defined(CONFIG_SUNXI_GEN_SUN4I) || defined(CONFIG_MACH_SUN8I_R40)
@ -376,6 +377,7 @@ void reset_cpu(void)
while (1) { } while (1) { }
#endif #endif
} }
#endif
#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) && !defined(CONFIG_ARM64) #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) && !defined(CONFIG_ARM64)
void enable_caches(void) void enable_caches(void)

View File

@ -118,8 +118,6 @@ config SYSRESET_TI_SCI
This enables the system reset driver support over TI System Control This enables the system reset driver support over TI System Control
Interface available on some new TI's SoCs. Interface available on some new TI's SoCs.
endif
config SYSRESET_SYSCON config SYSRESET_SYSCON
bool "Enable support for mfd syscon reboot driver" bool "Enable support for mfd syscon reboot driver"
select REGMAP select REGMAP
@ -133,6 +131,13 @@ config SYSRESET_WATCHDOG
help help
Reboot support for generic watchdog reset. 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 config SYSRESET_RESETCTL
bool "Enable support for reset controller reboot driver" bool "Enable support for reset controller reboot driver"
select DM_RESET select DM_RESET
@ -162,4 +167,6 @@ config SYSRESET_MPC83XX
help help
Reboot support for NXP MPC83xx SoCs. Reboot support for NXP MPC83xx SoCs.
endif
endmenu endmenu

View File

@ -33,7 +33,7 @@ static struct sysreset_ops gpio_reboot_ops = {
.request = gpio_reboot_request, .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); struct gpio_reboot_priv *priv = dev_get_priv(dev);

View File

@ -26,7 +26,7 @@ static struct sysreset_ops resetctl_reboot_ops = {
.request = resetctl_reboot_request, .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); struct resetctl_reboot_priv *priv = dev_get_priv(dev);

View File

@ -39,7 +39,7 @@ static struct sysreset_ops syscon_reboot_ops = {
.request = syscon_reboot_request, .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); struct syscon_reboot_priv *priv = dev_get_priv(dev);
int err; int err;

View File

@ -5,20 +5,22 @@
#include <common.h> #include <common.h>
#include <dm.h> #include <dm.h>
#include <dm/device-internal.h>
#include <errno.h> #include <errno.h>
#include <malloc.h>
#include <sysreset.h> #include <sysreset.h>
#include <wdt.h> #include <wdt.h>
struct wdt_reboot_priv { struct wdt_reboot_plat {
struct udevice *wdt; struct udevice *wdt;
}; };
static int wdt_reboot_request(struct udevice *dev, enum sysreset_t type) 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; int ret;
ret = wdt_expire_now(priv->wdt, 0); ret = wdt_expire_now(plat->wdt, 0);
if (ret) if (ret)
return ret; return ret;
@ -29,13 +31,13 @@ static struct sysreset_ops wdt_reboot_ops = {
.request = wdt_reboot_request, .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; int err;
err = uclass_get_device_by_phandle(UCLASS_WDT, dev, err = uclass_get_device_by_phandle(UCLASS_WDT, dev,
"wdt", &priv->wdt); "wdt", &plat->wdt);
if (err) { if (err) {
pr_err("unable to find wdt device\n"); pr_err("unable to find wdt device\n");
return err; return err;
@ -53,7 +55,29 @@ U_BOOT_DRIVER(wdt_reboot) = {
.name = "wdt_reboot", .name = "wdt_reboot",
.id = UCLASS_SYSRESET, .id = UCLASS_SYSRESET,
.of_match = wdt_reboot_ids, .of_match = wdt_reboot_ids,
.of_to_plat = wdt_reboot_of_to_plat,
.plat_auto = sizeof(struct wdt_reboot_plat),
.ops = &wdt_reboot_ops, .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

View File

@ -10,6 +10,7 @@
#include <errno.h> #include <errno.h>
#include <hang.h> #include <hang.h>
#include <log.h> #include <log.h>
#include <sysreset.h>
#include <time.h> #include <time.h>
#include <wdt.h> #include <wdt.h>
#include <asm/global_data.h> #include <asm/global_data.h>
@ -44,6 +45,13 @@ static void init_watchdog_dev(struct udevice *dev)
priv = dev_get_uclass_priv(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)) { if (!IS_ENABLED(CONFIG_WATCHDOG_AUTOSTART)) {
printf("WDT: Not starting %s\n", dev->name); printf("WDT: Not starting %s\n", dev->name);
return; return;

View File

@ -133,4 +133,14 @@ void sysreset_walk_halt(enum sysreset_t type);
*/ */
void reset_cpu(void); 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 #endif