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>
This commit is contained in:
Joel King
2012-09-30 12:43:15 -07:00
parent 069dcbcc07
commit bf3e4b526c
6 changed files with 23 additions and 1 deletions
+1
View File
@@ -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,
+1
View File
@@ -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
+5 -1
View File
@@ -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) {
+14
View File
@@ -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__);
+1
View File
@@ -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;
+1
View File
@@ -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,