FAILED: patch "[PATCH] usb: typec: tcpm: constrain TCPM_SOURCING_VBUS event handling" failed to apply to 5.15-stable tree
Subsystems (4)
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x cd3b9cea675bbfebc223f007dc2f4e79524fa54c
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026090803-mandolin-semantic-dfec@gregkh' --subject-prefix 'PATCH 5.15.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From cd3b9cea675bbfebc223f007dc2f4e79524fa54c Mon Sep 17 00:00:00 2001
From: Amit Sunil Dhamne <[email protected]>
Date: Thu, 27 Aug 2026 21:16:17 +0000
Subject: [PATCH] usb: typec: tcpm: constrain TCPM_SOURCING_VBUS event handling
When a sink detach occurs while waiting for TX send status, the old TCPM_SOURCING_VBUS event along with TCPM_VBUS_EVENT and TCPM_CC_EVENT can be queued in port->pd_events. Because TCPM_SOURCING_VBUS is evaluated after TCPM_VBUS_EVENT and TCPM_CC_EVENT in tcpm_pd_event_handler(), a stale TCPM_SOURCING_VBUS event can override the detach handling and incorrectly set port->vbus_source and port->vbus_present to true.
Add a state guard to check that the port is either operating as a Source (tcpm_port_is_source(port)) or in a Fast Role Swap (FRS) state up to FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED before processing TCPM_SOURCING_VBUS. Otherwise, discard and log the event.
Log snippet for error condition before fix:
[72792.204955] state change SRC_ATTACHED -> SRC_STARTUP [rev3 NONE_AMS] [72792.204960] sourcing vbus [72792.204962] VBUS on [72792.204970] AMS POWER_NEGOTIATION start [72792.204974] cc:=4 [72792.205319] state change SRC_STARTUP -> AMS_START [rev3 POWER_NEGOTIATION] [72792.205325] state change AMS_START -> SRC_SEND_CAPABILITIES [rev3 POWER_NEGOTIATION] [72792.205332] PD TX, header: 0x11a1 [72792.216911] PD TX complete, status: 2 [72792.216957] pending state change SRC_SEND_CAPABILITIES -> SRC_SEND_CAPABILITIES @ 150 ms [rev3 POWER_NEGOTIATION] [72792.218005] VBUS off [72792.218013] pending state change SRC_SEND_CAPABILITIES -> SNK_UNATTACHED @ 650 ms [rev3 POWER_NEGOTIATION] [72792.218020] VBUS VSAFE0V [72792.218024] state change SRC_SEND_CAPABILITIES -> SNK_UNATTACHED [rev3 POWER_NEGOTIATION] [72792.218458] CC1: 2 -> 0, CC2: 0 -> 0 [state SNK_UNATTACHED, polarity 0, disconnected] [72792.218467] VBUS on --> VBUS left on [72792.218980] disable vbus discharge ret:0 [72792.235193] Start toggling
After fix:
[ 1195.291691] state change SRC_ATTACHED -> SRC_STARTUP [rev3 NONE_AMS] [ 1195.291698] sourcing vbus [ 1195.291700] VBUS on [ 1195.291707] AMS POWER_NEGOTIATION start [ 1195.291710] cc:=4 [ 1195.291758] state change SRC_STARTUP -> AMS_START [rev3 POWER_NEGOTIATION] [ 1195.291794] state change AMS_START -> SRC_SEND_CAPABILITIES [rev3 POWER_NEGOTIATION] [ 1195.291798] PD TX, header: 0x11a1 [ 1195.297056] PD TX complete, status: 2 [ 1195.297092] pending state change SRC_SEND_CAPABILITIES -> SRC_SEND_CAPABILITIES @ 150 ms [rev3 POWER_NEGOTIATION] [ 1195.297177] VBUS off [ 1195.297184] pending state change SRC_SEND_CAPABILITIES -> SNK_UNATTACHED @ 650 ms [rev3 POWER_NEGOTIATION] [ 1195.297227] CC1: 2 -> 0, CC2: 0 -> 0 [state SRC_SEND_CAPABILITIES, polarity 0, disconnected] [ 1195.307469] cc:=2 [ 1195.307544] pending state change SRC_SEND_CAPABILITIES -> SNK_UNATTACHED @ 650 ms [rev3 POWER_NEGOTIATION] [ 1195.307555] Discarding sourcing vbus! Invalid state SRC_SEND_CAPABILITIES [ 1195.957636] state change SRC_SEND_CAPABILITIES -> SNK_UNATTACHED [delayed 650 ms] [ 1195.957732] disable vbus discharge ret:0 [ 1195.970196] Start toggling [ 1195.970468] VBUS off [ 1196.051637] VBUS off [ 1196.051642] VBUS VSAFE0V
drivers/usb/typec/tcpm/tcpm.c +22 -6
@@ -7119,16 +7119,32 @@ static void tcpm_pd_event_handler(struct kthread_work *work) } }if (events &TCPM_SOURCING_VBUS ) { -tcpm_log (port,"sourcing vbus" );/* * In fast role swap case TCPC autonomously sources vbus. Set vbus_source -* true as TCPM wouldn't have called tcpm_set_vbus. +* true conditionally as TCPM wouldn't have called tcpm_set_vbus. +* If TCPM calls tcpm_set_vbus to source vbus, vbus_source would already +* be true. * -* When vbus is sourced on the command on TCPM i.e. TCPM called -* tcpm_set_vbus to source vbus, vbus_source would already be true. +* When TCPM_FRS_EVENT and TCPM_SOURCING_VBUS arrive simultaneously, +* handling TCPM_FRS_EVENT above transitions the state to AMS_START +* with upcoming_state FR_SWAP_SEND. */ - port->vbus_source = true; -_tcpm_pd_vbus_on (port); + +if (tcpm_port_is_source (port) || +tcpm_port_is_debug_source (port) || + (port->state ==AMS_START && port->upcoming_state ==FR_SWAP_SEND ) || + port->state ==FR_SWAP_SEND || + port->state ==FR_SWAP_SEND_TIMEOUT || + port->state ==FR_SWAP_SNK_SRC_TRANSITION_TO_OFF || + port->state ==FR_SWAP_SNK_SRC_NEW_SINK_READY || + port->state ==FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED ) { +tcpm_log (port,"sourcing vbus" ); + port->vbus_source = true; +_tcpm_pd_vbus_on (port); + }else { +tcpm_log (port,"Discarding sourcing vbus! Invalid state %s" , + tcpm_states[port->state]); + } }if (events &TCPM_PORT_CLEAN ) {tcpm_log (port,"port clean" );
Sasha Levin
maintainerPATCH 1/2 usb: typec: tcpm: fix debug accessory mode detection for sink ports
From: Xu Yang <[email protected]>
[ Upstream commit f6ec9bb4acc7182b25a793ad094a764e1cb819a7 ]
The port in debug accessory mode can be either a source or sink. The previous tcpm_port_is_debug() function only checked for source port.
Commit 8db73e6a42b6 ("usb: typec: tcpm: allow sink (ufp) to toggle into accessory mode debug") changed the detection logic to support both roles, but left some logic in _tcpm_cc_change() unchanged, This causes the state machine to transition to an incorrect state when operating as a sink in debug accessory mode. Log as below:
[ 978.637541] CC1: 0 -> 5, CC2: 0 -> 5 [state TOGGLING, polarity 0, connected] [ 978.637567] state change TOGGLING -> SRC_ATTACH_WAIT [rev1 NONE_AMS] [ 978.637596] pending state change SRC_ATTACH_WAIT -> DEBUG_ACC_ATTACHED @ 180 ms [rev1 NONE_AMS] [ 978.647098] CC1: 5 -> 0, CC2: 5 -> 5 [state SRC_ATTACH_WAIT, polarity 0, connected] [ 978.647115] state change SRC_ATTACH_WAIT -> SRC_ATTACH_WAIT [rev1 NONE_AMS]
It should go to SNK_ATTACH_WAIT instead of SRC_ATTACH_WAIT state.
To fix this, add tcpm_port_is_debug_source() and tcpm_port_is_debug_sink() helper to explicitly identify the power mode in debug accessory mode. Update the state transition logic in _tcpm_cc_change() to ensure the state machine transitions comply with Type-C specification. Also update the logic in run_state_machine() to keep consistency.
[Backport to 6.12: This tree lacks 8db73e6a42b6 and the associated sink debug-accessory state-machine support. Retain only the source-debug macro extraction and source-side call-site updates. Keep tcpm_port_is_debug() source-only and omit the sink-debug macro and all sink/audio attachment transitions introduced by the upstream dependency. This preserves existing detection and state transitions while providing tcpm_port_is_debug_source() for cd3b9cea675b ("usb: typec: tcpm: constrain TCPM_SOURCING_VBUS event handling"). No functions are added.]
Stable-dep-of: cd3b9cea675b ("usb: typec: tcpm: constrain TCPM_SOURCING_VBUS event handling")
--- drivers/usb/typec/tcpm/tcpm.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/usb/typec/tcpm/tcpm.c +7 -4
@@ -514,9 +514,12 @@ static const char * const pd_rev[] = { (tcpm_cc_is_source((port)->cc2) && \ !tcpm_cc_is_source((port)->cc1))) -#define tcpm_port_is_debug (port) \ +#define tcpm_port_is_debug_source (port) \ (tcpm_cc_is_source((port)->cc1) && tcpm_cc_is_source((port)->cc2)) +#define tcpm_port_is_debug (port) \ + tcpm_port_is_debug_source(port) +#define tcpm_port_is_audio (port) \ (tcpm_cc_is_audio((port)->cc1) && tcpm_cc_is_audio((port)->cc2))
@@ -3951,7 +3954,7 @@ static void run_state_machine(struct tcpm_port *port)tcpm_set_state (port,SNK_UNATTACHED ,PD_T_DRP_SNK );break ;case SRC_ATTACH_WAIT : -if (tcpm_port_is_debug (port)) +if (tcpm_port_is_debug_source (port))tcpm_set_state (port,DEBUG_ACC_ATTACHED ,PD_T_CC_DEBOUNCE );else if (tcpm_port_is_audio (port))
@@ -4954,7 +4957,7 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1,switch (port->state) {case TOGGLING : -if (tcpm_port_is_debug (port) ||tcpm_port_is_audio (port) || +if (tcpm_port_is_debug_source (port) ||tcpm_port_is_audio (port) ||tcpm_port_is_source (port))tcpm_set_state (port,SRC_ATTACH_WAIT ,0 );else if (tcpm_port_is_sink (port))
@@ -4962,7 +4965,7 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1,break ;case SRC_UNATTACHED :case ACC_UNATTACHED : -if (tcpm_port_is_debug (port) ||tcpm_port_is_audio (port) || +if (tcpm_port_is_debug_source (port) ||tcpm_port_is_audio (port) ||tcpm_port_is_source (port))tcpm_set_state (port,SRC_ATTACH_WAIT ,0 );break ;
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 usb: typec: tcpm: constrain TCPM_SOURCING_VBUS event handling
From: Amit Sunil Dhamne <[email protected]>
[ Upstream commit cd3b9cea675bbfebc223f007dc2f4e79524fa54c ]
When a sink detach occurs while waiting for TX send status, the old TCPM_SOURCING_VBUS event along with TCPM_VBUS_EVENT and TCPM_CC_EVENT can be queued in port->pd_events. Because TCPM_SOURCING_VBUS is evaluated after TCPM_VBUS_EVENT and TCPM_CC_EVENT in tcpm_pd_event_handler(), a stale TCPM_SOURCING_VBUS event can override the detach handling and incorrectly set port->vbus_source and port->vbus_present to true.
Add a state guard to check that the port is either operating as a Source (tcpm_port_is_source(port)) or in a Fast Role Swap (FRS) state up to FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED before processing TCPM_SOURCING_VBUS. Otherwise, discard and log the event.
Log snippet for error condition before fix:
[72792.204955] state change SRC_ATTACHED -> SRC_STARTUP [rev3 NONE_AMS] [72792.204960] sourcing vbus [72792.204962] VBUS on [72792.204970] AMS POWER_NEGOTIATION start [72792.204974] cc:=4 [72792.205319] state change SRC_STARTUP -> AMS_START [rev3 POWER_NEGOTIATION] [72792.205325] state change AMS_START -> SRC_SEND_CAPABILITIES [rev3 POWER_NEGOTIATION] [72792.205332] PD TX, header: 0x11a1 [72792.216911] PD TX complete, status: 2 [72792.216957] pending state change SRC_SEND_CAPABILITIES -> SRC_SEND_CAPABILITIES @ 150 ms [rev3 POWER_NEGOTIATION] [72792.218005] VBUS off [72792.218013] pending state change SRC_SEND_CAPABILITIES -> SNK_UNATTACHED @ 650 ms [rev3 POWER_NEGOTIATION] [72792.218020] VBUS VSAFE0V [72792.218024] state change SRC_SEND_CAPABILITIES -> SNK_UNATTACHED [rev3 POWER_NEGOTIATION] [72792.218458] CC1: 2 -> 0, CC2: 0 -> 0 [state SNK_UNATTACHED, polarity 0, disconnected] [72792.218467] VBUS on --> VBUS left on [72792.218980] disable vbus discharge ret:0 [72792.235193] Start toggling
After fix:
[ 1195.291691] state change SRC_ATTACHED -> SRC_STARTUP [rev3 NONE_AMS] [ 1195.291698] sourcing vbus [ 1195.291700] VBUS on [ 1195.291707] AMS POWER_NEGOTIATION start [ 1195.291710] cc:=4 [ 1195.291758] state change SRC_STARTUP -> AMS_START [rev3 POWER_NEGOTIATION] [ 1195.291794] state change AMS_START -> SRC_SEND_CAPABILITIES [rev3 POWER_NEGOTIATION] [ 1195.291798] PD TX, header: 0x11a1 [ 1195.297056] PD TX complete, status: 2 [ 1195.297092] pending state change SRC_SEND_CAPABILITIES -> SRC_SEND_CAPABILITIES @ 150 ms [rev3 POWER_NEGOTIATION] [ 1195.297177] VBUS off [ 1195.297184] pending state change SRC_SEND_CAPABILITIES -> SNK_UNATTACHED @ 650 ms [rev3 POWER_NEGOTIATION] [ 1195.297227] CC1: 2 -> 0, CC2: 0 -> 0 [state SRC_SEND_CAPABILITIES, polarity 0, disconnected] [ 1195.307469] cc:=2 [ 1195.307544] pending state change SRC_SEND_CAPABILITIES -> SNK_UNATTACHED @ 650 ms [rev3 POWER_NEGOTIATION] [ 1195.307555] Discarding sourcing vbus! Invalid state SRC_SEND_CAPABILITIES [ 1195.957636] state change SRC_SEND_CAPABILITIES -> SNK_UNATTACHED [delayed 650 ms] [ 1195.957732] disable vbus discharge ret:0 [ 1195.970196] Start toggling [ 1195.970468] VBUS off [ 1196.051637] VBUS off [ 1196.051642] VBUS VSAFE0V
--- drivers/usb/typec/tcpm/tcpm.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-)
drivers/usb/typec/tcpm/tcpm.c +22 -6
@@ -5468,16 +5468,32 @@ static void tcpm_pd_event_handler(struct kthread_work *work) } }if (events &TCPM_SOURCING_VBUS ) { -tcpm_log (port,"sourcing vbus" );/* * In fast role swap case TCPC autonomously sources vbus. Set vbus_source -* true as TCPM wouldn't have called tcpm_set_vbus. +* true conditionally as TCPM wouldn't have called tcpm_set_vbus. +* If TCPM calls tcpm_set_vbus to source vbus, vbus_source would already +* be true. * -* When vbus is sourced on the command on TCPM i.e. TCPM called -* tcpm_set_vbus to source vbus, vbus_source would already be true. +* When TCPM_FRS_EVENT and TCPM_SOURCING_VBUS arrive simultaneously, +* handling TCPM_FRS_EVENT above transitions the state to AMS_START +* with upcoming_state FR_SWAP_SEND. */ - port->vbus_source = true; -_tcpm_pd_vbus_on (port); + +if (tcpm_port_is_source (port) || +tcpm_port_is_debug_source (port) || + (port->state ==AMS_START && port->upcoming_state ==FR_SWAP_SEND ) || + port->state ==FR_SWAP_SEND || + port->state ==FR_SWAP_SEND_TIMEOUT || + port->state ==FR_SWAP_SNK_SRC_TRANSITION_TO_OFF || + port->state ==FR_SWAP_SNK_SRC_NEW_SINK_READY || + port->state ==FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED ) { +tcpm_log (port,"sourcing vbus" ); + port->vbus_source = true; +_tcpm_pd_vbus_on (port); + }else { +tcpm_log (port,"Discarding sourcing vbus! Invalid state %s" , + tcpm_states[port->state]); + } }spin_lock (&port->pd_event_lock);
Signature · 1 line
2.53.0