FAILED: patch "[PATCH] usb: typec: ucsi: use UCSI_TIMEOUT_MS for sync command" failed to apply to 5.15-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x eb4573cf2fd860b20adfae050c3f6ec6ddc3abdb
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026090308-uneasy-legible-48cb@gregkh' --subject-prefix 'PATCH 5.15.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From eb4573cf2fd860b20adfae050c3f6ec6ddc3abdb Mon Sep 17 00:00:00 2001
From: Huang Wei <[email protected]>
Date: Wed, 5 Aug 2026 16:57:25 +0800
Subject: [PATCH] usb: typec: ucsi: use UCSI_TIMEOUT_MS for sync command
completion
The synchronous command completion path in ucsi_sync_control_common() hardcodes a 5 second (5 * HZ) timeout when waiting for the PPM to signal command completion via ACPI notification. This value matched UCSI_TIMEOUT_MS when it was still 5000 ms, but it was not updated when that macro was later raised to 10000 ms to fix PPM reset timeouts.
As a result, the two PPM communication paths are now inconsistent: the polling path in ucsi_reset_ppm() respects the 10 second timeout, while the event-driven completion path still uses 5 seconds. On machines where the firmware is slow to respond during boot (e.g. some Lenovo ThinkPad models such as the E14 Gen 7), commands sent after the PPM reset, such as SET_NOTIFICATION_ENABLE and GET_CAPABILITY, can exceed 5 seconds and cause UCSI initialization to fail with:
ucsi_acpi USBC000:00: error -ETIMEDOUT: PPM init failed
Once UCSI init aborts, USB-C PD negotiation never completes, which in turn blocks USB-C dock enumeration since the dock depends on a successful PD contract.
Replace the hardcoded 5 * HZ with msecs_to_jiffies(UCSI_TIMEOUT_MS) so that both communication paths share a single, consistent timeout value, and future adjustments to UCSI_TIMEOUT_MS are picked up automatically.
drivers/usb/typec/ucsi/ucsi.c +2 -1
@@ -91,7 +91,8 @@ int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci,if (ret) goto out_clear_bit; -if (!wait_for_completion_timeout (&ucsi->complete,5 *HZ )) +if (!wait_for_completion_timeout (&ucsi->complete, +msecs_to_jiffies (UCSI_TIMEOUT_MS ))) ret = -ETIMEDOUT ; out_clear_bit:
Sasha Levin
maintainerPATCH 1/2 usb: typec: ucsi: extract common code for command handling
From: Dmitry Baryshkov <[email protected]>
[ Upstream commit 584e8df58942338602c70686b451b5c3093543a1 ]
Extract common functions to handle command sending and to handle events from UCSI. This ensures that all UCSI glue drivers handle the ACKs in the same way.
The CCG driver used DEV_CMD_PENDING both for internal firmware-related commands and for UCSI control handling. Leave the former use case intact.
[ sashal: Reduced backport -- upstream 584e8df589423 touches 7 file(s), this
backport carries 4. Not backported here:
drivers/usb/typec/ucsi/ucsi_glink.c drivers/usb/typec/ucsi/ucsi_stm32g0.c drivers/usb/typec/ucsi/ucsi_yoga_c630.c
This note is generated from the file lists only; see the resolution record for the reasoning. ]
Stable-dep-of: eb4573cf2fd8 ("usb: typec: ucsi: use UCSI_TIMEOUT_MS for sync command completion")
--- drivers/usb/typec/ucsi/ucsi.c | 44 ++++++++++++++++++++++++++++++ drivers/usb/typec/ucsi/ucsi.h | 5 ++++ drivers/usb/typec/ucsi/ucsi_acpi.c | 36 ++---------------------- drivers/usb/typec/ucsi/ucsi_ccg.c | 24 +++------------- 4 files changed, 55 insertions(+), 54 deletions(-)
drivers/usb/typec/ucsi/ucsi.c +44 -0
@@ -36,6 +36,49 @@*/ #define UCSI_SWAP_TIMEOUT_MS 5000 +void ucsi_notify_common (struct ucsi *ucsi,u32 cci) +{ +if (UCSI_CCI_CONNECTOR (cci)) +ucsi_connector_change (ucsi,UCSI_CCI_CONNECTOR (cci)); + +if (cci &UCSI_CCI_ACK_COMPLETE && +test_bit (ACK_PENDING , &ucsi->flags)) +complete (&ucsi->complete); + +if (cci &UCSI_CCI_COMMAND_COMPLETE && +test_bit (COMMAND_PENDING , &ucsi->flags)) +complete (&ucsi->complete); +} +EXPORT_SYMBOL_GPL (ucsi_notify_common); + +int ucsi_sync_control_common (struct ucsi *ucsi,u64 command) +{ +bool ack =UCSI_COMMAND (command) ==UCSI_ACK_CC_CI ; +int ret; + +if (ack) +set_bit (ACK_PENDING , &ucsi->flags); +else +set_bit (COMMAND_PENDING , &ucsi->flags); + + ret = ucsi->ops->async_write (ucsi,UCSI_CONTROL , &command, +sizeof (command)); +if (ret) + goto out_clear_bit; + +if (!wait_for_completion_timeout (&ucsi->complete,5 *HZ )) + ret = -ETIMEDOUT ; + +out_clear_bit: +if (ack) +clear_bit (ACK_PENDING , &ucsi->flags); +else +clear_bit (COMMAND_PENDING , &ucsi->flags); + +return ret; +} +EXPORT_SYMBOL_GPL (ucsi_sync_control_common); +static int ucsi_acknowledge_command (struct ucsi *ucsi) {u64 ctrl;
@@ -1413,6 +1456,7 @@ struct ucsi *ucsi_create(struct device *dev, const struct ucsi_operations *ops)INIT_WORK (&ucsi->work, ucsi_init_work);mutex_init (&ucsi->ppm_lock); +init_completion (&ucsi->complete); ucsi->dev = dev; ucsi->ops = ops;
drivers/usb/typec/ucsi/ucsi.h +5 -0
@@ -4,6 +4,7 @@#define __DRIVER_USB_TYPEC_UCSI_H#include <linux/bitops.h> +#include <linux/completion.h> #include <linux/device.h> #include <linux/power_supply.h> #include <linux/types.h>
@@ -303,6 +304,7 @@ struct ucsi {#define EVENT_PENDING 0#define COMMAND_PENDING 1#define ACK_PENDING 2 +struct completion complete;#define EVENT_PROCESSING 3 };
@@ -348,6 +350,9 @@ int ucsi_send_command(struct ucsi *ucsi, u64 command,void ucsi_altmode_update_active (struct ucsi_connector *con);int ucsi_resume (struct ucsi *ucsi); +void ucsi_notify_common (struct ucsi *ucsi,u32 cci); +int ucsi_sync_control_common (struct ucsi *ucsi,u64 command); +#if IS_ENABLED (CONFIG_POWER_SUPPLY )int ucsi_register_port_psy (struct ucsi_connector *con);void ucsi_unregister_port_psy (struct ucsi_connector *con);
drivers/usb/typec/ucsi/ucsi_acpi.c +2 -34
@@ -20,8 +20,6 @@ struct ucsi_acpi {struct device *dev;struct ucsi *ucsi;void __iomem *base; -struct completion complete; -unsigned long flags;guid_t guid; };
@@ -69,29 +67,7 @@ static int ucsi_acpi_async_write(struct ucsi *ucsi, unsigned int offset,static int ucsi_acpi_sync_write (struct ucsi *ucsi,unsigned int offset,const void *val,size_t val_len) { -struct ucsi_acpi *ua =ucsi_get_drvdata (ucsi); -bool ack =UCSI_COMMAND (*(u64 *)val) ==UCSI_ACK_CC_CI ; -int ret; - -if (ack) -set_bit (ACK_PENDING , &ua->flags); -else -set_bit (COMMAND_PENDING , &ua->flags); - - ret =ucsi_acpi_async_write (ucsi, offset, val, val_len); -if (ret) - goto out_clear_bit; - -if (!wait_for_completion_timeout (&ua->complete,60 *HZ )) - ret = -ETIMEDOUT ; - -out_clear_bit: -if (ack) -clear_bit (ACK_PENDING , &ua->flags); -else -clear_bit (COMMAND_PENDING , &ua->flags); - -return ret; +return ucsi_sync_control_common (ucsi, *(u64 *)val); }static const struct ucsi_operations ucsi_acpi_ops = {
@@ -110,14 +86,7 @@ static void ucsi_acpi_notify(acpi_handle handle, u32 event, void *data)if (ret)return ; -if (UCSI_CCI_CONNECTOR (cci)) -ucsi_connector_change (ua->ucsi,UCSI_CCI_CONNECTOR (cci)); - -if (cci &UCSI_CCI_ACK_COMPLETE &&test_bit (ACK_PENDING , &ua->flags)) -complete (&ua->complete); -if (cci &UCSI_CCI_COMMAND_COMPLETE && -test_bit (COMMAND_PENDING , &ua->flags)) -complete (&ua->complete); +ucsi_notify_common (ua->ucsi, cci); }static int ucsi_acpi_probe (struct platform_device *pdev)
@@ -160,7 +129,6 @@ static int ucsi_acpi_probe(struct platform_device *pdev)if (ret)return ret; -init_completion (&ua->complete); ua->dev = &pdev->dev; ua->ucsi =ucsi_create (&pdev->dev, &ucsi_acpi_ops);
drivers/usb/typec/ucsi/ucsi_ccg.c +4 -20
@@ -211,8 +211,6 @@ struct ucsi_ccg {u16 fw_build;struct work_struct pm_work; -struct completion complete; -u64 last_cmd_sent;bool has_multiple_dp;struct ucsi_ccg_altmode orig[UCSI_MAX_ALTMODES ];
@@ -564,7 +562,6 @@ static int ucsi_ccg_sync_write(struct ucsi *ucsi, unsigned int offset,mutex_lock (&uc->lock);pm_runtime_get_sync (uc->dev); -set_bit (DEV_CMD_PENDING , &uc->flags);if (offset ==UCSI_CONTROL && val_len ==sizeof (uc->last_cmd_sent)) { uc->last_cmd_sent = *(u64 *)val;
@@ -582,15 +579,7 @@ static int ucsi_ccg_sync_write(struct ucsi *ucsi, unsigned int offset, } } - ret =ucsi_ccg_async_write (ucsi, offset, val, val_len); -if (ret) - goto err_clear_bit; - -if (!wait_for_completion_timeout (&uc->complete,msecs_to_jiffies (5000 ))) - ret = -ETIMEDOUT ; - -err_clear_bit: -clear_bit (DEV_CMD_PENDING , &uc->flags); + ret =ucsi_sync_control_common (ucsi, *(u64 *)val); err_put:pm_runtime_put_sync (uc->dev);mutex_unlock (&uc->lock);
@@ -621,16 +610,12 @@ static irqreturn_t ccg_irq_handler(int irq, void *data)if (ret) goto err_clear_irq; -if (UCSI_CCI_CONNECTOR (cci)) -ucsi_connector_change (uc->ucsi,UCSI_CCI_CONNECTOR (cci)); - -if (test_bit (DEV_CMD_PENDING , &uc->flags) && - cci & (UCSI_CCI_ACK_COMPLETE |UCSI_CCI_COMMAND_COMPLETE )) -complete (&uc->complete); - err_clear_irq:ccg_write (uc,CCGX_RAB_INTR_REG , &intr_reg,sizeof (intr_reg)); +if (!ret) +ucsi_notify_common (uc->ucsi, cci); +return IRQ_HANDLED ; }
@@ -1344,7 +1329,6 @@ static int ucsi_ccg_probe(struct i2c_client *client, uc->dev = dev; uc->client = client;mutex_init (&uc->lock); -init_completion (&uc->complete);INIT_WORK (&uc->work, ccg_update_firmware);INIT_WORK (&uc->pm_work, ccg_pm_workaround_work);
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 usb: typec: ucsi: use UCSI_TIMEOUT_MS for sync command completion
From: Huang Wei <[email protected]>
[ Upstream commit eb4573cf2fd860b20adfae050c3f6ec6ddc3abdb ]
The synchronous command completion path in ucsi_sync_control_common() hardcodes a 5 second (5 * HZ) timeout when waiting for the PPM to signal command completion via ACPI notification. This value matched UCSI_TIMEOUT_MS when it was still 5000 ms, but it was not updated when that macro was later raised to 10000 ms to fix PPM reset timeouts.
As a result, the two PPM communication paths are now inconsistent: the polling path in ucsi_reset_ppm() respects the 10 second timeout, while the event-driven completion path still uses 5 seconds. On machines where the firmware is slow to respond during boot (e.g. some Lenovo ThinkPad models such as the E14 Gen 7), commands sent after the PPM reset, such as SET_NOTIFICATION_ENABLE and GET_CAPABILITY, can exceed 5 seconds and cause UCSI initialization to fail with:
ucsi_acpi USBC000:00: error -ETIMEDOUT: PPM init failed
Once UCSI init aborts, USB-C PD negotiation never completes, which in turn blocks USB-C dock enumeration since the dock depends on a successful PD contract.
Replace the hardcoded 5 * HZ with msecs_to_jiffies(UCSI_TIMEOUT_MS) so that both communication paths share a single, consistent timeout value, and future adjustments to UCSI_TIMEOUT_MS are picked up automatically.
--- drivers/usb/typec/ucsi/ucsi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/typec/ucsi/ucsi.c +2 -1
@@ -66,7 +66,8 @@ int ucsi_sync_control_common(struct ucsi *ucsi, u64 command)if (ret) goto out_clear_bit; -if (!wait_for_completion_timeout (&ucsi->complete,5 *HZ )) +if (!wait_for_completion_timeout (&ucsi->complete, +msecs_to_jiffies (UCSI_TIMEOUT_MS ))) ret = -ETIMEDOUT ; out_clear_bit:
Signature · 1 line
2.53.0