]> git.baikalelectronics.ru Git - kernel.git/commitdiff
xhci: Add a flag to disable USB3 lpm on a xhci root port level.
authorMathias Nyman <mathias.nyman@linux.intel.com>
Mon, 16 Jan 2023 14:22:14 +0000 (16:22 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 24 Jan 2023 06:17:59 +0000 (07:17 +0100)
commit 0522b9a1653048440da5f21747f21e498b9220d1 upstream.

One USB3 roothub port may support link power management, while another
root port on the same xHC can't due to different retimers used for
the ports.

This is the case with Intel Alder Lake, and possible future platforms
where retimers used for USB4 ports cause too long exit latecy to
enable native USB3 lpm U1 and U2 states.

Add a flag in the xhci port structure to indicate if the port is
lpm_incapable, and check it while calculating exit latency.

Cc: stable@vger.kernel.org
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20230116142216.1141605-6-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h

index 6cec6fa9d602ccb1f63267c91ca660b1fc00f196..35d96796854d617cbdc6ca9b6aa8c1870e6abacb 100644 (file)
@@ -4999,6 +4999,7 @@ static int xhci_enable_usb3_lpm_timeout(struct usb_hcd *hcd,
                        struct usb_device *udev, enum usb3_link_state state)
 {
        struct xhci_hcd *xhci;
+       struct xhci_port *port;
        u16 hub_encoded_timeout;
        int mel;
        int ret;
@@ -5012,6 +5013,13 @@ static int xhci_enable_usb3_lpm_timeout(struct usb_hcd *hcd,
                        !xhci->devs[udev->slot_id])
                return USB3_LPM_DISABLED;
 
+       /* If connected to root port then check port can handle lpm */
+       if (udev->parent && !udev->parent->parent) {
+               port = xhci->usb3_rhub.ports[udev->portnum - 1];
+               if (port->lpm_incapable)
+                       return USB3_LPM_DISABLED;
+       }
+
        hub_encoded_timeout = xhci_calculate_lpm_timeout(hcd, udev, state);
        mel = calculate_max_exit_latency(udev, state, hub_encoded_timeout);
        if (mel < 0) {
index 16027d803811851ee1230190f4592d0c6480ee60..e696f1508318e9841d94595457cbd140f7f55eee 100644 (file)
@@ -1724,6 +1724,7 @@ struct xhci_port {
        int                     hcd_portnum;
        struct xhci_hub         *rhub;
        struct xhci_port_cap    *port_cap;
+       unsigned int            lpm_incapable:1;
 };
 
 struct xhci_hub {