diff options
Diffstat (limited to 'drivers/watchdog/imx_sc_wdt.c')
| -rw-r--r-- | drivers/watchdog/imx_sc_wdt.c | 51 |
1 files changed, 26 insertions, 25 deletions
diff --git a/drivers/watchdog/imx_sc_wdt.c b/drivers/watchdog/imx_sc_wdt.c index 8ac021748d16..1280b9b1ec2a 100644 --- a/drivers/watchdog/imx_sc_wdt.c +++ b/drivers/watchdog/imx_sc_wdt.c @@ -34,6 +34,7 @@ #define SC_IRQ_WDOG 1 #define SC_IRQ_GROUP_WDOG 1 +#define SC_TIMER_ERR_BUSY 10 static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0000); @@ -55,13 +56,34 @@ static int imx_sc_wdt_ping(struct watchdog_device *wdog) return 0; } +static bool imx_sc_wdt_is_running(void) +{ + struct arm_smccc_res res; + + arm_smccc_smc(IMX_SIP_TIMER, IMX_SIP_TIMER_START_WDOG, + 0, 0, 0, 0, 0, 0, &res); + + /* Already enabled (SC_TIMER_ERR_BUSY)? */ + if (res.a0 == SC_TIMER_ERR_BUSY) + return true; + + /* Undo only if that was us who has (successfully) enabled the WDT */ + if (!res.a0) + arm_smccc_smc(IMX_SIP_TIMER, IMX_SIP_TIMER_STOP_WDOG, + 0, 0, 0, 0, 0, 0, &res); + + return false; +} + static int imx_sc_wdt_start(struct watchdog_device *wdog) { struct arm_smccc_res res; arm_smccc_smc(IMX_SIP_TIMER, IMX_SIP_TIMER_START_WDOG, 0, 0, 0, 0, 0, 0, &res); - if (res.a0) + + /* Ignore if already enabled(SC_TIMER_ERR_BUSY) */ + if (res.a0 && res.a0 != SC_TIMER_ERR_BUSY) return -EACCES; arm_smccc_smc(IMX_SIP_TIMER, IMX_SIP_TIMER_SET_WDOG_ACT, @@ -180,6 +202,9 @@ static int imx_sc_wdt_probe(struct platform_device *pdev) if (ret) return ret; + if (imx_sc_wdt_is_running()) + set_bit(WDOG_HW_RUNNING, &wdog->status); + watchdog_stop_on_reboot(wdog); watchdog_stop_on_unregister(wdog); @@ -213,29 +238,6 @@ register_device: return devm_watchdog_register_device(dev, wdog); } -static int __maybe_unused imx_sc_wdt_suspend(struct device *dev) -{ - struct imx_sc_wdt_device *imx_sc_wdd = dev_get_drvdata(dev); - - if (watchdog_active(&imx_sc_wdd->wdd)) - imx_sc_wdt_stop(&imx_sc_wdd->wdd); - - return 0; -} - -static int __maybe_unused imx_sc_wdt_resume(struct device *dev) -{ - struct imx_sc_wdt_device *imx_sc_wdd = dev_get_drvdata(dev); - - if (watchdog_active(&imx_sc_wdd->wdd)) - imx_sc_wdt_start(&imx_sc_wdd->wdd); - - return 0; -} - -static SIMPLE_DEV_PM_OPS(imx_sc_wdt_pm_ops, - imx_sc_wdt_suspend, imx_sc_wdt_resume); - static const struct of_device_id imx_sc_wdt_dt_ids[] = { { .compatible = "fsl,imx-sc-wdt", }, { /* sentinel */ } @@ -247,7 +249,6 @@ static struct platform_driver imx_sc_wdt_driver = { .driver = { .name = "imx-sc-wdt", .of_match_table = imx_sc_wdt_dt_ids, - .pm = &imx_sc_wdt_pm_ops, }, }; module_platform_driver(imx_sc_wdt_driver); |
