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.
Unified · Split
| @@ -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; |