Skip to content

Commit 17a6ea2

Browse files
superm1gregkh
authored andcommitted
thunderbolt: Fix wake on connect at runtime
commit 58d71d4 upstream. commit 1a760d1 ("thunderbolt: Fix a logic error in wake on connect") fixated on the USB4 port sysfs wakeup file not working properly to control policy, but it had an unintended side effect that the sysfs file controls policy both at runtime and at suspend time. The sysfs file is supposed to only control behavior while system is suspended. Pass whether programming a port for runtime into usb4_switch_set_wake() and if runtime then ignore the value in the sysfs file. Cc: stable@vger.kernel.org Reported-by: Alexander Kovacs <Alexander.Kovacs@amd.com> Tested-by: Alexander Kovacs <Alexander.Kovacs@amd.com> Fixes: 1a760d1 ("thunderbolt: Fix a logic error in wake on connect") Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 1a1190b commit 17a6ea2

File tree

3 files changed

+10
-12
lines changed

3 files changed

+10
-12
lines changed

drivers/thunderbolt/switch.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3437,15 +3437,15 @@ void tb_sw_set_unplugged(struct tb_switch *sw)
34373437
}
34383438
}
34393439

3440-
static int tb_switch_set_wake(struct tb_switch *sw, unsigned int flags)
3440+
static int tb_switch_set_wake(struct tb_switch *sw, unsigned int flags, bool runtime)
34413441
{
34423442
if (flags)
34433443
tb_sw_dbg(sw, "enabling wakeup: %#x\n", flags);
34443444
else
34453445
tb_sw_dbg(sw, "disabling wakeup\n");
34463446

34473447
if (tb_switch_is_usb4(sw))
3448-
return usb4_switch_set_wake(sw, flags);
3448+
return usb4_switch_set_wake(sw, flags, runtime);
34493449
return tb_lc_set_wake(sw, flags);
34503450
}
34513451

@@ -3521,7 +3521,7 @@ int tb_switch_resume(struct tb_switch *sw, bool runtime)
35213521
tb_switch_check_wakes(sw);
35223522

35233523
/* Disable wakes */
3524-
tb_switch_set_wake(sw, 0);
3524+
tb_switch_set_wake(sw, 0, true);
35253525

35263526
err = tb_switch_tmu_init(sw);
35273527
if (err)
@@ -3602,7 +3602,7 @@ void tb_switch_suspend(struct tb_switch *sw, bool runtime)
36023602
flags |= TB_WAKE_ON_USB4 | TB_WAKE_ON_USB3 | TB_WAKE_ON_PCIE;
36033603
}
36043604

3605-
tb_switch_set_wake(sw, flags);
3605+
tb_switch_set_wake(sw, flags, runtime);
36063606

36073607
if (tb_switch_is_usb4(sw))
36083608
usb4_switch_set_sleep(sw);

drivers/thunderbolt/tb.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1299,7 +1299,7 @@ int usb4_switch_read_uid(struct tb_switch *sw, u64 *uid);
12991299
int usb4_switch_drom_read(struct tb_switch *sw, unsigned int address, void *buf,
13001300
size_t size);
13011301
bool usb4_switch_lane_bonding_possible(struct tb_switch *sw);
1302-
int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags);
1302+
int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags, bool runtime);
13031303
int usb4_switch_set_sleep(struct tb_switch *sw);
13041304
int usb4_switch_nvm_sector_size(struct tb_switch *sw);
13051305
int usb4_switch_nvm_read(struct tb_switch *sw, unsigned int address, void *buf,

drivers/thunderbolt/usb4.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -403,12 +403,12 @@ bool usb4_switch_lane_bonding_possible(struct tb_switch *sw)
403403
* usb4_switch_set_wake() - Enabled/disable wake
404404
* @sw: USB4 router
405405
* @flags: Wakeup flags (%0 to disable)
406+
* @runtime: Wake is being programmed during system runtime
406407
*
407408
* Enables/disables router to wake up from sleep.
408409
*/
409-
int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags)
410+
int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags, bool runtime)
410411
{
411-
struct usb4_port *usb4;
412412
struct tb_port *port;
413413
u64 route = tb_route(sw);
414414
u32 val;
@@ -438,13 +438,11 @@ int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags)
438438
val |= PORT_CS_19_WOU4;
439439
} else {
440440
bool configured = val & PORT_CS_19_PC;
441-
usb4 = port->usb4;
441+
bool wakeup = runtime || device_may_wakeup(&port->usb4->dev);
442442

443-
if (((flags & TB_WAKE_ON_CONNECT) &&
444-
device_may_wakeup(&usb4->dev)) && !configured)
443+
if ((flags & TB_WAKE_ON_CONNECT) && wakeup && !configured)
445444
val |= PORT_CS_19_WOC;
446-
if (((flags & TB_WAKE_ON_DISCONNECT) &&
447-
device_may_wakeup(&usb4->dev)) && configured)
445+
if ((flags & TB_WAKE_ON_DISCONNECT) && wakeup && configured)
448446
val |= PORT_CS_19_WOD;
449447
if ((flags & TB_WAKE_ON_USB4) && configured)
450448
val |= PORT_CS_19_WOU4;

0 commit comments

Comments
 (0)