]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
thunderbolt: Fix wake configurations after device unplug
authorGil Fine <gil.fine@linux.intel.com>
Fri, 1 Mar 2024 13:22:53 +0000 (15:22 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 2 May 2024 14:23:38 +0000 (16:23 +0200)
commit c38fa07dc69f0b9e6f43ecab96dc7861a70c827c upstream.

Currently we don't configure correctly the wake events after unplug of device
router. What can happen is that the downstream ports of host router will be
configured to wake on: USB4-wake and wake-on-disconnect, but not on
wake-on-connect. This may cause the later plugged device not to wake the
domain and fail in enumeration. Fix this by clearing downstream port's "USB4
Port is Configured" bit, after unplug of a device router.

Signed-off-by: Gil Fine <gil.fine@linux.intel.com>
Cc: stable@vger.kernel.org
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/thunderbolt/switch.c

index bbada6c25c04d7ca7269ab3e89e58d63dd6ca1f9..b13a944eb4620cbdf8eb8bc7a343cb98345569dc 100644 (file)
@@ -2402,22 +2402,29 @@ void tb_switch_unconfigure_link(struct tb_switch *sw)
 {
        struct tb_port *up, *down;
 
-       if (sw->is_unplugged)
-               return;
        if (!tb_route(sw) || tb_switch_is_icm(sw))
                return;
 
+       /*
+        * Unconfigure downstream port so that wake-on-connect can be
+        * configured after router unplug. No need to unconfigure upstream port
+        * since its router is unplugged.
+        */
        up = tb_upstream_port(sw);
-       if (tb_switch_is_usb4(up->sw))
-               usb4_port_unconfigure(up);
-       else
-               tb_lc_unconfigure_port(up);
-
        down = up->remote;
        if (tb_switch_is_usb4(down->sw))
                usb4_port_unconfigure(down);
        else
                tb_lc_unconfigure_port(down);
+
+       if (sw->is_unplugged)
+               return;
+
+       up = tb_upstream_port(sw);
+       if (tb_switch_is_usb4(up->sw))
+               usb4_port_unconfigure(up);
+       else
+               tb_lc_unconfigure_port(up);
 }
 
 static int tb_switch_port_hotplug_enable(struct tb_switch *sw)