msm: hsic: Disallow processor idle sleep while driving resume signal
HSIC controller should send SOF with in 3 msec after completing
the resume signal. If processor is in idle sleep state, the timer
interrupt generated by HSIC controller to indicate resume completion
gets delayed. If the interrupt handler is not run with in 3msec
after resume, the resume sequence is repeated. Disallow processor
idle sleep to avoid multiple resume cycles.
CRs-Fixed: 397154
Change-Id: Ibc8965ad8bcd94e0b1b1d39b5b2ad8f39cf51095
Signed-off-by: Pavankumar Kondeti <pkondeti@codeaurora.org>
(cherry picked from commit 4f5dc3be7b2b9939bc7a1b9526ccb70d93b53361)
Signed-off-by: Sudhir Sharma <sudsha@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 5f2d8fd..bc51d16 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -3072,6 +3072,8 @@
platform_add_devices(common_not_mpq_devices,
ARRAY_SIZE(common_not_mpq_devices));
enable_ddr3_regulator();
+ msm_hsic_pdata.swfi_latency =
+ msm_rpmrs_levels[0].latency_us;
if (machine_is_apq8064_mtp()) {
msm_hsic_pdata.log2_irq_thresh = 5,
apq8064_device_hsic_host.dev.platform_data = &msm_hsic_pdata;
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index 2b7f8b3..48e5b82 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -37,6 +37,7 @@
#include <linux/spinlock.h>
#include <linux/kthread.h>
#include <linux/wait.h>
+#include <linux/pm_qos.h>
#include <mach/msm_bus.h>
#include <mach/clk.h>
@@ -94,6 +95,8 @@
struct completion rt_completion;
int resume_status;
int resume_again;
+
+ struct pm_qos_request pm_qos_req_dma;
};
struct msm_hsic_hcd *__mehci;
@@ -934,6 +937,7 @@
unsigned long resume_needed = 0;
int retry_cnt = 0;
int tight_resume = 0;
+ struct msm_hsic_host_platform_data *pdata = mehci->dev->platform_data;
dbg_log_event(NULL, "Resume RH", 0);
@@ -1017,7 +1021,13 @@
&mehci->timer->gptimer1_ctrl);
spin_unlock_irq(&ehci->lock);
+ if (pdata && pdata->swfi_latency)
+ pm_qos_update_request(&mehci->pm_qos_req_dma,
+ pdata->swfi_latency + 1);
wait_for_completion(&mehci->gpt0_completion);
+ if (pdata && pdata->swfi_latency)
+ pm_qos_update_request(&mehci->pm_qos_req_dma,
+ PM_QOS_DEFAULT_VALUE);
spin_lock_irq(&ehci->lock);
} else {
dbg_log_event(NULL, "FPR: Tightloop", 0);
@@ -1630,6 +1640,10 @@
__mehci = mehci;
+ if (pdata && pdata->swfi_latency)
+ pm_qos_add_request(&mehci->pm_qos_req_dma,
+ PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE);
+
/*
* This pdev->dev is assigned parent of root-hub by USB core,
* hence, runtime framework automatically calls this driver's
@@ -1665,6 +1679,10 @@
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
+ struct msm_hsic_host_platform_data *pdata = mehci->dev->platform_data;
+
+ if (pdata && pdata->swfi_latency)
+ pm_qos_remove_request(&mehci->pm_qos_req_dma);
if (mehci->peripheral_status_irq)
free_irq(mehci->peripheral_status_irq, mehci);
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index a2a8225..e82afed 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -376,6 +376,7 @@
unsigned data;
struct msm_bus_scale_pdata *bus_scale_table;
unsigned log2_irq_thresh;
+ u32 swfi_latency;
};
struct msm_usb_host_platform_data {