diff options
author | Mika Westerberg <mika.westerberg@linux.intel.com> | 2023-11-17 13:58:39 +0300 |
---|---|---|
committer | Mika Westerberg <mika.westerberg@linux.intel.com> | 2023-12-14 09:07:45 +0300 |
commit | 09dc766bd60b7bc6a2742aaf2410e434f458893c (patch) | |
tree | bc4602bf6b929078902e5757a3f6820d03b8e9e0 /drivers/thunderbolt/tb.c | |
parent | 3c052ec6f4f866163573445a02d60b629805a6e7 (diff) | |
download | linux-09dc766bd60b7bc6a2742aaf2410e434f458893c.tar.xz |
thunderbolt: Disable CL states only when actually needed
If there is not going to be an actual transition to asymmetric or
symmetric, there is no point to disable and re-enable CL states either.
So instead disable them only when we know that an actual transition is
going to take place.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Diffstat (limited to 'drivers/thunderbolt/tb.c')
-rw-r--r-- | drivers/thunderbolt/tb.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index f81e7cf53d69..cf1a20a33b9a 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -1075,15 +1075,14 @@ static int tb_configure_asym(struct tb *tb, struct tb_port *src_port, struct tb_port *dst_port, int requested_up, int requested_down) { + bool clx = false, clx_disabled = false, downstream; struct tb_switch *sw; - bool clx, downstream; struct tb_port *up; int ret = 0; if (!asym_threshold) return 0; - /* Disable CL states before doing any transitions */ downstream = tb_port_path_direction_downstream(src_port, dst_port); /* Pick up router deepest in the hierarchy */ if (downstream) @@ -1091,8 +1090,6 @@ static int tb_configure_asym(struct tb *tb, struct tb_port *src_port, else sw = src_port->sw; - clx = tb_disable_clx(sw); - tb_for_each_upstream_port_on_path(src_port, dst_port, up) { struct tb_port *down = tb_switch_downstream_port(up->sw); enum tb_link_width width_up, width_down; @@ -1139,6 +1136,16 @@ static int tb_configure_asym(struct tb *tb, struct tb_port *src_port, !tb_port_width_supported(down, width_down)) continue; + /* + * Disable CL states before doing any transitions. We + * delayed it until now that we know there is a real + * transition taking place. + */ + if (!clx_disabled) { + clx = tb_disable_clx(sw); + clx_disabled = true; + } + tb_sw_dbg(up->sw, "configuring asymmetric link\n"); /* @@ -1175,15 +1182,14 @@ static int tb_configure_sym(struct tb *tb, struct tb_port *src_port, struct tb_port *dst_port, int requested_up, int requested_down) { + bool clx = false, clx_disabled = false, downstream; struct tb_switch *sw; - bool clx, downstream; struct tb_port *up; int ret = 0; if (!asym_threshold) return 0; - /* Disable CL states before doing any transitions */ downstream = tb_port_path_direction_downstream(src_port, dst_port); /* Pick up router deepest in the hierarchy */ if (downstream) @@ -1191,8 +1197,6 @@ static int tb_configure_sym(struct tb *tb, struct tb_port *src_port, else sw = src_port->sw; - clx = tb_disable_clx(sw); - tb_for_each_upstream_port_on_path(src_port, dst_port, up) { int consumed_up, consumed_down; @@ -1225,6 +1229,12 @@ static int tb_configure_sym(struct tb *tb, struct tb_port *src_port, if (up->sw->link_width == TB_LINK_WIDTH_DUAL) continue; + /* Disable CL states before doing any transitions */ + if (!clx_disabled) { + clx = tb_disable_clx(sw); + clx_disabled = true; + } + tb_sw_dbg(up->sw, "configuring symmetric link\n"); ret = tb_switch_set_link_width(up->sw, TB_LINK_WIDTH_DUAL); |