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/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 07acac6..f63f275 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1930,6 +1930,7 @@
.ramdump_delay_ms = 2000,
.early_power_on = 1,
.sfr_query = 1,
+ .send_shdn = 1,
.vddmin_resource = &mdm_vddmin_rscs,
.peripheral_platform_device = &apq8064_device_hsic_host,
.ramdump_timeout_ms = 120000,
diff --git a/arch/arm/mach-msm/include/mach/mdm2.h b/arch/arm/mach-msm/include/mach/mdm2.h
index 6ec12c1..fd63fd2 100644
--- a/arch/arm/mach-msm/include/mach/mdm2.h
+++ b/arch/arm/mach-msm/include/mach/mdm2.h
@@ -33,6 +33,7 @@
const unsigned int ramdump_timeout_ms;
int image_upgrade_supported;
struct gpiomux_setting *mdm2ap_status_gpio_run_cfg;
+ int send_shdn;
};
#endif
diff --git a/arch/arm/mach-msm/mdm2.c b/arch/arm/mach-msm/mdm2.c
index f548417..77eeb53 100644
--- a/arch/arm/mach-msm/mdm2.c
+++ b/arch/arm/mach-msm/mdm2.c
@@ -110,8 +110,12 @@
/* Wait for the modem to complete its power down actions. */
for (i = 20; i > 0; i--) {
- if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0)
+ if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0) {
+ if (mdm_debug_mask & MDM_DEBUG_MASK_SHDN_LOG)
+ pr_info("%s: mdm2ap_status went low, i = %d\n",
+ __func__, i);
break;
+ }
msleep(100);
}
if (i == 0) {
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__);
diff --git a/arch/arm/mach-msm/mdm_private.h b/arch/arm/mach-msm/mdm_private.h
index c406b89a..9e865c5 100644
--- a/arch/arm/mach-msm/mdm_private.h
+++ b/arch/arm/mach-msm/mdm_private.h
@@ -14,6 +14,7 @@
#define _ARCH_ARM_MACH_MSM_MDM_PRIVATE_H
#define MDM_DEBUG_MASK_VDDMIN_SETUP (0x00000002)
+#define MDM_DEBUG_MASK_SHDN_LOG (0x00000004)
#define GPIO_IS_VALID(gpio) \
(gpio != -1)
struct mdm_modem_drv;
diff --git a/include/linux/msm_charm.h b/include/linux/msm_charm.h
index 44d2553..1d1f3bb 100644
--- a/include/linux/msm_charm.h
+++ b/include/linux/msm_charm.h
@@ -12,6 +12,7 @@
#define WAIT_FOR_RESTART _IOR(CHARM_CODE, 7, int)
#define GET_DLOAD_STATUS _IOR(CHARM_CODE, 8, int)
#define IMAGE_UPGRADE _IOW(CHARM_CODE, 9, int)
+#define SHUTDOWN_CHARM _IOW(CHARM_CODE, 10, int)
enum charm_boot_type {
CHARM_NORMAL_BOOT = 0,