From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
To: Sebastian Reichel <sebastian.reichel@collabora.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Guenter Roeck <linux@roeck-us.net>,
Yueyao Zhu <yueyao@google.com>,
linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
kernel@collabora.com, stable@vger.kernel.org
Subject: Re: [PATCH] usb: typec: fusb302: cache PD RX state
Date: Mon, 21 Jul 2025 12:44:50 +0300 [thread overview]
Message-ID: <aH4MEsYX43afRO79@kuha.fi.intel.com> (raw)
In-Reply-To: <20250704-fusb302-race-condition-fix-v1-1-239012c0e27a@kernel.org>
On Fri, Jul 04, 2025 at 07:55:06PM +0200, Sebastian Reichel wrote:
> 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: c034a43e72dda ("staging: typec: Fairchild FUSB302 Type-c chip driver")
> Cc: stable@vger.kernel.org
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> ---
> drivers/usb/typec/tcpm/fusb302.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c
> index f15c63d3a8f441569ec98302f5b241430d8e4547..870a71f953f6cd8dfc618caea56f72782e40ee1c 100644
> --- a/drivers/usb/typec/tcpm/fusb302.c
> +++ b/drivers/usb/typec/tcpm/fusb302.c
> @@ -104,6 +104,7 @@ struct fusb302_chip {
> bool vconn_on;
> bool vbus_on;
> bool charge_on;
> + bool pd_rx_on;
> bool vbus_present;
> enum typec_cc_polarity cc_polarity;
> enum typec_cc_status cc1;
> @@ -841,6 +842,11 @@ static int tcpm_set_pd_rx(struct tcpc_dev *dev, bool on)
> int ret = 0;
>
> mutex_lock(&chip->lock);
> + if (chip->pd_rx_on == on) {
> + fusb302_log(chip, "pd is already %s", str_on_off(on));
> + goto done;
> + }
> +
> ret = fusb302_pd_rx_flush(chip);
> if (ret < 0) {
> fusb302_log(chip, "cannot flush pd rx buffer, ret=%d", ret);
> @@ -863,6 +869,8 @@ static int tcpm_set_pd_rx(struct tcpc_dev *dev, bool on)
> str_on_off(on), ret);
> goto done;
> }
> +
> + chip->pd_rx_on = on;
> fusb302_log(chip, "pd := %s", str_on_off(on));
> done:
> mutex_unlock(&chip->lock);
>
> ---
> base-commit: c435a4f487e8c6a3b23dafbda87d971d4fd14e0b
> change-id: 20250704-fusb302-race-condition-fix-9cc9de73f05d
>
> Best regards,
> --
> Sebastian Reichel <sre@kernel.org>
--
heikki
prev parent reply other threads:[~2025-07-21 9:44 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-04 17:55 [PATCH] usb: typec: fusb302: cache PD RX state Sebastian Reichel
2025-07-17 18:05 ` [PATCH] usb: typec: fusb302: cache PD RX state (fix for 6.16) Sebastian Reichel
2025-07-21 9:44 ` Heikki Krogerus [this message]
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=aH4MEsYX43afRO79@kuha.fi.intel.com \
--to=heikki.krogerus@linux.intel.com \
--cc=gregkh@linuxfoundation.org \
--cc=kernel@collabora.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=linux@roeck-us.net \
--cc=sebastian.reichel@collabora.com \
--cc=stable@vger.kernel.org \
--cc=yueyao@google.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