diff options
Diffstat (limited to 'drivers/usb/core/driver.c')
-rw-r--r-- | drivers/usb/core/driver.c | 29 |
1 files changed, 12 insertions, 17 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 874dec31a111..818369afff63 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -275,21 +275,6 @@ static int usb_unbind_device(struct device *dev) return 0; } -/* - * Cancel any pending scheduled resets - * - * [see usb_queue_reset_device()] - * - * Called after unconfiguring / when releasing interfaces. See - * comments in __usb_queue_reset_device() regarding - * udev->reset_running. - */ -static void usb_cancel_queued_reset(struct usb_interface *iface) -{ - if (iface->reset_running == 0) - cancel_work_sync(&iface->reset_ws); -} - /* called from driver core with dev locked */ static int usb_probe_interface(struct device *dev) { @@ -380,7 +365,6 @@ static int usb_probe_interface(struct device *dev) usb_set_intfdata(intf, NULL); intf->needs_remote_wakeup = 0; intf->condition = USB_INTERFACE_UNBOUND; - usb_cancel_queued_reset(intf); /* If the LPM disable succeeded, balance the ref counts. */ if (!lpm_disable_error) @@ -425,7 +409,6 @@ static int usb_unbind_interface(struct device *dev) usb_disable_interface(udev, intf, false); driver->disconnect(intf); - usb_cancel_queued_reset(intf); /* Free streams */ for (i = 0, j = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { @@ -1797,6 +1780,18 @@ static int autosuspend_check(struct usb_device *udev) dev_dbg(&udev->dev, "remote wakeup needed for autosuspend\n"); return -EOPNOTSUPP; } + + /* + * If the device is a direct child of the root hub and the HCD + * doesn't handle wakeup requests, don't allow autosuspend when + * wakeup is needed. + */ + if (w && udev->parent == udev->bus->root_hub && + bus_to_hcd(udev->bus)->cant_recv_wakeups) { + dev_dbg(&udev->dev, "HCD doesn't handle wakeup requests\n"); + return -EOPNOTSUPP; + } + udev->do_remote_wakeup = w; return 0; } |