msm: mdm: change the gpio pull value of mdm2ap_status after bootup
The mdm2ap_status gpio has been known to fluctuate in
its value during mdm bootup if set to PULL_NONE, so set
it to PULL_DOWN when the gpiomux is initialliy installed.
However, it needs to be reset to PULL_NONE after the mdm
is booted up in order to reduce leakage current.
CRs-Fixed: 368433
CRs-Fixed: 379343
Change-Id: Ia5a9046ed1ed98854750e8f4ae8d08e32ff427a9
Signed-off-by: Joel King <joelking@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
index 1c19442..7898cf6 100644
--- a/arch/arm/mach-msm/board-8064-gpiomux.c
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -788,7 +788,7 @@
static struct gpiomux_setting mdm2ap_status_cfg = {
.func = GPIOMUX_FUNC_GPIO,
.drv = GPIOMUX_DRV_8MA,
- .pull = GPIOMUX_PULL_NONE,
+ .pull = GPIOMUX_PULL_DOWN,
};
static struct gpiomux_setting mdm2ap_errfatal_cfg = {
@@ -828,6 +828,7 @@
{
.gpio = 49,
.settings = {
+ [GPIOMUX_ACTIVE] = &mdm2ap_status_cfg,
[GPIOMUX_SUSPENDED] = &mdm2ap_status_cfg,
}
},
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 90563ad..0fad463 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1727,6 +1727,12 @@
.mdm2ap_vddmin_gpio = 80,
};
+static struct gpiomux_setting mdm2ap_status_gpio_run_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
static struct mdm_platform_data mdm_platform_data = {
.mdm_version = "3.0",
.ramdump_delay_ms = 2000,
@@ -1735,6 +1741,7 @@
.vddmin_resource = &mdm_vddmin_rscs,
.peripheral_platform_device = &apq8064_device_hsic_host,
.ramdump_timeout_ms = 120000,
+ .mdm2ap_status_gpio_run_cfg = &mdm2ap_status_gpio_run_cfg,
};
static struct tsens_platform_data apq_tsens_pdata = {
diff --git a/arch/arm/mach-msm/include/mach/mdm2.h b/arch/arm/mach-msm/include/mach/mdm2.h
index c4877cc..6ec12c1 100644
--- a/arch/arm/mach-msm/include/mach/mdm2.h
+++ b/arch/arm/mach-msm/include/mach/mdm2.h
@@ -32,6 +32,7 @@
struct platform_device *peripheral_platform_device;
const unsigned int ramdump_timeout_ms;
int image_upgrade_supported;
+ struct gpiomux_setting *mdm2ap_status_gpio_run_cfg;
};
#endif
diff --git a/arch/arm/mach-msm/mdm_common.c b/arch/arm/mach-msm/mdm_common.c
index 6b40cda..d1865e4 100644
--- a/arch/arm/mach-msm/mdm_common.c
+++ b/arch/arm/mach-msm/mdm_common.c
@@ -30,6 +30,7 @@
#include <linux/workqueue.h>
#include <linux/clk.h>
#include <linux/mfd/pmic8058.h>
+#include <linux/msm_charm.h>
#include <asm/mach-types.h>
#include <asm/uaccess.h>
#include <mach/mdm2.h>
@@ -37,7 +38,7 @@
#include <mach/subsystem_notif.h>
#include <mach/subsystem_restart.h>
#include <mach/rpm.h>
-#include <linux/msm_charm.h>
+#include <mach/gpiomux.h>
#include "msm_watchdog.h"
#include "mdm_private.h"
#include "sysmon.h"
@@ -68,6 +69,13 @@
#define SFR_MAX_RETRIES 10
#define SFR_RETRY_INTERVAL 1000
+enum gpio_update_config {
+ GPIO_UPDATE_BOOTING_CONFIG = 1,
+ GPIO_UPDATE_RUNNING_CONFIG,
+};
+static int mdm2ap_status_valid_old_config;
+static struct gpiomux_setting mdm2ap_status_old_config;
+
static irqreturn_t mdm_vddmin_change(int irq, void *dev_id)
{
int value = gpio_get_value(
@@ -163,6 +171,37 @@
static DECLARE_DELAYED_WORK(mdm2ap_status_check_work, mdm2ap_status_check);
+static void mdm_update_gpio_configs(enum gpio_update_config gpio_config)
+{
+ /* Some gpio configuration may need updating after modem bootup.*/
+ switch (gpio_config) {
+ case GPIO_UPDATE_RUNNING_CONFIG:
+ if (mdm_drv->pdata->mdm2ap_status_gpio_run_cfg) {
+ if (msm_gpiomux_write(mdm_drv->mdm2ap_status_gpio,
+ GPIOMUX_ACTIVE,
+ mdm_drv->pdata->mdm2ap_status_gpio_run_cfg,
+ &mdm2ap_status_old_config))
+ pr_err("%s: failed updating running gpio config\n",
+ __func__);
+ else
+ mdm2ap_status_valid_old_config = 1;
+ }
+ break;
+ case GPIO_UPDATE_BOOTING_CONFIG:
+ if (mdm2ap_status_valid_old_config) {
+ msm_gpiomux_write(mdm_drv->mdm2ap_status_gpio,
+ GPIOMUX_ACTIVE,
+ &mdm2ap_status_old_config,
+ NULL);
+ mdm2ap_status_valid_old_config = 0;
+ }
+ break;
+ default:
+ pr_err("%s: called with no config\n", __func__);
+ break;
+ }
+}
+
long mdm_modem_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
@@ -205,11 +244,10 @@
else
first_boot = 0;
- /* Start a timer to check that the mdm2ap_status gpio
- * goes high.
+ /* If successful, start a timer to check that the mdm2ap_status
+ * gpio goes high.
*/
-
- if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0)
+ if (!status && gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0)
schedule_delayed_work(&mdm2ap_status_check_work,
msecs_to_jiffies(MDM2AP_STATUS_TIMEOUT_MS));
break;
@@ -266,6 +304,9 @@
pr_debug("%s: status:%d\n", __func__, value);
if (mdm_drv->mdm_ready && mdm_drv->ops->status_cb)
mdm_drv->ops->status_cb(mdm_drv, value);
+
+ /* Update gpio configuration to "running" config. */
+ mdm_update_gpio_configs(GPIO_UPDATE_RUNNING_CONFIG);
}
static DECLARE_WORK(mdm_status_work, mdm_status_fn);
@@ -364,6 +405,7 @@
static int mdm_subsys_shutdown(const struct subsys_desc *crashed_subsys)
{
mdm_drv->mdm_ready = 0;
+ cancel_delayed_work(&mdm2ap_status_check_work);
gpio_direction_output(mdm_drv->ap2mdm_errfatal_gpio, 1);
if (mdm_drv->pdata->ramdump_delay_ms > 0) {
/* Wait for the external modem to complete
@@ -371,10 +413,13 @@
*/
msleep(mdm_drv->pdata->ramdump_delay_ms);
}
- if (!mdm_drv->mdm_unexpected_reset_occurred)
+ if (!mdm_drv->mdm_unexpected_reset_occurred) {
mdm_drv->ops->reset_mdm_cb(mdm_drv);
- else
+ /* Update gpio configuration to "booting" config. */
+ mdm_update_gpio_configs(GPIO_UPDATE_BOOTING_CONFIG);
+ } else {
mdm_drv->mdm_unexpected_reset_occurred = 0;
+ }
return 0;
}
@@ -404,6 +449,7 @@
const struct subsys_desc *crashed_subsys)
{
mdm_drv->mdm_ram_dump_status = 0;
+ cancel_delayed_work(&mdm2ap_status_check_work);
if (want_dumps) {
mdm_drv->boot_type = CHARM_RAM_DUMPS;
complete(&mdm_needs_reload);
@@ -416,8 +462,11 @@
pr_info("%s: mdm modem ramdumps completed.\n",
__func__);
INIT_COMPLETION(mdm_ram_dumps);
- if (!mdm_drv->pdata->no_powerdown_after_ramdumps)
+ if (!mdm_drv->pdata->no_powerdown_after_ramdumps) {
mdm_drv->ops->power_down_mdm_cb(mdm_drv);
+ /* Update gpio configuration to "booting" config. */
+ mdm_update_gpio_configs(GPIO_UPDATE_BOOTING_CONFIG);
+ }
}
return mdm_drv->mdm_ram_dump_status;
}