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@xxxxxxxxxxxxxx> --- 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 -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html