Re: [PATCH] usb: typec: ucsi: acpi: Disable on devices with broken firmware
From: Mark Pearson
Date: Tue May 12 2026 - 14:34:58 EST
Hi Rong
On Tue, May 12, 2026, at 8:46 AM, Rong Zhang wrote:
> Hi Mark,
>
> On Mon, 2026-05-11 at 19:11 -0400, Mark Pearson wrote:
>> On Mon, May 11, 2026, at 3:12 PM, Rong Zhang wrote:
>> > (+CC Mark Pearson from Lenovo)
>> >
>> > Hi Greg,
>> >
>> > On Mon, 2026-05-11 at 20:25 +0200, Greg Kroah-Hartman wrote:
>> > > On Tue, May 12, 2026 at 01:59:34AM +0800, Rong Zhang wrote:
>> > > > Some Lenovo devices have broken firmware, which reads/writes half-valid-
>> > > > half-garbage values.
>> > >
>> > > How does this work with this firmware on other operating systems?
>> > >
>> >
>> > The timeout can hardly reached unless a bunch of events cause multiple
>> > drivers to compete for the same mutex simultaneously.
>> >
>> > If other operating systems' UCSI drivers don't send any command during
>> > power events, they won't suffer from the mutex acquisition timeout.
>> > Also, if other drivers on these operating systems don't touch the mutex
>> > on power events at all, their UCSI drivers should work well too.
>> >
>> > These operating systems' UCSI drivers are powered by undefined behavior
>> > (TM) in both cases.
>> >
>> > > What
>> > > is the odds of fixing the firmware?
>> >
>> > They are not Linux-certified devices, so Lenovo is very unlikely to fix
>> > the firmware unless it breaks Windows :(
>> >
>> > Quoting Mark Pearson's reply to the bugzilla thread:
>> >
>> > I can't promise anything - I don't have any official levers to pull for
>> > this platform I'm afraid (it is better to buy Linux supported/certified
>> > systems ;) )
>> >
>> > https://bugzilla.kernel.org/show_bug.cgi?id=221065#c38
>> >
>> > >
>> > > > Given that everything is broken, disable ucsi_acpi on these devices. The
>> > > > impact of disabling it is minimal, as Lenovo laptops usually have most
>> > > > USCI commands more or less stubbed, and the EC can always handles USB-C
>> > > > events on its own.
>> > > >
>> > > > Link: https://bugzilla.kernel.org/show_bug.cgi?id=221065#c33
>> > > > Signed-off-by: Rong Zhang <i@xxxxxxxx>
>> > > > ---
>> > > > drivers/usb/typec/ucsi/ucsi_acpi.c | 91 ++++++++++++++++++++++++++++++++++++++
>> > > > 1 file changed, 91 insertions(+)
>> > > >
>> > > > diff --git a/drivers/usb/typec/ucsi/ucsi_acpi.c b/drivers/usb/typec/ucsi/ucsi_acpi.c
>> > > > index 6b92f296e985..7632b441d401 100644
>> > > > --- a/drivers/usb/typec/ucsi/ucsi_acpi.c
>> > > > +++ b/drivers/usb/typec/ucsi/ucsi_acpi.c
>> > > > @@ -155,6 +155,91 @@ static const struct dmi_system_id ucsi_acpi_quirks[] = {
>> > > > { }
>> > > > };
>> > > >
>> > > > +static const struct dmi_system_id ucsi_acpi_broken_devices[] = {
>> > > > + /* Firmware reads/writes half-valid-half-garbage values. */
>> > > > +
>> > > > + /* BIOS: P1CN??WW */
>> > > > + {
>> > > > + .ident = "Lenovo IdeaPad 5 2-in-1 14AHP9",
>> > > > + .matches = {
>> > > > + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
>> > > > + DMI_MATCH(DMI_PRODUCT_NAME, "83DR"),
>> > > > + },
>> > > > + },
>> > > > + {
>> > > > + .ident = "Lenovo IdeaPad 5 2-in-1 16AHP9",
>> > > > + .matches = {
>> > > > + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
>> > > > + DMI_MATCH(DMI_PRODUCT_NAME, "83DS"),
>> > > > + },
>> > > > + },
>> > > > +
>> > > > + /* BIOS: R0CN??WW */
>> > > > + {
>> > > > + .ident = "Lenovo IdeaPad Slim 5 14AKP10",
>> > > > + .matches = {
>> > > > + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
>> > > > + DMI_MATCH(DMI_PRODUCT_NAME, "83NJ"),
>> > > > + },
>> > > > + },
>> > > > + {
>> > > > + .ident = "Lenovo IdeaPad Slim 5 14AKP10",
>> > > > + .matches = {
>> > > > + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
>> > > > + DMI_MATCH(DMI_PRODUCT_NAME, "83HX"),
>> > > > + },
>> > > > + },
>> > > > + {
>> > > > + .ident = "Lenovo IdeaPad Slim 5 16AKP10",
>> > > > + .matches = {
>> > > > + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
>> > > > + DMI_MATCH(DMI_PRODUCT_NAME, "83HY"),
>> > > > + },
>> > > > + },
>> > > > +
>> > > > + /* BIOS: QXCN??WW */
>> > > > + {
>> > > > + .ident = "Lenovo Yoga 7 2-in-1 14AKP10",
>> > > > + .matches = {
>> > > > + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
>> > > > + DMI_MATCH(DMI_PRODUCT_NAME, "83JR"),
>> > > > + },
>> > > > + },
>> > > > + {
>> > > > + .ident = "Lenovo Yoga 7 2-in-1 16AKP10",
>> > > > + .matches = {
>> > > > + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
>> > > > + DMI_MATCH(DMI_PRODUCT_NAME, "83JU"),
>> > > > + },
>> > > > + },
>> > > > +
>> > > > + /* BIOS: LNCN??WW */
>> > > > + {
>> > > > + .ident = "Lenovo Yoga Pro 7 14ARP8",
>> > > > + .matches = {
>> > > > + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
>> > > > + DMI_MATCH(DMI_PRODUCT_NAME, "83AU"),
>> > > > + },
>> > > > + },
>> > > > + {
>> > > > + .ident = "Lenovo Slim Pro 7 14ARP8",
>> > > > + .matches = {
>> > > > + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
>> > > > + DMI_MATCH(DMI_PRODUCT_NAME, "83AX"),
>> > > > + },
>> > > > + },
>> > > > +
>> > > > + /* BIOS: PSCN??WW */
>> > > > + {
>> > > > + .ident = "Lenovo Yoga Pro 7 14ASP9",
>> > > > + .matches = {
>> > > > + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
>> > > > + DMI_MATCH(DMI_PRODUCT_NAME, "83HN"),
>> > > > + },
>> > > > + },
>> > > > + { }
>> > > > +};
>> > >
>> > > That is a lot of devices to exclude, are you sure that none of them will
>> > > ever work properly?
>> >
>> > Yes. I carefully checked all acpidumps for these devices provided by
>> > device owners who replied to the bugzilla thread, and confirmed that
>> > they all share the same UCSI-ACPI implementation.
>> >
>> > 83DR, 83HN, 83HY, 83AU, 83JR are owned by these device owners. Other
>> > devices share the same BIOS images (see comments in the match table), so
>> > I added them as well.
>> >
>> > Device owners also reported their dmesg dumps/snips with ucsi_acpi
>> > errors.
>> >
>> > As a reference, buggy ASL methods are shown as below.
>> >
>> > \_SB.PCI0.LPC0.EC0:
>> > Method (ECRD, 1, Serialized)
>> > {
>> > Local0 = Acquire (ECMT, 0x03E8)
>> > If ((Local0 == Zero))
>> > {
>> > If (ECAV)
>> > {
>> > Local1 = DerefOf (Arg0)
>> > Release (ECMT)
>> > Return (Local1)
>> > }
>> > Else
>> > {
>> > Release (ECMT)
>> > }
>> > }
>> >
>> > Return (Zero)
>> > }
>> >
>> > Method (ECWT, 2, Serialized)
>> > {
>> > Local0 = Acquire (ECMT, 0x03E8)
>> > If ((Local0 == Zero))
>> > {
>> > If (ECAV)
>> > {
>> > Arg1 = Arg0
>> > }
>> >
>> > Release (ECMT)
>> > }
>> > }
>> >
>> > \_SB.UBTC:
>> > Method (ECWR, 0, Serialized)
>> > {
>> > IO80 = 0xD0
>> > \_SB.PCI0.LPC0.EC0.ECWT (MGO0, RefOf (\_SB.PCI0.LPC0.EC0.MGO0))
>> > \_SB.PCI0.LPC0.EC0.ECWT (MGO1, RefOf (\_SB.PCI0.LPC0.EC0.MGO1))
>> > \_SB.PCI0.LPC0.EC0.ECWT (MGO2, RefOf (\_SB.PCI0.LPC0.EC0.MGO2))
>> > \_SB.PCI0.LPC0.EC0.ECWT (MGO3, RefOf (\_SB.PCI0.LPC0.EC0.MGO3))
>> > \_SB.PCI0.LPC0.EC0.ECWT (MGO4, RefOf (\_SB.PCI0.LPC0.EC0.MGO4))
>> > \_SB.PCI0.LPC0.EC0.ECWT (MGO5, RefOf (\_SB.PCI0.LPC0.EC0.MGO5))
>> > \_SB.PCI0.LPC0.EC0.ECWT (MGO6, RefOf (\_SB.PCI0.LPC0.EC0.MGO6))
>> > \_SB.PCI0.LPC0.EC0.ECWT (MGO7, RefOf (\_SB.PCI0.LPC0.EC0.MGO7))
>> > \_SB.PCI0.LPC0.EC0.ECWT (MGO8, RefOf (\_SB.PCI0.LPC0.EC0.MGO8))
>> > \_SB.PCI0.LPC0.EC0.ECWT (MGO9, RefOf (\_SB.PCI0.LPC0.EC0.MGO9))
>> > \_SB.PCI0.LPC0.EC0.ECWT (MGOA, RefOf (\_SB.PCI0.LPC0.EC0.MGOA))
>> > \_SB.PCI0.LPC0.EC0.ECWT (MGOB, RefOf (\_SB.PCI0.LPC0.EC0.MGOB))
>> > \_SB.PCI0.LPC0.EC0.ECWT (MGOC, RefOf (\_SB.PCI0.LPC0.EC0.MGOC))
>> > \_SB.PCI0.LPC0.EC0.ECWT (MGOD, RefOf (\_SB.PCI0.LPC0.EC0.MGOD))
>> > \_SB.PCI0.LPC0.EC0.ECWT (MGOE, RefOf (\_SB.PCI0.LPC0.EC0.MGOE))
>> > \_SB.PCI0.LPC0.EC0.ECWT (MGOF, RefOf (\_SB.PCI0.LPC0.EC0.MGOF))
>> > \_SB.PCI0.LPC0.EC0.ECWT (CTL0, RefOf (\_SB.PCI0.LPC0.EC0.CTL0))
>> > \_SB.PCI0.LPC0.EC0.ECWT (CTL1, RefOf (\_SB.PCI0.LPC0.EC0.CTL1))
>> > \_SB.PCI0.LPC0.EC0.ECWT (CTL2, RefOf (\_SB.PCI0.LPC0.EC0.CTL2))
>> > \_SB.PCI0.LPC0.EC0.ECWT (CTL3, RefOf (\_SB.PCI0.LPC0.EC0.CTL3))
>> > \_SB.PCI0.LPC0.EC0.ECWT (CTL4, RefOf (\_SB.PCI0.LPC0.EC0.CTL4))
>> > \_SB.PCI0.LPC0.EC0.ECWT (CTL5, RefOf (\_SB.PCI0.LPC0.EC0.CTL5))
>> > \_SB.PCI0.LPC0.EC0.ECWT (CTL6, RefOf (\_SB.PCI0.LPC0.EC0.CTL6))
>> > \_SB.PCI0.LPC0.EC0.ECWT (CTL7, RefOf (\_SB.PCI0.LPC0.EC0.CTL7))
>> > \_SB.PCI0.LPC0.EC0.ECWT (0xE0, RefOf (\_SB.PCI0.LPC0.EC0.USDC))
>> > IO80 = 0xD1
>> > }
>> >
>> > Method (ECRD, 0, Serialized)
>> > {
>> > IO80 = 0xD3
>> > MGI0 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGI0))
>> > MGI1 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGI1))
>> > MGI2 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGI2))
>> > MGI3 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGI3))
>> > MGI4 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGI4))
>> > MGI5 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGI5))
>> > MGI6 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGI6))
>> > MGI7 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGI7))
>> > MGI8 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGI8))
>> > MGI9 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGI9))
>> > MGIA = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGIA))
>> > MGIB = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGIB))
>> > MGIC = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGIC))
>> > MGID = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGID))
>> > MGIE = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGIE))
>> > MGIF = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGIF))
>> > VER1 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.VER1))
>> > VER2 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.VER2))
>> > RSV1 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.RSV1))
>> > RSV2 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.RSV2))
>> > CCI0 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.CCI0))
>> > CCI1 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.CCI1))
>> > CCI2 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.CCI2))
>> > CCI3 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.CCI3))
>> > \_SB.PCI0.LPC0.EC0.ECWT (0xE1, RefOf (\_SB.PCI0.LPC0.EC0.USGC))
>> > IO80 = 0xD4
>> > }
>> >
>> > Method (_DSM, 4, Serialized) // _DSM: Device-Specific
>> > Method
>> > {
>> > If ((Arg0 == ToUUID
>> > ("6f8398c2-7ca4-11e4-ad36-631042b5008f") /* Unknown UUID */))
>> > {
>> > If ((ToInteger (Arg2) == Zero))
>> > {
>> > Return (Buffer (One)
>> > {
>> > 0x0F
>> > // .
>> > })
>> > }
>> > ElseIf ((ToInteger (Arg2) == One))
>> > {
>> > ECWR ()
>> > }
>> > ElseIf ((ToInteger (Arg2) == 0x02))
>> > {
>> > ECRD ()
>> > }
>> > Else
>> > {
>> > Return (Zero)
>> > }
>> > }
>> >
>> > Return (Zero)
>> > }
>> > }
>> >
>> > Thanks,
>> > Rong
>> >
>> > >
>> > > thanks,
>> > >
>> > > greg k-h
>>
>> My biggest concern with this patch is it stands a chance of growing rapidly and extensively.
>
> If the length of match table is a concern, we can turn this into an
> allow list, i.e., disable ucsi_acpi on all Ryzen-based (after Rembrandt-
> R) IdeaPad and Yoga devices by default if the allow list doesn't
> matches, as it seems that these devices heavily shares the same UCSI-
> ACPI implementation (probably developed by the same teams?).
>
> I don't have a strong preference on either, so it's up to you and Greg.
>
An allow list would be worse from my (slightly selfish) perspective.
>> We've been having a ton of UCSI issues on this years Thinkpad systems. We'll get them fixed, though it's been slow going.
>
> I don't think ThinkPad devices have the same issue, as their USCI-ACPI
> implementations are completely different, which matches with my
> understanding to Lenovo firmware, i.e., ThinkPad firmware is generally
> developed by different teams compared to IdeaPad/Yoga teams.
>
> For example, ThinkPad Z16 Gen 1 (21D4/21D5) seems to implement the UCSI-
> ACPI DSM properly (my analysis attached at the end of the reply). Even
> if it is problematic, it must be caused by a different bug.
>
I'm testing on platforms that aren't released yet. Generally you're right - it's not a problem. But this years platforms have been bad (I don't think it's related to the CPU vendor)
>>
>> I don't understand it yet (and your notes above might be useful for narrowing it down). The FW team says the FW passes all the UCSI tests under Windows,
>>
>
> It's just like you can safely use MT-unsafe libc functions in a single-
> threaded program -- this doesn't prove the MT-safety of these functions.
>
> As I've said, the timeout will only reach when a lot of ACPI methods
> compete for the ECMT mutex as the same time. If they tested it with
> little background noise, the mutex acquisition timeout was never reached
> so no test failed.
>
>> but on Linux it's really bad and I see the same on my HW.
>
> Well, I have another conjecture. Typical Windows users don't bother
> taking a look at Windows Event Viewer at all, so they never notices any
> error related to the ECMT mutex. In contrast, checking dmesg is much
> easier.
>
You might be right. I'm told there is a bunch of qualification testing they do against Windows but I don't know the details and I've definitely previously seen garbage results previously with invalid connector numbers being returned (that we got fixed); so I'm personally dubious.
Agreed that regular Windows users won't notice. I get this all the time - we fix stuff (usually ACPI errors) that Windows just covers up. Such is the penalty for being a superior OS ;)
>>
>> Hopefully once we figure out what is going on with the Thinkpads the other platforms will benefit? but flagging that this error is not uncommon.
>
> See my analysis at the end of the reply.
>
>>
>> I'd be surprised if this is Lenovo only to be honest.
>>
>
> That's not surprising. This is not an issue of EC itself, but rather an
> issue of improper implementation of the UCSI-ACPI DSM method, as well as
> other EC-related ACPI methods.
>
My concern is that you could end up seeing this on a lot of different HW.
Maybe we just need to be more brutal when an error is detected and quit at that point with a pr_err "your UCSI FW is bad, report it to the vendor" and not retry?
There's a huge number of different PCs being released every year, Linux usage is growing, any list approach feels doomed to me.
>> I might be wrong, but there's really not a lot common between an Ideapad and Thinkpad - they're completely different FW teams. I would expect the chances that this shows up elsewhere to be reasonable, in which case your list will grow even more.
>
> That's why the best solution is BIOS update. It would be great if Lenovo
> provides BIOS updates to fix all these ECMT chaos.
>
> Meanwhile, some devices (namely, 83JR and 83JU) in the match table have,
> unfortunately, reached the "End of Development Support" as their BIOS
> download pages show:
>
> https://pcsupport.lenovo.com/us/en/products/laptops-and-netbooks/yoga-series/yoga-7-2-in-1-14akp10/83jr/downloads/ds573496
> https://pcsupport.lenovo.com/us/en/products/laptops-and-netbooks/yoga-series/yoga-7-2-in-1-16akp10/83ju/downloads/ds573496
>
> ... and PSREF says 83DR, 83AU and 83AX are "withdrawn," which means they
> are EOL according to the FAQs:
>
> https://psref.lenovo.com/WDProduct/IdeaPad/IdeaPad_5_2_in_1_14AHP9
> https://psref.lenovo.com/WDProduct/Yoga/Yoga_Pro_7_14ARP8
> https://psref.lenovo.com/WDProduct/lenovo_slim_pro_7_14arp8
>
Yeah, I know. And it sucks that we can't just have Linux on everything with vendor suport. One day we'll get there.....
>>
>> Can we wait until a bit more investigation has been done on Thinkpad?
>>
>
> I originally decided to wait a few months before submitting this. Three
> months had passed and Hans suggested I should submit this:
>
> https://bugzilla.kernel.org/show_bug.cgi?id=221065#c68
>
> As my analysis will show, I don't think the issue on IdeaPad/Yoga has
> anything in common with ThinkPad.
>
> My speculation on the UCSI issues on ThinkPad is that they might be
> caused by the EC itself or the local mutex (so other ACPI methods may
> access EC simultaneously while ucsi_acpi accessing the EC).
>
>> Right now it's on a small list of gating issues on a few of our platforms - so it is getting a bit more attention.
>>
>
> Did you refer to "a ton of UCSI issues on this years Thinkpad systems,"
> or the ECMT chaos on these IdeaPad/Yoga devices?
>
>> Once we have root cause it might be easier to find a better solution?
>>
>> Mark
>
> UCSI-ACPI DSM on ThinkPad Z16 Gen 1 (21D4/21D5):
>
> /*
> * This is an example of my comments.
> */
>
> /*
> * ThinkPad: UBSY is a local mutex, so no other methods compete for it.
> *
> * IdeaPad/Yoga: ECMT is shared among a lot of ACPI methods:
> *
> * $ grep -rE 'Acquire \(.*ECMT' | wc -l
> * 21
> * $ grep -orE 'Acquire \(.*ECMT[^)]+' | cut -d ',' -f2 | xargs -i
> bash -c 'echo $(( {} ))ms' | sort -n | uniq -c
> * 1 300ms
> * 2 1000ms
> * 4 2000ms
> * 4 8192ms
> * 10 40960ms
> */
> Mutex (UBSY, 0x00)
> Method (SECM, 1, Serialized)
> {
> Local0 = 0x64
> While (((\_SB.SCMD != 0x00) && (Local0 != 0x00)))
> {
> Sleep (0x01)
> Local0--
> }
>
> \_SB.SCMD = Arg0
> If ((Arg0 == 0x02))
> {
> Local0 = 0x64
> While (((\_SB.SCMD != 0x00) && (Local0 != 0x00)))
> {
> Sleep (0x01)
> Local0--
> }
> }
> }
>
> /*
> * ThinkPad: the UBSY mutex protects the whole UCSI methods.
> *
> * IdeaPad/Yoga: the ECMT mutex protects a single byte read/write to the EC,
> * i.e., protects \_SB.PCI0.LPC0.EC0.ECWT and \_SB.PCI0.LPC0.EC0.ECRD.
> */
> Method (ECWR, 0, Serialized)
> {
> /*
> * ThinkPad: the acquisition of UBSY has no timeout (0xFFFF means no timeout
> * according to the ACPI spec), so it will never fail.
> *
> * IdeaPad/Yoga: \_SB.PCI0.LPC0.EC0.ECWT and \_SB.PCI0.LPC0.EC0.ECRD silently
> * fail after the 1s timeout is reached while their callers never check for
> * failure.
> */
> Acquire (UBSY, 0xFFFF)
> /*
> * ThinkPad: direct EC access, the UCSI buffer and the EC are synchronized.
> *
> * IdeaPad/Yoga: the helper functions fail silently when the timeout is reached,
> * leaving the UCSI buffer and the EC are out of sync.
> */
> \_SB.MGO0 = MGO0 /* \_SB_.UBTC.MGO0 */
> \_SB.MGO1 = MGO1 /* \_SB_.UBTC.MGO1 */
> \_SB.MGO2 = MGO2 /* \_SB_.UBTC.MGO2 */
> \_SB.MGO3 = MGO3 /* \_SB_.UBTC.MGO3 */
> \_SB.MGO4 = MGO4 /* \_SB_.UBTC.MGO4 */
> \_SB.MGO5 = MGO5 /* \_SB_.UBTC.MGO5 */
> \_SB.MGO6 = MGO6 /* \_SB_.UBTC.MGO6 */
> \_SB.MGO7 = MGO7 /* \_SB_.UBTC.MGO7 */
> \_SB.MGO8 = MGO8 /* \_SB_.UBTC.MGO8 */
> \_SB.MGO9 = MGO9 /* \_SB_.UBTC.MGO9 */
> \_SB.MGOA = MGOA /* \_SB_.UBTC.MGOA */
> \_SB.MGOB = MGOB /* \_SB_.UBTC.MGOB */
> \_SB.MGOC = MGOC /* \_SB_.UBTC.MGOC */
> \_SB.MGOD = MGOD /* \_SB_.UBTC.MGOD */
> \_SB.MGOE = MGOE /* \_SB_.UBTC.MGOE */
> \_SB.MGOF = MGOF /* \_SB_.UBTC.MGOF */
> \_SB.CTL0 = CTL0 /* \_SB_.UBTC.CTL0 */
> \_SB.CTL1 = CTL1 /* \_SB_.UBTC.CTL1 */
> \_SB.CTL2 = CTL2 /* \_SB_.UBTC.CTL2 */
> \_SB.CTL3 = CTL3 /* \_SB_.UBTC.CTL3 */
> \_SB.CTL4 = CTL4 /* \_SB_.UBTC.CTL4 */
> \_SB.CTL5 = CTL5 /* \_SB_.UBTC.CTL5 */
> \_SB.CTL6 = CTL6 /* \_SB_.UBTC.CTL6 */
> \_SB.CTL7 = CTL7 /* \_SB_.UBTC.CTL7 */
> Sleep (0x19)
> SECM (0x01)
> Release (UBSY)
> }
>
> Method (ECRD, 0, Serialized)
> {
> /*
> * Same as above.
> */
> Acquire (UBSY, 0xFFFF)
> SECM (0x02)
> Sleep (0x19)
> MGI0 = \_SB.MGI0
> MGI1 = \_SB.MGI1
> MGI2 = \_SB.MGI2
> MGI3 = \_SB.MGI3
> MGI4 = \_SB.MGI4
> MGI5 = \_SB.MGI5
> MGI6 = \_SB.MGI6
> MGI7 = \_SB.MGI7
> MGI8 = \_SB.MGI8
> MGI9 = \_SB.MGI9
> MGIA = \_SB.MGIA
> MGIB = \_SB.MGIB
> MGIC = \_SB.MGIC
> MGID = \_SB.MGID
> MGIE = \_SB.MGIE
> MGIF = \_SB.MGIF
> CCI0 = \_SB.CCI0
> CCI1 = \_SB.CCI1
> CCI2 = \_SB.CCI2
> CCI3 = \_SB.CCI3
> Release (UBSY)
> }
>
> [...]
>
> Method (_DSM, 4, Serialized) // _DSM: Device-Specific
> Method
> {
> If ((Arg0 == ToUUID
> ("6f8398c2-7ca4-11e4-ad36-631042b5008f") /* Unknown UUID */))
> {
> If ((ToInteger (Arg2) == 0x00))
> {
> Return (Buffer (0x01)
> {
> 0x0F
> // .
> })
> }
> ElseIf ((ToInteger (Arg2) == 0x01))
> {
> ECWR ()
> }
> ElseIf ((ToInteger (Arg2) == 0x02))
> {
> ECRD ()
> }
> }
>
> Return (0x00)
> }
>
> The acpidump can be found at
> https://github.com/linuxhw/ACPI/blob/master/Notebook/Lenovo/ThinkPad/ThinkPad%20Z16%20Gen%201%2021D4S02A00/41C7BA241943.bin
>
Been tied up in meetings today, but I do plan on seeing if this matches what I'm seeing. On my todo list...
Mark