From: David Lin Date: Fri, 15 Apr 2016 19:45:16 +0000 (+0530) Subject: greybus: svc watchdog: Disable watchdog upon entering suspend X-Git-Tag: v4.9-rc1~119^2~378^2~21^2~533 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=192c70dcf6c6f8c39a108f9ba56e916808f23cca;p=karo-tx-linux.git greybus: svc watchdog: Disable watchdog upon entering suspend SVC watchdog should be disabled when device is entering suspend mode. Testing done: - Sanity tested on EVT1.5 - Check no SVC ping during the suspend process - Check SVC watchdog is back on pinging once device is resumed Signed-off-by: David Lin Signed-off-by: Vaibhav Hiremath [vaibhav.hiremath@linaro.org: Removed unwanted check in notifier callback and Updated commit description] Tested-by: Sandeep Patil Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/greybus/svc_watchdog.c b/drivers/staging/greybus/svc_watchdog.c index 9bd68f4f4cf7..6cd3bac59852 100644 --- a/drivers/staging/greybus/svc_watchdog.c +++ b/drivers/staging/greybus/svc_watchdog.c @@ -7,6 +7,7 @@ */ #include +#include #include #include "greybus.h" @@ -16,10 +17,31 @@ struct gb_svc_watchdog { struct delayed_work work; struct gb_svc *svc; bool enabled; + struct notifier_block pm_notifier; }; static struct delayed_work reset_work; +static int svc_watchdog_pm_notifier(struct notifier_block *notifier, + unsigned long pm_event, void *unused) +{ + struct gb_svc_watchdog *watchdog = + container_of(notifier, struct gb_svc_watchdog, pm_notifier); + + switch (pm_event) { + case PM_SUSPEND_PREPARE: + gb_svc_watchdog_disable(watchdog->svc); + break; + case PM_POST_SUSPEND: + gb_svc_watchdog_enable(watchdog->svc); + break; + default: + break; + } + + return NOTIFY_DONE; +} + static void greybus_reset(struct work_struct *work) { static char start_path[256] = "/system/bin/start"; @@ -82,6 +104,7 @@ static void do_work(struct work_struct *work) int gb_svc_watchdog_create(struct gb_svc *svc) { struct gb_svc_watchdog *watchdog; + int retval; if (svc->watchdog) return 0; @@ -95,7 +118,27 @@ int gb_svc_watchdog_create(struct gb_svc *svc) INIT_DELAYED_WORK(&watchdog->work, do_work); svc->watchdog = watchdog; - return gb_svc_watchdog_enable(svc); + watchdog->pm_notifier.notifier_call = svc_watchdog_pm_notifier; + retval = register_pm_notifier(&watchdog->pm_notifier); + if (retval) { + dev_err(&svc->dev, "error registering pm notifier(%d)\n", + retval); + goto svc_watchdog_create_err; + } + + retval = gb_svc_watchdog_enable(svc); + if (retval) { + dev_err(&svc->dev, "error enabling watchdog (%d)\n", retval); + unregister_pm_notifier(&watchdog->pm_notifier); + goto svc_watchdog_create_err; + } + return retval; + +svc_watchdog_create_err: + svc->watchdog = NULL; + kfree(watchdog); + + return retval; } void gb_svc_watchdog_destroy(struct gb_svc *svc) @@ -105,6 +148,7 @@ void gb_svc_watchdog_destroy(struct gb_svc *svc) if (!watchdog) return; + unregister_pm_notifier(&watchdog->pm_notifier); gb_svc_watchdog_disable(svc); svc->watchdog = NULL; kfree(watchdog);