mdm2: Disconnect and connect hsic when mdm status goes high

Once all the images are downloaded to mdm(using flashless-boot
procedure) mdm will boot to HLOS(high-level os) and will turn on
hsic controller. mdm staus gpio will be pulled high during early
stages of HLOS. Indicate hsic disconnection/connection when mdm
status gpio goes high.

Change-Id: Ib014404ddde39313e6c6347664ed17360e8a8908
Signed-off-by: Vamsi Krishna <vskrishn@codeaurora.org>
Signed-off-by: Ramakrishna Prasad N <crpn@codeaurora.org>
diff --git a/arch/arm/mach-msm/mdm2.c b/arch/arm/mach-msm/mdm2.c
index 91f8fc2..bf4e6a4 100644
--- a/arch/arm/mach-msm/mdm2.c
+++ b/arch/arm/mach-msm/mdm2.c
@@ -116,6 +116,16 @@
 	mdm_debug_on = value;
 }
 
+static void mdm_status_changed(int value)
+{
+	MDM_DBG("%s: value:%d\n", __func__, value);
+
+	if (value) {
+		peripheral_disconnect();
+		peripheral_connect();
+	}
+}
+
 static int __init mdm_modem_probe(struct platform_device *pdev)
 {
 	/* Instantiate driver object. */
@@ -123,6 +133,7 @@
 	mdm_cb.power_down_mdm_cb = power_down_mdm;
 	mdm_cb.normal_boot_done_cb = normal_boot_done;
 	mdm_cb.debug_state_changed_cb = debug_state_changed;
+	mdm_cb.status_cb = mdm_status_changed;
 	return mdm_common_create(pdev, &mdm_cb);
 }
 
diff --git a/arch/arm/mach-msm/mdm_common.c b/arch/arm/mach-msm/mdm_common.c
index 1262ce3..023df69 100644
--- a/arch/arm/mach-msm/mdm_common.c
+++ b/arch/arm/mach-msm/mdm_common.c
@@ -136,8 +136,18 @@
 
 static void mdm_status_fn(struct work_struct *work)
 {
-	MDM_DBG("%s: Reseting the mdm because status changed\n", __func__);
-	subsystem_restart(EXTERNAL_MODEM);
+	int value = gpio_get_value(mdm_drv->mdm2ap_status_gpio);
+
+	mdm_drv->status_cb(value);
+
+	MDM_DBG("%s: status:%d\n", __func__, value);
+
+	if ((value == 0) && mdm_drv->mdm_ready) {
+		MDM_DBG("%s: scheduling work now\n", __func__);
+		subsystem_restart(EXTERNAL_MODEM);
+	} else if (value == 1) {
+		MDM_DBG("%s: mdm is now ready\n", __func__);
+	}
 }
 
 static DECLARE_WORK(mdm_status_work, mdm_status_fn);
@@ -209,13 +219,9 @@
 static irqreturn_t mdm_status_change(int irq, void *dev_id)
 {
 	MDM_DBG("%s: mdm sent status change interrupt\n", __func__);
-	if ((gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0)
-		 && mdm_drv->mdm_ready) {
-		MDM_DBG("%s: scheduling work now\n", __func__);
-		queue_work(mdm_queue, &mdm_status_work);
-	} else if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 1) {
-		MDM_DBG("%s: mdm is now ready\n", __func__);
-	}
+
+	queue_work(mdm_queue, &mdm_status_work);
+
 	return IRQ_HANDLED;
 }
 
@@ -350,6 +356,7 @@
 	mdm_drv->power_down_mdm_cb          = p_mdm_cb->power_down_mdm_cb;
 	mdm_drv->normal_boot_done_cb        = p_mdm_cb->normal_boot_done_cb;
 	mdm_drv->debug_state_changed_cb     = p_mdm_cb->debug_state_changed_cb;
+	mdm_drv->status_cb                  = p_mdm_cb->status_cb;
 }
 
 int mdm_common_create(struct platform_device  *pdev,
@@ -432,8 +439,8 @@
 	}
 
 	ret = request_threaded_irq(irq, NULL, mdm_status_change,
-		IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-		"mdm status", NULL);
+		IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_SHARED,
+		"mdm status", mdm_drv);
 
 	if (ret < 0) {
 		pr_err("%s: MDM2AP_STATUS IRQ#%d request failed with error=%d"
diff --git a/arch/arm/mach-msm/mdm_private.h b/arch/arm/mach-msm/mdm_private.h
index 701eb7a..bc8541e 100644
--- a/arch/arm/mach-msm/mdm_private.h
+++ b/arch/arm/mach-msm/mdm_private.h
@@ -38,6 +38,7 @@
 	void (*normal_boot_done_cb)(struct mdm_modem_drv *mdm_drv);
 	void (*power_down_mdm_cb)(struct mdm_modem_drv *mdm_drv);
 	void (*debug_state_changed_cb)(int value);
+	void (*status_cb)(int value);
 };
 
 struct mdm_callbacks {
@@ -45,6 +46,7 @@
 	void (*normal_boot_done_cb)(struct mdm_modem_drv *mdm_drv);
 	void (*power_down_mdm_cb)(struct mdm_modem_drv *mdm_drv);
 	void (*debug_state_changed_cb)(int value);
+	void (*status_cb)(int value);
 };
 
 int mdm_common_create(struct platform_device  *pdev,