Commit 4a420eb1 authored by Mika Westerberg's avatar Mika Westerberg

thunderbolt: Make tb_switch_clx_disable() return CL states that were enabled

This allows us to disable all CL states temporarily when running lane
margining and then return back the previously enabled states.
Signed-off-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
parent 768e6fe6
......@@ -317,6 +317,9 @@ int tb_switch_clx_enable(struct tb_switch *sw, unsigned int clx)
struct tb_port *up, *down;
int ret;
if (!clx)
return 0;
if (!validate_mask(clx))
return -EINVAL;
......@@ -380,7 +383,8 @@ int tb_switch_clx_enable(struct tb_switch *sw, unsigned int clx)
* Disables all CL states of the given router. Can be called on any
* router and if the states were not enabled already does nothing.
*
* Returns %0 on success or an error code on failure.
* Returns the CL states that were disabled or negative errno in case of
* failure.
*/
int tb_switch_clx_disable(struct tb_switch *sw)
{
......@@ -408,5 +412,5 @@ int tb_switch_clx_disable(struct tb_switch *sw)
sw->clx = 0;
tb_sw_dbg(sw, "CLx: %s disabled\n", clx_name(clx));
return 0;
return clx;
}
......@@ -553,8 +553,9 @@ static int margining_run_write(void *data, u64 val)
struct usb4_port *usb4 = port->usb4;
struct tb_switch *sw = port->sw;
struct tb_margining *margining;
struct tb_switch *down_sw;
struct tb *tb = sw->tb;
int ret;
int ret, clx;
if (val != 1)
return -EINVAL;
......@@ -566,15 +567,24 @@ static int margining_run_write(void *data, u64 val)
goto out_rpm_put;
}
/*
* CL states may interfere with lane margining so inform the user know
* and bail out.
*/
if (tb_port_clx_is_enabled(port, TB_CL1 | TB_CL2)) {
tb_port_warn(port,
"CL states are enabled, Disable them with clx=0 and re-connect\n");
ret = -EINVAL;
goto out_unlock;
if (tb_is_upstream_port(port))
down_sw = sw;
else if (port->remote)
down_sw = port->remote->sw;
else
down_sw = NULL;
if (down_sw) {
/*
* CL states may interfere with lane margining so
* disable them temporarily now.
*/
ret = tb_switch_clx_disable(down_sw);
if (ret < 0) {
tb_sw_warn(down_sw, "failed to disable CL states\n");
goto out_unlock;
}
clx = ret;
}
margining = usb4->margining;
......@@ -586,7 +596,7 @@ static int margining_run_write(void *data, u64 val)
margining->right_high,
USB4_MARGIN_SW_COUNTER_CLEAR);
if (ret)
goto out_unlock;
goto out_clx;
ret = usb4_port_sw_margin_errors(port, &margining->results[0]);
} else {
......@@ -600,6 +610,9 @@ static int margining_run_write(void *data, u64 val)
margining->right_high, margining->results);
}
out_clx:
if (down_sw)
tb_switch_clx_enable(down_sw, clx);
out_unlock:
mutex_unlock(&tb->lock);
out_rpm_put:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment