]> 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>
Thu, 2 May 2024 14:23:38 +0000 (16:23 +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 22e5c4de345b56627273485da134279db1a96ea1..bbada6c25c04d7ca7269ab3e89e58d63dd6ca1f9 100644 (file)
@@ -2631,7 +2631,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;
@@ -2676,6 +2695,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);
 
@@ -2702,7 +2724,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 a56ea540af00b48dd6b50a203a75545ee7cd6587..26a78847985ba96d5666454e0db599c77ad2f28f 100644 (file)
@@ -1385,7 +1385,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);
@@ -1488,7 +1488,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 266f3bf8ff5c66b2e405bd2dfee0f0d0abfcbcf4..f3df5655f7a1bc26303add41afcf188f6e13747d 100644 (file)
@@ -653,7 +653,7 @@ int tb_switch_configure(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);
 void tb_sw_set_unplugged(struct tb_switch *sw);
 struct tb_port *tb_switch_find_port(struct tb_switch *sw,
@@ -957,6 +957,7 @@ static inline struct tb_retimer *tb_to_retimer(struct device *dev)
        return NULL;
 }
 
+void usb4_switch_check_wakes(struct tb_switch *sw);
 int usb4_switch_setup(struct tb_switch *sw);
 int usb4_switch_read_uid(struct tb_switch *sw, u64 *uid);
 int usb4_switch_drom_read(struct tb_switch *sw, unsigned int address, void *buf,
index 5b45c45e7c5bf2ea4123253972dec9b7037b78cf..78c895abb1e48e3f8479ced13ebfd2cfacd26be2 100644 (file)
@@ -197,15 +197,18 @@ static int usb4_switch_op(struct tb_switch *sw, u16 opcode, u8 *status)
        return 0;
 }
 
-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)
 {
        struct tb_port *port;
        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;
@@ -270,8 +273,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;