History

watchdog: msc313e: Fix spurious reset on suspend

If the hardware watchdog was started by the bootloader and the device is suspended before userspace opens it, the ping worker (from watchdog core) is frozen and the active hardware timer continues running. This leads to a spurious system reset. Check both watchdog_active() and watchdog_hw_running() when deciding whether to start or stop the watchdog during suspend and resume. Additionally, call watchdog_stop_ping_on_suspend() to ensure the ping worker be correctly paused and restarted during suspend and resume.

Tzung-Bi Shih committed 2 months ago

Commit 4f6817c1 parent 3db2df21 file · +3 −2Browse files

Unified · Split

drivers/watchdog/msc313e_wdt.c+3−2
@@ -156,6 +156,7 @@ static int msc313e_wdt_probe(struct platform_device *pdev) · 155 unmodified lines
156 watchdog_init_timeout(&priv->wdev, timeout, dev);156 watchdog_init_timeout(&priv->wdev, timeout, dev);
157 watchdog_stop_on_reboot(&priv->wdev);157 watchdog_stop_on_reboot(&priv->wdev);
158 watchdog_stop_on_unregister(&priv->wdev);158 watchdog_stop_on_unregister(&priv->wdev);
159 watchdog_stop_ping_on_suspend(&priv->wdev);
159 160
160 ret = devm_watchdog_register_device(dev, &priv->wdev);161 ret = devm_watchdog_register_device(dev, &priv->wdev);
161 162
@@ -170,7 +171,7 @@ static int __maybe_unused msc313e_wdt_suspend(struct device *dev) · 8 unmodified lines
170{171{
171 struct msc313e_wdt_priv *priv = dev_get_drvdata(dev);172 struct msc313e_wdt_priv *priv = dev_get_drvdata(dev);
172 173
173 if (watchdog_active(&priv->wdev))174 if (watchdog_active(&priv->wdev) || watchdog_hw_running(&priv->wdev))
174 msc313e_wdt_stop(&priv->wdev);175 msc313e_wdt_stop(&priv->wdev);
175 176
176 return 0;177 return 0;
@@ -180,7 +181,7 @@ static int __maybe_unused msc313e_wdt_resume(struct device *dev) · 3 unmodified lines
180{181{
181 struct msc313e_wdt_priv *priv = dev_get_drvdata(dev);182 struct msc313e_wdt_priv *priv = dev_get_drvdata(dev);
182 183
183 if (watchdog_active(&priv->wdev))184 if (watchdog_active(&priv->wdev) || watchdog_hw_running(&priv->wdev))
184 msc313e_wdt_start(&priv->wdev);185 msc313e_wdt_start(&priv->wdev);
185 186
186 return 0;187 return 0;