From 62ea1d38b613c7fbdd10ed03d0d3123d8c44d232 Mon Sep 17 00:00:00 2001 From: Neeraj Upadhyay Date: Thu, 3 Sep 2020 07:55:46 +0530 Subject: [PATCH] soc: qcom: Move watchdog suspend/resume callbacks to syscore ops Move suspend resume callbacks to syscore ops, to ensure that watchdog is kept enabled while _noirq callbacks are run; to catch any watchdog hang during these callbacks run. Change-Id: I5ef61eb2ce2cd74a07847d6f5ff048a7b27b95a1 Signed-off-by: Neeraj Upadhyay Signed-off-by: Prateek Sood --- drivers/soc/qcom/qcom_soc_wdt.c | 11 ------ drivers/soc/qcom/qcom_wdt_core.c | 60 +++++++++++++++++++------------- drivers/virt/haven/hh_virt_wdt.c | 11 ------ include/soc/qcom/watchdog.h | 2 -- 4 files changed, 35 insertions(+), 49 deletions(-) diff --git a/drivers/soc/qcom/qcom_soc_wdt.c b/drivers/soc/qcom/qcom_soc_wdt.c index 302751c1725e..b2c66f92a26d 100644 --- a/drivers/soc/qcom/qcom_soc_wdt.c +++ b/drivers/soc/qcom/qcom_soc_wdt.c @@ -105,16 +105,6 @@ static int qcom_soc_wdt_probe(struct platform_device *pdev) return qcom_wdt_register(pdev, wdog_dd, "msm-watchdog"); } -#ifdef CONFIG_PM_SLEEP -static const struct dev_pm_ops qcom_soc_dev_pm_ops = { - .suspend_noirq = qcom_wdt_suspend, - .resume_noirq = qcom_wdt_resume, -}; -#else -static const struct dev_pm_ops qcom_soc_dev_pm_ops = { -}; -#endif - static const struct of_device_id qcom_soc_match_table[] = { { .compatible = "qcom,msm-watchdog" }, {} @@ -125,7 +115,6 @@ static struct platform_driver qcom_soc_wdt_driver = { .remove = qcom_wdt_remove, .driver = { .name = "msm_watchdog", - .pm = &qcom_soc_dev_pm_ops, .of_match_table = qcom_soc_match_table, }, }; diff --git a/drivers/soc/qcom/qcom_wdt_core.c b/drivers/soc/qcom/qcom_wdt_core.c index f21ec0572096..165bd279442f 100644 --- a/drivers/soc/qcom/qcom_wdt_core.c +++ b/drivers/soc/qcom/qcom_wdt_core.c @@ -20,6 +20,7 @@ #include #include #include +#include #define MASK_SIZE 32 @@ -45,23 +46,22 @@ static void qcom_wdt_dump_cpu_alive_mask(struct msm_watchdog_data *wdog_dd) * will cause the watchdog counter to be frozen. * */ -int qcom_wdt_suspend(struct device *dev) +static int qcom_wdt_suspend(void) { - struct msm_watchdog_data *wdog_dd = dev_get_drvdata(dev); - - if (!wdog_dd) + if (!wdog_data) return 0; - wdog_dd->ops->reset_wdt(wdog_dd); - if (wdog_dd->wakeup_irq_enable) { - wdog_dd->last_pet = sched_clock(); + + wdog_data->ops->reset_wdt(wdog_data); + if (wdog_data->wakeup_irq_enable) { + wdog_data->last_pet = sched_clock(); return 0; } - wdog_dd->ops->disable_wdt(wdog_dd); - wdog_dd->enabled = false; - wdog_dd->last_pet = sched_clock(); + + wdog_data->ops->disable_wdt(wdog_data); + wdog_data->enabled = false; + wdog_data->last_pet = sched_clock(); return 0; } -EXPORT_SYMBOL(qcom_wdt_suspend); /** * qcom_wdt_resume() - Resumes qcom watchdog after a suspend. @@ -72,26 +72,32 @@ EXPORT_SYMBOL(qcom_wdt_suspend); * This will cause the watchdog counter to be reset and resumed. * */ -int qcom_wdt_resume(struct device *dev) +static void qcom_wdt_resume(void) { - struct msm_watchdog_data *wdog_dd = dev_get_drvdata(dev); + if (!wdog_data) + return; - if (!wdog_dd) - return 0; - if (wdog_dd->wakeup_irq_enable) { - wdog_dd->ops->reset_wdt(wdog_dd); - wdog_dd->last_pet = sched_clock(); - return 0; + if (wdog_data->wakeup_irq_enable) { + wdog_data->ops->reset_wdt(wdog_data); + wdog_data->last_pet = sched_clock(); + return; } - wdog_dd->ops->enable_wdt(1, wdog_dd); - wdog_dd->ops->reset_wdt(wdog_dd); - wdog_dd->enabled = true; - wdog_dd->last_pet = sched_clock(); - return 0; + + wdog_data->ops->enable_wdt(1, wdog_data); + wdog_data->ops->reset_wdt(wdog_data); + wdog_data->enabled = true; + wdog_data->last_pet = sched_clock(); + return; } -EXPORT_SYMBOL(qcom_wdt_resume); #endif +static struct syscore_ops qcom_wdt_syscore_ops = { +#ifdef CONFIG_PM_SLEEP + .suspend = qcom_wdt_suspend, + .resume = qcom_wdt_resume, +#endif +}; + static int qcom_wdt_panic_handler(struct notifier_block *this, unsigned long event, void *ptr) { @@ -374,6 +380,7 @@ int qcom_wdt_remove(struct platform_device *pdev) { struct msm_watchdog_data *wdog_dd = platform_get_drvdata(pdev); + unregister_syscore_ops(&qcom_wdt_syscore_ops); if (!IPI_CORES_IN_LPM) cpu_pm_unregister_notifier(&wdog_dd->wdog_cpu_pm_nb); @@ -575,6 +582,9 @@ int qcom_wdt_register(struct platform_device *pdev, md_entry.size = sizeof(*wdog_dd); if (msm_minidump_add_region(&md_entry) < 0) dev_err(wdog_dd->dev, "Failed to add Wdt data in Minidump\n"); + + register_syscore_ops(&qcom_wdt_syscore_ops); + return 0; err: return ret; diff --git a/drivers/virt/haven/hh_virt_wdt.c b/drivers/virt/haven/hh_virt_wdt.c index 442f9e5d1f0b..51c1b6c2eeb1 100644 --- a/drivers/virt/haven/hh_virt_wdt.c +++ b/drivers/virt/haven/hh_virt_wdt.c @@ -261,16 +261,6 @@ static int hh_wdt_probe(struct platform_device *pdev) return qcom_wdt_register(pdev, wdog_dd, "hh-watchdog"); } -#ifdef CONFIG_PM_SLEEP -static const struct dev_pm_ops hh_wdt_dev_pm_ops = { - .suspend_noirq = qcom_wdt_suspend, - .resume_noirq = qcom_wdt_resume, -}; -#else -static const struct dev_pm_ops hh_wdt_dev_pm_ops = { -}; -#endif - static const struct of_device_id hh_wdt_match_table[] = { { .compatible = "qcom,hh-watchdog" }, {} @@ -281,7 +271,6 @@ static struct platform_driver hh_wdt_driver = { .remove = qcom_wdt_remove, .driver = { .name = "hh-watchdog", - .pm = &hh_wdt_dev_pm_ops, .of_match_table = hh_wdt_match_table, }, }; diff --git a/include/soc/qcom/watchdog.h b/include/soc/qcom/watchdog.h index 4040a22f4edf..7b60f053ce1e 100644 --- a/include/soc/qcom/watchdog.h +++ b/include/soc/qcom/watchdog.h @@ -126,8 +126,6 @@ struct msm_watchdog_data { }; extern void qcom_wdt_trigger_bite(void); -int qcom_wdt_suspend(struct device *dev); -int qcom_wdt_resume(struct device *dev); int qcom_wdt_register(struct platform_device *pdev, struct msm_watchdog_data *wdog_dd, char *wdog_dd_name);