usb: hub: Add quirk to decrease IN-ep poll interval for Microchip USB491x hub
authorHardik Gajjar <hgajjar@de.adit-jv.com>
Tue, 5 Dec 2023 18:18:29 +0000 (19:18 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 6 Dec 2023 03:37:07 +0000 (12:37 +0900)
There is a potential delay in notifying Linux USB drivers of downstream
USB bus activity when connecting a high-speed or superSpeed device via the
Microchip USB491x hub. This delay is due to the fixed bInterval value of
12 in the silicon of the Microchip USB491x hub.

Microchip requested to ignore the device descriptor and decrease that
value to 9 as it was too late to modify that in silicon.

This patch speeds up the USB enummeration process that helps to pass
Apple Carplay certifications and improve the User experience when utilizing
the USB device via Microchip Multihost USB491x Hub.

A new hub quirk HUB_QUIRK_REDUCE_FRAME_INTR_BINTERVAL speeds up
the notification process for Microchip USB491x hub by limiting
the maximum bInterval value to 9.

Signed-off-by: Hardik Gajjar <hgajjar@de.adit-jv.com>
Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
Link: https://lore.kernel.org/r/20231205181829.127353-2-hgajjar@de.adit-jv.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/core/hub.c

index 7b6bfffbdc5583dc54bcb654290b027e092daaf2..ffd7c99e24a3624fba07e8277866a5526c6695eb 100644 (file)
 #define USB_VENDOR_TEXAS_INSTRUMENTS           0x0451
 #define USB_PRODUCT_TUSB8041_USB3              0x8140
 #define USB_PRODUCT_TUSB8041_USB2              0x8142
+#define USB_VENDOR_MICROCHIP                   0x0424
+#define USB_PRODUCT_USB4913                    0x4913
+#define USB_PRODUCT_USB4914                    0x4914
+#define USB_PRODUCT_USB4915                    0x4915
 #define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND       BIT(0)
 #define HUB_QUIRK_DISABLE_AUTOSUSPEND          BIT(1)
+#define HUB_QUIRK_REDUCE_FRAME_INTR_BINTERVAL  BIT(2)
 
 #define USB_TP_TRANSMISSION_DELAY      40      /* ns */
 #define USB_TP_TRANSMISSION_DELAY_MAX  65535   /* ns */
 #define USB_PING_RESPONSE_TIME         400     /* ns */
+#define USB_REDUCE_FRAME_INTR_BINTERVAL        9
 
 /*
  * The SET_ADDRESS request timeout will be 500 ms when
@@ -1910,6 +1916,14 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
                usb_autopm_get_interface_no_resume(intf);
        }
 
+       if ((id->driver_info & HUB_QUIRK_REDUCE_FRAME_INTR_BINTERVAL) &&
+           desc->endpoint[0].desc.bInterval > USB_REDUCE_FRAME_INTR_BINTERVAL) {
+               desc->endpoint[0].desc.bInterval =
+                       USB_REDUCE_FRAME_INTR_BINTERVAL;
+               /* Tell the HCD about the interrupt ep's new bInterval */
+               usb_set_interface(hdev, 0, 0);
+       }
+
        if (hub_configure(hub, &desc->endpoint[0].desc) >= 0) {
                onboard_hub_create_pdevs(hdev, &hub->onboard_hub_devs);
 
@@ -5906,6 +5920,21 @@ static const struct usb_device_id hub_id_table[] = {
       .idVendor = USB_VENDOR_TEXAS_INSTRUMENTS,
       .idProduct = USB_PRODUCT_TUSB8041_USB3,
       .driver_info = HUB_QUIRK_DISABLE_AUTOSUSPEND},
+       { .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+                       | USB_DEVICE_ID_MATCH_PRODUCT,
+         .idVendor = USB_VENDOR_MICROCHIP,
+         .idProduct = USB_PRODUCT_USB4913,
+         .driver_info = HUB_QUIRK_REDUCE_FRAME_INTR_BINTERVAL},
+       { .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+                       | USB_DEVICE_ID_MATCH_PRODUCT,
+         .idVendor = USB_VENDOR_MICROCHIP,
+         .idProduct = USB_PRODUCT_USB4914,
+         .driver_info = HUB_QUIRK_REDUCE_FRAME_INTR_BINTERVAL},
+       { .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+                       | USB_DEVICE_ID_MATCH_PRODUCT,
+         .idVendor = USB_VENDOR_MICROCHIP,
+         .idProduct = USB_PRODUCT_USB4915,
+         .driver_info = HUB_QUIRK_REDUCE_FRAME_INTR_BINTERVAL},
     { .match_flags = USB_DEVICE_ID_MATCH_DEV_CLASS,
       .bDeviceClass = USB_CLASS_HUB},
     { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,