From: Sasha Levin <sashal@kernel.org>
To: stable@vger.kernel.org
Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
Heikki Krogerus <heikki.krogerus@linux.intel.com>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Sasha Levin <sashal@kernel.org>
Subject: [PATCH 6.1.y 2/3] usb: typec: ucsi: split read operation
Date: Fri, 4 Sep 2026 14:35:28 -0400 [thread overview]
Message-ID: <20260904183529.1325058-2-sashal@kernel.org> (raw)
In-Reply-To: <20260904183529.1325058-1-sashal@kernel.org>
From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
[ Upstream commit 467399d989d799433ec7dd8da2ebbfbc70207d03 ]
The read operation is only used to read fixed data at fixed offsets
(UCSI_VERSION, UCSI_CCI, UCSI_MESSAGE_IN). In some cases drivers apply
offset-specific overrides. Split the read() operation into three
operations, read_version(), read_cci(), read_message_in().
Tested-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Link: https://lore.kernel.org/r/20240627-ucsi-rework-interface-v4-3-289ddc6874c7@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The read split depends on newer UCSI callbacks that are not present in this
stable tree and is not needed by the dependent timeout fix. For the stable
backport, instead move the existing ACPI synchronous command handling into
the UCSI core while retaining the old callback interface. This places the
hard-coded completion timeout where the dependent fix expects it without
adding the unrelated read-operation wrappers.
[ sashal: Reduced backport -- upstream 467399d989d79 touches 7 file(s), this
backport carries 3. Not backported here:
drivers/usb/typec/ucsi/ucsi_ccg.c
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")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/typec/ucsi/ucsi.c | 29 +++++++++++++++++
drivers/usb/typec/ucsi/ucsi.h | 3 ++
drivers/usb/typec/ucsi/ucsi_acpi.c | 51 ++++++------------------------
3 files changed, 42 insertions(+), 41 deletions(-)
diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
index fa0609cb7f6e6..dd4ce8723b225 100644
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -36,6 +36,34 @@
*/
#define UCSI_SWAP_TIMEOUT_MS 5000
+int ucsi_sync_control_common(struct ucsi *ucsi, unsigned int offset,
+ const void *val, size_t val_len)
+{
+ bool ack = UCSI_COMMAND(*(u64 *)val) == 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, offset, val, val_len);
+ 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(struct ucsi *ucsi, bool conn_ack)
{
u64 ctrl;
@@ -1541,6 +1569,7 @@ struct ucsi *ucsi_create(struct device *dev, const struct ucsi_operations *ops)
INIT_WORK(&ucsi->resume_work, ucsi_resume_work);
INIT_DELAYED_WORK(&ucsi->work, ucsi_init_work);
mutex_init(&ucsi->ppm_lock);
+ init_completion(&ucsi->complete);
ucsi->dev = dev;
ucsi->ops = ops;
diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
index cee43f19adf5d..c78b29affeead 100644
--- a/drivers/usb/typec/ucsi/ucsi.h
+++ b/drivers/usb/typec/ucsi/ucsi.h
@@ -67,6 +67,8 @@ bool ucsi_con_mutex_lock(struct ucsi_connector *con);
void ucsi_con_mutex_unlock(struct ucsi_connector *con);
void ucsi_connector_change(struct ucsi *ucsi, u8 num);
+int ucsi_sync_control_common(struct ucsi *ucsi, unsigned int offset,
+ const void *val, size_t val_len);
/* -------------------------------------------------------------------------- */
@@ -308,6 +310,7 @@ struct ucsi {
#define EVENT_PENDING 0
#define COMMAND_PENDING 1
#define ACK_PENDING 2
+ struct completion complete;
};
#define UCSI_MAX_SVID 5
diff --git a/drivers/usb/typec/ucsi/ucsi_acpi.c b/drivers/usb/typec/ucsi/ucsi_acpi.c
index 03c820fe5b0c4..7ed5eb9801b75 100644
--- a/drivers/usb/typec/ucsi/ucsi_acpi.c
+++ b/drivers/usb/typec/ucsi/ucsi_acpi.c
@@ -21,11 +21,8 @@ struct ucsi_acpi {
struct device *dev;
struct ucsi *ucsi;
void *base;
- struct completion complete;
unsigned long flags;
#define UCSI_ACPI_SUPPRESS_EVENT 0
-#define UCSI_ACPI_COMMAND_PENDING 1
-#define UCSI_ACPI_ACK_PENDING 2
guid_t guid;
u64 cmd;
};
@@ -72,37 +69,9 @@ static int ucsi_acpi_async_write(struct ucsi *ucsi, unsigned int offset,
return ucsi_acpi_dsm(ua, UCSI_DSM_FUNC_WRITE);
}
-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(UCSI_ACPI_ACK_PENDING, &ua->flags);
- else
- set_bit(UCSI_ACPI_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, 5 * HZ))
- ret = -ETIMEDOUT;
-
-out_clear_bit:
- if (ack)
- clear_bit(UCSI_ACPI_ACK_PENDING, &ua->flags);
- else
- clear_bit(UCSI_ACPI_COMMAND_PENDING, &ua->flags);
-
- return ret;
-}
-
static const struct ucsi_operations ucsi_acpi_ops = {
.read = ucsi_acpi_read,
- .sync_write = ucsi_acpi_sync_write,
+ .sync_write = ucsi_sync_control_common,
.async_write = ucsi_acpi_async_write
};
@@ -125,7 +94,7 @@ ucsi_zenbook_read(struct ucsi *ucsi, unsigned int offset, void *val, size_t val_
static const struct ucsi_operations ucsi_zenbook_ops = {
.read = ucsi_zenbook_read,
- .sync_write = ucsi_acpi_sync_write,
+ .sync_write = ucsi_sync_control_common,
.async_write = ucsi_acpi_async_write
};
@@ -155,15 +124,15 @@ ucsi_dell_sync_write(struct ucsi *ucsi, unsigned int offset,
* still report the very event that the core is trying to clear.
*/
set_bit(UCSI_ACPI_SUPPRESS_EVENT, &ua->flags);
- ret = ucsi_acpi_sync_write(ucsi, UCSI_CONTROL, &dummycmd,
- sizeof(dummycmd));
+ ret = ucsi_sync_control_common(ucsi, UCSI_CONTROL, &dummycmd,
+ sizeof(dummycmd));
clear_bit(UCSI_ACPI_SUPPRESS_EVENT, &ua->flags);
if (ret < 0)
return ret;
}
- return ucsi_acpi_sync_write(ucsi, UCSI_CONTROL, &cmd, sizeof(cmd));
+ return ucsi_sync_control_common(ucsi, UCSI_CONTROL, &cmd, sizeof(cmd));
}
static const struct ucsi_operations ucsi_dell_ops = {
@@ -203,11 +172,12 @@ static void ucsi_acpi_notify(acpi_handle handle, u32 event, void *data)
!test_bit(UCSI_ACPI_SUPPRESS_EVENT, &ua->flags))
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_ACK_COMPLETE &&
+ test_bit(ACK_PENDING, &ua->ucsi->flags))
+ complete(&ua->ucsi->complete);
if (cci & UCSI_CCI_COMMAND_COMPLETE &&
- test_bit(UCSI_ACPI_COMMAND_PENDING, &ua->flags))
- complete(&ua->complete);
+ test_bit(COMMAND_PENDING, &ua->ucsi->flags))
+ complete(&ua->ucsi->complete);
}
static int ucsi_acpi_probe(struct platform_device *pdev)
@@ -241,7 +211,6 @@ static int ucsi_acpi_probe(struct platform_device *pdev)
if (ret)
return ret;
- init_completion(&ua->complete);
ua->dev = &pdev->dev;
id = dmi_first_match(ucsi_acpi_quirks);
--
2.53.0
next prev parent reply other threads:[~2026-09-04 18:35 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-03 12:40 FAILED: patch "[PATCH] usb: typec: ucsi: use UCSI_TIMEOUT_MS for sync command" failed to apply to 6.1-stable tree gregkh
2026-09-04 18:35 ` [PATCH 6.1.y 1/3] usb: typec: ucsi: move ucsi_acknowledge() from ucsi_read_error() Sasha Levin
2026-09-04 18:35 ` Sasha Levin [this message]
2026-09-04 18:35 ` [PATCH 6.1.y 3/3] usb: typec: ucsi: use UCSI_TIMEOUT_MS for sync command completion Sasha Levin
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=20260904183529.1325058-2-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=dmitry.baryshkov@linaro.org \
--cc=gregkh@linuxfoundation.org \
--cc=heikki.krogerus@linux.intel.com \
--cc=stable@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.