aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavankumar Kondeti <pkondeti@codeaurora.org>2012-09-18 12:22:51 (GMT)
committerPavankumar Kondeti <pkondeti@codeaurora.org>2012-09-26 06:21:34 (GMT)
commit6f199aa800253a69e5679d1057823039f1bd65c9 (patch)
treebf74f23562ad13dd02af55ea64dcc91dfa143693
parentd3309fde11871d54690da34a7eb669015142c3df (diff)
USB: Allow skipping device resume during system resume
Some buses would like to keep their devices in suspend state during system resume. For example HSIC controller driver prevent system suspend when HSIC device is active. If this device is resumed, during system resume HSIC controller acquire wake lock and prevent the subsequent suspend till HSIC device is auto suspended. CRs-Fixed: 403975 Change-Id: I93ccd874bf489190e4afb94b533db47bb2911db8 Signed-off-by: Pavankumar Kondeti <pkondeti@codeaurora.org>
-rw-r--r--drivers/usb/core/driver.c12
-rw-r--r--drivers/usb/host/ehci-msm-hsic.c11
-rw-r--r--include/linux/usb.h9
3 files changed, 32 insertions, 0 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 19e1244..a292416 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1357,6 +1357,9 @@ 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;
+
unbind_no_pm_drivers_interfaces(udev);
/* From now on we are sure all drivers support suspend/resume
@@ -1386,6 +1389,15 @@ int usb_resume(struct device *dev, pm_message_t msg)
struct usb_device *udev = to_usb_device(dev);
int status;
+ /*
+ * Some buses would like to keep their devices in suspend
+ * state after system resume. Their resume happen when
+ * a remote wakeup is detected or interface driver start
+ * I/O.
+ */
+ if (udev->bus->skip_resume)
+ return 0;
+
/* For all calls, take the device back to full power and
* tell the PM core in case it was autosuspended previously.
* Unbind the interfaces that will need rebinding later,
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index b7f1878..0a48a6e 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -1522,6 +1522,8 @@ static int __devinit ehci_hsic_msm_probe(struct platform_device *pdev)
return -ENOMEM;
}
+ hcd_to_bus(hcd)->skip_resume = true;
+
hcd->irq = platform_get_irq(pdev, 0);
if (hcd->irq < 0) {
dev_err(&pdev->dev, "Unable to get IRQ resource\n");
@@ -1791,6 +1793,15 @@ static int msm_hsic_pm_resume(struct device *dev)
if (device_may_wakeup(dev))
disable_irq_wake(hcd->irq);
+ /*
+ * Keep HSIC in Low Power Mode if system is resumed
+ * by any other wakeup source. HSIC is resumed later
+ * when remote wakeup is received or interface driver
+ * start I/O.
+ */
+ if (!atomic_read(&mehci->pm_usage_cnt))
+ return 0;
+
ret = msm_hsic_resume(mehci);
if (ret)
return ret;
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 68a87bf..44c64e8 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -368,6 +368,15 @@ struct usb_bus {
struct mon_bus *mon_bus; /* non-null when associated */
int monitored; /* non-zero when monitored */
#endif
+ unsigned skip_resume:1; /* All USB devices are brought into full
+ * power state after system resume. It
+ * is desirable for some buses to keep
+ * their devices in suspend state even
+ * after system resume. The devices
+ * are resumed later when a remote
+ * wakeup is detected or an interface
+ * driver starts I/O.
+ */
};
/* ----------------------------------------------------------------------- */