summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2021-02-02 14:35:18 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2021-02-16 10:33:04 +0100
commit38d66cab36571de775c395e3831463f7e3f3ab65 (patch)
tree0fa8fe0cfca16dc121ebcde2927894d2c182a705
parent082d530591c41323fa91cb8b5cab41e67e0a84db (diff)
downloadbarebox-38d66cab36571de775c395e3831463f7e3f3ab65.tar.gz
barebox-38d66cab36571de775c395e3831463f7e3f3ab65.tar.xz
watchdog: Print seconds to expire
This adds a parameter to the watchdog devices that shows what we think when the watchdog expires. The watchdog should reset the system once the counter hits zero. When the system resets earlier or the counter shows negative values then there might be problems with the watchdog. Useful for debugging watchdog related problems. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--drivers/watchdog/wd_core.c29
-rw-r--r--include/watchdog.h3
2 files changed, 32 insertions, 0 deletions
diff --git a/drivers/watchdog/wd_core.c b/drivers/watchdog/wd_core.c
index 643c53268f..4b0ee31d5b 100644
--- a/drivers/watchdog/wd_core.c
+++ b/drivers/watchdog/wd_core.c
@@ -54,6 +54,9 @@ int watchdog_set_timeout(struct watchdog *wd, unsigned timeout)
if (ret)
return ret;
+ wd->last_ping = get_time_ns();
+ wd->timeout_cur = timeout;
+
wd->running = timeout ? WDOG_HW_RUNNING : WDOG_HW_NOT_RUNNING;
return 0;
@@ -155,6 +158,25 @@ static unsigned int dev_get_watchdog_priority(struct device_d *dev)
return priority;
}
+static int seconds_to_expire_get(struct param_d *p, void *priv)
+{
+ struct watchdog *wd = priv;
+ uint64_t diff;
+
+ if (!wd->timeout_cur) {
+ wd->seconds_to_expire = -1;
+ return 0;
+ }
+
+ diff = get_time_ns() - wd->last_ping;
+
+ do_div(diff, 1000000000);
+
+ wd->seconds_to_expire = wd->timeout_cur - diff;
+
+ return 0;
+}
+
int watchdog_register(struct watchdog *wd)
{
struct param_d *p;
@@ -218,6 +240,13 @@ int watchdog_register(struct watchdog *wd)
goto error_unregister;
}
+ p = dev_add_param_uint32(&wd->dev, "seconds_to_expire", param_set_readonly,
+ seconds_to_expire_get, &wd->seconds_to_expire, "%d", wd);
+ if (IS_ERR(p)) {
+ ret = PTR_ERR(p);
+ goto error_unregister;
+ }
+
list_add_tail(&wd->list, &watchdog_list);
pr_debug("registering watchdog %s with priority %d\n", watchdog_name(wd),
diff --git a/include/watchdog.h b/include/watchdog.h
index 4d755a5a79..281885686e 100644
--- a/include/watchdog.h
+++ b/include/watchdog.h
@@ -22,8 +22,11 @@ struct watchdog {
struct device_d dev;
unsigned int priority;
unsigned int timeout_max;
+ unsigned int timeout_cur;
unsigned int poller_timeout_cur;
unsigned int poller_enable;
+ uint64_t last_ping;
+ int seconds_to_expire;
struct poller_async poller;
struct list_head list;
int running; /* enum wdog_hw_running */