Linux USB
 help / color / mirror / Atom feed
* [RFC PATCH] usb: typec: ucsi: retry init when the PPM answers early commands incorrectly
  2026-08-06  2:18 ucsi_acpi: intermittent "PPM init failed" at boot is never retried, Type-C event handling stays dead for the session Jacob Riff
@ 2026-08-15  0:57 ` Jacob Riff
  2026-08-24 10:45   ` Heikki Krogerus
  0 siblings, 1 reply; 4+ messages in thread
From: Jacob Riff @ 2026-08-15  0:57 UTC (permalink / raw)
  To: Heikki Krogerus; +Cc: linux-usb, Greg Kroah-Hartman, Huang Wei, Jacob Riff

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");
 }
 
 /**

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC PATCH] usb: typec: ucsi: retry init when the PPM answers early commands incorrectly
       [not found] <202608171119200877083@kylinos.cn>
@ 2026-08-17  4:37 ` Jacob Riff
  2026-08-17  9:01   ` huangwei
  0 siblings, 1 reply; 4+ messages in thread
From: Jacob Riff @ 2026-08-17  4:37 UTC (permalink / raw)
  To: huangwei, Heikki Krogerus; +Cc: linux-usb, Greg Kroah-Hartman

On Mon, 17 Aug 2026 11:19:24 +0800, huangwei wrote:
> There the commands do complete, but the EC takes longer than the 5s
> hardcoded wait in ucsi_sync_control_common(). The fix for that case is
> already reviewed [1] (thanks Heikki, Fedor), so both failure modes of
> the "PPM not ready during boot" window would be covered:
>
>   - slow answers  -> longer completion timeout [1]
>   - wrong answers -> init retry (this RFC)

Hi Huang Wei,

Thanks for taking a look, and good to see the two failure modes of
the boot window end up with complementary fixes.

> One small question on the -EINVAL retry: ucsi_read_error() also
> returns -EINVAL for UCSI_ERROR_INVALID_CON_NUM / UNREGONIZED_CMD /
> INVALID_CMD_ARGUMENT, which are logged as "possible UCSI driver bug".
> Retrying those is harmless in practice (debug-level logging, bounded
> attempts), but it delays the report of a genuine driver bug from the
> first occurrence to the 100th. Did you consider distinguishing the
> PPM-not-ready case from the real error case, or is the simplicity of
> retrying both worth that trade-off?

I considered it, but by error code the two cases are identical. On
this machine the not-ready PPM answers a valid standard init command
with UNREGONIZED_CMD / INVALID_CMD_ARGUMENT - exactly the codes
ucsi_read_error() maps to "possible UCSI driver bug". So the only
discriminators left are context and persistence, which is what the
patch relies on: the retry exists only in the ucsi_init_work() path
(a runtime -EINVAL is unaffected), the not-ready window has cleared
after a single retry in every boot observed here, and a genuine bug
fails deterministically, exhausts the bounded attempts (100 x 100ms
= 10s with the role switch constants) and still ends in the loud
"PPM init failed, stop trying".

On delaying the report: the "possible UCSI driver bug" message is
dev_err in ucsi_read_error() and this patch does not touch it, so it
still fires on the first occurrence. With the retries a deterministic
bug would print it on every attempt before the final error, so the
cost is a 10 second delay of the final verdict rather than a hidden
report. That seemed a fair price for reusing the existing role switch
retry machinery unchanged.

Best regards,
Jacob

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Re: [RFC PATCH] usb: typec: ucsi: retry init when the PPM answers early commands incorrectly
  2026-08-17  4:37 ` [RFC PATCH] usb: typec: ucsi: retry init when the PPM answers early commands incorrectly Jacob Riff
@ 2026-08-17  9:01   ` huangwei
  0 siblings, 0 replies; 4+ messages in thread
From: huangwei @ 2026-08-17  9:01 UTC (permalink / raw)
  To: Jacob Riff, Heikki Krogerus
  Cc: 黄伟, linux-usb, Greg Kroah-Hartman

Hi Jacob,

Thanks - that resolves my concern. I had missed that the "possible
UCSI driver bug" dev_err in ucsi_read_error() is untouched by your
patch, so first-occurrence visibility is preserved and the bounded
retry only delays the final verdict by ~10s. Restricting the retry
to the ucsi_init_work() path is a reasonable discriminator, given
the error codes really are identical between the two cases.

No further comments from my side. Good luck with the RFC.

Best regards,
Huang Wei




于 2026-08-17 12:37, Jacob Riff 写道: 



On Mon, 17 Aug 2026 11:19:24 +0800, huangwei wrote:



> There the commands do complete, but the EC takes longer than the 5s



> hardcoded wait in ucsi_sync_control_common(). The fix for that case is



> already reviewed [1] (thanks Heikki, Fedor), so both failure modes of



> the "PPM not ready during boot" window would be covered:



>



>   - slow answers  -> longer completion timeout [1]



>   - wrong answers -> init retry (this RFC)



 



Hi Huang Wei,



 



Thanks for taking a look, and good to see the two failure modes of



the boot window end up with complementary fixes.



 



> One small question on the -EINVAL retry: ucsi_read_error() also



> returns -EINVAL for UCSI_ERROR_INVALID_CON_NUM / UNREGONIZED_CMD /



> INVALID_CMD_ARGUMENT, which are logged as "possible UCSI driver bug".



> Retrying those is harmless in practice (debug-level logging, bounded



> attempts), but it delays the report of a genuine driver bug from the



> first occurrence to the 100th. Did you consider distinguishing the



> PPM-not-ready case from the real error case, or is the simplicity of



> retrying both worth that trade-off?



 



I considered it, but by error code the two cases are identical. On



this machine the not-ready PPM answers a valid standard init command



with UNREGONIZED_CMD / INVALID_CMD_ARGUMENT - exactly the codes



ucsi_read_error() maps to "possible UCSI driver bug". So the only



discriminators left are context and persistence, which is what the



patch relies on: the retry exists only in the ucsi_init_work() path



(a runtime -EINVAL is unaffected), the not-ready window has cleared



after a single retry in every boot observed here, and a genuine bug



fails deterministically, exhausts the bounded attempts (100 x 100ms



= 10s with the role switch constants) and still ends in the loud



"PPM init failed, stop trying".



 



On delaying the report: the "possible UCSI driver bug" message is



dev_err in ucsi_read_error() and this patch does not touch it, so it



still fires on the first occurrence. With the retries a deterministic



bug would print it on every attempt before the final error, so the



cost is a 10 second delay of the final verdict rather than a hidden



report. That seemed a fair price for reusing the existing role switch



retry machinery unchanged.



 



Best regards,



Jacob







2026-08-17



公司:麒麟软件有限公司



姓名:黄伟 (Daway.Huang)



地址:上海市徐汇区番禺路1028号数娱大厦12楼



邮编:200030



电话:021-51098866-6033



手机:13814996575



Email:huangwei@kylinos.cn



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC PATCH] usb: typec: ucsi: retry init when the PPM answers early commands incorrectly
  2026-08-15  0:57 ` [RFC PATCH] usb: typec: ucsi: retry init when the PPM answers early commands incorrectly Jacob Riff
@ 2026-08-24 10:45   ` Heikki Krogerus
  0 siblings, 0 replies; 4+ messages in thread
From: Heikki Krogerus @ 2026-08-24 10:45 UTC (permalink / raw)
  To: Jacob Riff; +Cc: linux-usb, Greg Kroah-Hartman, Huang Wei

On Fri, Aug 14, 2026 at 05:57:24PM -0700, Jacob Riff wrote:
> 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.

Thanks for the patch. I don't have currently any better ideas so we
can go ahead with this.

Thanks,

> --- 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");
>  }
>  
>  /**

-- 
heikki

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-08-24 10:46 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <202608171119200877083@kylinos.cn>
2026-08-17  4:37 ` [RFC PATCH] usb: typec: ucsi: retry init when the PPM answers early commands incorrectly Jacob Riff
2026-08-17  9:01   ` huangwei
2026-08-06  2:18 ucsi_acpi: intermittent "PPM init failed" at boot is never retried, Type-C event handling stays dead for the session Jacob Riff
2026-08-15  0:57 ` [RFC PATCH] usb: typec: ucsi: retry init when the PPM answers early commands incorrectly Jacob Riff
2026-08-24 10:45   ` Heikki Krogerus

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox