diff options
authorPavankumar Kondeti <pkondeti@codeaurora.org>2012-11-09 05:24:00 (GMT)
committerPavankumar Kondeti <pkondeti@codeaurora.org>2012-11-28 12:21:40 (GMT)
commit41d004c4eaa5565cb8d9113862c3cef1e51be648 (patch)
parentfb8ed5b9b12a5c8eac8094c84f39b31b7d1472e8 (diff)
USB: Prevent system suspend when HSIC device is active
Some buses like HSIC would like to keep device in suspend state after system resume. The remote wakeup or interface activity later will auto resume the device. This will work only if the device is auto suspended before system suspend. If the device runtime state had been active during system suspend and system suspend routine put the device in suspend, it will not be resumed during system resume. When remote wakeup happen for this device, the runtime resume will not bring the device to active as runtime core think it is already active. The HSIC bus ensure that device is auto suspended prior to system suspend by holding a wakelock till the bus is suspended. HSIC bus is not handling the case where device is auto resumed immediately after system suspend begins. HSIC bus simply put the device into suspend in system suspend routine. This patch fixes above issue by returning an error code if the device is not auto suspended during system suspend. Also add a safe guard check in HSIC system resume routine to skip device resume only if it is auto suspended prior to system suspend. CRs-Fixed: 422876 Change-Id: I888585ed872d808aa4dbca33b529fcc32994349b Signed-off-by: Pavankumar Kondeti <pkondeti@codeaurora.org>
2 files changed, 10 insertions, 3 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 494ec49..55ff980 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1357,8 +1357,14 @@ int usb_suspend(struct device *dev, pm_message_t msg)
struct usb_device *udev = to_usb_device(dev);
- if (udev->bus->skip_resume && udev->state == USB_STATE_SUSPENDED)
- return 0;
+ if (udev->bus->skip_resume) {
+ if (udev->state == USB_STATE_SUSPENDED) {
+ return 0;
+ } else {
+ dev_err(dev, "abort suspend\n");
+ return -EBUSY;
+ }
+ }
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index 8c22f8e..7d12598 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -1886,7 +1886,8 @@ static int msm_hsic_pm_resume(struct device *dev)
* when remote wakeup is received or interface driver
* start I/O.
- if (!atomic_read(&mehci->pm_usage_cnt))
+ if (!atomic_read(&mehci->pm_usage_cnt) &&
+ pm_runtime_suspended(dev))
return 0;
ret = msm_hsic_resume(mehci);