aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/hub.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core/hub.c')
-rw-r--r--drivers/usb/core/hub.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 8d4631c81b9f..2f94568ba385 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3174,13 +3174,14 @@ static int usb_disable_remote_wakeup(struct usb_device *udev)
3174} 3174}
3175 3175
3176/* Count of wakeup-enabled devices at or below udev */ 3176/* Count of wakeup-enabled devices at or below udev */
3177static unsigned wakeup_enabled_descendants(struct usb_device *udev) 3177unsigned usb_wakeup_enabled_descendants(struct usb_device *udev)
3178{ 3178{
3179 struct usb_hub *hub = usb_hub_to_struct_hub(udev); 3179 struct usb_hub *hub = usb_hub_to_struct_hub(udev);
3180 3180
3181 return udev->do_remote_wakeup + 3181 return udev->do_remote_wakeup +
3182 (hub ? hub->wakeup_enabled_descendants : 0); 3182 (hub ? hub->wakeup_enabled_descendants : 0);
3183} 3183}
3184EXPORT_SYMBOL_GPL(usb_wakeup_enabled_descendants);
3184 3185
3185/* 3186/*
3186 * usb_port_suspend - suspend a usb device's upstream port 3187 * usb_port_suspend - suspend a usb device's upstream port
@@ -3282,7 +3283,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
3282 * Therefore we will turn on the suspend feature if udev or any of its 3283 * Therefore we will turn on the suspend feature if udev or any of its
3283 * descendants is enabled for remote wakeup. 3284 * descendants is enabled for remote wakeup.
3284 */ 3285 */
3285 else if (PMSG_IS_AUTO(msg) || wakeup_enabled_descendants(udev) > 0) 3286 else if (PMSG_IS_AUTO(msg) || usb_wakeup_enabled_descendants(udev) > 0)
3286 status = set_port_feature(hub->hdev, port1, 3287 status = set_port_feature(hub->hdev, port1,
3287 USB_PORT_FEAT_SUSPEND); 3288 USB_PORT_FEAT_SUSPEND);
3288 else { 3289 else {
@@ -3668,7 +3669,6 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
3668 struct usb_hub *hub = usb_get_intfdata(intf); 3669 struct usb_hub *hub = usb_get_intfdata(intf);
3669 struct usb_device *hdev = hub->hdev; 3670 struct usb_device *hdev = hub->hdev;
3670 unsigned port1; 3671 unsigned port1;
3671 int status;
3672 3672
3673 /* 3673 /*
3674 * Warn if children aren't already suspended. 3674 * Warn if children aren't already suspended.
@@ -3687,7 +3687,7 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
3687 } 3687 }
3688 if (udev) 3688 if (udev)
3689 hub->wakeup_enabled_descendants += 3689 hub->wakeup_enabled_descendants +=
3690 wakeup_enabled_descendants(udev); 3690 usb_wakeup_enabled_descendants(udev);
3691 } 3691 }
3692 3692
3693 if (hdev->do_remote_wakeup && hub->quirk_check_port_auto_suspend) { 3693 if (hdev->do_remote_wakeup && hub->quirk_check_port_auto_suspend) {
@@ -3702,12 +3702,12 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
3702 if (hub_is_superspeed(hdev) && hdev->do_remote_wakeup) { 3702 if (hub_is_superspeed(hdev) && hdev->do_remote_wakeup) {
3703 /* Enable hub to send remote wakeup for all ports. */ 3703 /* Enable hub to send remote wakeup for all ports. */
3704 for (port1 = 1; port1 <= hdev->maxchild; port1++) { 3704 for (port1 = 1; port1 <= hdev->maxchild; port1++) {
3705 status = set_port_feature(hdev, 3705 set_port_feature(hdev,
3706 port1 | 3706 port1 |
3707 USB_PORT_FEAT_REMOTE_WAKE_CONNECT | 3707 USB_PORT_FEAT_REMOTE_WAKE_CONNECT |
3708 USB_PORT_FEAT_REMOTE_WAKE_DISCONNECT | 3708 USB_PORT_FEAT_REMOTE_WAKE_DISCONNECT |
3709 USB_PORT_FEAT_REMOTE_WAKE_OVER_CURRENT, 3709 USB_PORT_FEAT_REMOTE_WAKE_OVER_CURRENT,
3710 USB_PORT_FEAT_REMOTE_WAKE_MASK); 3710 USB_PORT_FEAT_REMOTE_WAKE_MASK);
3711 } 3711 }
3712 } 3712 }
3713 3713
@@ -5902,7 +5902,10 @@ int usb_reset_device(struct usb_device *udev)
5902 cintf->needs_binding = 1; 5902 cintf->needs_binding = 1;
5903 } 5903 }
5904 } 5904 }
5905 usb_unbind_and_rebind_marked_interfaces(udev); 5905
5906 /* If the reset failed, hub_wq will unbind drivers later */
5907 if (ret == 0)
5908 usb_unbind_and_rebind_marked_interfaces(udev);
5906 } 5909 }
5907 5910
5908 usb_autosuspend_device(udev); 5911 usb_autosuspend_device(udev);