USB: OTG: prevent idle standalone PC when USB cable is connected.
When USB cable is connected, the mass storage function in the
device will get interrupts for every 3ms. Entering and exiting the
idle standalone PC itself will take around 3ms on 8960. Hence allowing
idle standalone PC when USB cable is connected causes processor to
spend most of the time in entering and exiting the idle standalone PC.
Hence Vote for minimum DMA latency to prevent idle standalone PC
when USB cable is connected.
Change-Id: Id625dc01f253ed553b2f65f08900022a8c6e1daa
Signed-off-by: Anji jonnala <anjir@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 06d63d9..b6acf41 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -2154,6 +2154,8 @@
msm_otg_pdata.phy_init_seq =
liquid_v1_phy_init_seq;
}
+ msm_otg_pdata.swfi_latency =
+ msm_rpmrs_levels[0].latency_us;
#ifdef CONFIG_USB_EHCI_MSM_HSIC
if (machine_is_msm8960_liquid()) {
if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 2)
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index ec922f1..c55ba6e 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -37,6 +37,7 @@
#include <linux/usb/msm_hsusb_hw.h>
#include <linux/regulator/consumer.h>
#include <linux/mfd/pm8xxx/pm8921-charger.h>
+#include <linux/pm_qos_params.h>
#include <mach/clk.h>
#include <mach/msm_xo.h>
@@ -63,6 +64,25 @@
static struct msm_otg *the_msm_otg;
static bool debug_aca_enabled;
+/* Prevent idle power collapse(pc) while operating in peripheral mode */
+static void otg_pm_qos_update_latency(struct msm_otg *dev, int vote)
+{
+ struct msm_otg_platform_data *pdata = dev->pdata;
+ u32 swfi_latency = 0;
+
+ if (!pdata || !pdata->swfi_latency)
+ return;
+
+ swfi_latency = pdata->swfi_latency + 1;
+
+ if (vote)
+ pm_qos_update_request(&dev->pm_qos_req_dma,
+ swfi_latency);
+ else
+ pm_qos_update_request(&dev->pm_qos_req_dma,
+ PM_QOS_DEFAULT_VALUE);
+}
+
static struct regulator *hsusb_3p3;
static struct regulator *hsusb_1p8;
static struct regulator *hsusb_vddcx;
@@ -991,10 +1011,16 @@
*/
if (pdata->setup_gpio)
pdata->setup_gpio(OTG_STATE_B_PERIPHERAL);
+ /*
+ * vote for minimum dma_latency to prevent idle
+ * power collapse(pc) while running in peripheral mode.
+ */
+ otg_pm_qos_update_latency(motg, 1);
usb_gadget_vbus_connect(otg->gadget);
} else {
dev_dbg(otg->dev, "gadget off\n");
usb_gadget_vbus_disconnect(otg->gadget);
+ otg_pm_qos_update_latency(motg, 0);
if (pdata->setup_gpio)
pdata->setup_gpio(OTG_STATE_UNDEFINED);
}
@@ -2240,6 +2266,10 @@
}
clk_set_rate(motg->clk, 60000000);
+ /* pm qos request to prevent apps idle power collapse */
+ if (motg->pdata->swfi_latency)
+ pm_qos_add_request(&motg->pm_qos_req_dma,
+ PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE);
/*
* If USB Core is running its protocol engine based on CORE CLK,
* CORE CLK must be running at >55Mhz for correct HSUSB
@@ -2460,6 +2490,8 @@
if (!IS_ERR(motg->phy_reset_clk))
clk_put(motg->phy_reset_clk);
free_motg:
+ if (motg->pdata->swfi_latency)
+ pm_qos_remove_request(&motg->pm_qos_req_dma);
kfree(motg);
return ret;
}
@@ -2535,8 +2567,10 @@
if (!IS_ERR(motg->system_clk))
clk_put(motg->system_clk);
- kfree(motg);
+ if (motg->pdata->swfi_latency)
+ pm_qos_remove_request(&motg->pm_qos_req_dma);
+ kfree(motg);
return 0;
}
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index a2251fe..68fc67c 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -21,6 +21,7 @@
#include <linux/types.h>
#include <linux/usb/otg.h>
#include <linux/wakelock.h>
+#include <linux/pm_qos_params.h>
/**
* Supported USB modes
@@ -145,6 +146,7 @@
* dfab_usb_hs_clk in case of 8660 and 8960.
* @pmic_id_irq: IRQ number assigned for PMIC USB ID line.
* @mhl_enable: indicates MHL connector or not.
+ * @swfi_latency: miminum latency to allow swfi.
*/
struct msm_otg_platform_data {
int *phy_init_seq;
@@ -158,6 +160,7 @@
const char *pclk_src_name;
int pmic_id_irq;
bool mhl_enable;
+ u32 swfi_latency;
};
/**
@@ -188,6 +191,8 @@
* connected. Useful only when ACA_A charger is
* connected.
* @mA_port: The amount of current drawn by the attached B-device.
+ * @pm_qos_req_dma: miminum DMA latency to vote against idle power
+ collapse when cable is connected.
* @id_timer: The timer used for polling ID line to detect ACA states.
* @xo_handle: TCXO buffer handle
*/
@@ -244,6 +249,7 @@
#define PHY_PWR_COLLAPSED BIT(0)
#define PHY_RETENTIONED BIT(1)
#define PHY_OTG_COMP_DISABLED BIT(2)
+ struct pm_qos_request_list pm_qos_req_dma;
};
struct msm_hsic_host_platform_data {