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/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;
}