https://bugzilla.kernel.org/show_bug.cgi?id=220505
--- Comment #22 from tropicaal ([email protected]) --- Alright, I can fairly confidently say *why* this happens, and it seems to be due to Lenovo not implementing Microsoft's Modern Standby firmware notifications in a spec-compliant way for this laptop. For a rundown: - The driver theoretically at fault here is drivers/acpi/x86/s2idle.c, where acpi_sleep_run_lps0_dsm is invoked with Microsoft's DSM GUID for presumably performing some extra modern standby operations on the PEP/SPMC that aren't described by Intel's spec https://uefi.org/sites/default/files/resources/Intel_ACPI_Low_Power_S0_Idle.pdf (see section 3). - The "_DSM" method on the PEP takes four arguments, wherein the first argument is a GUID and the third argument is a function number. The meaning of the function number changes depending on the GUID. Intel's GUID is c4eb40a0-6cd2-11e2-bcfd-0800200c9a66 and Microsoft's GUID is 11e00d56-ce64-47ce-837b-1f898f9aa461. Looking at both the implementation and my ACPICA trace, the kernel uses both GUIDs in the s2idle implementation. - On this laptop, Microsoft's GUID branch will unconditionally call \_SB.PC00.LPCB.EC0.UPHK with the function number (argument 2) of PEP _DSM which performs power mangement operations on the EC. The kernel specifically invokes these DSMs with Microsoft's GUID in this order: - On suspend: _DSM(Unknown, 1, 3, Unknown) -> UPHK(3), which sets DPLF to 0 and writes an EC command. At this point, some keyboard controls stop responding. - On suspend: _DSM(Unknown, 1, 7, Unknown) -> UPHK(7), which is a noop for UPHK. - On suspend: _DSM(Unknown, 1, 5, Unknown) -> UPHK(5), which sets a GPIO pin on the EC low, presumably bringing it into a low power state. At this point, the fans stop working. - On resume: _DSM(Unknown, 1, 6, Unknown) -> UPHK(6), which is a noop for UPHK. - On resume: _DSM(Unknown, 1, 8, Unknown) -> UPHK(8), which appears to update a timer value based on the RTC. - On resume: _DSM(Unknown, 1, 4, Unknown) -> UPHK(4), which presumably undoes the effects of UPHK(3) based on the disassembly, but in practice seems to be dependent on UPHK(9) to restore keyboard controls based on Jakob's findings. - So on sleep, the kernel calls DSM functions 3, 7, 5, and on resume calls functions 6, 8, 4. Notably missing is DSM function 9, which undoes the work of function 5 to wake the EC from low power, which we've already determined. These _DSM calls are done by the aformentioned s2idle.c driver, where 3=ACPI_LPS0_SCREEN_OFF, 7=ACPI_LPS0_MS_ENTRY, 5=ACPI_LPS0_ENTRY, and 6=ACPI_LPS0_EXIT, 8=ACPI_LPS0_MS_EXIT, and 4=ACPI_LPS0_SCREEN_ON. So ACPI_LPS0_SCREEN_OFF is what shuts off the keyboard controls and ACPI_LPS0_ENTRY is what disables the EC functionality that never gets turned back on in resume. Once again, there is no mention anywhere of a function with an ID of 9, nor is there any mention of it in Microsoft's specification (https://learn.microsoft.com/en-us/windows-hardware/design/device-experiences/modern-standby-firmware-notifications), yet the ACPI tables specifically implement and require a Function 9 to be called to correctly wake the EC from its low power state. That's why this is happening. Now that we know exactly what's at fault here, bugging Lenovo might be worth a shot even though they *technically* require a Windows reproduction. Alternatively, I guess a patch could be implemented to call acpi_sleep_run_lps0_dsm(9, lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft) in acpi_s2idle_restore_early_lps0 specifically for this model. I have some doubts this would be upstreamable though, given that this is such a specific OEM quirk. -- You may reply to this email to add a comment. You are receiving this mail because: You are watching the assignee of the bug. _______________________________________________ acpi-bugzilla mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/acpi-bugzilla
