mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-25 20:05:39 +00:00
thunderbolt: Fixes for v6.9-rc5
This includes following USB4/Thunderbolt fixes for v6.9-rc5: - Avoid creating DisplayPort tunnels for the adapters on the same router - Correct wake configurations after device router unplug - Fix immediate wake when "wakeup_count" is used to enter system sleep. All these have been in linux-next with no reported issues. -----BEGIN PGP SIGNATURE----- iQJUBAABCgA+FiEEVTdhRGBbNzLrSUBaAP2fSd+ZWKAFAmYcxVAgHG1pa2Eud2Vz dGVyYmVyZ0BsaW51eC5pbnRlbC5jb20ACgkQAP2fSd+ZWKB21w//bv0mVOJd06Pv /1yqZDT/5+0U2E4Rb3VAwinwKz/3RqtKQ9dC2iKI0P9oQ4s57LE3dIyrNiJhJ/Xz wixsLKqiqIcssOt9rd3WNLrfSjzLXmVucDiolVb8nvYleVvVQTp/uPz7tLrpUR+g xuCv6n63Cw33XxsCNJOEW+0iynkDsb2LA8lMbcGdJk96JVlmQPoIDsgbyZ5au/FA 6qqxf08cYVkbrUs8/E/k5oDBRWZPr/Do05pSwO5LktF63JzjJ3vGJaGTOcojXC2a NGF0Z8PZvf0oDt2csgGnQNTN+I/yVXyaKcdh0rcaBBIOUBGluL4prnGlLcwGFmlH Hwv3IXFqLm7fk9Lvyt0QCV+RQ2mhA2DuSgXw09Z5yy3p/IvxcG6+Z4/2iov/lgZe 4xn+kYT70BmJZP3JuatdbQeToejmpcm3qrGLLasqtFcq22bYTv3LmwyM6b2d4oqs pHRLkeGINlze/Fa8yjsfffMhO97kp0iAWzM7z7a29eZeu/JnYRLPhs27SQkgCOQI vuRCmn7KAmzHxtESByE8+rbrp7w1YcnEuCPSTEfrA0uy6+9gaPUeNFlow9W8iloo pzrIaPvLQKQ0O40BrKo5p3qbqA/Kg40QuDomLJbep49O/8CxNLzGtUWRfGmbi0iR QDxbHQmxN2vLlp1+rw6obklQ3Ws/0HU= =8qyc -----END PGP SIGNATURE----- Merge tag 'thunderbolt-for-v6.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt into usb-linus Mika writes: thunderbolt: Fixes for v6.9-rc5 This includes following USB4/Thunderbolt fixes for v6.9-rc5: - Avoid creating DisplayPort tunnels for the adapters on the same router - Correct wake configurations after device router unplug - Fix immediate wake when "wakeup_count" is used to enter system sleep. All these have been in linux-next with no reported issues. * tag 'thunderbolt-for-v6.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt: thunderbolt: Avoid notify PM core about runtime PM resume thunderbolt: Fix wake configurations after device unplug thunderbolt: Do not create DisplayPort tunnels on adapters of the same router
This commit is contained in:
commit
c281d18dda
4 changed files with 57 additions and 19 deletions
|
@ -3180,22 +3180,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);
|
||||
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);
|
||||
|
||||
down = up->remote;
|
||||
if (tb_switch_is_usb4(down->sw))
|
||||
usb4_port_unconfigure(down);
|
||||
else
|
||||
tb_lc_unconfigure_port(down);
|
||||
}
|
||||
|
||||
static void tb_switch_credits_init(struct tb_switch *sw)
|
||||
|
@ -3441,7 +3448,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;
|
||||
|
@ -3490,6 +3516,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);
|
||||
|
||||
|
@ -3519,7 +3548,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);
|
||||
|
|
|
@ -1801,6 +1801,12 @@ static struct tb_port *tb_find_dp_out(struct tb *tb, struct tb_port *in)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Needs to be on different routers */
|
||||
if (in->sw == port->sw) {
|
||||
tb_port_dbg(port, "skipping DP OUT on same router\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
tb_port_dbg(port, "DP OUT available\n");
|
||||
|
||||
/*
|
||||
|
@ -2936,7 +2942,7 @@ static int tb_resume_noirq(struct tb *tb)
|
|||
if (!tb_switch_is_usb4(tb->root_switch))
|
||||
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);
|
||||
|
@ -3062,7 +3068,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)
|
||||
|
|
|
@ -827,7 +827,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);
|
||||
|
@ -1288,6 +1288,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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue