From 2e4946a60e539d649fcce01cf55d642dd720cfaf Mon Sep 17 00:00:00 2001
From: tzuhsuan_chen <tzuhsuan_chen@asus.com>
Date: Sun, 17 Nov 2013 22:12:22 -0500
Subject: [PATCH] deb: mdm: Implement RESET_CHARM in the ioctl function.

Use RESET_CHARM to do subsystem-restart.

Change-Id: I90adbfcad310d7f1c95c93cc4f713ca282456060
Signed-off-by: tzuhsuan_chen <tzuhsuan_chen@asus.com>
---
 arch/arm/mach-msm/mdm_common.c | 35 ++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/arch/arm/mach-msm/mdm_common.c b/arch/arm/mach-msm/mdm_common.c
index 1c10427d878f..2d3ee6305879 100644
--- a/arch/arm/mach-msm/mdm_common.c
+++ b/arch/arm/mach-msm/mdm_common.c
@@ -111,6 +111,7 @@ static DEFINE_SPINLOCK(ssr_lock);
 static unsigned int mdm_debug_mask;
 int vddmin_gpios_sent;
 static struct mdm_ops *mdm_ops;
+static struct mutex restart_lock;
 
 static void mdm_device_list_add(struct mdm_device *mdev)
 {
@@ -361,6 +362,32 @@ static void mdm_update_gpio_configs(struct mdm_device *mdev,
 	}
 }
 
+static int reset_mdm(struct mdm_modem_drv *mdm_drv)
+{
+	int value;
+
+	pr_info("%s++\n", __func__);
+
+	if (!mutex_trylock(&restart_lock))
+		return -EINVAL;
+
+	value = gpio_get_value(mdm_drv->mdm2ap_status_gpio);
+	if (value == 0 || atomic_read(&mdm_drv->mdm_ready) == 0) {
+		pr_err("%s: mdm_status = %d, mdm_ready = %d, return\n",
+			__func__, value, atomic_read(&mdm_drv->mdm_ready));
+		mutex_unlock(&restart_lock);
+		return -EINVAL;
+	}
+
+	atomic_set(&mdm_drv->mdm_ready, 0);
+	mutex_unlock(&restart_lock);
+
+	subsystem_restart(EXTERNAL_MODEM);
+
+	pr_info("%s--\n", __func__);
+	return 0;
+}
+
 static long mdm_modem_ioctl(struct file *filp, unsigned int cmd,
 				unsigned long arg)
 {
@@ -383,6 +410,10 @@ static long mdm_modem_ioctl(struct file *filp, unsigned int cmd,
 				__func__, mdev->mdm_data.device_id);
 		mdm_ops->power_on_mdm_cb(mdm_drv);
 		break;
+	case RESET_CHARM:
+		pr_info("RESET_CHARM");
+		ret = reset_mdm(mdm_drv);
+		break;
 	case CHECK_FOR_BOOT:
 		if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0)
 			put_user(1, (unsigned long __user *) arg);
@@ -1089,6 +1120,8 @@ static int __devinit mdm_modem_probe(struct platform_device *pdev)
 			mdm_ops->power_on_mdm_cb(&mdev->mdm_data);
 	}
 
+	mutex_init(&restart_lock);
+
 	return ret;
 
 init_err:
@@ -1107,6 +1140,8 @@ static int __devexit mdm_modem_remove(struct platform_device *pdev)
 	ret = misc_deregister(&mdev->misc_device);
 	mdm_device_list_remove(mdev);
 	kfree(mdev);
+	mutex_destroy(&restart_lock);
+
 	return ret;
 }
 
-- 
GitLab