summaryrefslogtreecommitdiff
path: root/drivers/thunderbolt/switch.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/thunderbolt/switch.c')
-rw-r--r--drivers/thunderbolt/switch.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
index 37a81206636f..df119a87ee75 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -2035,7 +2035,7 @@ int tb_switch_configure(struct tb_switch *sw)
route = tb_route(sw);
tb_dbg(tb, "%s Switch at %#llx (depth: %d, up port: %d)\n",
- sw->config.enabled ? "restoring " : "initializing", route,
+ sw->config.enabled ? "restoring" : "initializing", route,
tb_route_length(route), sw->config.upstream_port_number);
sw->config.enabled = 1;
@@ -2501,6 +2501,13 @@ int tb_switch_add(struct tb_switch *sw)
return ret;
}
+ /*
+ * Thunderbolt routers do not generate wakeups themselves but
+ * they forward wakeups from tunneled protocols, so enable it
+ * here.
+ */
+ device_init_wakeup(&sw->dev, true);
+
pm_runtime_set_active(&sw->dev);
if (sw->rpm) {
pm_runtime_set_autosuspend_delay(&sw->dev, TB_AUTOSUSPEND_DELAY);
@@ -2578,6 +2585,18 @@ void tb_sw_set_unplugged(struct tb_switch *sw)
}
}
+static int tb_switch_set_wake(struct tb_switch *sw, unsigned int flags)
+{
+ if (flags)
+ tb_sw_dbg(sw, "enabling wakeup: %#x\n", flags);
+ else
+ tb_sw_dbg(sw, "disabling wakeup\n");
+
+ if (tb_switch_is_usb4(sw))
+ return usb4_switch_set_wake(sw, flags);
+ return tb_lc_set_wake(sw, flags);
+}
+
int tb_switch_resume(struct tb_switch *sw)
{
struct tb_port *port;
@@ -2623,6 +2642,9 @@ int tb_switch_resume(struct tb_switch *sw)
if (err)
return err;
+ /* Disable wakes */
+ tb_switch_set_wake(sw, 0);
+
err = tb_switch_tmu_init(sw);
if (err)
return err;
@@ -2658,6 +2680,7 @@ int tb_switch_resume(struct tb_switch *sw)
void tb_switch_suspend(struct tb_switch *sw)
{
+ unsigned int flags = 0;
struct tb_port *port;
int err;
@@ -2670,6 +2693,11 @@ void tb_switch_suspend(struct tb_switch *sw)
tb_switch_suspend(port->remote->sw);
}
+ if (device_may_wakeup(&sw->dev))
+ flags = TB_WAKE_ON_USB4 | TB_WAKE_ON_USB3 | TB_WAKE_ON_PCIE;
+
+ tb_switch_set_wake(sw, flags);
+
if (tb_switch_is_usb4(sw))
usb4_switch_set_sleep(sw);
else