diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2016-11-18 01:54:54 -0800 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-11-18 01:54:53 -0800 |
| commit | d1a64e4014108e81c92b580951fa2cb16647e213 (patch) | |
| tree | b4f813772599aed4104b2992c5e82f75576edfbe | |
| parent | a8277a5b93f583a96ca7e7d80efa53a535180a17 (diff) | |
| parent | 7b553e1abd0af7770907081b4aab83d72043e1fd (diff) | |
Merge "USB: Allow skipping device resume during system resume"
| -rw-r--r-- | drivers/usb/core/driver.c | 12 | ||||
| -rw-r--r-- | drivers/usb/host/xhci-plat.c | 4 | ||||
| -rw-r--r-- | include/linux/usb.h | 9 |
3 files changed, 25 insertions, 0 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index dadd1e8dfe09..26a305f43ff6 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1441,6 +1441,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 @@ -1470,6 +1473,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/xhci-plat.c b/drivers/usb/host/xhci-plat.c index c025dccdd8f1..fcb9b4b822aa 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -167,6 +167,8 @@ static int xhci_plat_probe(struct platform_device *pdev) if (!hcd) return -ENOMEM; + hcd_to_bus(hcd)->skip_resume = true; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { @@ -221,6 +223,8 @@ static int xhci_plat_probe(struct platform_device *pdev) goto disable_clk; } + hcd_to_bus(xhci->shared_hcd)->skip_resume = true; + if ((node && of_property_read_bool(node, "usb3-lpm-capable")) || (pdata && pdata->usb3_lpm_capable)) xhci->quirks |= XHCI_LPM_SUPPORT; diff --git a/include/linux/usb.h b/include/linux/usb.h index 440248ba4123..7e6e4665212f 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -395,6 +395,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. + */ }; struct usb_dev_state; |
