Message ID | 20190614125310.29458-1-ksloat@aampglobal.com (mailing list archive) |
---|---|
State | Mainlined |
Commit | 8d209eb0b167ac6998ef330150a3960032a31c50 |
Headers | show |
Series | [v2,1/1] watchdog: atmel: atmel-sama5d4-wdt: Disable watchdog on system suspend | expand |
On Fri, Jun 14, 2019 at 12:53:22PM +0000, 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> > --- > Changes in v2: > -Consolidate resume and resume early statements. > > drivers/watchdog/sama5d4_wdt.c | 21 ++++++++++++++++++--- > 1 file changed, 18 insertions(+), 3 deletions(-) > > diff --git a/drivers/watchdog/sama5d4_wdt.c b/drivers/watchdog/sama5d4_wdt.c > index 111695223aae..0d123f8cbcc6 100644 > --- a/drivers/watchdog/sama5d4_wdt.c > +++ b/drivers/watchdog/sama5d4_wdt.c > @@ -280,7 +280,17 @@ 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_resume(struct device *dev) > +static int sama5d4_wdt_suspend_late(struct device *dev) > +{ > + struct sama5d4_wdt *wdt = dev_get_drvdata(dev); > + > + if (watchdog_active(&wdt->wdd)) > + sama5d4_wdt_stop(&wdt->wdd); > + > + return 0; > +} > + > +static int sama5d4_wdt_resume_early(struct device *dev) > { > struct sama5d4_wdt *wdt = dev_get_drvdata(dev); > > @@ -291,12 +301,17 @@ static int sama5d4_wdt_resume(struct device *dev) > */ > sama5d4_wdt_init(wdt); > > + if (watchdog_active(&wdt->wdd)) > + sama5d4_wdt_start(&wdt->wdd); > + The call to sama5d4_wdt_init() above now explicitly stops the watchdog even if we want to (re)start it. I think this would be better handled with an else case here else sama5d4_wdt_stop(&wdt->wdd); Guenter > 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_LATE_SYSTEM_SLEEP_PM_OPS(sama5d4_wdt_suspend_late, > + sama5d4_wdt_resume_early) > +}; > > static struct platform_driver sama5d4_wdt_driver = { > .probe = sama5d4_wdt_probe, > -- > 2.17.1 >
> -----Original Message----- > From: Guenter Roeck <groeck7@gmail.com> On Behalf Of Guenter Roeck > Sent: Friday, June 14, 2019 12:46 PM > To: Ken Sloat <KSloat@aampglobal.com> > Cc: nicolas.ferre@microchip.com; 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 v2 1/1] watchdog: atmel: atmel-sama5d4-wdt: Disable > watchdog on system suspend > > [This is an EXTERNAL EMAIL] > ________________________________ > > On Fri, Jun 14, 2019 at 12:53:22PM +0000, 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> > > --- > > Changes in v2: > > -Consolidate resume and resume early statements. > > > > drivers/watchdog/sama5d4_wdt.c | 21 ++++++++++++++++++--- > > 1 file changed, 18 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/watchdog/sama5d4_wdt.c > > b/drivers/watchdog/sama5d4_wdt.c index 111695223aae..0d123f8cbcc6 > > 100644 > > --- a/drivers/watchdog/sama5d4_wdt.c > > +++ b/drivers/watchdog/sama5d4_wdt.c > > @@ -280,7 +280,17 @@ 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_resume(struct device *dev) > > +static int sama5d4_wdt_suspend_late(struct device *dev) { > > + struct sama5d4_wdt *wdt = dev_get_drvdata(dev); > > + > > + if (watchdog_active(&wdt->wdd)) > > + sama5d4_wdt_stop(&wdt->wdd); > > + > > + return 0; > > +} > > + > > +static int sama5d4_wdt_resume_early(struct device *dev) > > { > > struct sama5d4_wdt *wdt = dev_get_drvdata(dev); > > > > @@ -291,12 +301,17 @@ static int sama5d4_wdt_resume(struct device > *dev) > > */ > > sama5d4_wdt_init(wdt); > > > > + if (watchdog_active(&wdt->wdd)) > > + sama5d4_wdt_start(&wdt->wdd); > > + > > The call to sama5d4_wdt_init() above now explicitly stops the watchdog > even if we want to (re)start it. I think this would be better handled with an > else case here > > else > sama5d4_wdt_stop(&wdt->wdd); > So we completely remove the sama5d4_wdt_init() call then correct? To leave the code as it behaves today with the addition of wdt stop/start, shouldn't we call init in the else instead? if (watchdog_active(&wdt->wdd)) sama5d4_wdt_start(&wdt->wdd); else sama5d4_wdt_init(); I guess I don't really understand the purpose of having the init statement in resume in the first place. I agree, calling this first does end up essentially resetting the wdt it will start again if it was running before, but the count will be reset. > Guenter > > > 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_LATE_SYSTEM_SLEEP_PM_OPS(sama5d4_wdt_suspend_late, > > + sama5d4_wdt_resume_early) }; > > > > static struct platform_driver sama5d4_wdt_driver = { > > .probe = sama5d4_wdt_probe, > > -- > > 2.17.1 > > Thanks, Ken Sloat
On 14/06/2019 17:53:01+0000, Ken Sloat wrote: > > The call to sama5d4_wdt_init() above now explicitly stops the watchdog > > even if we want to (re)start it. I think this would be better handled with an > > else case here > > > > else > > sama5d4_wdt_stop(&wdt->wdd); > > > > So we completely remove the sama5d4_wdt_init() call then correct? > > To leave the code as it behaves today with the addition > of wdt stop/start, shouldn't we call init in the else instead? > > if (watchdog_active(&wdt->wdd)) > sama5d4_wdt_start(&wdt->wdd); > else > sama5d4_wdt_init(); > > I guess I don't really understand the purpose of having the init statement in resume > in the first place. I agree, calling this first does end up essentially resetting the wdt > it will start again if it was running before, but the count will be reset. > There is a nice comment explaining why ;)
> -----Original Message----- > From: Alexandre Belloni <alexandre.belloni@bootlin.com> > Sent: Friday, June 14, 2019 2:08 PM > To: Ken Sloat <KSloat@aampglobal.com> > Cc: Guenter Roeck <linux@roeck-us.net>; nicolas.ferre@microchip.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 v2 1/1] watchdog: atmel: atmel-sama5d4-wdt: Disable > watchdog on system suspend > > [This is an EXTERNAL EMAIL] > ________________________________ > > On 14/06/2019 17:53:01+0000, Ken Sloat wrote: > > > The call to sama5d4_wdt_init() above now explicitly stops the > > > watchdog even if we want to (re)start it. I think this would be > > > better handled with an else case here > > > > > > else > > > sama5d4_wdt_stop(&wdt->wdd); > > > > > > > So we completely remove the sama5d4_wdt_init() call then correct? > > > > To leave the code as it behaves today with the addition of wdt > > stop/start, shouldn't we call init in the else instead? > > > > if (watchdog_active(&wdt->wdd)) > > sama5d4_wdt_start(&wdt->wdd); > > else > > sama5d4_wdt_init(); > > > > I guess I don't really understand the purpose of having the init > > statement in resume in the first place. I agree, calling this first > > does end up essentially resetting the wdt it will start again if it was running > before, but the count will be reset. > > > > There is a nice comment explaining why ;) Well I'm a little confused still because there are two separate comments in these statements. The first within resume implies that the init should be called because we might have lost register values for some reason unexplained. Then within the init it says that the bootloader might have modified the registers so we should check them and then update it or otherwise disable it. I'm not trying to pick apart the logic or anything, I'm just readily assuming it is good as it was already reviewed before. So without digging into that too much, if we don't know if any of the runtime situations above might have occurred, then isn't it best to leave my patch as is? Yes this has the side effect of resetting the timer count, but if the init call is needed and we don't have any way to know if any of the situations occurred, then we have no choice right? Happy to modify it either way, just didn't want to change logic without understanding it thoroughly. > > -- > Alexandre Belloni, Bootlin > Embedded Linux and Kernel engineering > https://bootlin.com Thanks, Ken Sloat
On 14/06/2019 18:43:22+0000, Ken Sloat wrote: > Well I'm a little confused still because there are two separate comments > in these statements. The first within resume implies that the init should > be called because we might have lost register values for some reason > unexplained. The sama5d2 has a suspend mode where power to the core is completely cut. Only a few IPs remain powered (in the backup power domain). Unfortunately, the watchdog is not in that domain and may lose its registers. > Then within the init it says that the bootloader might have > modified the registers so we should check them and then update it or > otherwise disable it. I'm not trying to pick apart the logic or anything, > I'm just readily assuming it is good as it was already reviewed before. > The bootloaders may have started the watchdog (this makes sense if you really care about reliability) and so we need to be careful to keep the proper parameters. > So without digging into that too much, if we don't know if any of the runtime > situations above might have occurred, then isn't it best to leave my patch > as is? Yes this has the side effect of resetting the timer count, but if > the init call is needed and we don't have any way to know if any > of the situations occurred, then we have no choice right? > Until we can differentiate between suspend modes, we have no other choice.
> -----Original Message----- > From: Alexandre Belloni <alexandre.belloni@bootlin.com> > Sent: Friday, June 14, 2019 4:33 PM > To: Ken Sloat <KSloat@aampglobal.com> > Cc: Guenter Roeck <linux@roeck-us.net>; nicolas.ferre@microchip.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 v2 1/1] watchdog: atmel: atmel-sama5d4-wdt: Disable > watchdog on system suspend > > [This is an EXTERNAL EMAIL] > ________________________________ > > On 14/06/2019 18:43:22+0000, Ken Sloat wrote: > > Well I'm a little confused still because there are two separate > > comments in these statements. The first within resume implies that the > > init should be called because we might have lost register values for > > some reason unexplained. > > The sama5d2 has a suspend mode where power to the core is completely > cut. Only a few IPs remain powered (in the backup power domain). > Unfortunately, the watchdog is not in that domain and may lose its registers. > > > Then within the init it says that the bootloader might have modified > > the registers so we should check them and then update it or otherwise > > disable it. I'm not trying to pick apart the logic or anything, I'm > > just readily assuming it is good as it was already reviewed before. > > > > The bootloaders may have started the watchdog (this makes sense if you > really care about reliability) and so we need to be careful to keep the proper > parameters. Thanks for the explanation Alexandre I appreciate it. > > So without digging into that too much, if we don't know if any of the > > runtime situations above might have occurred, then isn't it best to > > leave my patch as is? Yes this has the side effect of resetting the > > timer count, but if the init call is needed and we don't have any way > > to know if any of the situations occurred, then we have no choice right? > > > > Until we can differentiate between suspend modes, we have no other > choice. Ok I will leave my patch as is for now then > -- > Alexandre Belloni, Bootlin > Embedded Linux and Kernel engineering > https://bootlin.com Thanks, Ken Sloat
On Fri, Jun 14, 2019 at 08:45:28PM +0000, Ken Sloat wrote: > > -----Original Message----- > > From: Alexandre Belloni <alexandre.belloni@bootlin.com> > > Sent: Friday, June 14, 2019 4:33 PM > > To: Ken Sloat <KSloat@aampglobal.com> > > Cc: Guenter Roeck <linux@roeck-us.net>; nicolas.ferre@microchip.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 v2 1/1] watchdog: atmel: atmel-sama5d4-wdt: Disable > > watchdog on system suspend > > > > [This is an EXTERNAL EMAIL] > > ________________________________ > > > > On 14/06/2019 18:43:22+0000, Ken Sloat wrote: > > > Well I'm a little confused still because there are two separate > > > comments in these statements. The first within resume implies that the > > > init should be called because we might have lost register values for > > > some reason unexplained. > > > > The sama5d2 has a suspend mode where power to the core is completely > > cut. Only a few IPs remain powered (in the backup power domain). > > Unfortunately, the watchdog is not in that domain and may lose its registers. > > > > > Then within the init it says that the bootloader might have modified > > > the registers so we should check them and then update it or otherwise > > > disable it. I'm not trying to pick apart the logic or anything, I'm > > > just readily assuming it is good as it was already reviewed before. > > > > > > > The bootloaders may have started the watchdog (this makes sense if you > > really care about reliability) and so we need to be careful to keep the proper > > parameters. > > Thanks for the explanation Alexandre I appreciate it. > > > > So without digging into that too much, if we don't know if any of the > > > runtime situations above might have occurred, then isn't it best to > > > leave my patch as is? Yes this has the side effect of resetting the > > > timer count, but if the init call is needed and we don't have any way > > > to know if any of the situations occurred, then we have no choice right? > > > > > > > Until we can differentiate between suspend modes, we have no other > > choice. > > Ok I will leave my patch as is for now then > If that is what those involved in this discussion argue for, they will need to confirm with Reviewed-by: or Acked-by: tags. Thanks, Guenter > > -- > > Alexandre Belloni, Bootlin > > Embedded Linux and Kernel engineering > > https://bootlin.com > > Thanks, > Ken Sloat
On 14/06/2019 12:53:22+0000, 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> Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com> > --- > Changes in v2: > -Consolidate resume and resume early statements. > > drivers/watchdog/sama5d4_wdt.c | 21 ++++++++++++++++++--- > 1 file changed, 18 insertions(+), 3 deletions(-) > > diff --git a/drivers/watchdog/sama5d4_wdt.c b/drivers/watchdog/sama5d4_wdt.c > index 111695223aae..0d123f8cbcc6 100644 > --- a/drivers/watchdog/sama5d4_wdt.c > +++ b/drivers/watchdog/sama5d4_wdt.c > @@ -280,7 +280,17 @@ 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_resume(struct device *dev) > +static int sama5d4_wdt_suspend_late(struct device *dev) > +{ > + struct sama5d4_wdt *wdt = dev_get_drvdata(dev); > + > + if (watchdog_active(&wdt->wdd)) > + sama5d4_wdt_stop(&wdt->wdd); > + > + return 0; > +} > + > +static int sama5d4_wdt_resume_early(struct device *dev) > { > struct sama5d4_wdt *wdt = dev_get_drvdata(dev); > > @@ -291,12 +301,17 @@ static int sama5d4_wdt_resume(struct device *dev) > */ > sama5d4_wdt_init(wdt); > > + 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_LATE_SYSTEM_SLEEP_PM_OPS(sama5d4_wdt_suspend_late, > + sama5d4_wdt_resume_early) > +}; > > static struct platform_driver sama5d4_wdt_driver = { > .probe = sama5d4_wdt_probe, > -- > 2.17.1 >
On Fri, Jun 14, 2019 at 12:53:22PM +0000, 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> > Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com> Reviewed-by: Guenter Roeck <linux@roeck-us.net> > --- > Changes in v2: > -Consolidate resume and resume early statements. > > drivers/watchdog/sama5d4_wdt.c | 21 ++++++++++++++++++--- > 1 file changed, 18 insertions(+), 3 deletions(-) > > diff --git a/drivers/watchdog/sama5d4_wdt.c b/drivers/watchdog/sama5d4_wdt.c > index 111695223aae..0d123f8cbcc6 100644 > --- a/drivers/watchdog/sama5d4_wdt.c > +++ b/drivers/watchdog/sama5d4_wdt.c > @@ -280,7 +280,17 @@ 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_resume(struct device *dev) > +static int sama5d4_wdt_suspend_late(struct device *dev) > +{ > + struct sama5d4_wdt *wdt = dev_get_drvdata(dev); > + > + if (watchdog_active(&wdt->wdd)) > + sama5d4_wdt_stop(&wdt->wdd); > + > + return 0; > +} > + > +static int sama5d4_wdt_resume_early(struct device *dev) > { > struct sama5d4_wdt *wdt = dev_get_drvdata(dev); > > @@ -291,12 +301,17 @@ static int sama5d4_wdt_resume(struct device *dev) > */ > sama5d4_wdt_init(wdt); > > + 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_LATE_SYSTEM_SLEEP_PM_OPS(sama5d4_wdt_suspend_late, > + sama5d4_wdt_resume_early) > +}; > > static struct platform_driver sama5d4_wdt_driver = { > .probe = sama5d4_wdt_probe,
diff --git a/drivers/watchdog/sama5d4_wdt.c b/drivers/watchdog/sama5d4_wdt.c index 111695223aae..0d123f8cbcc6 100644 --- a/drivers/watchdog/sama5d4_wdt.c +++ b/drivers/watchdog/sama5d4_wdt.c @@ -280,7 +280,17 @@ 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_resume(struct device *dev) +static int sama5d4_wdt_suspend_late(struct device *dev) +{ + struct sama5d4_wdt *wdt = dev_get_drvdata(dev); + + if (watchdog_active(&wdt->wdd)) + sama5d4_wdt_stop(&wdt->wdd); + + return 0; +} + +static int sama5d4_wdt_resume_early(struct device *dev) { struct sama5d4_wdt *wdt = dev_get_drvdata(dev); @@ -291,12 +301,17 @@ static int sama5d4_wdt_resume(struct device *dev) */ sama5d4_wdt_init(wdt); + 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_LATE_SYSTEM_SLEEP_PM_OPS(sama5d4_wdt_suspend_late, + sama5d4_wdt_resume_early) +}; static struct platform_driver sama5d4_wdt_driver = { .probe = sama5d4_wdt_probe,