diff options
author | rajaram <rajaram.ragupathy@stericsson.com> | 2011-11-10 08:40:09 +0530 |
---|---|---|
committer | Philippe Langlais <philippe.langlais@stericsson.com> | 2012-05-22 11:03:12 +0200 |
commit | 8ec6202f325cc95f90c8769368f9684abe68b3f9 (patch) | |
tree | 7cf6eeb2e1597d4ecaa2841b19807cb7b5f39bd9 | |
parent | 7d3cfe37174feb905b2c1bded337fd5f13242ed5 (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.c | 33 |
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, |