public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Sebastian Reichel <sebastian.reichel@collabora.com>,
	Heikki Krogerus <heikki.krogerus@linux.intel.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Sasha Levin <sashal@kernel.org>,
	rdbabiera@google.com, linux@roeck-us.net, badhri@google.com,
	kyletso@google.com, xu.yang_2@nxp.com, linux-usb@vger.kernel.org
Subject: [PATCH AUTOSEL 6.10 07/23] usb: typec: tcpm: avoid resets for missing source capability messages
Date: Sun, 28 Jul 2024 12:04:48 -0400	[thread overview]
Message-ID: <20240728160538.2051879-7-sashal@kernel.org> (raw)
In-Reply-To: <20240728160538.2051879-1-sashal@kernel.org>

From: Sebastian Reichel <sebastian.reichel@collabora.com>

[ Upstream commit 122968f8dda8205c5735d7e1b1ccb041a54906d1 ]

When the Linux Type-C controller drivers probe, they requests a soft
reset, which should result in the source restarting to send Source
Capability messages again independently of the previous state.
Unfortunately some USB PD sources do not follow the specification and
do not send them after a soft reset when they already negotiated a
specific contract before. The current way (and what is described in the
specificiation) to resolve this problem is triggering a hard reset.

But a hard reset is fatal on batteryless platforms powered via USB-C PD,
since that removes VBUS for some time. Since this is triggered at boot
time, the system will be stuck in a boot loop. Examples for platforms
affected by this are the Radxa Rock 5B or the Libre Computer Renegade
Elite ROC-RK3399-PC.

Instead of directly trying a hard reset when no Source Capability
message is send by the USB-PD source automatically, this changes the
state machine to try explicitly asking for the capabilities by sending
a Get Source Capability control message.

For me this solves issues with 2 different USB-PD sources - a RAVPower
powerbank and a Lemorele USB-C dock. Every other PD source I own
follows the specification and automatically sends the Source Capability
message after a soft reset, which works with or without this change.

I decided against making this extra step limited to devices not having
the self_powered flag set, since I don't see any huge drawbacks in this
approach and it keeps the logic simpler. The worst case scenario would
be a power source, which is really stuck. In that case the hard reset
is delayed by another 310ms.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://lore.kernel.org/r/20240523171806.223727-1-sebastian.reichel@collabora.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/usb/typec/tcpm/tcpm.c | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
index 5d4da962acc87..5f7ea0fab47ab 100644
--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -57,6 +57,7 @@
 	S(SNK_DISCOVERY_DEBOUNCE),		\
 	S(SNK_DISCOVERY_DEBOUNCE_DONE),		\
 	S(SNK_WAIT_CAPABILITIES),		\
+	S(SNK_WAIT_CAPABILITIES_TIMEOUT),	\
 	S(SNK_NEGOTIATE_CAPABILITIES),		\
 	S(SNK_NEGOTIATE_PPS_CAPABILITIES),	\
 	S(SNK_TRANSITION_SINK),			\
@@ -3110,7 +3111,8 @@ static void tcpm_pd_data_request(struct tcpm_port *port,
 						   PD_MSG_CTRL_REJECT :
 						   PD_MSG_CTRL_NOT_SUPP,
 						   NONE_AMS);
-		} else if (port->state == SNK_WAIT_CAPABILITIES) {
+		} else if (port->state == SNK_WAIT_CAPABILITIES ||
+			   port->state == SNK_WAIT_CAPABILITIES_TIMEOUT) {
 		/*
 		 * This message may be received even if VBUS is not
 		 * present. This is quite unexpected; see USB PD
@@ -5041,10 +5043,31 @@ 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, hard_reset_state(port),
+			tcpm_set_state(port, SNK_WAIT_CAPABILITIES_TIMEOUT,
 				       PD_T_SINK_WAIT_CAP);
 		}
 		break;
+	case SNK_WAIT_CAPABILITIES_TIMEOUT:
+		/*
+		 * There are some USB PD sources in the field, which do not
+		 * properly implement the specification and fail to start
+		 * sending Source Capability messages after a soft reset. The
+		 * specification suggests to do a hard reset when no Source
+		 * capability message is received within PD_T_SINK_WAIT_CAP,
+		 * but that might effectively kil the machine's power source.
+		 *
+		 * This slightly diverges from the specification and tries to
+		 * recover from this by explicitly asking for the capabilities
+		 * using the Get_Source_Cap control message before falling back
+		 * to a hard reset. The control message should also be supported
+		 * and handled by all USB PD source and dual role devices
+		 * according to the specification.
+		 */
+		if (tcpm_pd_send_control(port, PD_CTRL_GET_SOURCE_CAP, TCPC_TX_SOP))
+			tcpm_set_state_cond(port, hard_reset_state(port), 0);
+		else
+			tcpm_set_state(port, hard_reset_state(port), PD_T_SINK_WAIT_CAP);
+		break;
 	case SNK_NEGOTIATE_CAPABILITIES:
 		port->pd_capable = true;
 		tcpm_set_partner_usb_comm_capable(port,
-- 
2.43.0


  parent reply	other threads:[~2024-07-28 16:05 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-07-28 16:04 [PATCH AUTOSEL 6.10 01/23] PCI: Add ACS quirk for Broadcom BCM5760X NIC Sasha Levin
2024-07-28 16:04 ` [PATCH AUTOSEL 6.10 02/23] ASoC: Intel: sof_sdw: Add quirks for some new Dell laptops Sasha Levin
2024-07-28 16:04 ` [PATCH AUTOSEL 6.10 03/23] PCI: Use preserve_config in place of pci_flags Sasha Levin
2024-07-28 16:04 ` [PATCH AUTOSEL 6.10 04/23] usb: cdns3: Add quirk flag to enable suspend residency Sasha Levin
2024-07-28 16:04 ` [PATCH AUTOSEL 6.10 05/23] usb: cdns3-ti: Add workaround for Errata i2409 Sasha Levin
2024-07-28 16:04 ` [PATCH AUTOSEL 6.10 06/23] usb: dwc2: gadget: Don't write invalid mapped sg entries into dma_desc with iommu enabled Sasha Levin
2024-07-28 16:04 ` Sasha Levin [this message]
2024-07-28 16:04 ` [PATCH AUTOSEL 6.10 08/23] usb: typec: ucsi: Fix null pointer dereference in trace Sasha Levin
2024-07-28 16:04 ` [PATCH AUTOSEL 6.10 09/23] MIPS: Loongson64: DTS: Fix msi node for ls7a Sasha Levin
2024-07-28 16:04 ` [PATCH AUTOSEL 6.10 10/23] MIPS: Loongson64: DTS: Fix PCIe port nodes " Sasha Levin
2024-07-28 16:04 ` [PATCH AUTOSEL 6.10 11/23] PCI: Add INTEL_HDA_PTL to pci_ids.h Sasha Levin
2024-07-28 16:04 ` [PATCH AUTOSEL 6.10 12/23] PCI/AER: Disable AER service on suspend Sasha Levin
2024-07-28 16:04 ` [PATCH AUTOSEL 6.10 13/23] PCI/DPC: Disable DPC " Sasha Levin
2024-07-28 16:04 ` [PATCH AUTOSEL 6.10 14/23] ASoC: Intel: sof_sdw: fix jack detection on ADL-N variant RVP Sasha Levin
2024-07-28 16:04 ` [PATCH AUTOSEL 6.10 15/23] ASoC: Intel: sof_sdw: add quirk for Dell SKU 0B8C Sasha Levin
2024-07-28 16:04 ` [PATCH AUTOSEL 6.10 16/23] usb: gadget: aspeed_udc: validate endpoint index for ast udc Sasha Levin
2024-07-28 16:04 ` [PATCH AUTOSEL 6.10 17/23] crypto: qat - initialize user_input.lock for rate_limiting Sasha Levin
2024-07-28 16:04 ` [PATCH AUTOSEL 6.10 18/23] PCI: keystone: Add workaround for Errata #i2037 (AM65x SR 1.0) Sasha Levin
2024-07-28 16:05 ` [PATCH AUTOSEL 6.10 19/23] scsi: ufs: core: Remove SCSI host only if added Sasha Levin
2024-07-28 16:05 ` [PATCH AUTOSEL 6.10 20/23] PCI: qcom: Override NO_SNOOP attribute for SA8775P RC Sasha Levin
2024-07-28 16:05 ` [PATCH AUTOSEL 6.10 21/23] PCI: vmd: Create domain symlink before pci_bus_add_devices() Sasha Levin
2024-07-28 16:05 ` [PATCH AUTOSEL 6.10 22/23] PCI: Add missing bridge lock to pci_bus_lock() Sasha Levin
2024-07-28 16:05 ` [PATCH AUTOSEL 6.10 23/23] ALSA: usb: Fix UBSAN warning in parse_audio_unit() Sasha Levin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240728160538.2051879-7-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=badhri@google.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=heikki.krogerus@linux.intel.com \
    --cc=kyletso@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=linux@roeck-us.net \
    --cc=rdbabiera@google.com \
    --cc=sebastian.reichel@collabora.com \
    --cc=stable@vger.kernel.org \
    --cc=xu.yang_2@nxp.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox