Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: hub: Add quirk to decrease IN-ep poll interval for Microchip USB491x hub

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>

authored by

Hardik Gajjar and committed by
Greg Kroah-Hartman
855d75cf 6666ea93

+29
+29
drivers/usb/core/hub.c
··· 47 47 #define USB_VENDOR_TEXAS_INSTRUMENTS 0x0451 48 48 #define USB_PRODUCT_TUSB8041_USB3 0x8140 49 49 #define USB_PRODUCT_TUSB8041_USB2 0x8142 50 + #define USB_VENDOR_MICROCHIP 0x0424 51 + #define USB_PRODUCT_USB4913 0x4913 52 + #define USB_PRODUCT_USB4914 0x4914 53 + #define USB_PRODUCT_USB4915 0x4915 50 54 #define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND BIT(0) 51 55 #define HUB_QUIRK_DISABLE_AUTOSUSPEND BIT(1) 56 + #define HUB_QUIRK_REDUCE_FRAME_INTR_BINTERVAL BIT(2) 52 57 53 58 #define USB_TP_TRANSMISSION_DELAY 40 /* ns */ 54 59 #define USB_TP_TRANSMISSION_DELAY_MAX 65535 /* ns */ 55 60 #define USB_PING_RESPONSE_TIME 400 /* ns */ 61 + #define USB_REDUCE_FRAME_INTR_BINTERVAL 9 56 62 57 63 /* 58 64 * The SET_ADDRESS request timeout will be 500 ms when ··· 1914 1908 if (id->driver_info & HUB_QUIRK_DISABLE_AUTOSUSPEND) { 1915 1909 hub->quirk_disable_autosuspend = 1; 1916 1910 usb_autopm_get_interface_no_resume(intf); 1911 + } 1912 + 1913 + if ((id->driver_info & HUB_QUIRK_REDUCE_FRAME_INTR_BINTERVAL) && 1914 + desc->endpoint[0].desc.bInterval > USB_REDUCE_FRAME_INTR_BINTERVAL) { 1915 + desc->endpoint[0].desc.bInterval = 1916 + USB_REDUCE_FRAME_INTR_BINTERVAL; 1917 + /* Tell the HCD about the interrupt ep's new bInterval */ 1918 + usb_set_interface(hdev, 0, 0); 1917 1919 } 1918 1920 1919 1921 if (hub_configure(hub, &desc->endpoint[0].desc) >= 0) { ··· 5920 5906 .idVendor = USB_VENDOR_TEXAS_INSTRUMENTS, 5921 5907 .idProduct = USB_PRODUCT_TUSB8041_USB3, 5922 5908 .driver_info = HUB_QUIRK_DISABLE_AUTOSUSPEND}, 5909 + { .match_flags = USB_DEVICE_ID_MATCH_VENDOR 5910 + | USB_DEVICE_ID_MATCH_PRODUCT, 5911 + .idVendor = USB_VENDOR_MICROCHIP, 5912 + .idProduct = USB_PRODUCT_USB4913, 5913 + .driver_info = HUB_QUIRK_REDUCE_FRAME_INTR_BINTERVAL}, 5914 + { .match_flags = USB_DEVICE_ID_MATCH_VENDOR 5915 + | USB_DEVICE_ID_MATCH_PRODUCT, 5916 + .idVendor = USB_VENDOR_MICROCHIP, 5917 + .idProduct = USB_PRODUCT_USB4914, 5918 + .driver_info = HUB_QUIRK_REDUCE_FRAME_INTR_BINTERVAL}, 5919 + { .match_flags = USB_DEVICE_ID_MATCH_VENDOR 5920 + | USB_DEVICE_ID_MATCH_PRODUCT, 5921 + .idVendor = USB_VENDOR_MICROCHIP, 5922 + .idProduct = USB_PRODUCT_USB4915, 5923 + .driver_info = HUB_QUIRK_REDUCE_FRAME_INTR_BINTERVAL}, 5923 5924 { .match_flags = USB_DEVICE_ID_MATCH_DEV_CLASS, 5924 5925 .bDeviceClass = USB_CLASS_HUB}, 5925 5926 { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,