Linux USB
 help / color / mirror / Atom feed
From: Jacob Riff <jacob@riff.dk>
To: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Cc: linux-usb@vger.kernel.org,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Huang Wei <huangwei@kylinos.cn>, Jacob Riff <jacob@riff.dk>
Subject: [RFC PATCH] usb: typec: ucsi: retry init when the PPM answers early commands incorrectly
Date: Fri, 14 Aug 2026 17:57:24 -0700	[thread overview]
Message-ID: <20260815005724.8741-1-jacob@riff.dk> (raw)
In-Reply-To: <CAAw_mu=c96SYR2QGtoE=EoVRu+iGDo7x=vDjDYP4nc2yfkMnvw@mail.gmail.com>

On some platforms the PPM is not ready to answer commands correctly
for a short window during boot. On the Lenovo ThinkPad X1 Carbon
Gen 14 (21V7, tested on BIOS 1.12 and 1.14) roughly half of all boots
fail ucsi_init() with either -ENODEV (GET_CAPABILITY completes but
reports zero connectors) or -EINVAL (a standard command is rejected,
logged as "possible UCSI driver bug"). The failure is not a timeout:
increasing the sync command completion wait does not change the rate.

Since ucsi_init_work() only requeues on -EPROBE_DEFER, a single bad
answer during that window leaves UCSI dead for the whole session, so
Type-C events are never handled again; most visibly, the machine
silently never resumes charging after the charger is replugged.
Manually reloading ucsi_acpi a few seconds later has succeeded on
every attempt observed, which suggests simply retrying is enough.

Retry -ENODEV and -EINVAL the same way as the role switch wait, log
the retries at debug level, keep the loud report for the case where
the retries are exhausted, and note when init only succeeded after
retrying.

Tested on the affected machine: across 8 consecutive boots with this
patch, 5 hit the failure (matching the historical ~50-60% rate) and
all 5 recovered on the first retry ("PPM init succeeded after 2
attempts"). 0 of 8 boots ended with UCSI unusable, where ~5 of 8
would have without the patch.

Signed-off-by: Jacob Riff <jacob@riff.dk>
---
This is the failure previously reported in the thread
"ucsi_acpi: intermittent PPM init failed at boot is never retried"
and reproduces on the latest firmware for the machine. Happy to test
alternative approaches on this hardware.

--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -2211,18 +2211,36 @@
 	int ret;
 
 	ret = ucsi_init(ucsi);
-	if (ret)
-		dev_err_probe(ucsi->dev, ret, "PPM init failed\n");
+	if (!ret) {
+		if (ucsi->work_count)
+			dev_info(ucsi->dev,
+				 "PPM init succeeded after %u attempts\n",
+				 ucsi->work_count + 1);
+		return;
+	}
 
-	if (ret == -EPROBE_DEFER) {
-		if (ucsi->work_count++ > UCSI_ROLE_SWITCH_WAIT_COUNT) {
-			dev_err(ucsi->dev, "PPM init failed, stop trying\n");
+	/*
+	 * On some platforms the PPM is not ready to answer commands
+	 * correctly for a short window during boot: standard commands are
+	 * rejected or GET_CAPABILITY reports zero connectors, seen as
+	 * -EINVAL or -ENODEV from ucsi_init(), and a retry moments later
+	 * succeeds (observed on Lenovo ThinkPad X1 Carbon Gen 14, where
+	 * this affects roughly half of all boots). Retry those like the
+	 * USB role switch wait instead of giving up on the first attempt.
+	 */
+	if (ret == -EPROBE_DEFER || ret == -ENODEV || ret == -EINVAL) {
+		if (ucsi->work_count++ < UCSI_ROLE_SWITCH_WAIT_COUNT) {
+			dev_dbg(ucsi->dev, "PPM init failed (%pe), retrying\n",
+				ERR_PTR(ret));
+			queue_delayed_work(system_dfl_long_wq, &ucsi->work,
+					   UCSI_ROLE_SWITCH_INTERVAL);
 			return;
 		}
-
-		queue_delayed_work(system_dfl_long_wq, &ucsi->work,
-				   UCSI_ROLE_SWITCH_INTERVAL);
+		dev_err(ucsi->dev, "PPM init failed, stop trying\n");
+		return;
 	}
+
+	dev_err_probe(ucsi->dev, ret, "PPM init failed\n");
 }
 
 /**

      reply	other threads:[~2026-08-15  0:57 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-25 21:31 ucsi_acpi: intermittent "PPM init failed" at boot is never retried, Type-C event handling stays dead for the session Jacob Riff
2026-08-05 12:11 ` Heikki Krogerus
2026-08-05 12:46   ` Heikki Krogerus
2026-08-06  2:18     ` Jacob Riff
2026-08-15  0:57       ` Jacob Riff [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=20260815005724.8741-1-jacob@riff.dk \
    --to=jacob@riff.dk \
    --cc=gregkh@linuxfoundation.org \
    --cc=heikki.krogerus@linux.intel.com \
    --cc=huangwei@kylinos.cn \
    --cc=linux-usb@vger.kernel.org \
    /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