summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrajaram <rajaram.ragupathy@stericsson.com>2011-11-10 08:40:09 +0530
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:03:12 +0200
commit8ec6202f325cc95f90c8769368f9684abe68b3f9 (patch)
tree7cf6eeb2e1597d4ecaa2841b19807cb7b5f39bd9
parent7d3cfe37174feb905b2c1bded337fd5f13242ed5 (diff)
ux500 : usb : prevent sleep during usb host audio load
When playing audio in usb host audio UC noise is observed, The system wake up latency from sleep adds an extra overhead when transferring ISO packets in host mode. Hence managing latency when there is high usb activity in host mode and releasing when there is no activity. Change-Id: I2589a98adc793d62c325baa056784d8a2ed67143 Signed-off-by: rajaram <rajaram.ragupathy@stericsson.com> Signed-off-by: Philippe Langlais <philippe.langlais@linaro.org> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/37240 Tested-by: Rajaram REGUPATHY <ragupathy.rajaram@stericsson.com> Reviewed-by: QABUILD Reviewed-by: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com> Reviewed-by: Praveena NADAHALLY <praveen.nadahally@stericsson.com>
-rw-r--r--drivers/usb/otg/ab8500-usb.c33
1 files changed, 25 insertions, 8 deletions
diff --git a/drivers/usb/otg/ab8500-usb.c b/drivers/usb/otg/ab8500-usb.c
index 93a99915b66..6b1b268acbc 100644
--- a/drivers/usb/otg/ab8500-usb.c
+++ b/drivers/usb/otg/ab8500-usb.c
@@ -36,6 +36,7 @@
#include <linux/regulator/consumer.h>
#include <linux/mfd/dbx500-prcmu.h>
#include <linux/kernel_stat.h>
+#include <linux/pm_qos.h>
#include <asm/io.h>
@@ -71,6 +72,8 @@
#define AB8500_USB_PHY_TUNE2 0x06
#define AB8500_USB_PHY_TUNE3 0x07
+static struct pm_qos_request usb_pm_qos_latency;
+static bool usb_pm_qos_is_latency_0;
#define USB_PROBE_DELAY 1000 /* 1 seconds */
#define USB_LIMIT (200) /* If we have more than 200 irqs per second */
@@ -170,13 +173,27 @@ static void ab8500_usb_load(struct work_struct *work)
num_irqs += kstat_irqs_cpu(IRQ_DB8500_USBOTG, cpu);
if ((num_irqs > old_num_irqs) &&
- (num_irqs - old_num_irqs) > USB_LIMIT)
- prcmu_qos_update_requirement(PRCMU_QOS_ARM_OPP,
+ (num_irqs - old_num_irqs) > USB_LIMIT) {
+
+ prcmu_qos_update_requirement(PRCMU_QOS_ARM_OPP,
"usb", 125);
- else
- prcmu_qos_update_requirement(PRCMU_QOS_ARM_OPP,
- "usb", 25);
+ if (!usb_pm_qos_is_latency_0) {
+
+ pm_qos_add_request(&usb_pm_qos_latency,
+ PM_QOS_CPU_DMA_LATENCY, 0);
+ usb_pm_qos_is_latency_0 = true;
+ }
+ } else {
+
+ if (usb_pm_qos_is_latency_0) {
+
+ pm_qos_remove_request(&usb_pm_qos_latency);
+ usb_pm_qos_is_latency_0 = false;
+ }
+ prcmu_qos_update_requirement(PRCMU_QOS_ARM_OPP,
+ "usb", 25);
+ }
old_num_irqs = num_irqs;
schedule_delayed_work_on(0,
@@ -221,6 +238,7 @@ static void ab8500_usb_regulator_ctrl(struct ab8500_usb *ab, bool sel_host,
}
}
+
static void ab8500_usb_phy_enable(struct ab8500_usb *ab, bool sel_host)
{
u8 bit;
@@ -234,11 +252,10 @@ static void ab8500_usb_phy_enable(struct ab8500_usb *ab, bool sel_host)
prcmu_qos_update_requirement(PRCMU_QOS_APE_OPP,
(char *)dev_name(ab->dev), 100);
- if (!sel_host) {
- schedule_delayed_work_on(0,
+
+ schedule_delayed_work_on(0,
&ab->work_usb_workaround,
msecs_to_jiffies(USB_PROBE_DELAY));
- }
abx500_mask_and_set_register_interruptible(ab->dev,
AB8500_USB,