Merge tag 'v3.10.103' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / usb / core / hub.c
index 66c287e756ecf588143fd4b734029ac76bb73850..c09b87b489f536ba7ab6a811c981a65c32970a2d 100644 (file)
@@ -262,6 +262,10 @@ struct usb_hub *usb_hub_to_struct_hub(struct usb_device *hdev)
 
 static int usb_device_supports_lpm(struct usb_device *udev)
 {
+       /* Some devices have trouble with LPM */
+       if (udev->quirks & USB_QUIRK_NO_LPM)
+               return 0;
+
        /* USB 2.1 (and greater) devices indicate LPM support through
         * their USB 2.0 Extended Capabilities BOS descriptor.
         */
@@ -1157,7 +1161,6 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
                }
                if (type == HUB_INIT2)
                        goto init2;
-
                goto init3;
        }
        kref_get(&hub->kref);
@@ -4415,7 +4418,13 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
                                                r = -EPROTO;
                                        break;
                                }
-                               if (r == 0)
+                               /*
+                                * Some devices time out if they are powered on
+                                * when already connected. They need a second
+                                * reset. But only on the first attempt,
+                                * lest we get into a time out/reset loop
+                                */
+                               if (r == 0  || (r == -ETIMEDOUT && j == 0))
                                        break;
 
 #if defined(CONFIG_USBIF_COMPLIANCE) && defined(CONFIG_USB_XHCI_HCD)
@@ -4548,6 +4557,8 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
                goto fail;
        }
 
+       usb_detect_quirks(udev);
+
        if (udev->wusb == 0 && le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0201) {
                retval = usb_get_bos_descriptor(udev);
                if (!retval) {
@@ -4798,7 +4809,6 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                }
                MYDBG("");
 
-               usb_detect_quirks(udev);
                if (udev->quirks & USB_QUIRK_DELAY_INIT)
                        msleep(1000);