diff mbox series

[v5,07/12] watchdog: wdt-uclass.c: add wdt_stop_all() helper

Message ID 20210811124800.2593226-8-rasmus.villemoes@prevas.dk
State Changes Requested
Delegated to: Stefan Roese
Headers show
Series handling all DM watchdogs in watchdog_reset() | expand

Commit Message

Rasmus Villemoes Aug. 11, 2021, 12:47 p.m. UTC
Since the watchdog_dev member of struct global_data is going away in
favor of the wdt-uclass handling all watchdog devices, prepare for
that by adding a helper to call wdt_stop() on all known devices.

Initially, this will only be used in one single
place (board/alliedtelesis/x530/x530.c), and that user currently
ignores the return value of wdt_stop(). It's not clear what one should
do if we encounter an error (remember the error but still stop the
remaining ones? return immediately? try to unwind and
restart the devices already stopped?). Moreover, some watchdogs are by
design always-running (and don't have a ->stop method at all), so at
the very least some exception for -ENOSYS would be in order.

So for now, and until a real use case appears from which we can decide
the desired semantics, have the function return void and just emit a
log_debug() if an error is encountered.

Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
---
 drivers/watchdog/wdt-uclass.c | 25 +++++++++++++++++++++++++
 include/wdt.h                 |  5 +++++
 2 files changed, 30 insertions(+)
diff mbox series

Patch

diff --git a/drivers/watchdog/wdt-uclass.c b/drivers/watchdog/wdt-uclass.c
index 358fc68e27..75ff4c2a6c 100644
--- a/drivers/watchdog/wdt-uclass.c
+++ b/drivers/watchdog/wdt-uclass.c
@@ -116,6 +116,31 @@  int wdt_stop(struct udevice *dev)
 	return ret;
 }
 
+void wdt_stop_all(void)
+{
+	struct wdt_priv *priv;
+	struct udevice *dev;
+	struct uclass *uc;
+	int ret;
+
+	ret = uclass_get(UCLASS_WDT, &uc);
+	if (ret) {
+		log_debug("Error getting UCLASS_WDT: %d\n", ret);
+		return;
+	}
+
+	uclass_foreach_dev(dev, uc) {
+		if (!device_active(dev))
+			continue;
+		priv = dev_get_uclass_priv(dev);
+		if (!priv->running)
+			continue;
+		ret = wdt_stop(dev);
+		if (ret)
+			log_debug("wdt_stop(%s) failed: %d\n", dev->name, ret);
+	}
+}
+
 int wdt_reset(struct udevice *dev)
 {
 	const struct wdt_ops *ops = device_get_ops(dev);
diff --git a/include/wdt.h b/include/wdt.h
index bc242c2eb2..5ab5cecbe0 100644
--- a/include/wdt.h
+++ b/include/wdt.h
@@ -37,6 +37,11 @@  int wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags);
  */
 int wdt_stop(struct udevice *dev);
 
+/*
+ * Stop all registered watchdog devices.
+ */
+void wdt_stop_all(void);
+
 /*
  * Reset the timer, typically restoring the counter to
  * the value configured by start()