msm: modem-8960: Invoke SSR from within the watchdog IRQ handler
To account for corner cases during system suspend, the
subsystem restart API needs to be invoked directly
from within the context of the watchdog interrupt
handler. Call subsystem_restart from within the modem
FW/SW watchdog bite handler instead of scheduling
a work item to do the same.
CRs-Fixed: 367923
Change-Id: I7b6e56d60accf5eeb6abffc41f304755f9e11ccb
Signed-off-by: Vikram Mulukutla <markivx@codeaurora.org>
diff --git a/arch/arm/mach-msm/modem-8960.c b/arch/arm/mach-msm/modem-8960.c
index 824178f..5d02bda 100644
--- a/arch/arm/mach-msm/modem-8960.c
+++ b/arch/arm/mach-msm/modem-8960.c
@@ -63,6 +63,12 @@
wmb();
}
+static void restart_modem(void)
+{
+ log_modem_sfr();
+ subsystem_restart("modem");
+}
+
static void modem_wdog_check(struct work_struct *work)
{
void __iomem *q6_sw_wdog_addr;
@@ -75,8 +81,7 @@
regval = readl_relaxed(q6_sw_wdog_addr);
if (!regval) {
pr_err("modem-8960: Modem watchdog wasn't activated!. Restarting the modem now.\n");
- log_modem_sfr();
- subsystem_restart("modem");
+ restart_modem();
}
iounmap(q6_sw_wdog_addr);
@@ -84,23 +89,6 @@
static DECLARE_DELAYED_WORK(modem_wdog_check_work, modem_wdog_check);
-static void modem_sw_fatal_fn(struct work_struct *work)
-{
- pr_err("Watchdog bite received from modem SW!\n");
- log_modem_sfr();
- subsystem_restart("modem");
-}
-
-static void modem_fw_fatal_fn(struct work_struct *work)
-{
- pr_err("Watchdog bite received from modem FW!\n");
- log_modem_sfr();
- subsystem_restart("modem");
-}
-
-static DECLARE_WORK(modem_sw_fatal_work, modem_sw_fatal_fn);
-static DECLARE_WORK(modem_fw_fatal_work, modem_fw_fatal_fn);
-
static void smsm_state_cb(void *data, uint32_t old_state, uint32_t new_state)
{
/* Ignore if we're the one that set SMSM_RESET */
@@ -109,8 +97,7 @@
if (new_state & SMSM_RESET) {
pr_err("Probable fatal error on the modem.\n");
- log_modem_sfr();
- subsystem_restart("modem");
+ restart_modem();
}
}
@@ -228,15 +215,15 @@
static irqreturn_t modem_wdog_bite_irq(int irq, void *dev_id)
{
- int ret;
-
switch (irq) {
case Q6SW_WDOG_EXPIRED_IRQ:
- ret = schedule_work(&modem_sw_fatal_work);
+ pr_err("Watchdog bite received from modem software!\n");
+ restart_modem();
break;
case Q6FW_WDOG_EXPIRED_IRQ:
- ret = schedule_work(&modem_fw_fatal_work);
+ pr_err("Watchdog bite received from modem firmware!\n");
+ restart_modem();
break;
break;