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 <neeraju@codeaurora.org>
Signed-off-by: Prateek Sood <prsood@codeaurora.org>
This commit is contained in:
Neeraj Upadhyay 2020-09-03 07:55:46 +05:30 • committed by Gerrit - the friendly Code Review server
commit 62ea1d38b6
4 changed files with 35 additions and 49 deletions

View file

@ -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,
},
};

View file

@ -20,6 +20,7 @@
#include <uapi/linux/sched/types.h>
#include <linux/sched/clock.h>
#include <linux/irq.h>
#include <linux/syscore_ops.h>
#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;

View file

@ -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,
},
};

View file

@ -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);