[PATCH 5/6] watchdog: suspend/resume PM helper
Janusz Uzycki
j.uzycki at elproma.com.pl
Mon Sep 22 13:55:49 PDT 2014
The helper replaces watchdog_active() condition
usually used in device-specific drivers for PM support.
It also solves race between ping timer and
driver-specific suspend function.
Signed-off-by: Janusz Uzycki <j.uzycki at elproma.com.pl>
---
drivers/watchdog/watchdog_dev.c | 38 +++++++++++++++++++++++++++
include/linux/watchdog.h | 4 +++
2 files changed, 42 insertions(+)
diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c
index d289eab..2df88b7 100644
--- a/drivers/watchdog/watchdog_dev.c
+++ b/drivers/watchdog/watchdog_dev.c
@@ -311,6 +311,44 @@ static void watchdog_keepon_stop(struct watchdog_device *wdd)
}
/*
+ * watchdog_suspend: deactivate ping timer if enabled and
+ * stop the watchdog if active
+ * @wdd: the watchdog device to do the suspend on
+ */
+void watchdog_suspend(struct watchdog_device *wdd)
+{
+ if (test_bit(WDOG_UNREGISTERED, &wdd->status))
+ return;
+
+ if (test_bit(WDOG_KEEP_ON, &wdd->status) &&
+ !test_bit(WDOG_DEV_OPEN, &wdd->status))
+ del_timer_sync(&wdd->ping_timer);
+
+ if (watchdog_active(wdd))
+ wdd->ops->stop(wdd);
+}
+EXPORT_SYMBOL_GPL(watchdog_suspend);
+
+/*
+ * watchdog_resume: start the watchdog if it was active
+ * and activate ping timer if it was enabled
+ * @wdd: the watchdog device to do the resume on
+ */
+void watchdog_resume(struct watchdog_device *wdd)
+{
+ if (test_bit(WDOG_UNREGISTERED, &wdd->status))
+ return;
+
+ if (watchdog_active(wdd))
+ wdd->ops->start(wdd);
+
+ if (test_bit(WDOG_KEEP_ON, &wdd->status) &&
+ !test_bit(WDOG_DEV_OPEN, &wdd->status))
+ watchdog_ping_timer_cb((unsigned long)wdd);
+}
+EXPORT_SYMBOL_GPL(watchdog_resume);
+
+/*
* watchdog_write: writes to the watchdog.
* @file: file from VFS
* @data: user address of data
diff --git a/include/linux/watchdog.h b/include/linux/watchdog.h
index 650e0d5..eee1b65 100644
--- a/include/linux/watchdog.h
+++ b/include/linux/watchdog.h
@@ -147,4 +147,8 @@ extern int watchdog_init_timeout(struct watchdog_device *wdd,
extern int watchdog_register_device(struct watchdog_device *);
extern void watchdog_unregister_device(struct watchdog_device *);
+/* drivers/watchdog/watchdog_dev.c */
+extern void watchdog_suspend(struct watchdog_device *);
+extern void watchdog_resume(struct watchdog_device *);
+
#endif /* ifndef _LINUX_WATCHDOG_H */
--
1.7.11.3
More information about the linux-arm-kernel
mailing list