]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
thunderbolt: Avoid notify PM core about runtime PM resume
authorGil Fine <gil.fine@linux.intel.com>
Fri, 1 Mar 2024 13:11:18 +0000 (15:11 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 27 Apr 2024 15:11:38 +0000 (17:11 +0200)
commit dcd12acaf384c30437fa5a9a1f71df06fc9835fd upstream.

Currently we notify PM core about occurred wakes after any resume. This
is not actually needed after resume from runtime suspend. Hence, notify
PM core about occurred wakes only after resume from system sleep. Also,
if the wake occurred in USB4 router upstream port, we don't notify the
PM core about it since it is not actually needed and can cause
unexpected autowake (e.g. if /sys/power/wakeup_count is used).

While there add the missing kernel-doc for tb_switch_resume().

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
drivers/thunderbolt/tb.c
drivers/thunderbolt/tb.h
drivers/thunderbolt/usb4.c

index 34290a3692ed1879f79399669ec42520247ba207..257d6fb37ed51b8b5bf50d4a417b42f1fba0d9a6 100644 (file)
@@ -3208,7 +3208,26 @@ static int tb_switch_set_wake(struct tb_switch *sw, unsigned int flags)
        return tb_lc_set_wake(sw, flags);
 }
 
-int tb_switch_resume(struct tb_switch *sw)
+static void tb_switch_check_wakes(struct tb_switch *sw)
+{
+       if (device_may_wakeup(&sw->dev)) {
+               if (tb_switch_is_usb4(sw))
+                       usb4_switch_check_wakes(sw);
+       }
+}
+
+/**
+ * tb_switch_resume() - Resume a switch after sleep
+ * @sw: Switch to resume
+ * @runtime: Is this resume from runtime suspend or system sleep
+ *
+ * Resumes and re-enumerates router (and all its children), if still plugged
+ * after suspend. Don't enumerate device router whose UID was changed during
+ * suspend. If this is resume from system sleep, notifies PM core about the
+ * wakes occurred during suspend. Disables all wakes, except USB4 wake of
+ * upstream port for USB4 routers that shall be always enabled.
+ */
+int tb_switch_resume(struct tb_switch *sw, bool runtime)
 {
        struct tb_port *port;
        int err;
@@ -3257,6 +3276,9 @@ int tb_switch_resume(struct tb_switch *sw)
        if (err)
                return err;
 
+       if (!runtime)
+               tb_switch_check_wakes(sw);
+
        /* Disable wakes */
        tb_switch_set_wake(sw, 0);
 
@@ -3286,7 +3308,8 @@ int tb_switch_resume(struct tb_switch *sw)
                         */
                        if (tb_port_unlock(port))
                                tb_port_warn(port, "failed to unlock port\n");
-                       if (port->remote && tb_switch_resume(port->remote->sw)) {
+                       if (port->remote &&
+                           tb_switch_resume(port->remote->sw, runtime)) {
                                tb_port_warn(port,
                                             "lost during suspend, disconnecting\n");
                                tb_sw_set_unplugged(port->remote->sw);
index 6b1ecb791098ec7e2d883303d866efba002f927d..00d07e1fb592b6690701bd898b52ac1bbb6ffa0e 100644 (file)
@@ -2262,7 +2262,7 @@ static int tb_resume_noirq(struct tb *tb)
        /* remove any pci devices the firmware might have setup */
        tb_switch_reset(tb->root_switch);
 
-       tb_switch_resume(tb->root_switch);
+       tb_switch_resume(tb->root_switch, false);
        tb_free_invalid_tunnels(tb);
        tb_free_unplugged_children(tb->root_switch);
        tb_restore_children(tb->root_switch);
@@ -2388,7 +2388,7 @@ static int tb_runtime_resume(struct tb *tb)
        struct tb_tunnel *tunnel, *n;
 
        mutex_lock(&tb->lock);
-       tb_switch_resume(tb->root_switch);
+       tb_switch_resume(tb->root_switch, true);
        tb_free_invalid_tunnels(tb);
        tb_restore_children(tb->root_switch);
        list_for_each_entry_safe(tunnel, n, &tcm->tunnel_list, list)
index f8b09e0a0d9c3d63eaf053abd4e81a5e09e29719..8a75aabb9ce8e5459619eda84900b61c2f5371c7 100644 (file)
@@ -802,7 +802,7 @@ int tb_switch_configuration_valid(struct tb_switch *sw);
 int tb_switch_add(struct tb_switch *sw);
 void tb_switch_remove(struct tb_switch *sw);
 void tb_switch_suspend(struct tb_switch *sw, bool runtime);
-int tb_switch_resume(struct tb_switch *sw);
+int tb_switch_resume(struct tb_switch *sw, bool runtime);
 int tb_switch_reset(struct tb_switch *sw);
 int tb_switch_wait_for_bit(struct tb_switch *sw, u32 offset, u32 bit,
                           u32 value, int timeout_msec);
@@ -1224,6 +1224,7 @@ static inline bool tb_switch_is_usb4(const struct tb_switch *sw)
        return usb4_switch_version(sw) > 0;
 }
 
+void usb4_switch_check_wakes(struct tb_switch *sw);
 int usb4_switch_setup(struct tb_switch *sw);
 int usb4_switch_configuration_valid(struct tb_switch *sw);
 int usb4_switch_read_uid(struct tb_switch *sw, u64 *uid);
index 6b29cbd02ea154ef253d61d8879b7bfbed39b092..3aa32d7f9f6a1d14df2a9e0c7843a152a40dca9a 100644 (file)
@@ -155,7 +155,13 @@ static inline int usb4_switch_op_data(struct tb_switch *sw, u16 opcode,
                                tx_dwords, rx_data, rx_dwords);
 }
 
-static void usb4_switch_check_wakes(struct tb_switch *sw)
+/**
+ * usb4_switch_check_wakes() - Check for wakes and notify PM core about them
+ * @sw: Router whose wakes to check
+ *
+ * Checks wakes occurred during suspend and notify the PM core about them.
+ */
+void usb4_switch_check_wakes(struct tb_switch *sw)
 {
        bool wakeup_usb4 = false;
        struct usb4_port *usb4;
@@ -163,9 +169,6 @@ static void usb4_switch_check_wakes(struct tb_switch *sw)
        bool wakeup = false;
        u32 val;
 
-       if (!device_may_wakeup(&sw->dev))
-               return;
-
        if (tb_route(sw)) {
                if (tb_sw_read(sw, &val, TB_CFG_SWITCH, ROUTER_CS_6, 1))
                        return;
@@ -244,8 +247,6 @@ int usb4_switch_setup(struct tb_switch *sw)
        u32 val = 0;
        int ret;
 
-       usb4_switch_check_wakes(sw);
-
        if (!tb_route(sw))
                return 0;