linux/drivers/usb
Sebastian Reichel 31c6235301 usb: typec: fusb302: cache PD RX state
[ Upstream commit 1e61f6ab08 ]

This patch fixes a race condition communication error, which ends up in
PD hard resets when losing the race. Some systems, like the Radxa ROCK
5B are powered through USB-C without any backup power source and use a
FUSB302 chip to do the PD negotiation. This means it is quite important
to avoid hard resets, since that effectively kills the system's
power-supply.

I've found the following race condition while debugging unplanned power
loss during booting the board every now and then:

1. lots of TCPM/FUSB302/PD initialization stuff
2. TCPM ends up in SNK_WAIT_CAPABILITIES (tcpm_set_pd_rx is enabled here)
3. the remote PD source does not send anything, so TCPM does a SOFT RESET
4. TCPM ends up in SNK_WAIT_CAPABILITIES for the second time
   (tcpm_set_pd_rx is enabled again, even though it is still on)

At this point I've seen broken CRC good messages being send by the
FUSB302 with a logic analyzer sniffing the CC lines. Also it looks like
messages are being lost and things generally going haywire with one of
the two sides doing a hard reset once a broken CRC good message was send
to the bus.

I think the system is running into a race condition, that the FIFOs are
being cleared and/or the automatic good CRC message generation flag is
being updated while a message is already arriving.

Let's avoid this by caching the PD RX enabled state, as we have already
processed anything in the FIFOs and are in a good state. As a side
effect that this also optimizes I2C bus usage :)

As far as I can tell the problem theoretically also exists when TCPM
enters SNK_WAIT_CAPABILITIES the first time, but I believe this is less
critical for the following reason:

On devices like the ROCK 5B, which are powered through a TCPM backed
USB-C port, the bootloader must have done some prior PD communication
(initial communication must happen within 5 seconds after plugging the
USB-C plug). This means the first time the kernel TCPM state machine
reaches SNK_WAIT_CAPABILITIES, the remote side is not sending messages
actively. On other devices a hard reset simply adds some extra delay and
things should be good afterwards.

Fixes: c034a43e72 ("staging: typec: Fairchild FUSB302 Type-c chip driver")
Cc: stable <stable@kernel.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://lore.kernel.org/r/20250704-fusb302-race-condition-fix-v1-1-239012c0e27a@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
History 2025-08-28 16:31:03 +02:00
..
atm usb: atm: cxacru: Merge cxacru_upload_firmware() into cxacru_heavy_init() 2025-08-28 16:30:54 +02:00
c67x00 USB: c67x00: Remove unused declaration c67x00_hcd_msg_received() 2023-10-02 16:42:33 +02:00
cdns3 usb: cdnsp: Fix issue with CV Bad Descriptor test 2025-07-10 16:05:11 +02:00
chipidea usb: chipidea: udc: disconnect/reconnect from host when do suspend/resume 2025-07-10 16:05:11 +02:00
class cdc-acm: fix race between initial clearing halt and open 2025-08-20 18:30:52 +02:00
common usb: common: usb-conn-gpio: use a unique name for usb connector device 2025-07-06 11:01:35 +02:00
core usb: core: config: Prevent OOB read in SS endpoint companion parsing 2025-08-20 18:30:52 +02:00
dwc2 usb: dwc2: gadget: Fix enter to hibernation for UTMI+ PHY 2025-07-24 08:56:20 +02:00
dwc3 usb: dwc3: imx8mp: fix device leak at unbind 2025-08-28 16:30:54 +02:00
early usb: early: xhci-dbc: Fix early_ioremap leak 2025-08-15 12:13:36 +02:00
fotg210 move asm/unaligned.h to linux/unaligned.h 2024-10-02 17:23:23 -04:00
gadget usb: gadget: udc: renesas_usb3: fix device leak at unbind 2025-08-28 16:30:54 +02:00
host usb: xhci: Avoid showing errors during surprise removal 2025-08-20 18:30:22 +02:00
image scsi: core: Add a dma_alignment field to the host and host template 2024-04-11 21:37:48 -04:00
isp1760 move asm/unaligned.h to linux/unaligned.h 2024-10-02 17:23:23 -04:00
misc usb: misc: apple-mfi-fastcharge: Make power supply names unique 2025-08-15 12:13:34 +02:00
mon [tree-wide] finally take no_llseek out 2024-09-27 08:18:43 -07:00
mtu3 tracing/treewide: Remove second parameter of __assign_str() 2024-05-22 20:14:47 -04:00
musb usb: musb: omap2430: fix device leak at unbind 2025-08-28 16:30:54 +02:00
phy usb: phy: generic: Use proper helper for property detection 2025-03-22 12:54:16 -07:00
renesas_usbhs usb: renesas_usbhs: Reorder clock handling and power management in probe 2025-06-19 15:32:11 +02:00
roles usb: roles: set switch registered flag early on 2025-02-21 14:01:30 +01:00
serial USB: serial: option: add Foxconn T99W709 2025-08-15 12:14:12 +02:00
storage usb: storage: Ignore UAS driver for SanDisk 3.2 Gen2 storage device 2025-06-10 07:12:59 -04:00
typec usb: typec: fusb302: cache PD RX state 2025-08-28 16:31:03 +02:00
usbip Merge 6.11-rc3 into usb-next 2024-08-12 18:49:00 +02:00
Kconfig usb: pci-quirks: handle HAS_IOPORT dependency for AMD quirk 2023-10-02 16:19:12 +02:00
Makefile USB: xen-hcd: Traverse host/ when CONFIG_USB_XEN_HCD is selected 2024-06-04 15:33:38 +02:00
usb-skeleton.c usb: add usb_set_intfdata() documentation 2022-11-29 08:56:09 +01:00