[PATCH 02/11] usb: tcpm: avoid hard reset for sink-only ports on Source_Cap timeout

Peng Fan (OSS) peng.fan at oss.nxp.com
Wed Jun 17 10:23:01 CEST 2026


From: Peng Fan <peng.fan at nxp.com>

When a sink-only port times out waiting for Source_Capabilities in
SNK_WAIT_CAPABILITIES, the current code falls through to
hard_reset_state() which sends a Hard Reset. For sink-only ports
powered via VBUS, this causes the source to cut VBUS, resetting
the board.

Unlike DRP ports which can potentially recover by switching roles,
sink-only ports have no recovery path after a Hard Reset induced
VBUS loss. Instead, gracefully fall back to SNK_READY to operate
at the Type-C default current.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/usb/tcpm/tcpm.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/tcpm/tcpm.c b/drivers/usb/tcpm/tcpm.c
index d6c0be82333..25ff0926cdf 100644
--- a/drivers/usb/tcpm/tcpm.c
+++ b/drivers/usb/tcpm/tcpm.c
@@ -1647,6 +1647,8 @@ static void run_state_machine(struct udevice *dev)
 			port->vbus_never_low = false;
 			tcpm_set_state(dev, SOFT_RESET_SEND,
 				       PD_T_SINK_WAIT_CAP);
+		} else if (port->port_type == TYPEC_PORT_SNK) {
+			tcpm_set_state(dev, SNK_READY, 0);
 		} else {
 			tcpm_set_state(dev, hard_reset_state(port),
 				       PD_T_SINK_WAIT_CAP);
@@ -1770,9 +1772,13 @@ static void run_state_machine(struct udevice *dev)
 		port->message_id = 0;
 		port->rx_msgid = -1;
 		if (tcpm_pd_send_control(dev, PD_CTRL_SOFT_RESET))
-			tcpm_set_state_cond(dev, hard_reset_state(port), 0);
+			tcpm_set_state_cond(dev,
+					    port->port_type == TYPEC_PORT_SNK ?
+					    SNK_READY : hard_reset_state(port), 0);
 		else
-			tcpm_set_state_cond(dev, hard_reset_state(port),
+			tcpm_set_state_cond(dev,
+					    port->port_type == TYPEC_PORT_SNK ?
+					    SNK_READY : hard_reset_state(port),
 					    PD_T_SENDER_RESPONSE);
 		break;
 

-- 
2.51.0



More information about the U-Boot mailing list