msm: modem-8960: Implement subsystem restart phase 3
Implement functionality to allow the modem to be
restarted independent of other subsystems.
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 907a1cf..8baa800 100644
--- a/arch/arm/mach-msm/modem-8960.c
+++ b/arch/arm/mach-msm/modem-8960.c
@@ -89,13 +89,32 @@
static int modem_shutdown(const struct subsys_data *subsys)
{
- /* TODO: Call into PIL to shutdown the modem */
+ int smsm_notif_unregistered = 0;
+
+ if (!(smsm_get_state(SMSM_MODEM_STATE) & SMSM_RESET)) {
+ smsm_state_cb_deregister(SMSM_MODEM_STATE, SMSM_RESET,
+ smsm_state_cb, 0);
+ smsm_notif_unregistered = 1;
+ smsm_reset_modem(SMSM_RESET);
+ }
+
+ pil_force_shutdown("modem");
+ disable_irq_nosync(Q6FW_WDOG_EXPIRED_IRQ);
+ disable_irq_nosync(Q6SW_WDOG_EXPIRED_IRQ);
+
+ if (smsm_notif_unregistered)
+ smsm_state_cb_register(SMSM_MODEM_STATE, SMSM_RESET,
+ smsm_state_cb, 0);
+
return 0;
}
static int modem_powerup(const struct subsys_data *subsys)
{
/* TODO: Call into PIL to powerup the modem */
+ pil_force_boot("modem");
+ enable_irq(Q6FW_WDOG_EXPIRED_IRQ);
+ enable_irq(Q6SW_WDOG_EXPIRED_IRQ);
return 0;
}
@@ -119,9 +138,11 @@
case Q6SW_WDOG_EXPIRED_IRQ:
ret = schedule_work(&modem_sw_fatal_work);
disable_irq_nosync(Q6SW_WDOG_EXPIRED_IRQ);
+ disable_irq_nosync(Q6FW_WDOG_EXPIRED_IRQ);
break;
case Q6FW_WDOG_EXPIRED_IRQ:
ret = schedule_work(&modem_fw_fatal_work);
+ disable_irq_nosync(Q6SW_WDOG_EXPIRED_IRQ);
disable_irq_nosync(Q6FW_WDOG_EXPIRED_IRQ);
break;
break;
@@ -148,11 +169,8 @@
static int modem_debug_set(void *data, u64 val)
{
- if (val == 1) {
- pr_info("%s: Intentionally setting the SMSM_RESET bit.\n",
- __func__);
- smsm_reset_modem(SMSM_RESET);
- }
+ if (val == 1)
+ subsystem_restart("modem");
return 0;
}