mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
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>
This commit is contained in:
@@ -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,
|
struct tb_port *dst_port, int requested_up,
|
||||||
int requested_down)
|
int requested_down)
|
||||||
{
|
{
|
||||||
|
bool clx = false, clx_disabled = false, downstream;
|
||||||
struct tb_switch *sw;
|
struct tb_switch *sw;
|
||||||
bool clx, downstream;
|
|
||||||
struct tb_port *up;
|
struct tb_port *up;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (!asym_threshold)
|
if (!asym_threshold)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Disable CL states before doing any transitions */
|
|
||||||
downstream = tb_port_path_direction_downstream(src_port, dst_port);
|
downstream = tb_port_path_direction_downstream(src_port, dst_port);
|
||||||
/* Pick up router deepest in the hierarchy */
|
/* Pick up router deepest in the hierarchy */
|
||||||
if (downstream)
|
if (downstream)
|
||||||
@@ -1091,8 +1090,6 @@ static int tb_configure_asym(struct tb *tb, struct tb_port *src_port,
|
|||||||
else
|
else
|
||||||
sw = src_port->sw;
|
sw = src_port->sw;
|
||||||
|
|
||||||
clx = tb_disable_clx(sw);
|
|
||||||
|
|
||||||
tb_for_each_upstream_port_on_path(src_port, dst_port, up) {
|
tb_for_each_upstream_port_on_path(src_port, dst_port, up) {
|
||||||
struct tb_port *down = tb_switch_downstream_port(up->sw);
|
struct tb_port *down = tb_switch_downstream_port(up->sw);
|
||||||
enum tb_link_width width_up, width_down;
|
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))
|
!tb_port_width_supported(down, width_down))
|
||||||
continue;
|
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");
|
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,
|
struct tb_port *dst_port, int requested_up,
|
||||||
int requested_down)
|
int requested_down)
|
||||||
{
|
{
|
||||||
|
bool clx = false, clx_disabled = false, downstream;
|
||||||
struct tb_switch *sw;
|
struct tb_switch *sw;
|
||||||
bool clx, downstream;
|
|
||||||
struct tb_port *up;
|
struct tb_port *up;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (!asym_threshold)
|
if (!asym_threshold)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Disable CL states before doing any transitions */
|
|
||||||
downstream = tb_port_path_direction_downstream(src_port, dst_port);
|
downstream = tb_port_path_direction_downstream(src_port, dst_port);
|
||||||
/* Pick up router deepest in the hierarchy */
|
/* Pick up router deepest in the hierarchy */
|
||||||
if (downstream)
|
if (downstream)
|
||||||
@@ -1191,8 +1197,6 @@ static int tb_configure_sym(struct tb *tb, struct tb_port *src_port,
|
|||||||
else
|
else
|
||||||
sw = src_port->sw;
|
sw = src_port->sw;
|
||||||
|
|
||||||
clx = tb_disable_clx(sw);
|
|
||||||
|
|
||||||
tb_for_each_upstream_port_on_path(src_port, dst_port, up) {
|
tb_for_each_upstream_port_on_path(src_port, dst_port, up) {
|
||||||
int consumed_up, consumed_down;
|
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)
|
if (up->sw->link_width == TB_LINK_WIDTH_DUAL)
|
||||||
continue;
|
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");
|
tb_sw_dbg(up->sw, "configuring symmetric link\n");
|
||||||
|
|
||||||
ret = tb_switch_set_link_width(up->sw, TB_LINK_WIDTH_DUAL);
|
ret = tb_switch_set_link_width(up->sw, TB_LINK_WIDTH_DUAL);
|
||||||
|
|||||||
Reference in New Issue
Block a user