[PATCH 1/5] usb: typec: tcpm: Stop a source from repeating a cable Soft_Reset
From: Alexey Charkov
Date: Tue Nov 03 2026 - 07:21:09 EST
A soft reset AMS starts with upcoming_state set to SOFT_RESET_SEND and a
call to tcpm_ams_start(). A sink then enters SOFT_RESET_SEND through
upcoming_state, which consumes it. A source enters SOFT_RESET_SEND right
away and leaves upcoming_state set, for the next SRC_READY to replay.
After an SOP Soft_Reset that is harmless, as the Accept handler or a
hard reset replaces upcoming_state. The SOP' Soft_Reset sent after a
VCONN swap returns to SRC_READY instead, so a source resets the cable
plug a second time, outside of any AMS.
Clear upcoming_state when a source enters SOFT_RESET_SEND right away.
Cc: stable@xxxxxxxxxxxxxxx
Fixes: 6bd181ba60e1 ("usb: typec: tcpm: add control message support to sop'")
Signed-off-by: Alexey Charkov <alchark@xxxxxxxxxxx>
---
drivers/usb/typec/tcpm/tcpm.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
index d721baef5210..c0c54caf99d6 100644
--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -1914,6 +1914,8 @@ static int tcpm_ams_start(struct tcpm_port *port, enum tcpm_ams ams)
} else if (ams == SOFT_RESET_AMS) {
if (!port->explicit_contract)
tcpm_set_cc(port, tcpm_rp_cc(port));
+ /* entered right away, so don't leave it to be replayed */
+ port->upcoming_state = INVALID_STATE;
tcpm_set_state(port, SOFT_RESET_SEND, 0);
return ret;
} else if (tcpm_vdm_ams(port)) {
--
2.56.0