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. Crs-Fixed: 401598 Signed-off-by: Joel King <joelking@codeaurora.org>
This commit is contained in:
committed by
Iliyan Malchev
parent
d44697e328
commit
613e3b6f4c
@@ -112,8 +112,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) {
|
||||
|
||||
@@ -290,6 +290,15 @@ long mdm_modem_ioctl(struct file *filp, unsigned int cmd,
|
||||
} else
|
||||
pr_debug("%s Image upgrade not supported\n", __func__);
|
||||
break;
|
||||
case SHUTDOWN_CHARM:
|
||||
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 +391,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__);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -158,6 +158,33 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* sysmon_send_shutdown() - send shutdown command to a
|
||||
* subsystem.
|
||||
* @dest_ss: ID of subsystem to send to.
|
||||
*
|
||||
* Returns 0 for success, -EINVAL for an invalid destination, -ENODEV if
|
||||
* the SMD transport channel is not open, -ETIMEDOUT if the destination
|
||||
* subsystem does not respond, and -ENOSYS if the destination subsystem
|
||||
* responds with something unexpected.
|
||||
*
|
||||
* If CONFIG_MSM_SYSMON_COMM is not defined, always return success (0).
|
||||
*/
|
||||
int sysmon_send_shutdown(enum subsys_id dest_ss)
|
||||
{
|
||||
struct sysmon_subsys *ss = &subsys[dest_ss];
|
||||
const char tx_buf[] = "ssr:poweroff";
|
||||
int ret;
|
||||
|
||||
if (dest_ss < 0 || dest_ss >= SYSMON_NUM_SS)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&ss->lock);
|
||||
ret = sysmon_send_msg(ss, tx_buf, ARRAY_SIZE(tx_buf));
|
||||
mutex_unlock(&ss->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* sysmon_get_reason() - Retrieve failure reason from a subsystem.
|
||||
* @dest_ss: ID of subsystem to query
|
||||
|
||||
@@ -38,6 +38,7 @@ enum subsys_id {
|
||||
int sysmon_send_event(enum subsys_id dest_ss, const char *event_ss,
|
||||
enum subsys_notif_type notif);
|
||||
int sysmon_get_reason(enum subsys_id dest_ss, char *buf, size_t len);
|
||||
int sysmon_send_shutdown(enum subsys_id dest_ss);
|
||||
#else
|
||||
static inline int sysmon_send_event(enum subsys_id dest_ss,
|
||||
const char *event_ss,
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user