* [PATCH AUTOSEL 6.1 10/19] usb: typec: ucsi: acpi: add quirk for ASUS Zenbook UM325
[not found] <20230507003417.4077259-1-sashal@kernel.org>
@ 2023-05-07 0:34 ` Sasha Levin
2023-05-07 0:34 ` [PATCH AUTOSEL 6.1 17/19] usb: typec: tcpm: fix multiple times discover svids error Sasha Levin
1 sibling, 0 replies; 2+ messages in thread
From: Sasha Levin @ 2023-05-07 0:34 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Samuel Čavoj, Heikki Krogerus, Greg Kroah-Hartman,
Sasha Levin, error27, hdegoede, linux-usb
From: Samuel Čavoj <samuel@cavoj.net>
[ Upstream commit 326e1c208f3f24d14b93f910b8ae32c94923d22c ]
On some ACPI platforms (namely the ASUS Zenbook UM325) the _DSM method must
not be called after a notification is received but instead the mailbox
should be read immediately from RAM. This is because the ACPI interrupt
handler destroys the CCI in ERAM after copying to system memory, and when
_DSM is later called to perform a second copy, it retrieves a garbage
value.
Instead, the _DSM(read) method should only be called when necessary, i.e.
for polling the state after reset and for retrieving the version. Other
reads should not call _DSM and only peek into the RAM region.
This adds a separate read operation for the Zenbook that syncs the
ACPI mailbox only with polled commands.
Link: https://lore.kernel.org/linux-usb/20210823180626.tb6m7h5tp6adhvt2@fastboi.localdomain/
Signed-off-by: Samuel Čavoj <samuel@cavoj.net>
[ heikki : handling everything in ucsi_acpi.c with DMI quirk ]
Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://lore.kernel.org/r/20230405134456.49607-1-heikki.krogerus@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/typec/ucsi/ucsi_acpi.c | 44 ++++++++++++++++++++++++++++--
1 file changed, 42 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/typec/ucsi/ucsi_acpi.c b/drivers/usb/typec/ucsi/ucsi_acpi.c
index 62206a6b8ea75..217355f1f9b94 100644
--- a/drivers/usb/typec/ucsi/ucsi_acpi.c
+++ b/drivers/usb/typec/ucsi/ucsi_acpi.c
@@ -9,6 +9,7 @@
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/acpi.h>
+#include <linux/dmi.h>
#include "ucsi.h"
@@ -23,6 +24,7 @@ struct ucsi_acpi {
struct completion complete;
unsigned long flags;
guid_t guid;
+ u64 cmd;
};
static int ucsi_acpi_dsm(struct ucsi_acpi *ua, int func)
@@ -62,6 +64,7 @@ static int ucsi_acpi_async_write(struct ucsi *ucsi, unsigned int offset,
struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
memcpy(ua->base + offset, val, val_len);
+ ua->cmd = *(u64 *)val;
return ucsi_acpi_dsm(ua, UCSI_DSM_FUNC_WRITE);
}
@@ -93,13 +96,46 @@ static const struct ucsi_operations ucsi_acpi_ops = {
.async_write = ucsi_acpi_async_write
};
+static int
+ucsi_zenbook_read(struct ucsi *ucsi, unsigned int offset, void *val, size_t val_len)
+{
+ struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
+ int ret;
+
+ if (offset == UCSI_VERSION || UCSI_COMMAND(ua->cmd) == UCSI_PPM_RESET) {
+ ret = ucsi_acpi_dsm(ua, UCSI_DSM_FUNC_READ);
+ if (ret)
+ return ret;
+ }
+
+ memcpy(val, ua->base + offset, val_len);
+
+ return 0;
+}
+
+static const struct ucsi_operations ucsi_zenbook_ops = {
+ .read = ucsi_zenbook_read,
+ .sync_write = ucsi_acpi_sync_write,
+ .async_write = ucsi_acpi_async_write
+};
+
+static const struct dmi_system_id zenbook_dmi_id[] = {
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UA_UM325UA"),
+ },
+ },
+ { }
+};
+
static void ucsi_acpi_notify(acpi_handle handle, u32 event, void *data)
{
struct ucsi_acpi *ua = data;
u32 cci;
int ret;
- ret = ucsi_acpi_read(ua->ucsi, UCSI_CCI, &cci, sizeof(cci));
+ ret = ua->ucsi->ops->read(ua->ucsi, UCSI_CCI, &cci, sizeof(cci));
if (ret)
return;
@@ -114,6 +150,7 @@ static void ucsi_acpi_notify(acpi_handle handle, u32 event, void *data)
static int ucsi_acpi_probe(struct platform_device *pdev)
{
struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
+ const struct ucsi_operations *ops = &ucsi_acpi_ops;
struct ucsi_acpi *ua;
struct resource *res;
acpi_status status;
@@ -143,7 +180,10 @@ static int ucsi_acpi_probe(struct platform_device *pdev)
init_completion(&ua->complete);
ua->dev = &pdev->dev;
- ua->ucsi = ucsi_create(&pdev->dev, &ucsi_acpi_ops);
+ if (dmi_check_system(zenbook_dmi_id))
+ ops = &ucsi_zenbook_ops;
+
+ ua->ucsi = ucsi_create(&pdev->dev, ops);
if (IS_ERR(ua->ucsi))
return PTR_ERR(ua->ucsi);
--
2.39.2
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH AUTOSEL 6.1 17/19] usb: typec: tcpm: fix multiple times discover svids error
[not found] <20230507003417.4077259-1-sashal@kernel.org>
2023-05-07 0:34 ` [PATCH AUTOSEL 6.1 10/19] usb: typec: ucsi: acpi: add quirk for ASUS Zenbook UM325 Sasha Levin
@ 2023-05-07 0:34 ` Sasha Levin
1 sibling, 0 replies; 2+ messages in thread
From: Sasha Levin @ 2023-05-07 0:34 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Frank Wang, Heikki Krogerus, Greg Kroah-Hartman, Sasha Levin,
linux, linux-usb
From: Frank Wang <frank.wang@rock-chips.com>
[ Upstream commit dac3b192107b978198e89ec0f77375738352e0c8 ]
PD3.0 Spec 6.4.4.3.2 say that only Responder supports 12 or more SVIDs,
the Discover SVIDs Command Shall be executed multiple times until a
Discover SVIDs VDO is returned ending either with a SVID value of
0x0000 in the last part of the last VDO or with a VDO containing two
SVIDs with values of 0x0000.
In the current implementation, if the last VDO does not find that the
Discover SVIDs Command would be executed multiple times even if the
Responder SVIDs are less than 12, and we found some odd dockers just
meet this case. So fix it.
Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Frank Wang <frank.wang@rock-chips.com>
Link: https://lore.kernel.org/r/20230316081149.24519-1-frank.wang@rock-chips.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/typec/tcpm/tcpm.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
index 032d21a967799..524099634a1d4 100644
--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -1514,7 +1514,21 @@ static bool svdm_consume_svids(struct tcpm_port *port, const u32 *p, int cnt)
pmdata->svids[pmdata->nsvids++] = svid;
tcpm_log(port, "SVID %d: 0x%x", pmdata->nsvids, svid);
}
- return true;
+
+ /*
+ * PD3.0 Spec 6.4.4.3.2: The SVIDs are returned 2 per VDO (see Table
+ * 6-43), and can be returned maximum 6 VDOs per response (see Figure
+ * 6-19). If the Respondersupports 12 or more SVID then the Discover
+ * SVIDs Command Shall be executed multiple times until a Discover
+ * SVIDs VDO is returned ending either with a SVID value of 0x0000 in
+ * the last part of the last VDO or with a VDO containing two SVIDs
+ * with values of 0x0000.
+ *
+ * However, some odd dockers support SVIDs less than 12 but without
+ * 0x0000 in the last VDO, so we need to break the Discover SVIDs
+ * request and return false here.
+ */
+ return cnt == 7;
abort:
tcpm_log(port, "SVID_DISCOVERY_MAX(%d) too low!", SVID_DISCOVERY_MAX);
return false;
--
2.39.2
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2023-05-07 1:13 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20230507003417.4077259-1-sashal@kernel.org>
2023-05-07 0:34 ` [PATCH AUTOSEL 6.1 10/19] usb: typec: ucsi: acpi: add quirk for ASUS Zenbook UM325 Sasha Levin
2023-05-07 0:34 ` [PATCH AUTOSEL 6.1 17/19] usb: typec: tcpm: fix multiple times discover svids error Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).