msm: mdm: Add shutdown ioctl and send poweroff request to the mdm

When the whole phone is being powered off, a poweroff request needs
to be sent to the external modem so that it can shutdown gracefully.
This request needs to be triggered from userspace before kernel drivers
start unloading so that other drivers needed to send the request are
still available. The shutdown ioctl is provided for this purpose.
The request is sent over system monitor.

Since the mdm driver is common to platforms that support sysmon as
well as those that don't, a platform specific flag named send_shdn
is added for runtime detection.

Crs-Fixed: 401598
Change-Id: I53231579ae4f7e794725165439183c29ca977d62
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 ea15a17..58b26f2 100644
--- a/arch/arm/mach-msm/mdm_common.c
+++ b/arch/arm/mach-msm/mdm_common.c
@@ -290,6 +290,17 @@
 		} else
 			pr_debug("%s Image upgrade not supported\n", __func__);
 		break;
+	case SHUTDOWN_CHARM:
+		if (!mdm_drv->pdata->send_shdn)
+			break;
+		mdm_drv->mdm_ready = 0;
+		if (mdm_debug_mask & MDM_DEBUG_MASK_SHDN_LOG)
+			pr_info("Sending shutdown request to mdm\n");
+		ret = sysmon_send_shutdown(SYSMON_SS_EXT_MODEM);
+		if (ret)
+			pr_err("%s: Graceful shutdown of the external modem failed, ret = %d\n",
+				   __func__, ret);
+		break;
 	default:
 		pr_err("%s: invalid ioctl cmd = %d\n", __func__, _IOC_NR(cmd));
 		ret = -EINVAL;
@@ -382,6 +393,9 @@
 {
 	int value = gpio_get_value(mdm_drv->mdm2ap_status_gpio);
 
+	if ((mdm_debug_mask & MDM_DEBUG_MASK_SHDN_LOG) && (value == 0))
+		pr_info("%s: mdm2ap_status went low\n", __func__);
+
 	pr_debug("%s: mdm sent status change interrupt\n", __func__);
 	if (value == 0 && mdm_drv->mdm_ready == 1) {
 		pr_info("%s: unexpected reset external modem\n", __func__);