From bf3e4b526c55ea765a92f54cf91540330d0b75ae Mon Sep 17 00:00:00 2001 From: Joel King Date: Wed, 26 Sep 2012 09:10:34 -0700 Subject: [PATCH] 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 --- arch/arm/mach-msm/board-8064.c | 1 + arch/arm/mach-msm/include/mach/mdm2.h | 1 + arch/arm/mach-msm/mdm2.c | 6 +++++- arch/arm/mach-msm/mdm_common.c | 14 ++++++++++++++ arch/arm/mach-msm/mdm_private.h | 1 + include/linux/msm_charm.h | 1 + 6 files changed, 23 insertions(+), 1 deletion(-) 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,