Skip to content

Commit cf6e4bc

Browse files
alistair23Wim Van Sebroeck
authored andcommitted
watchdog: imx2_wdg: Alow ping on suspend
The i.MX watchdog cannot be disabled by software once it has been enabled. This means that it can't be stopped before suspend. For systems that enter low power mode this is fine, as the watchdog will be automatically stopped by hardware in low power mode. Not all i.MX platforms support low power mode in the mainline kernel. For example the i.MX7D does not enter low power mode and so will be rebooted 2 minutes after entering sleep states. This patch introduces a device tree property "fsl,ping-during-suspend" that can be used to enable ping on suspend support for these systems. Signed-off-by: Alistair Francis <alistair@alistair23.me> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Link: https://lore.kernel.org/r/20220127104739.312592-1-alistair@alistair23.me Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
1 parent 09688c0 commit cf6e4bc

1 file changed

Lines changed: 20 additions & 7 deletions

File tree

drivers/watchdog/imx2_wdt.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ struct imx2_wdt_device {
6666
struct watchdog_device wdog;
6767
bool ext_reset;
6868
bool clk_is_on;
69+
bool no_ping;
6970
};
7071

7172
static bool nowayout = WATCHDOG_NOWAYOUT;
@@ -312,12 +313,18 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
312313

313314
wdev->ext_reset = of_property_read_bool(dev->of_node,
314315
"fsl,ext-reset-output");
316+
/*
317+
* The i.MX7D doesn't support low power mode, so we need to ping the watchdog
318+
* during suspend.
319+
*/
320+
wdev->no_ping = !of_device_is_compatible(dev->of_node, "fsl,imx7d-wdt");
315321
platform_set_drvdata(pdev, wdog);
316322
watchdog_set_drvdata(wdog, wdev);
317323
watchdog_set_nowayout(wdog, nowayout);
318324
watchdog_set_restart_priority(wdog, 128);
319325
watchdog_init_timeout(wdog, timeout, dev);
320-
watchdog_stop_ping_on_suspend(wdog);
326+
if (wdev->no_ping)
327+
watchdog_stop_ping_on_suspend(wdog);
321328

322329
if (imx2_wdt_is_running(wdev)) {
323330
imx2_wdt_set_timeout(wdog, wdog->timeout);
@@ -366,9 +373,11 @@ static int __maybe_unused imx2_wdt_suspend(struct device *dev)
366373
imx2_wdt_ping(wdog);
367374
}
368375

369-
clk_disable_unprepare(wdev->clk);
376+
if (wdev->no_ping) {
377+
clk_disable_unprepare(wdev->clk);
370378

371-
wdev->clk_is_on = false;
379+
wdev->clk_is_on = false;
380+
}
372381

373382
return 0;
374383
}
@@ -380,11 +389,14 @@ static int __maybe_unused imx2_wdt_resume(struct device *dev)
380389
struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
381390
int ret;
382391

383-
ret = clk_prepare_enable(wdev->clk);
384-
if (ret)
385-
return ret;
392+
if (wdev->no_ping) {
393+
ret = clk_prepare_enable(wdev->clk);
386394

387-
wdev->clk_is_on = true;
395+
if (ret)
396+
return ret;
397+
398+
wdev->clk_is_on = true;
399+
}
388400

389401
if (watchdog_active(wdog) && !imx2_wdt_is_running(wdev)) {
390402
/*
@@ -407,6 +419,7 @@ static SIMPLE_DEV_PM_OPS(imx2_wdt_pm_ops, imx2_wdt_suspend,
407419

408420
static const struct of_device_id imx2_wdt_dt_ids[] = {
409421
{ .compatible = "fsl,imx21-wdt", },
422+
{ .compatible = "fsl,imx7d-wdt", },
410423
{ /* sentinel */ }
411424
};
412425
MODULE_DEVICE_TABLE(of, imx2_wdt_dt_ids);

0 commit comments

Comments
 (0)