thunderbolt: Take CL states into account when waiting for link to come up
If CL states are enabled for the link it may be in these states too when reading the lane adapter state but it will enter CL0 as soon as there is traffic in the high-speed lanes. Upon discovery we want to make sure that is accounted as the link being up, otherwise we end up tearing down the topology with no good reason. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
This commit is contained in:
parent
2426fdf77a
commit
e70a8f3698
2 changed files with 29 additions and 17 deletions
|
@ -513,27 +513,33 @@ int tb_wait_for_port(struct tb_port *port, bool wait_if_unplugged)
|
||||||
|
|
||||||
while (retries--) {
|
while (retries--) {
|
||||||
state = tb_port_state(port);
|
state = tb_port_state(port);
|
||||||
if (state < 0)
|
switch (state) {
|
||||||
return state;
|
case TB_PORT_DISABLED:
|
||||||
if (state == TB_PORT_DISABLED) {
|
|
||||||
tb_port_dbg(port, "is disabled (state: 0)\n");
|
tb_port_dbg(port, "is disabled (state: 0)\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
if (state == TB_PORT_UNPLUGGED) {
|
case TB_PORT_UNPLUGGED:
|
||||||
if (wait_if_unplugged) {
|
if (wait_if_unplugged) {
|
||||||
/* used during resume */
|
/* used during resume */
|
||||||
tb_port_dbg(port,
|
tb_port_dbg(port,
|
||||||
"is unplugged (state: 7), retrying...\n");
|
"is unplugged (state: 7), retrying...\n");
|
||||||
msleep(100);
|
msleep(100);
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
tb_port_dbg(port, "is unplugged (state: 7)\n");
|
tb_port_dbg(port, "is unplugged (state: 7)\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
if (state == TB_PORT_UP) {
|
case TB_PORT_UP:
|
||||||
tb_port_dbg(port, "is connected, link is up (state: 2)\n");
|
case TB_PORT_TX_CL0S:
|
||||||
|
case TB_PORT_RX_CL0S:
|
||||||
|
case TB_PORT_CL1:
|
||||||
|
case TB_PORT_CL2:
|
||||||
|
tb_port_dbg(port, "is connected, link is up (state: %d)\n", state);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
|
default:
|
||||||
|
if (state < 0)
|
||||||
|
return state;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* After plug-in the state is TB_PORT_CONNECTING. Give it some
|
* After plug-in the state is TB_PORT_CONNECTING. Give it some
|
||||||
|
@ -544,6 +550,8 @@ int tb_wait_for_port(struct tb_port *port, bool wait_if_unplugged)
|
||||||
state);
|
state);
|
||||||
msleep(100);
|
msleep(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
tb_port_warn(port,
|
tb_port_warn(port,
|
||||||
"failed to reach state TB_PORT_UP. Ignoring port...\n");
|
"failed to reach state TB_PORT_UP. Ignoring port...\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -50,6 +50,10 @@ enum tb_port_state {
|
||||||
TB_PORT_DISABLED = 0, /* tb_cap_phy.disable == 1 */
|
TB_PORT_DISABLED = 0, /* tb_cap_phy.disable == 1 */
|
||||||
TB_PORT_CONNECTING = 1, /* retry */
|
TB_PORT_CONNECTING = 1, /* retry */
|
||||||
TB_PORT_UP = 2,
|
TB_PORT_UP = 2,
|
||||||
|
TB_PORT_TX_CL0S = 3,
|
||||||
|
TB_PORT_RX_CL0S = 4,
|
||||||
|
TB_PORT_CL1 = 5,
|
||||||
|
TB_PORT_CL2 = 6,
|
||||||
TB_PORT_UNPLUGGED = 7,
|
TB_PORT_UNPLUGGED = 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue