Skip to content

Commit bad201b

Browse files
claudiubezneaWim Van Sebroeck
authored andcommitted
watchdog: rzg2l_wdt: Power on the watchdog domain in the restart handler
On RZ/G3S the watchdog can be part of a software-controlled PM domain. In this case, the watchdog device need to be powered on in struct watchdog_ops::restart API. This can be done though pm_runtime_resume_and_get() API if the watchdog PM domain and watchdog device are marked as IRQ safe. We mark the watchdog PM domain as IRQ safe with GENPD_FLAG_IRQ_SAFE when the watchdog PM domain is registered and the watchdog device though pm_runtime_irq_safe(). Before commit e4cf895 ("watchdog: rzg2l_wdt: Fix 'BUG: Invalid wait context'") pm_runtime_get_sync() was used in watchdog restart handler (which is similar to pm_runtime_resume_and_get() except the later one handles the runtime resume errors). Commit e4cf895 ("watchdog: rzg2l_wdt: Fix 'BUG: Invalid wait context'") dropped the pm_runtime_get_sync() and replaced it with clk_prepare_enable() to avoid invalid wait context due to genpd_lock() in genpd_runtime_resume() being called from atomic context. But clk_prepare_enable() doesn't fit for this either (as reported by Ulf Hansson) as clk_prepare() can also sleep (it just not throw invalid wait context warning as it is not written for this). Because the watchdog device is marked now as IRQ safe (though this patch) the irq_safe_dev_in_sleep_domain() call from genpd_runtime_resume() returns 1 for devices not registering an IRQ safe PM domain for watchdog (as the watchdog device is IRQ safe, PM domain is not and watchdog PM domain is always-on), this being the case for RZ/G3S with old device trees and the rest of the SoCs that use this driver, we can now drop also the clk_prepare_enable() calls in restart handler and rely on pm_runtime_resume_and_get(). Thus, drop clk_prepare_enable() and use pm_runtime_resume_and_get() in watchdog restart handler. Signed-off-by: Claudiu Beznea <[email protected]> Reviewed-by: Ulf Hansson <[email protected]> Reviewed-by: Geert Uytterhoeven <[email protected]> Acked-by: Guenter Roeck <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Guenter Roeck <[email protected]> Signed-off-by: Wim Van Sebroeck <[email protected]>
1 parent 562b0b0 commit bad201b

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

drivers/watchdog/rzg2l_wdt.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/module.h>
1313
#include <linux/of.h>
1414
#include <linux/platform_device.h>
15+
#include <linux/pm_domain.h>
1516
#include <linux/pm_runtime.h>
1617
#include <linux/reset.h>
1718
#include <linux/units.h>
@@ -166,8 +167,22 @@ static int rzg2l_wdt_restart(struct watchdog_device *wdev,
166167
struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
167168
int ret;
168169

169-
clk_prepare_enable(priv->pclk);
170-
clk_prepare_enable(priv->osc_clk);
170+
/*
171+
* In case of RZ/G3S the watchdog device may be part of an IRQ safe power
172+
* domain that is currently powered off. In this case we need to power
173+
* it on before accessing registers. Along with this the clocks will be
174+
* enabled. We don't undo the pm_runtime_resume_and_get() as the device
175+
* need to be on for the reboot to happen.
176+
*
177+
* For the rest of SoCs not registering a watchdog IRQ safe power
178+
* domain it is safe to call pm_runtime_resume_and_get() as the
179+
* irq_safe_dev_in_sleep_domain() call in genpd_runtime_resume()
180+
* returns non zero value and the genpd_lock() is avoided, thus, there
181+
* will be no invalid wait context reported by lockdep.
182+
*/
183+
ret = pm_runtime_resume_and_get(wdev->parent);
184+
if (ret)
185+
return ret;
171186

172187
if (priv->devtype == WDT_RZG2L) {
173188
ret = reset_control_deassert(priv->rstc);
@@ -275,6 +290,7 @@ static int rzg2l_wdt_probe(struct platform_device *pdev)
275290

276291
priv->devtype = (uintptr_t)of_device_get_match_data(dev);
277292

293+
pm_runtime_irq_safe(&pdev->dev);
278294
pm_runtime_enable(&pdev->dev);
279295

280296
priv->wdev.info = &rzg2l_wdt_ident;

0 commit comments

Comments
 (0)