usb: msm_otg: Enable VBUS MPM interrupt
When otg_control is set to OTG_PHY_CONTROL and PMIC interrupts are
not used for VBUS notification, a cable connection will fail to
wake up the device from VDD minimized low power mode. The MPM needs
to be configured to wake up the system when the USB_PHY_OTGSESSVLD
interrupt is triggered. As this interrupt may vary by SoC populate
it in the msm_otg_platform_data->mpm_otgsessvld_int member in the
various board files.
CRs-fixed: 376740
Change-Id: Ia54828f538c695ff6b28f5d7b2b49630a45cc673
Signed-off-by: Jack Pham <jackp@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 2a8ac87..ea7fb32 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -890,6 +890,8 @@
#define PMIC_GPIO_DP 27 /* PMIC GPIO for D+ change */
#define PMIC_GPIO_DP_IRQ PM8921_GPIO_IRQ(PM8921_IRQ_BASE, PMIC_GPIO_DP)
+#define MSM_MPM_PIN_USB1_OTGSESSVLD 40
+
static struct msm_otg_platform_data msm_otg_pdata = {
.mode = USB_OTG,
.otg_control = OTG_PMIC_CONTROL,
@@ -898,6 +900,7 @@
.power_budget = 750,
.bus_scale_table = &usb_bus_scale_pdata,
.phy_init_seq = phy_init_seq,
+ .mpm_otgsessvld_int = MSM_MPM_PIN_USB1_OTGSESSVLD,
};
static struct msm_usb_host_platform_data msm_ehci_host_pdata3 = {
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index fb20307..b20c876 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -1455,6 +1455,8 @@
0x13, 0x83, /* set source impedance adjusment */
-1};
+#define MSM_MPM_PIN_USB1_OTGSESSVLD 40
+
static struct msm_otg_platform_data msm_otg_pdata = {
.mode = USB_OTG,
.otg_control = OTG_PMIC_CONTROL,
@@ -1467,6 +1469,7 @@
#ifdef CONFIG_FB_MSM_HDMI_MHL_8334
.mhl_dev_name = "sii8334",
#endif
+ .mpm_otgsessvld_int = MSM_MPM_PIN_USB1_OTGSESSVLD,
};
#endif
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 50a5ed2..25677c3 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -1486,6 +1486,8 @@
};
#endif
+#define MSM_MPM_PIN_USB1_OTGSESSVLD 40
+
static struct msm_otg_platform_data msm_otg_pdata = {
.mode = USB_OTG,
.otg_control = OTG_PMIC_CONTROL,
@@ -1494,6 +1496,7 @@
.power_budget = 750,
#ifdef CONFIG_MSM_BUS_SCALING
.bus_scale_table = &usb_bus_scale_pdata,
+ .mpm_otgsessvld_int = MSM_MPM_PIN_USB1_OTGSESSVLD,
#endif
#ifdef CONFIG_FB_MSM_HDMI_MHL_8334
.mhl_dev_name = "sii8334",
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 3884c81..0e1267b 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -43,6 +43,7 @@
#include <linux/mhl_8334.h>
#include <mach/clk.h>
+#include <mach/mpm.h>
#include <mach/msm_xo.h>
#include <mach/msm_bus.h>
#include <mach/rpm-regulator.h>
@@ -876,6 +877,9 @@
enable_irq_wake(motg->irq);
if (motg->pdata->pmic_id_irq)
enable_irq_wake(motg->pdata->pmic_id_irq);
+ if (pdata->otg_control == OTG_PHY_CONTROL &&
+ pdata->mpm_otgsessvld_int)
+ msm_mpm_set_pin_wake(pdata->mpm_otgsessvld_int, 1);
}
if (bus)
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &(bus_to_hcd(bus))->flags);
@@ -893,6 +897,7 @@
{
struct usb_phy *phy = &motg->phy;
struct usb_bus *bus = phy->otg->host;
+ struct msm_otg_platform_data *pdata = motg->pdata;
int cnt = 0;
unsigned temp;
u32 phy_ctrl_val = 0;
@@ -971,6 +976,9 @@
disable_irq_wake(motg->irq);
if (motg->pdata->pmic_id_irq)
disable_irq_wake(motg->pdata->pmic_id_irq);
+ if (pdata->otg_control == OTG_PHY_CONTROL &&
+ pdata->mpm_otgsessvld_int)
+ msm_mpm_set_pin_wake(pdata->mpm_otgsessvld_int, 0);
}
if (bus)
set_bit(HCD_FLAG_HW_ACCESSIBLE, &(bus_to_hcd(bus))->flags);
@@ -3583,6 +3591,9 @@
goto destroy_wlock;
}
+ if (pdata->otg_control == OTG_PHY_CONTROL && pdata->mpm_otgsessvld_int)
+ msm_mpm_enable_pin(pdata->mpm_otgsessvld_int, 1);
+
phy->init = msm_otg_reset;
phy->set_power = msm_otg_set_power;
phy->set_suspend = msm_otg_set_suspend;
@@ -3734,6 +3745,10 @@
usb_set_transceiver(NULL);
free_irq(motg->irq, motg);
+ if (motg->pdata->otg_control == OTG_PHY_CONTROL &&
+ motg->pdata->mpm_otgsessvld_int)
+ msm_mpm_enable_pin(motg->pdata->mpm_otgsessvld_int, 0);
+
/*
* Put PHY in low power mode.
*/
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index b9ecd60..763e977 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -187,6 +187,8 @@
* @default_mode: Default operational mode. Applicable only if
* OTG switch is controller by user.
* @pmic_id_irq: IRQ number assigned for PMIC USB ID line.
+ * @mpm_otgsessvld_int: MPM wakeup pin assigned for OTG SESSVLD
+ * interrupt. Used when .otg_control == OTG_PHY_CONTROL.
* @mhl_enable: indicates MHL connector or not.
* @disable_reset_on_disconnect: perform USB PHY and LINK reset
* on USB cable disconnection.
@@ -211,6 +213,7 @@
enum msm_usb_phy_type phy_type;
void (*setup_gpio)(enum usb_otg_state state);
int pmic_id_irq;
+ unsigned int mpm_otgsessvld_int;
bool mhl_enable;
bool disable_reset_on_disconnect;
bool enable_dcd;