On Wed, Oct 23, 2024 at 07:22:30PM -0700, Amit Sunil Dhamne wrote: > PD3.1 spec ("8.3.3.3.3 PE_SNK_Wait_for_Capabilities State") mandates > that the policy engine perform a hard reset when SinkWaitCapTimer > expires. Instead the code explicitly does a GET_SOURCE_CAP when the > timer expires as part of SNK_WAIT_CAPABILITIES_TIMEOUT. Due to this the > following compliance test failures are reported by the compliance tester > (added excerpts from the PD Test Spec): > > * COMMON.PROC.PD.2#1: > The Tester receives a Get_Source_Cap Message from the UUT. This > message is valid except the following conditions: [COMMON.PROC.PD.2#1] > a. The check fails if the UUT sends this message before the Tester > has established an Explicit Contract > ... > > * TEST.PD.PROT.SNK.4: > ... > 4. The check fails if the UUT does not send a Hard Reset between > tTypeCSinkWaitCap min and max. [TEST.PD.PROT.SNK.4#1] The delay is > between the VBUS present vSafe5V min and the time of the first bit > of Preamble of the Hard Reset sent by the UUT. > > For the purpose of interoperability, restrict the quirk introduced in > https://lore.kernel.org/all/20240523171806.223727-1-sebastian.reichel@xxxxxxxxxxxxx/ > to only non self-powered devices as battery powered devices will not > have the issue mentioned in that commit. > > Cc: stable@xxxxxxxxxxxxxxx > Fixes: 122968f8dda8 ("usb: typec: tcpm: avoid resets for missing source capability messages") > Reported-by: Badhri Jagan Sridharan <badhri@xxxxxxxxxx> > Closes: https://lore.kernel.org/all/CAPTae5LAwsVugb0dxuKLHFqncjeZeJ785nkY4Jfd+M-tCjHSnQ@xxxxxxxxxxxxxx/ > Signed-off-by: Amit Sunil Dhamne <amitsd@xxxxxxxxxx> > Reviewed-by: Badhri Jagan Sridharan <badhri@xxxxxxxxxx> Tested-by: Xu Yang <xu.yang_2@xxxxxxx> Thanks, Xu Yang > --- > drivers/usb/typec/tcpm/tcpm.c | 10 +++++++--- > 1 file changed, 7 insertions(+), 3 deletions(-) > > diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c > index d6f2412381cf..c8f467d24fbb 100644 > --- a/drivers/usb/typec/tcpm/tcpm.c > +++ b/drivers/usb/typec/tcpm/tcpm.c > @@ -4515,7 +4515,8 @@ static inline enum tcpm_state hard_reset_state(struct tcpm_port *port) > return ERROR_RECOVERY; > if (port->pwr_role == TYPEC_SOURCE) > return SRC_UNATTACHED; > - if (port->state == SNK_WAIT_CAPABILITIES_TIMEOUT) > + if (port->state == SNK_WAIT_CAPABILITIES || > + port->state == SNK_WAIT_CAPABILITIES_TIMEOUT) > return SNK_READY; > return SNK_UNATTACHED; > } > @@ -5043,8 +5044,11 @@ static void run_state_machine(struct tcpm_port *port) > tcpm_set_state(port, SNK_SOFT_RESET, > PD_T_SINK_WAIT_CAP); > } else { > - tcpm_set_state(port, SNK_WAIT_CAPABILITIES_TIMEOUT, > - PD_T_SINK_WAIT_CAP); > + if (!port->self_powered) > + upcoming_state = SNK_WAIT_CAPABILITIES_TIMEOUT; > + else > + upcoming_state = hard_reset_state(port); > + tcpm_set_state(port, upcoming_state, PD_T_SINK_WAIT_CAP); > } > break; > case SNK_WAIT_CAPABILITIES_TIMEOUT: > > base-commit: c6d9e43954bfa7415a1e9efdb2806ec1d8a8afc8 > -- > 2.47.0.105.g07ac214952-goog >