Message ID | 20220422072713.3172345-2-primoz.fiser@norik.com |
---|---|
State | New |
Headers | show |
Series | None | expand |
On 22 April 2022 08:27, Primoz Fiser wrote: > Optionally disable watchdog during suspend (if enabled) and re-enable > it upon resume. > This enables boards to sleep without being interrupted by the watchdog. > > This patch is based on commit f6c98b08381c ("watchdog: da9062: add > power management ops") and commit 8541673d2a5f ("watchdog: da9062: fix > power management ops") and brings the same functionality to DA9063. There's a WATCHDOG_PD bit (set to 0) to achieve this I believe, and thus removes the need for the suspend/resume PM functions. Is this something you've tried? Also seems to be present for DA9061/2 as well so can't remember why that wasn't used there.
On 9. 05. 22 12:38, DLG Adam Thomson wrote: > On 22 April 2022 08:27, Primoz Fiser wrote: > >> Optionally disable watchdog during suspend (if enabled) and re-enable >> it upon resume. >> This enables boards to sleep without being interrupted by the watchdog. >> >> This patch is based on commit f6c98b08381c ("watchdog: da9062: add >> power management ops") and commit 8541673d2a5f ("watchdog: da9062: fix >> power management ops") and brings the same functionality to DA9063. > > There's a WATCHDOG_PD bit (set to 0) to achieve this I believe, and thus > removes the need for the suspend/resume PM functions. Is this something you've > tried? Also seems to be present for DA9061/2 as well so can't remember why that > wasn't used there. Ideally one should be able to use WATCHDOG_PD bit indeed. However there are boards out there which don't have the ability to use the PMIC's powerdown/active mode due to PCB design and thus PMIC is left enabled during suspend i.e. cannot use the POWERDOWN mode. Check mailing list correspondence [1] which already gave explanation why there was a need to implement such quirks for da9062 and the need to handle this in software instead of hardware. Links: [1] https://lore.kernel.org/all/20191128171931.22563-1-m.felsch@pengutronix.de/
On 11 May 2022 09:48, Primoz Fiser wrote: > >> Optionally disable watchdog during suspend (if enabled) and re-enable > >> it upon resume. > >> This enables boards to sleep without being interrupted by the watchdog. > >> > >> This patch is based on commit f6c98b08381c ("watchdog: da9062: add > >> power management ops") and commit 8541673d2a5f ("watchdog: da9062: fix > >> power management ops") and brings the same functionality to DA9063. > > > > There's a WATCHDOG_PD bit (set to 0) to achieve this I believe, and thus > > removes the need for the suspend/resume PM functions. Is this something > you've > > tried? Also seems to be present for DA9061/2 as well so can't remember why > that > > wasn't used there. > > Ideally one should be able to use WATCHDOG_PD bit indeed. > > However there are boards out there which don't have the ability to use > the PMIC's powerdown/active mode due to PCB design and thus PMIC is left > enabled during suspend i.e. cannot use the POWERDOWN mode. > > Check mailing list correspondence [1] which already gave explanation why > there was a need to implement such quirks for da9062 and the need to > handle this in software instead of hardware. > > Links: > > [1] > https://lore.kernel.org/all/20191128171931.22563-1-m.felsch@pengutronix.de/ At least I'm consistent in my first response :) Yes I remember the discussion now. Thanks for the reminder. In which case: Reviewed-by: Adam Thomson <DLG-Adam.Thomson.Opensource@dm.renesas.com>
On Fri, Apr 22, 2022 at 09:27:12AM +0200, Primoz Fiser wrote: > Optionally disable watchdog during suspend (if enabled) and re-enable > it upon resume. > This enables boards to sleep without being interrupted by the watchdog. > > This patch is based on commit f6c98b08381c ("watchdog: da9062: add > power management ops") and commit 8541673d2a5f ("watchdog: da9062: fix > power management ops") and brings the same functionality to DA9063. > > Signed-off-by: Primoz Fiser <primoz.fiser@norik.com> > Reviewed-by: Adam Thomson <DLG-Adam.Thomson.Opensource@dm.renesas.com> Reviewed-by: Guenter Roeck <linux@roeck-us.net> > --- > drivers/watchdog/da9063_wdt.c | 36 +++++++++++++++++++++++++++++++++++ > 1 file changed, 36 insertions(+) > > diff --git a/drivers/watchdog/da9063_wdt.c b/drivers/watchdog/da9063_wdt.c > index 9adad1862bbd..09a4af4c58fc 100644 > --- a/drivers/watchdog/da9063_wdt.c > +++ b/drivers/watchdog/da9063_wdt.c > @@ -18,6 +18,7 @@ > #include <linux/delay.h> > #include <linux/mfd/da9063/registers.h> > #include <linux/mfd/da9063/core.h> > +#include <linux/property.h> > #include <linux/regmap.h> > > /* > @@ -26,6 +27,8 @@ > * others: timeout = 2048 ms * 2^(TWDSCALE-1). > */ > static const unsigned int wdt_timeout[] = { 0, 2, 4, 8, 16, 32, 65, 131 }; > +static bool use_sw_pm; > + > #define DA9063_TWDSCALE_DISABLE 0 > #define DA9063_TWDSCALE_MIN 1 > #define DA9063_TWDSCALE_MAX (ARRAY_SIZE(wdt_timeout) - 1) > @@ -218,6 +221,8 @@ static int da9063_wdt_probe(struct platform_device *pdev) > if (!wdd) > return -ENOMEM; > > + use_sw_pm = device_property_present(dev, "dlg,use-sw-pm"); > + > wdd->info = &da9063_watchdog_info; > wdd->ops = &da9063_watchdog_ops; > wdd->min_timeout = DA9063_WDT_MIN_TIMEOUT; > @@ -228,6 +233,7 @@ static int da9063_wdt_probe(struct platform_device *pdev) > > watchdog_set_restart_priority(wdd, 128); > watchdog_set_drvdata(wdd, da9063); > + dev_set_drvdata(dev, wdd); > > wdd->timeout = DA9063_WDG_TIMEOUT; > > @@ -249,10 +255,40 @@ static int da9063_wdt_probe(struct platform_device *pdev) > return devm_watchdog_register_device(dev, wdd); > } > > +static int __maybe_unused da9063_wdt_suspend(struct device *dev) > +{ > + struct watchdog_device *wdd = dev_get_drvdata(dev); > + > + if (!use_sw_pm) > + return 0; > + > + if (watchdog_active(wdd)) > + return da9063_wdt_stop(wdd); > + > + return 0; > +} > + > +static int __maybe_unused da9063_wdt_resume(struct device *dev) > +{ > + struct watchdog_device *wdd = dev_get_drvdata(dev); > + > + if (!use_sw_pm) > + return 0; > + > + if (watchdog_active(wdd)) > + return da9063_wdt_start(wdd); > + > + return 0; > +} > + > +static SIMPLE_DEV_PM_OPS(da9063_wdt_pm_ops, > + da9063_wdt_suspend, da9063_wdt_resume); > + > static struct platform_driver da9063_wdt_driver = { > .probe = da9063_wdt_probe, > .driver = { > .name = DA9063_DRVNAME_WATCHDOG, > + .pm = &da9063_wdt_pm_ops, > }, > }; > module_platform_driver(da9063_wdt_driver);
diff --git a/drivers/watchdog/da9063_wdt.c b/drivers/watchdog/da9063_wdt.c index 9adad1862bbd..09a4af4c58fc 100644 --- a/drivers/watchdog/da9063_wdt.c +++ b/drivers/watchdog/da9063_wdt.c @@ -18,6 +18,7 @@ #include <linux/delay.h> #include <linux/mfd/da9063/registers.h> #include <linux/mfd/da9063/core.h> +#include <linux/property.h> #include <linux/regmap.h> /* @@ -26,6 +27,8 @@ * others: timeout = 2048 ms * 2^(TWDSCALE-1). */ static const unsigned int wdt_timeout[] = { 0, 2, 4, 8, 16, 32, 65, 131 }; +static bool use_sw_pm; + #define DA9063_TWDSCALE_DISABLE 0 #define DA9063_TWDSCALE_MIN 1 #define DA9063_TWDSCALE_MAX (ARRAY_SIZE(wdt_timeout) - 1) @@ -218,6 +221,8 @@ static int da9063_wdt_probe(struct platform_device *pdev) if (!wdd) return -ENOMEM; + use_sw_pm = device_property_present(dev, "dlg,use-sw-pm"); + wdd->info = &da9063_watchdog_info; wdd->ops = &da9063_watchdog_ops; wdd->min_timeout = DA9063_WDT_MIN_TIMEOUT; @@ -228,6 +233,7 @@ static int da9063_wdt_probe(struct platform_device *pdev) watchdog_set_restart_priority(wdd, 128); watchdog_set_drvdata(wdd, da9063); + dev_set_drvdata(dev, wdd); wdd->timeout = DA9063_WDG_TIMEOUT; @@ -249,10 +255,40 @@ static int da9063_wdt_probe(struct platform_device *pdev) return devm_watchdog_register_device(dev, wdd); } +static int __maybe_unused da9063_wdt_suspend(struct device *dev) +{ + struct watchdog_device *wdd = dev_get_drvdata(dev); + + if (!use_sw_pm) + return 0; + + if (watchdog_active(wdd)) + return da9063_wdt_stop(wdd); + + return 0; +} + +static int __maybe_unused da9063_wdt_resume(struct device *dev) +{ + struct watchdog_device *wdd = dev_get_drvdata(dev); + + if (!use_sw_pm) + return 0; + + if (watchdog_active(wdd)) + return da9063_wdt_start(wdd); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(da9063_wdt_pm_ops, + da9063_wdt_suspend, da9063_wdt_resume); + static struct platform_driver da9063_wdt_driver = { .probe = da9063_wdt_probe, .driver = { .name = DA9063_DRVNAME_WATCHDOG, + .pm = &da9063_wdt_pm_ops, }, }; module_platform_driver(da9063_wdt_driver);
Optionally disable watchdog during suspend (if enabled) and re-enable it upon resume. This enables boards to sleep without being interrupted by the watchdog. This patch is based on commit f6c98b08381c ("watchdog: da9062: add power management ops") and commit 8541673d2a5f ("watchdog: da9062: fix power management ops") and brings the same functionality to DA9063. Signed-off-by: Primoz Fiser <primoz.fiser@norik.com> --- drivers/watchdog/da9063_wdt.c | 36 +++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+)