msm: mdm: Add support for remote MDM image upgrade
mdm-driver is informed that an image upgrade of the remote modem is required, at which point it stops monitoring the error gpios and takes the appropriate actions. Support for the "USB Switch" gpio is added. This is needed to write a image to an empty modem flash. Change-Id: I4c05a80955124a3eb7edc11e99f4945f9de79e6b Signed-off-by: Ameya Thakur <ameyat@codeaurora.org>
This commit is contained in:
committed by
Stephen Boyd
parent
6c84e45301
commit
27a0e1f889
@@ -240,6 +240,12 @@ static struct gpiomux_setting ap2mdm_kpdpwr_n_cfg = {
|
|||||||
.pull = GPIOMUX_PULL_DOWN,
|
.pull = GPIOMUX_PULL_DOWN,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct gpiomux_setting usbsw_cfg = {
|
||||||
|
.func = GPIOMUX_FUNC_GPIO,
|
||||||
|
.drv = GPIOMUX_DRV_8MA,
|
||||||
|
.pull = GPIOMUX_PULL_DOWN,
|
||||||
|
};
|
||||||
|
|
||||||
static struct gpiomux_setting mdp_vsync_suspend_cfg = {
|
static struct gpiomux_setting mdp_vsync_suspend_cfg = {
|
||||||
.func = GPIOMUX_FUNC_GPIO,
|
.func = GPIOMUX_FUNC_GPIO,
|
||||||
.drv = GPIOMUX_DRV_2MA,
|
.drv = GPIOMUX_DRV_2MA,
|
||||||
@@ -760,6 +766,13 @@ static struct msm_gpiomux_config sglte_configs[] __initdata = {
|
|||||||
[GPIOMUX_SUSPENDED] = &ap2mdm_cfg,
|
[GPIOMUX_SUSPENDED] = &ap2mdm_cfg,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/* USB_SW */
|
||||||
|
{
|
||||||
|
.gpio = 25,
|
||||||
|
.settings = {
|
||||||
|
[GPIOMUX_SUSPENDED] = &usbsw_cfg,
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct msm_gpiomux_config msm8960_mdp_vsync_configs[] __initdata = {
|
static struct msm_gpiomux_config msm8960_mdp_vsync_configs[] __initdata = {
|
||||||
|
|||||||
@@ -1293,6 +1293,7 @@ static struct mdm_platform_data sglte_platform_data = {
|
|||||||
.peripheral_platform_device = NULL,
|
.peripheral_platform_device = NULL,
|
||||||
.ramdump_timeout_ms = 600000,
|
.ramdump_timeout_ms = 600000,
|
||||||
.no_powerdown_after_ramdumps = 1,
|
.no_powerdown_after_ramdumps = 1,
|
||||||
|
.image_upgrade_supported = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MSM_TSIF0_PHYS (0x18200000)
|
#define MSM_TSIF0_PHYS (0x18200000)
|
||||||
|
|||||||
@@ -3812,6 +3812,7 @@ struct platform_device msm8960_cache_dump_device = {
|
|||||||
#define AP2MDM_PMIC_PWR_EN 22
|
#define AP2MDM_PMIC_PWR_EN 22
|
||||||
#define AP2MDM_KPDPWR_N 79
|
#define AP2MDM_KPDPWR_N 79
|
||||||
#define AP2MDM_SOFT_RESET 78
|
#define AP2MDM_SOFT_RESET 78
|
||||||
|
#define USB_SW 25
|
||||||
|
|
||||||
static struct resource sglte_resources[] = {
|
static struct resource sglte_resources[] = {
|
||||||
{
|
{
|
||||||
@@ -3856,6 +3857,12 @@ static struct resource sglte_resources[] = {
|
|||||||
.name = "AP2MDM_SOFT_RESET",
|
.name = "AP2MDM_SOFT_RESET",
|
||||||
.flags = IORESOURCE_IO,
|
.flags = IORESOURCE_IO,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.start = USB_SW,
|
||||||
|
.end = USB_SW,
|
||||||
|
.name = "USB_SW",
|
||||||
|
.flags = IORESOURCE_IO,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
struct platform_device mdm_sglte_device = {
|
struct platform_device mdm_sglte_device = {
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ struct mdm_platform_data {
|
|||||||
struct mdm_vddmin_resource *vddmin_resource;
|
struct mdm_vddmin_resource *vddmin_resource;
|
||||||
struct platform_device *peripheral_platform_device;
|
struct platform_device *peripheral_platform_device;
|
||||||
const unsigned int ramdump_timeout_ms;
|
const unsigned int ramdump_timeout_ms;
|
||||||
|
int image_upgrade_supported;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -249,6 +249,33 @@ static void mdm_status_changed(struct mdm_modem_drv *mdm_drv, int value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mdm_image_upgrade(struct mdm_modem_drv *mdm_drv, int type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case APQ_CONTROLLED_UPGRADE:
|
||||||
|
pr_debug("%s APQ controlled modem image upgrade\n", __func__);
|
||||||
|
mdm_drv->mdm_ready = 0;
|
||||||
|
mdm_toggle_soft_reset(mdm_drv);
|
||||||
|
break;
|
||||||
|
case MDM_CONTROLLED_UPGRADE:
|
||||||
|
pr_debug("%s MDM controlled modem image upgrade\n", __func__);
|
||||||
|
mdm_drv->mdm_ready = 0;
|
||||||
|
/*
|
||||||
|
* If we have no image currently present on the modem, then we
|
||||||
|
* would be in PBL, in which case the status gpio would not go
|
||||||
|
* high.
|
||||||
|
*/
|
||||||
|
mdm_drv->disable_status_check = 1;
|
||||||
|
if (mdm_drv->usb_switch_gpio > 0) {
|
||||||
|
pr_info("%s Switching usb control to MDM\n", __func__);
|
||||||
|
gpio_direction_output(mdm_drv->usb_switch_gpio, 1);
|
||||||
|
} else
|
||||||
|
pr_err("%s usb switch gpio unavailable\n", __func__);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pr_err("%s invalid upgrade type\n", __func__);
|
||||||
|
}
|
||||||
|
}
|
||||||
static struct mdm_ops mdm_cb = {
|
static struct mdm_ops mdm_cb = {
|
||||||
.power_on_mdm_cb = mdm_power_on_common,
|
.power_on_mdm_cb = mdm_power_on_common,
|
||||||
.reset_mdm_cb = mdm_power_on_common,
|
.reset_mdm_cb = mdm_power_on_common,
|
||||||
@@ -256,6 +283,7 @@ static struct mdm_ops mdm_cb = {
|
|||||||
.power_down_mdm_cb = mdm_power_down_common,
|
.power_down_mdm_cb = mdm_power_down_common,
|
||||||
.debug_state_changed_cb = debug_state_changed,
|
.debug_state_changed_cb = debug_state_changed,
|
||||||
.status_cb = mdm_status_changed,
|
.status_cb = mdm_status_changed,
|
||||||
|
.image_upgrade_cb = mdm_image_upgrade,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init mdm_modem_probe(struct platform_device *pdev)
|
static int __init mdm_modem_probe(struct platform_device *pdev)
|
||||||
|
|||||||
@@ -151,11 +151,13 @@ static void mdm2ap_status_check(struct work_struct *work)
|
|||||||
* If the mdm modem did not pull the MDM2AP_STATUS gpio
|
* If the mdm modem did not pull the MDM2AP_STATUS gpio
|
||||||
* high then call subsystem_restart.
|
* high then call subsystem_restart.
|
||||||
*/
|
*/
|
||||||
if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0) {
|
if (!mdm_drv->disable_status_check) {
|
||||||
pr_err("%s: MDM2AP_STATUS gpio did not go high\n",
|
if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0) {
|
||||||
__func__);
|
pr_err("%s: MDM2AP_STATUS gpio did not go high\n",
|
||||||
mdm_drv->mdm_ready = 0;
|
__func__);
|
||||||
subsystem_restart_dev(mdm_subsys_dev);
|
mdm_drv->mdm_ready = 0;
|
||||||
|
subsystem_restart_dev(mdm_subsys_dev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,6 +241,15 @@ long mdm_modem_ioctl(struct file *filp, unsigned int cmd,
|
|||||||
else
|
else
|
||||||
put_user(0, (unsigned long __user *) arg);
|
put_user(0, (unsigned long __user *) arg);
|
||||||
break;
|
break;
|
||||||
|
case IMAGE_UPGRADE:
|
||||||
|
pr_debug("%s Image upgrade ioctl recieved\n", __func__);
|
||||||
|
if (mdm_drv->pdata->image_upgrade_supported &&
|
||||||
|
mdm_drv->ops->image_upgrade_cb) {
|
||||||
|
get_user(status, (unsigned long __user *) arg);
|
||||||
|
mdm_drv->ops->image_upgrade_cb(mdm_drv, status);
|
||||||
|
} else
|
||||||
|
pr_debug("%s Image upgrade not supported\n", __func__);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
pr_err("%s: invalid ioctl cmd = %d\n", __func__, _IOC_NR(cmd));
|
pr_err("%s: invalid ioctl cmd = %d\n", __func__, _IOC_NR(cmd));
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
@@ -364,7 +375,6 @@ static int mdm_subsys_shutdown(const struct subsys_desc *crashed_subsys)
|
|||||||
mdm_drv->ops->reset_mdm_cb(mdm_drv);
|
mdm_drv->ops->reset_mdm_cb(mdm_drv);
|
||||||
else
|
else
|
||||||
mdm_drv->mdm_unexpected_reset_occurred = 0;
|
mdm_drv->mdm_unexpected_reset_occurred = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -515,6 +525,12 @@ static void mdm_modem_initialize_data(struct platform_device *pdev,
|
|||||||
if (pres)
|
if (pres)
|
||||||
mdm_drv->mdm2ap_pblrdy = pres->start;
|
mdm_drv->mdm2ap_pblrdy = pres->start;
|
||||||
|
|
||||||
|
/*USB_SW*/
|
||||||
|
pres = platform_get_resource_byname(pdev, IORESOURCE_IO,
|
||||||
|
"USB_SW");
|
||||||
|
if (pres)
|
||||||
|
mdm_drv->usb_switch_gpio = pres->start;
|
||||||
|
|
||||||
mdm_drv->boot_type = CHARM_NORMAL_BOOT;
|
mdm_drv->boot_type = CHARM_NORMAL_BOOT;
|
||||||
|
|
||||||
mdm_drv->ops = mdm_ops;
|
mdm_drv->ops = mdm_ops;
|
||||||
@@ -557,6 +573,13 @@ int mdm_common_create(struct platform_device *pdev,
|
|||||||
if (mdm_drv->ap2mdm_wakeup_gpio > 0)
|
if (mdm_drv->ap2mdm_wakeup_gpio > 0)
|
||||||
gpio_request(mdm_drv->ap2mdm_wakeup_gpio, "AP2MDM_WAKEUP");
|
gpio_request(mdm_drv->ap2mdm_wakeup_gpio, "AP2MDM_WAKEUP");
|
||||||
|
|
||||||
|
if (mdm_drv->usb_switch_gpio > 0) {
|
||||||
|
if (gpio_request(mdm_drv->usb_switch_gpio, "USB_SW")) {
|
||||||
|
pr_err("%s Failed to get usb switch gpio\n", __func__);
|
||||||
|
mdm_drv->usb_switch_gpio = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gpio_direction_output(mdm_drv->ap2mdm_status_gpio, 1);
|
gpio_direction_output(mdm_drv->ap2mdm_status_gpio, 1);
|
||||||
gpio_direction_output(mdm_drv->ap2mdm_errfatal_gpio, 0);
|
gpio_direction_output(mdm_drv->ap2mdm_errfatal_gpio, 0);
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ struct mdm_ops {
|
|||||||
void (*power_down_mdm_cb)(struct mdm_modem_drv *mdm_drv);
|
void (*power_down_mdm_cb)(struct mdm_modem_drv *mdm_drv);
|
||||||
void (*debug_state_changed_cb)(int value);
|
void (*debug_state_changed_cb)(int value);
|
||||||
void (*status_cb)(struct mdm_modem_drv *mdm_drv, int value);
|
void (*status_cb)(struct mdm_modem_drv *mdm_drv, int value);
|
||||||
|
void (*image_upgrade_cb)(struct mdm_modem_drv *mdm_drv, int type);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Private mdm2 data structure */
|
/* Private mdm2 data structure */
|
||||||
@@ -37,6 +38,7 @@ struct mdm_modem_drv {
|
|||||||
unsigned ap2mdm_soft_reset_gpio;
|
unsigned ap2mdm_soft_reset_gpio;
|
||||||
unsigned ap2mdm_pmic_pwr_en_gpio;
|
unsigned ap2mdm_pmic_pwr_en_gpio;
|
||||||
unsigned mdm2ap_pblrdy;
|
unsigned mdm2ap_pblrdy;
|
||||||
|
unsigned usb_switch_gpio;
|
||||||
|
|
||||||
int mdm_errfatal_irq;
|
int mdm_errfatal_irq;
|
||||||
int mdm_status_irq;
|
int mdm_status_irq;
|
||||||
@@ -46,6 +48,7 @@ struct mdm_modem_drv {
|
|||||||
enum charm_boot_type boot_type;
|
enum charm_boot_type boot_type;
|
||||||
int mdm_debug_on;
|
int mdm_debug_on;
|
||||||
int mdm_unexpected_reset_occurred;
|
int mdm_unexpected_reset_occurred;
|
||||||
|
int disable_status_check;
|
||||||
|
|
||||||
struct mdm_ops *ops;
|
struct mdm_ops *ops;
|
||||||
struct mdm_platform_data *pdata;
|
struct mdm_platform_data *pdata;
|
||||||
|
|||||||
@@ -11,10 +11,15 @@
|
|||||||
#define RAM_DUMP_DONE _IOW(CHARM_CODE, 6, int)
|
#define RAM_DUMP_DONE _IOW(CHARM_CODE, 6, int)
|
||||||
#define WAIT_FOR_RESTART _IOR(CHARM_CODE, 7, int)
|
#define WAIT_FOR_RESTART _IOR(CHARM_CODE, 7, int)
|
||||||
#define GET_DLOAD_STATUS _IOR(CHARM_CODE, 8, int)
|
#define GET_DLOAD_STATUS _IOR(CHARM_CODE, 8, int)
|
||||||
|
#define IMAGE_UPGRADE _IOW(CHARM_CODE, 9, int)
|
||||||
|
|
||||||
enum charm_boot_type {
|
enum charm_boot_type {
|
||||||
CHARM_NORMAL_BOOT = 0,
|
CHARM_NORMAL_BOOT = 0,
|
||||||
CHARM_RAM_DUMPS,
|
CHARM_RAM_DUMPS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum image_upgrade_type {
|
||||||
|
APQ_CONTROLLED_UPGRADE = 0,
|
||||||
|
MDM_CONTROLLED_UPGRADE,
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user