mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-20 20:04:46 +00:00
watchdog: Integrate watchdog triggering into the cyclic framework
This patch integrates the watchdog triggering into the recently added cyclic infrastructure. Each watchdog device that shall be triggered registers it's own cyclic function. This way, multiple watchdog devices are still supported, each via a cyclic function with separate trigger intervals. Signed-off-by: Stefan Roese <sr@denx.de> Reviewed-by: Simon Glass <sjg@chromium.org> Tested-by: Tom Rini <trini@konsulko.com> [am335x_evm, mx6cuboxi, rpi_3,dra7xx_evm, pine64_plus, am65x_evm, j721e_evm]
This commit is contained in:
parent
d219fc06b3
commit
c2fd0ca1a8
2 changed files with 43 additions and 32 deletions
|
@ -3,6 +3,7 @@ menu "Watchdog Timer Support"
|
||||||
config WATCHDOG
|
config WATCHDOG
|
||||||
bool "Enable U-Boot watchdog reset"
|
bool "Enable U-Boot watchdog reset"
|
||||||
depends on !HW_WATCHDOG
|
depends on !HW_WATCHDOG
|
||||||
|
select CYCLIC
|
||||||
help
|
help
|
||||||
This option enables U-Boot watchdog support where U-Boot is using
|
This option enables U-Boot watchdog support where U-Boot is using
|
||||||
watchdog_reset function to service watchdog device in U-Boot. Enable
|
watchdog_reset function to service watchdog device in U-Boot. Enable
|
||||||
|
@ -74,6 +75,7 @@ config WDT
|
||||||
bool "Enable driver model for watchdog timer drivers"
|
bool "Enable driver model for watchdog timer drivers"
|
||||||
depends on DM
|
depends on DM
|
||||||
imply WATCHDOG
|
imply WATCHDOG
|
||||||
|
select CYCLIC
|
||||||
help
|
help
|
||||||
Enable driver model for watchdog timer. At the moment the API
|
Enable driver model for watchdog timer. At the moment the API
|
||||||
is very simple and only supports four operations:
|
is very simple and only supports four operations:
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#define LOG_CATEGORY UCLASS_WDT
|
#define LOG_CATEGORY UCLASS_WDT
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <cyclic.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <hang.h>
|
#include <hang.h>
|
||||||
|
@ -38,8 +39,25 @@ struct wdt_priv {
|
||||||
bool running;
|
bool running;
|
||||||
/* No autostart */
|
/* No autostart */
|
||||||
bool noautostart;
|
bool noautostart;
|
||||||
|
|
||||||
|
struct cyclic_info *cyclic;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void wdt_cyclic(void *ctx)
|
||||||
|
{
|
||||||
|
struct udevice *dev = ctx;
|
||||||
|
struct wdt_priv *priv;
|
||||||
|
|
||||||
|
if (!device_active(dev))
|
||||||
|
return;
|
||||||
|
|
||||||
|
priv = dev_get_uclass_priv(dev);
|
||||||
|
if (!priv->running)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wdt_reset(dev);
|
||||||
|
}
|
||||||
|
|
||||||
static void init_watchdog_dev(struct udevice *dev)
|
static void init_watchdog_dev(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct wdt_priv *priv;
|
struct wdt_priv *priv;
|
||||||
|
@ -64,9 +82,6 @@ static void init_watchdog_dev(struct udevice *dev)
|
||||||
printf("WDT: Failed to start %s\n", dev->name);
|
printf("WDT: Failed to start %s\n", dev->name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("WDT: Started %s with%s servicing (%ds timeout)\n", dev->name,
|
|
||||||
IS_ENABLED(CONFIG_WATCHDOG) ? "" : "out", priv->timeout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int initr_watchdog(void)
|
int initr_watchdog(void)
|
||||||
|
@ -105,8 +120,29 @@ int wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
|
||||||
ret = ops->start(dev, timeout_ms, flags);
|
ret = ops->start(dev, timeout_ms, flags);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
struct wdt_priv *priv = dev_get_uclass_priv(dev);
|
struct wdt_priv *priv = dev_get_uclass_priv(dev);
|
||||||
|
char str[16];
|
||||||
|
|
||||||
priv->running = true;
|
priv->running = true;
|
||||||
|
|
||||||
|
memset(str, 0, 16);
|
||||||
|
if (IS_ENABLED(CONFIG_WATCHDOG)) {
|
||||||
|
/* Register the watchdog driver as a cyclic function */
|
||||||
|
priv->cyclic = cyclic_register(wdt_cyclic,
|
||||||
|
priv->reset_period * 1000,
|
||||||
|
dev->name, dev);
|
||||||
|
if (!priv->cyclic) {
|
||||||
|
printf("cyclic_register for %s failed\n",
|
||||||
|
dev->name);
|
||||||
|
return -ENODEV;
|
||||||
|
} else {
|
||||||
|
snprintf(str, 16, "every %ldms",
|
||||||
|
priv->reset_period);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("WDT: Started %s with%s servicing %s (%ds timeout)\n",
|
||||||
|
dev->name, IS_ENABLED(CONFIG_WATCHDOG) ? "" : "out",
|
||||||
|
str, priv->timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -194,37 +230,10 @@ int wdt_expire_now(struct udevice *dev, ulong flags)
|
||||||
*/
|
*/
|
||||||
void watchdog_reset(void)
|
void watchdog_reset(void)
|
||||||
{
|
{
|
||||||
struct wdt_priv *priv;
|
|
||||||
struct udevice *dev;
|
|
||||||
struct uclass *uc;
|
|
||||||
ulong now;
|
|
||||||
|
|
||||||
/* Exit if GD is not ready or watchdog is not initialized yet */
|
|
||||||
if (!gd || !(gd->flags & GD_FLG_WDT_READY))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (uclass_get(UCLASS_WDT, &uc))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All devices bound to the wdt uclass should have been probed
|
* Empty function for now. The actual WDT handling is now done in
|
||||||
* in initr_watchdog(). But just in case something went wrong,
|
* the cyclic function instead.
|
||||||
* check device_active() before accessing the uclass private
|
|
||||||
* data.
|
|
||||||
*/
|
*/
|
||||||
uclass_foreach_dev(dev, uc) {
|
|
||||||
if (!device_active(dev))
|
|
||||||
continue;
|
|
||||||
priv = dev_get_uclass_priv(dev);
|
|
||||||
if (!priv->running)
|
|
||||||
continue;
|
|
||||||
/* Do not reset the watchdog too often */
|
|
||||||
now = get_timer(0);
|
|
||||||
if (time_after_eq(now, priv->next_reset)) {
|
|
||||||
priv->next_reset = now + priv->reset_period;
|
|
||||||
wdt_reset(dev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue