misc: mdm6600_ctrl: update shutdown to reset unresponsive modem.

- fix initialization of BP_PWRON (PS6), and BP_RESIN (PZ1) gpios,
    - cleanup kernel log messages,
    - assert BP_RESIN gpio to reset unresponsive modem.

Change-Id: Iaf6b7d553fec1a6e9254b7183c1beacf7ad4d555
Signed-off-by: James Wylder <james.wylder@motorola.com>
This commit is contained in:
James Wylder
2010-08-19 20:23:12 -05:00
committed by Colin Cross
parent 2e760aa5ab
commit d7eb4745b7
2 changed files with 43 additions and 23 deletions

View File

@@ -37,6 +37,27 @@
#define BP_STATUS_SHUTDOWN_ACK 0x06
#define BP_STATUS_UNDEFINED 0x07
#define LOOP_DELAY_TIME_MS 500
char *bp_status[8] = {
"panic",
"panic busy wait",
"qc dload",
"ram downloader",
"awake",
"asleep",
"shutdown ack",
"undefined",
};
static char *bp_status_string(unsigned int stat)
{
if (stat < 8)
return bp_status[stat];
else
return "status out of range";
}
static unsigned int mdm_gpio_get_value(struct mdm_ctrl_gpio gpio)
{
return gpio_get_value(gpio.number);
@@ -57,13 +78,12 @@ static void mdm_gpio_free(struct mdm_ctrl_gpio *gpio)
static int mdm_gpio_setup(struct mdm_ctrl_gpio *gpio)
{
snprintf(gpio->name, MAX_GPIO_NAME, "mdm_gpio_%05d", gpio->number);
if (gpio_request(gpio->number, gpio->name)) {
printk(KERN_ERR "failed to aquire gpio %s", gpio->name);
return -1;
}
gpio->allocated = 1;
gpio_export(gpio->number, false);
if (gpio->direction == MDM_GPIO_DIRECTION_IN)
gpio_direction_input(gpio->number);
else if (gpio->direction == MDM_GPIO_DIRECTION_OUT)
@@ -160,31 +180,34 @@ static int __devexit mdm_ctrl_remove(struct platform_device *pdev)
}
static unsigned int __devexit bp_shutdown_wait(struct platform_device *pdev,
struct mdm_ctrl_platform_data *pdata)
struct mdm_ctrl_platform_data *pdata,
unsigned int delay_sec)
{
unsigned int delay;
unsigned int i, loop_count;
unsigned int bp_status;
unsigned int gpio_value;
unsigned int pd_failure = 1;
for (delay = 0; delay < 10; delay++) {
loop_count = (delay_sec * 1000) / LOOP_DELAY_TIME_MS;
for (i = 0; i < loop_count; i++) {
msleep(LOOP_DELAY_TIME_MS);
bp_status = get_bp_status(pdata);
if (bp_status == BP_STATUS_SHUTDOWN_ACK) {
dev_info(&pdev->dev, "Modem power down success.\n");
dev_info(&pdev->dev, "Modem powered off (with ack).\n");
pd_failure = 0;
break;
}
gpio_value = mdm_gpio_get_value(
pdata->gpios[MDM_CTRL_GPIO_BP_RESOUT]);
dev_info(&pdev->dev, "gpio_resout_gpio = %d\n", gpio_value);
if (!gpio_value) {
dev_info(&pdev->dev, "Modem reporting Panic.\n");
if (gpio_value == 0) {
dev_info(&pdev->dev, "Modem powered off.\n");
pd_failure = 0;
break;
} else {
dev_info(&pdev->dev, "Modem status 0x%x\n", bp_status);
msleep(500);
dev_info(&pdev->dev, "Modem status %s [0x%x]\n",
bp_status_string(bp_status), bp_status);
}
}
return pd_failure;
@@ -193,16 +216,15 @@ static unsigned int __devexit bp_shutdown_wait(struct platform_device *pdev,
static void __devexit mdm_ctrl_shutdown(struct platform_device *pdev)
{
unsigned int pd_failure;
unsigned int bp_status;
struct mdm_ctrl_platform_data *pdata = pdev->dev.platform_data;
dev_info(&pdev->dev, "Shutting down modem.\n");
dev_info(&pdev->dev, "Initial modem status 0x%x\n",
get_bp_status(pdata));
dev_info(&pdev->dev, "Initial ap status 0x%x\n",
get_ap_status(pdata));
bp_status = get_bp_status(pdata);
dev_info(&pdev->dev, "Initial Modem status %s [0x%x]\n",
bp_status_string(bp_status), bp_status);
set_ap_status(pdata, AP_STATUS_BP_SHUTDOWN_REQ);
@@ -220,16 +242,15 @@ static void __devexit mdm_ctrl_shutdown(struct platform_device *pdev)
/* if this doesn't work, reset the modem and try */
/* one more time, ultimately the modem will be */
/* hard powered off */
pd_failure = bp_shutdown_wait(pdev, pdata);
pd_failure = bp_shutdown_wait(pdev, pdata, 5);
if (pd_failure) {
mdm_gpio_set_value(pdata->gpios[MDM_CTRL_GPIO_BP_PWRON], 1);
pd_failure = bp_shutdown_wait(pdev, pdata);
dev_info(&pdev->dev, "Resetting unresponsive modem.\n");
mdm_gpio_set_value(pdata->gpios[MDM_CTRL_GPIO_BP_RESIN], 1);
pd_failure = bp_shutdown_wait(pdev, pdata, 5);
}
if (pd_failure)
dev_err(&pdev->dev, "Modem failed to power down.\n");
else
dev_info(&pdev->dev, "Modem successfully powered down.\n");
}
static struct platform_driver mdm6x00_ctrl_driver = {

View File

@@ -38,7 +38,6 @@ enum {
enum {
MDM_GPIO_DIRECTION_IN,
MDM_GPIO_DIRECTION_OUT,
MDM_GPIO_DIRECTION_OUT_NO_DEFAULT,
};
struct mdm_ctrl_gpio {
@@ -46,7 +45,7 @@ struct mdm_ctrl_gpio {
unsigned int direction;
unsigned int default_value;
unsigned int allocated;
char name[MAX_GPIO_NAME];
char *name;
};
struct mdm_ctrl_platform_data {