diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c index 07acac68123..f63f275bdd5 100644 --- a/arch/arm/mach-msm/board-8064.c +++ b/arch/arm/mach-msm/board-8064.c @@ -1930,6 +1930,7 @@ static struct mdm_platform_data mdm_platform_data = { .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 6ec12c1d2a1..fd63fd28ff3 100644 --- a/arch/arm/mach-msm/include/mach/mdm2.h +++ b/arch/arm/mach-msm/include/mach/mdm2.h @@ -33,6 +33,7 @@ struct mdm_platform_data { 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 f5484171d11..77eeb530ff3 100644 --- a/arch/arm/mach-msm/mdm2.c +++ b/arch/arm/mach-msm/mdm2.c @@ -110,8 +110,12 @@ static void mdm_power_down_common(struct mdm_modem_drv *mdm_drv) /* 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 ea15a173f5b..58b26f201ae 100644 --- a/arch/arm/mach-msm/mdm_common.c +++ b/arch/arm/mach-msm/mdm_common.c @@ -290,6 +290,17 @@ long mdm_modem_ioctl(struct file *filp, unsigned int cmd, } 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 @@ static irqreturn_t mdm_status_change(int irq, void *dev_id) { 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 c406b89adc8..9e865c5adee 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 44d25532f1e..1d1f3bb3dd4 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,