mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Ahmad Fatoum <a.fatoum@pengutronix.de>
To: barebox@lists.infradead.org
Cc: Ahmad Fatoum <a.fatoum@pengutronix.de>
Subject: [PATCH v2 2/4] watchdog: implement generic support for .running device parameter
Date: Mon,  4 Nov 2019 23:14:05 +0100	[thread overview]
Message-ID: <20191104221407.14791-2-a.fatoum@pengutronix.de> (raw)
In-Reply-To: <20191104221407.14791-1-a.fatoum@pengutronix.de>

Linux watchdog have an optional WDOG_HW_RUNNING bit that is used in
conjunction with CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED to automatically
ping running watchdogs until userspace takes over.

So far, when we ported Linux drivers, we dropped this detection, but it
would be useful to have this information in barebox as well:

The American Megatrends BIOS I am using allows configuring the hardware
watchdog from the BIOS. barebox enables the WDT as well, so in normal
operation we would never notice if after a BIOS update, the watchdog is
no longer enabled. If we maintain a running parameter on watchdog
devices, board code can be written to check whether the watchdog device
is indeed running.

To achieve this, add the necessary bits to the watchdog API. How we go
about it differs from Linux a little:

- We add a WDOG_HW_RUNNING_SUPPORTED bit to differentiate between
  watchdogs that are not running and watchdogs whose running status is
  unknown.
- Because we can check whether watchdog_hw_running is supported, it now
  can fail and return a negative value in that case
- We do the maintenance of the running parameter after barebox
  feeds/disables the watchdog in the core, so it doesn't need to
  be replicated across drivers. Drivers will only need to initialize the
  bitmask once at probe time.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
v1 -> v2:
  - WDOG_HW_RUNNING: add comment describing use
  - struct watchdog: drop status_supported member in favor of having a
    single WDOG_HW_RUNNING_SUPPORTED bit
  - watchdog_set_timeout: return 0 instead of ret, when we now that ret
    == 0
---
 drivers/watchdog/wd_core.c | 33 ++++++++++++++++++++++++++++++++-
 include/watchdog.h         | 19 +++++++++++++++++++
 2 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/drivers/watchdog/wd_core.c b/drivers/watchdog/wd_core.c
index 39cac6f6c494..034508d4ad73 100644
--- a/drivers/watchdog/wd_core.c
+++ b/drivers/watchdog/wd_core.c
@@ -37,6 +37,8 @@ static const char *watchdog_name(struct watchdog *wd)
  */
 int watchdog_set_timeout(struct watchdog *wd, unsigned timeout)
 {
+	int ret;
+
 	if (!wd)
 		return -ENODEV;
 
@@ -45,7 +47,18 @@ int watchdog_set_timeout(struct watchdog *wd, unsigned timeout)
 
 	pr_debug("setting timeout on %s to %ds\n", watchdog_name(wd), timeout);
 
-	return wd->set_timeout(wd, timeout);
+	ret = wd->set_timeout(wd, timeout);
+	if (ret)
+		return ret;
+
+	if (test_bit(WDOG_HW_RUNNING_SUPPORTED, &wd->status)) {
+		if (timeout)
+			set_bit(WDOG_HW_RUNNING, &wd->status);
+		else
+			clear_bit(WDOG_HW_RUNNING, &wd->status);
+	}
+
+	return 0;
 }
 EXPORT_SYMBOL(watchdog_set_timeout);
 
@@ -118,6 +131,15 @@ static int watchdog_register_poller(struct watchdog *wd)
 	return PTR_ERR_OR_ZERO(p);
 }
 
+static const char *watchdog_get_running(struct device_d *dev, struct param_d *p)
+{
+	/*
+	 * This won't ever fail, because the parameter is only registed when
+	 * test_bit(WDOG_HW_RUNNING_SUPPORTED, &w->status) is true
+	 */
+	return watchdog_hw_running((struct watchdog *)p->value) ? "1" : "0";
+}
+
 static int watchdog_register_dev(struct watchdog *wd, const char *name, int id)
 {
 	wd->dev.parent = wd->hwdev;
@@ -162,6 +184,15 @@ int watchdog_register(struct watchdog *wd)
 	if (ret)
 		return ret;
 
+	if (test_bit(WDOG_HW_RUNNING_SUPPORTED, &wd->status)) {
+		p = dev_add_param(&wd->dev, "running", NULL,
+				  watchdog_get_running, PARAM_FLAG_RO);
+		if (IS_ERR(p))
+			return PTR_ERR(p);
+
+		p->value = (char *)wd;
+	}
+
 	if (!wd->priority)
 		wd->priority = dev_get_watchdog_priority(wd->hwdev);
 
diff --git a/include/watchdog.h b/include/watchdog.h
index 105b7ca81093..25b9d6840922 100644
--- a/include/watchdog.h
+++ b/include/watchdog.h
@@ -15,6 +15,7 @@
 
 #include <poller.h>
 #include <driver.h>
+#include <linux/bitops.h>
 
 struct watchdog {
 	int (*set_timeout)(struct watchdog *, unsigned);
@@ -27,8 +28,26 @@ struct watchdog {
 	unsigned int poller_enable;
 	struct poller_async poller;
 	struct list_head list;
+/* Bit numbers for status flags */
+#define	WDOG_HW_RUNNING			3	/* True if HW watchdog running */
+#define	WDOG_HW_RUNNING_SUPPORTED	31	/* True if querying HW for
+						 * running status is supported
+						 */
+	unsigned long status;
 };
 
+/*
+ * Use the following function to check whether or not the hardware watchdog
+ * is running
+ */
+static inline int watchdog_hw_running(struct watchdog *w)
+{
+	if (!test_bit(WDOG_HW_RUNNING_SUPPORTED, &w->status))
+		return -ENOSYS;
+
+	return !!test_bit(WDOG_HW_RUNNING, &w->status);
+}
+
 #ifdef CONFIG_WATCHDOG
 int watchdog_register(struct watchdog *);
 int watchdog_deregister(struct watchdog *);
-- 
2.24.0.rc1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

  reply	other threads:[~2019-11-04 22:14 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-04 22:14 [PATCH v2 1/4] watchdog: always populate watchdog priority from device tree if possible Ahmad Fatoum
2019-11-04 22:14 ` Ahmad Fatoum [this message]
2019-11-05 10:40   ` [PATCH v2 2/4] watchdog: implement generic support for .running device parameter Sascha Hauer
2019-11-05 10:46     ` Ahmad Fatoum
2019-11-05 10:51       ` Sascha Hauer
2019-11-05 11:10       ` Ahmad Fatoum
2019-11-05 11:18         ` Sascha Hauer
2019-11-08 11:04           ` Ahmad Fatoum
2019-11-04 22:14 ` [PATCH v2 3/4] watchdog: imxwd: support .running device parameter on i.MX2+ Ahmad Fatoum
2019-11-04 22:14 ` [PATCH v2 4/4] watchdog: f71808e: support .running device parameter Ahmad Fatoum

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=20191104221407.14791-2-a.fatoum@pengutronix.de \
    --to=a.fatoum@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