USB: Avoid runtime suspend right after getting remote wake up interrupt
HSIC phy stuck issue is observed when runtime suspend happens right after
remote wake up interrupt comes during system resume. Fix this issue by
delaying runtime suspend by 500ms, so that root hub gets a chance to
resume.
CRs-Fixed: 353954
Change-Id: I04ddf928980f3ffd554d1081c71f1e3a0a142e8a
Signed-off-by: Hemant Kumar <hemantk@codeaurora.org>
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index 1457ab2..a83f6d3 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -40,6 +40,8 @@
#include <mach/msm_xo.h>
#include <linux/spinlock.h>
+#define RUNTIME_SUSP_DELAY 500
+
#define MSM_USB_BASE (hcd->regs)
struct msm_hsic_hcd {
@@ -57,6 +59,7 @@
int peripheral_status_irq;
int wakeup_irq;
bool wakeup_irq_enabled;
+ bool pm_resume;
uint32_t bus_perf_client;
};
@@ -766,8 +769,6 @@
debugfs_remove_recursive(ehci_hsic_msm_dbg_root);
}
-
-
static int __devinit ehci_hsic_msm_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd;
@@ -954,6 +955,7 @@
ehci_hsic_msm_debugfs_cleanup();
device_init_wakeup(&pdev->dev, 0);
+ mehci->pm_resume = false;
pm_runtime_set_suspended(&pdev->dev);
usb_remove_hcd(hcd);
@@ -979,6 +981,8 @@
if (device_may_wakeup(dev))
enable_irq_wake(hcd->irq);
+ mehci->pm_resume = false;
+
return msm_hsic_suspend(mehci);
}
@@ -1015,6 +1019,8 @@
disable_irq_nosync(mehci->wakeup_irq);
}
+ mehci->pm_resume = true;
+
ret = msm_hsic_resume(mehci);
if (ret)
return ret;
@@ -1031,8 +1037,17 @@
#ifdef CONFIG_PM_RUNTIME
static int msm_hsic_runtime_idle(struct device *dev)
{
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
+
dev_dbg(dev, "EHCI runtime idle\n");
+ if (mehci->pm_resume) {
+ mehci->pm_resume = false;
+ pm_schedule_suspend(dev, RUNTIME_SUSP_DELAY);
+ return -EAGAIN;
+ }
+
return 0;
}