Message ID | 20190612150154.16778-1-ksloat@aampglobal.com (mailing list archive) |
---|---|
State | Changes Requested |
Headers | show |
Series | [v1,1/1] watchdog: atmel: atmel-sama5d4-wdt: Disable watchdog on system suspend | expand |
On 6/12/19 8:02 AM, Ken Sloat wrote: > From: Ken Sloat <ksloat@aampglobal.com> > > Currently, the atmel-sama5d4-wdt continues to run after system suspend. > Unless the system resumes within the watchdog timeout period so the > userspace can kick it, the system will be reset. This change disables > the watchdog on suspend if it is active and re-enables on resume. These > actions occur during the late and early phases of suspend and resume > respectively to minimize chances where a lock could occur while the > watchdog is disabled. > > Signed-off-by: Ken Sloat <ksloat@aampglobal.com> > --- > drivers/watchdog/sama5d4_wdt.c | 31 +++++++++++++++++++++++++++++-- > 1 file changed, 29 insertions(+), 2 deletions(-) > > diff --git a/drivers/watchdog/sama5d4_wdt.c b/drivers/watchdog/sama5d4_wdt.c > index 111695223aae..84eb4db23993 100644 > --- a/drivers/watchdog/sama5d4_wdt.c > +++ b/drivers/watchdog/sama5d4_wdt.c > @@ -280,6 +280,18 @@ static const struct of_device_id sama5d4_wdt_of_match[] = { > MODULE_DEVICE_TABLE(of, sama5d4_wdt_of_match); > > #ifdef CONFIG_PM_SLEEP > +static int sama5d4_wdt_suspend_late(struct device *dev) > +{ > + struct sama5d4_wdt *wdt; > + > + wdt = dev_get_drvdata(dev); > + > + if (watchdog_active(&wdt->wdd)) > + sama5d4_wdt_stop(&wdt->wdd); > + > + return 0; > +} > + > static int sama5d4_wdt_resume(struct device *dev) > { > struct sama5d4_wdt *wdt = dev_get_drvdata(dev); > @@ -293,10 +305,25 @@ static int sama5d4_wdt_resume(struct device *dev) > > return 0; > } > + > +static int sama5d4_wdt_resume_early(struct device *dev) > +{ > + struct sama5d4_wdt *wdt; > + > + wdt = dev_get_drvdata(dev); > + > + if (watchdog_active(&wdt->wdd)) > + sama5d4_wdt_start(&wdt->wdd); > + > + return 0; > +} > #endif > > -static SIMPLE_DEV_PM_OPS(sama5d4_wdt_pm_ops, NULL, > - sama5d4_wdt_resume); > +static const struct dev_pm_ops sama5d4_wdt_pm_ops = { > + SET_SYSTEM_SLEEP_PM_OPS(NULL, sama5d4_wdt_resume) > + SET_LATE_SYSTEM_SLEEP_PM_OPS(sama5d4_wdt_suspend_late, > + sama5d4_wdt_resume_early) I don't think you need both sama5d4_wdt_resume() and sama5d4_wdt_resume_early(). Guenter > +}; > > static struct platform_driver sama5d4_wdt_driver = { > .probe = sama5d4_wdt_probe, >
Hi Guenter, > -----Original Message----- > From: Guenter Roeck <groeck7@gmail.com> On Behalf Of Guenter Roeck > Sent: Wednesday, June 12, 2019 11:24 AM > To: Ken Sloat <KSloat@aampglobal.com>; nicolas.ferre@microchip.com > Cc: alexandre.belloni@bootlin.com; ludovic.desroches@microchip.com; > wim@linux-watchdog.org; linux-arm-kernel@lists.infradead.org; linux- > watchdog@vger.kernel.org; linux-kernel@vger.kernel.org > Subject: Re: [PATCH v1 1/1] watchdog: atmel: atmel-sama5d4-wdt: Disable > watchdog on system suspend > > [This is an EXTERNAL EMAIL] > ________________________________ > > On 6/12/19 8:02 AM, Ken Sloat wrote: > > From: Ken Sloat <ksloat@aampglobal.com> > > > > Currently, the atmel-sama5d4-wdt continues to run after system suspend. > > Unless the system resumes within the watchdog timeout period so the > > userspace can kick it, the system will be reset. This change disables > > the watchdog on suspend if it is active and re-enables on resume. > > These actions occur during the late and early phases of suspend and > > resume respectively to minimize chances where a lock could occur while > > the watchdog is disabled. > > > > Signed-off-by: Ken Sloat <ksloat@aampglobal.com> > > --- > > drivers/watchdog/sama5d4_wdt.c | 31 > +++++++++++++++++++++++++++++-- > > 1 file changed, 29 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/watchdog/sama5d4_wdt.c > > b/drivers/watchdog/sama5d4_wdt.c index 111695223aae..84eb4db23993 > > 100644 > > --- a/drivers/watchdog/sama5d4_wdt.c > > +++ b/drivers/watchdog/sama5d4_wdt.c > > @@ -280,6 +280,18 @@ static const struct of_device_id > sama5d4_wdt_of_match[] = { > > MODULE_DEVICE_TABLE(of, sama5d4_wdt_of_match); > > > > #ifdef CONFIG_PM_SLEEP > > +static int sama5d4_wdt_suspend_late(struct device *dev) { > > + struct sama5d4_wdt *wdt; > > + > > + wdt = dev_get_drvdata(dev); > > + > > + if (watchdog_active(&wdt->wdd)) > > + sama5d4_wdt_stop(&wdt->wdd); > > + > > + return 0; > > +} > > + > > static int sama5d4_wdt_resume(struct device *dev) > > { > > struct sama5d4_wdt *wdt = dev_get_drvdata(dev); @@ -293,10 > > +305,25 @@ static int sama5d4_wdt_resume(struct device *dev) > > > > return 0; > > } > > + > > +static int sama5d4_wdt_resume_early(struct device *dev) { > > + struct sama5d4_wdt *wdt; > > + > > + wdt = dev_get_drvdata(dev); > > + > > + if (watchdog_active(&wdt->wdd)) > > + sama5d4_wdt_start(&wdt->wdd); > > + > > + return 0; > > +} > > #endif > > > > -static SIMPLE_DEV_PM_OPS(sama5d4_wdt_pm_ops, NULL, > > - sama5d4_wdt_resume); > > +static const struct dev_pm_ops sama5d4_wdt_pm_ops = { > > + SET_SYSTEM_SLEEP_PM_OPS(NULL, sama5d4_wdt_resume) > > + SET_LATE_SYSTEM_SLEEP_PM_OPS(sama5d4_wdt_suspend_late, > > + sama5d4_wdt_resume_early) > > I don't think you need both sama5d4_wdt_resume() and > sama5d4_wdt_resume_early(). Yes I was wondering about that but wanted feedback on the subject first. I can simply consolidate the statements, the sama5d4_wdt_init statement present now should probably be called first anyways, so something like this within resume_early: struct sama5d4_wdt = dev_get_drvdata(dev); sama5d4_wdt_init(wdt); if (watchdog_active(&wdt->wdd)) sama5d4_wdt_start(&wdt->wdd); return 0; If that sounds good I will resubmit. > Guenter > > > +}; > > > > static struct platform_driver sama5d4_wdt_driver = { > > .probe = sama5d4_wdt_probe, > > Thanks, Ken Sloat
diff --git a/drivers/watchdog/sama5d4_wdt.c b/drivers/watchdog/sama5d4_wdt.c index 111695223aae..84eb4db23993 100644 --- a/drivers/watchdog/sama5d4_wdt.c +++ b/drivers/watchdog/sama5d4_wdt.c @@ -280,6 +280,18 @@ static const struct of_device_id sama5d4_wdt_of_match[] = { MODULE_DEVICE_TABLE(of, sama5d4_wdt_of_match); #ifdef CONFIG_PM_SLEEP +static int sama5d4_wdt_suspend_late(struct device *dev) +{ + struct sama5d4_wdt *wdt; + + wdt = dev_get_drvdata(dev); + + if (watchdog_active(&wdt->wdd)) + sama5d4_wdt_stop(&wdt->wdd); + + return 0; +} + static int sama5d4_wdt_resume(struct device *dev) { struct sama5d4_wdt *wdt = dev_get_drvdata(dev); @@ -293,10 +305,25 @@ static int sama5d4_wdt_resume(struct device *dev) return 0; } + +static int sama5d4_wdt_resume_early(struct device *dev) +{ + struct sama5d4_wdt *wdt; + + wdt = dev_get_drvdata(dev); + + if (watchdog_active(&wdt->wdd)) + sama5d4_wdt_start(&wdt->wdd); + + return 0; +} #endif -static SIMPLE_DEV_PM_OPS(sama5d4_wdt_pm_ops, NULL, - sama5d4_wdt_resume); +static const struct dev_pm_ops sama5d4_wdt_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(NULL, sama5d4_wdt_resume) + SET_LATE_SYSTEM_SLEEP_PM_OPS(sama5d4_wdt_suspend_late, + sama5d4_wdt_resume_early) +}; static struct platform_driver sama5d4_wdt_driver = { .probe = sama5d4_wdt_probe,