From: Sascha Hauer <s.hauer@pengutronix.de>
To: "open list:BAREBOX" <barebox@lists.infradead.org>
Subject: [PATCH 2/3] watchdog: add watchdog ping support
Date: Tue, 12 Nov 2024 10:16:05 +0100 [thread overview]
Message-ID: <20241112-k3-watchdog-v1-2-ceb254779735@pengutronix.de> (raw)
In-Reply-To: <20241112-k3-watchdog-v1-0-ceb254779735@pengutronix.de>
The barebox watchdog API is quite limited. the set_timeout() hook is an
all purpose function for enabling and disabling the watchdog and also to
configure the timeout.
This is not suitable for watchdogs which for example can't change the
timeout anymore once started.
This patch introduces a watchdog_ping() function which hooks into the
drivers with a struct watchdog::ping function. With this the watchdog
can be pinged without caring about the timeout. The ping hook is
optional. When not implemented watchdog_ping() falls back to call
watchdog_set_timeout() with the current watchdog timeout.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
commands/wd.c | 17 ++++++++++++++++-
drivers/watchdog/wd_core.c | 28 ++++++++++++++++++++++++----
include/watchdog.h | 7 +++++++
3 files changed, 47 insertions(+), 5 deletions(-)
diff --git a/commands/wd.c b/commands/wd.c
index 11f888133a..18e8e03378 100644
--- a/commands/wd.c
+++ b/commands/wd.c
@@ -17,14 +17,18 @@ static int do_wd(int argc, char *argv[])
struct watchdog *wd = watchdog_get_default();
int opt;
int rc;
+ bool do_ping = false;
- while ((opt = getopt(argc, argv, "d:x")) > 0) {
+ while ((opt = getopt(argc, argv, "d:xp")) > 0) {
switch (opt) {
case 'd':
wd = watchdog_get_by_name(optarg);
break;
case 'x':
return watchdog_inhibit_all();
+ case 'p':
+ do_ping = true;
+ break;
default:
return COMMAND_ERROR_USAGE;
}
@@ -39,6 +43,16 @@ static int do_wd(int argc, char *argv[])
}
}
+ if (do_ping) {
+ rc = watchdog_ping(wd);
+ if (rc) {
+ printf("watchdog ping failed: %pe (%d)\n", ERR_PTR(rc), rc);
+ return COMMAND_ERROR;
+ }
+
+ return 0;
+ }
+
rc = watchdog_set_timeout(wd, timeout);
if (rc < 0) {
switch (rc) {
@@ -68,6 +82,7 @@ BAREBOX_CMD_HELP_TEXT("When TIME is 0, the watchdog gets disabled,")
BAREBOX_CMD_HELP_TEXT("Without a parameter the watchdog will be re-triggered.")
BAREBOX_CMD_HELP_TEXT("Options:")
BAREBOX_CMD_HELP_OPT("-d DEVICE\t", "watchdog name (default is highest priority watchdog)")
+BAREBOX_CMD_HELP_OPT("-p\t", "ping watchdog")
BAREBOX_CMD_HELP_OPT("-x\t", "inhibit all watchdogs (i.e. disable or autopoll if possible)")
BAREBOX_CMD_HELP_END
diff --git a/drivers/watchdog/wd_core.c b/drivers/watchdog/wd_core.c
index 663a6e5c75..27371672f3 100644
--- a/drivers/watchdog/wd_core.c
+++ b/drivers/watchdog/wd_core.c
@@ -57,6 +57,29 @@ int watchdog_set_timeout(struct watchdog *wd, unsigned timeout)
}
EXPORT_SYMBOL(watchdog_set_timeout);
+int watchdog_ping(struct watchdog *wd)
+{
+ int ret;
+
+ if (!wd)
+ return -ENODEV;
+
+ if (!watchdog_hw_running(wd))
+ return 0;
+
+ if (wd->ping) {
+ ret = wd->ping(wd);
+ if (!ret)
+ wd->last_ping = get_time_ns();
+ } else {
+ if (!wd->timeout_cur)
+ wd->timeout_cur = wd->timeout_max;
+ ret = watchdog_set_timeout(wd, wd->timeout_cur);
+ }
+
+ return ret;
+}
+
static int watchdog_set_priority(struct param_d *param, void *priv)
{
struct watchdog *wd = priv;
@@ -78,11 +101,8 @@ static void watchdog_poller_cb(void *priv);
static void watchdog_poller_start(struct watchdog *wd)
{
- unsigned int timeout_s;
-
- timeout_s = wd->timeout_cur ?: wd->timeout_max;
+ watchdog_ping(wd);
- watchdog_set_timeout(wd, timeout_s);
poller_call_async(&wd->poller, 500 * MSECOND,
watchdog_poller_cb, wd);
diff --git a/include/watchdog.h b/include/watchdog.h
index 8084f27596..c70883fbd0 100644
--- a/include/watchdog.h
+++ b/include/watchdog.h
@@ -17,6 +17,7 @@ struct device_node;
struct watchdog {
int (*set_timeout)(struct watchdog *, unsigned);
+ int (*ping)(struct watchdog *);
const char *name;
struct device *hwdev;
struct device dev;
@@ -49,6 +50,7 @@ struct watchdog *watchdog_get_default(void);
struct watchdog *watchdog_get_by_name(const char *name);
int watchdog_get_alias_id_from(struct watchdog *, struct device_node *);
int watchdog_set_timeout(struct watchdog*, unsigned);
+int watchdog_ping(struct watchdog *);
int watchdog_inhibit_all(void);
#else
static inline int watchdog_register(struct watchdog *w)
@@ -76,6 +78,11 @@ static inline int watchdog_set_timeout(struct watchdog*w, unsigned t)
return 0;
}
+static inline int watchdog_ping(struct watchdog *)
+{
+ return 0;
+}
+
static inline int watchdog_inhibit_all(void)
{
return -ENOSYS;
--
2.39.5
next prev parent reply other threads:[~2024-11-12 9:16 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-12 9:16 [PATCH 0/3] watchdog: Add TI rti_wdg support Sascha Hauer
2024-11-12 9:16 ` [PATCH 1/3] watchdog: cleanup timeout_cur parameter Sascha Hauer
2024-11-12 9:16 ` Sascha Hauer [this message]
2024-11-12 9:16 ` [PATCH 3/3] watchdog: add rti_wdt support Sascha Hauer
2024-11-13 11:33 ` [PATCH 0/3] watchdog: Add TI rti_wdg support Sascha Hauer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241112-k3-watchdog-v1-2-ceb254779735@pengutronix.de \
--to=s.hauer@pengutronix.de \
--cc=barebox@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox