summaryrefslogtreecommitdiff
path: root/drivers/watchdog
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2022-10-03 22:39:46 +0300
committerTom Rini <trini@konsulko.com>2022-10-03 22:39:46 +0300
commit2d4591353452638132d711551fec3495b7644731 (patch)
treee12058de7f553e84f8d13e545f130c7a48973589 /drivers/watchdog
parent4debc57a3da6c3f4d3f89a637e99206f4cea0a96 (diff)
parent6ee6e15975cad3c99fad3a66223f3fd9287a369b (diff)
downloadu-boot-2d4591353452638132d711551fec3495b7644731.tar.xz
Merge branch 'next'
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/Kconfig2
-rw-r--r--drivers/watchdog/mtk_wdt.c1
-rw-r--r--drivers/watchdog/wdt-uclass.c73
3 files changed, 44 insertions, 32 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 50e6a1efba..e55deaf906 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -3,6 +3,7 @@ menu "Watchdog Timer Support"
config WATCHDOG
bool "Enable U-Boot watchdog reset"
depends on !HW_WATCHDOG
+ select CYCLIC
help
This option enables U-Boot watchdog support where U-Boot is using
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"
depends on DM
imply WATCHDOG
+ select CYCLIC
help
Enable driver model for watchdog timer. At the moment the API
is very simple and only supports four operations:
diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
index b098b2e3cf..368b36849c 100644
--- a/drivers/watchdog/mtk_wdt.c
+++ b/drivers/watchdog/mtk_wdt.c
@@ -145,6 +145,7 @@ static const struct wdt_ops mtk_wdt_ops = {
static const struct udevice_id mtk_wdt_ids[] = {
{ .compatible = "mediatek,wdt"},
{ .compatible = "mediatek,mt6589-wdt"},
+ { .compatible = "mediatek,mt7986-wdt" },
{}
};
diff --git a/drivers/watchdog/wdt-uclass.c b/drivers/watchdog/wdt-uclass.c
index dbf556467d..3f342cd99f 100644
--- a/drivers/watchdog/wdt-uclass.c
+++ b/drivers/watchdog/wdt-uclass.c
@@ -6,6 +6,7 @@
#define LOG_CATEGORY UCLASS_WDT
#include <common.h>
+#include <cyclic.h>
#include <dm.h>
#include <errno.h>
#include <hang.h>
@@ -38,8 +39,25 @@ struct wdt_priv {
bool running;
/* No autostart */
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)
{
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);
return;
}
-
- printf("WDT: Started %s with%s servicing (%ds timeout)\n", dev->name,
- IS_ENABLED(CONFIG_WATCHDOG) ? "" : "out", priv->timeout);
}
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);
if (ret == 0) {
struct wdt_priv *priv = dev_get_uclass_priv(dev);
+ char str[16];
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;
@@ -194,37 +230,10 @@ int wdt_expire_now(struct udevice *dev, ulong flags)
*/
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
- * in initr_watchdog(). But just in case something went wrong,
- * check device_active() before accessing the uclass private
- * data.
+ * Empty function for now. The actual WDT handling is now done in
+ * the cyclic function instead.
*/
- 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