msm: mdm: add a timer to check that mdm2ap_status gpio goes high
The timer is started after flashless boot is completed but before
the mdm2ap_status gpio is pulled high by the external modem. If
the mdm2ap_status gpio does not go high within a period of time
a subsystem restart is initiated.
CRs-Fixed: 358868
Change-Id: Iba410a38a0b21fea8425c7e5a47bfec5f3a203e7
Signed-off-by: Joel King <joelking@codeaurora.org>
diff --git a/arch/arm/mach-msm/mdm_common.c b/arch/arm/mach-msm/mdm_common.c
index ffff782..74bf25d 100644
--- a/arch/arm/mach-msm/mdm_common.c
+++ b/arch/arm/mach-msm/mdm_common.c
@@ -45,6 +45,7 @@
#define MDM_MODEM_DELTA 100
#define MDM_BOOT_TIMEOUT 60000L
#define MDM_RDUMP_TIMEOUT 60000L
+#define MDM2AP_STATUS_TIMEOUT_MS 60000L
static int mdm_debug_on;
static struct workqueue_struct *mdm_queue;
@@ -90,6 +91,22 @@
static DECLARE_WORK(sfr_reason_work, mdm_restart_reason_fn);
+static void mdm2ap_status_check(struct work_struct *work)
+{
+ /*
+ * If the mdm modem did not pull the MDM2AP_STATUS gpio
+ * high then call subsystem_restart.
+ */
+ if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0) {
+ pr_err("%s: MDM2AP_STATUS gpio did not go high\n",
+ __func__);
+ mdm_drv->mdm_ready = 0;
+ subsystem_restart(EXTERNAL_MODEM);
+ }
+}
+
+static DECLARE_DELAYED_WORK(mdm2ap_status_check_work, mdm2ap_status_check);
+
long mdm_modem_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
@@ -131,6 +148,14 @@
complete(&mdm_boot);
else
first_boot = 0;
+
+ /* Start a timer to check that the mdm2ap_status gpio
+ * goes high.
+ */
+
+ if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0)
+ schedule_delayed_work(&mdm2ap_status_check_work,
+ msecs_to_jiffies(MDM2AP_STATUS_TIMEOUT_MS));
break;
case RAM_DUMP_DONE:
pr_debug("%s: mdm done collecting RAM dumps\n", __func__);
@@ -256,6 +281,7 @@
mdm_drv->mdm_ready = 0;
subsystem_restart(EXTERNAL_MODEM);
} else if (value == 1) {
+ cancel_delayed_work(&mdm2ap_status_check_work);
pr_info("%s: status = 1: mdm is now ready\n", __func__);
queue_work(mdm_queue, &mdm_status_work);
}