[TRACKING] Framework AMD Ryzen 7040 Series lid wakeup behavior feedback

ACPI is a very messy affair. This wakeup is coming from the EC and I haven’t been able to disable it through /proc/acpi/wakeup. Based on my light research, it needs to be read from the EC through the cros module so I’m not going to bet on any universal solution being picked up for quirks like this.

Scratch that, I’m making some process on disabling wakeups using udev

Ah, I might’ve misunderstood which solution you wanted. My first idea was to make the system suspend back again if it’s woken up with the lid closed, because from @Kieran_Levin’s description it sounded like the firmware waking the OS when the laptop’s plugged or unplugged is just the new normal in this S3-less world we’re now in, and is not actually Framework-specific. So deal with the spurious wakeup rather than trying to make it not happen. But now I’m not sure.

Spurious wakeup is rather problematic. Given that the system can cycle the AC-DC state when you’re fully charged, your system never sleeps if left on the charge. That means you should just shutdown or hibernate if you’ll leave it to charge. Almost makes me not want to use sleep at all and just make my system hibernate the moment the lid is closed just to have a predictable behaviour.

I just was discussing this with our friends at AMD. One thought they had is that when the system wakes up from a lid open or ac adapter event, these will be happened by the kernel s2idle loop.
As part of the wakeup process, they thought there may be a second interrupt that is triggered. For example a GPIO event that also transitions as part of the S0i3->S0 which may cause linux to stay awake.
This may be a good exploration direction.

6 Likes

I don’t have a laptop in hand yet to try this with, but I bet you could use this indicator with a systemd timer that runs say, every 30s. If the lid is closed for two consecutive events, you put the system to sleep.

Hacky, but workable :slight_smile:

1 Like

Alright, here’s the deal. I disabled the Lid Switch /sys/*/power/wakeup, but that didn’t do it. Me and a friend did some more testing and found out that when you close the lid, it sends two wake-ups, one from the Lid Switch and another is a wake-up from the keyboard! When you plug in the AC, it also sends a keyboard wake-up! I’ll post some udev rules soon to disable this soon!

2 Likes

Isn’t that controlled by a BIOS setting on the 11 gen? On this 11 gen system for example (Fedora 38 with BIOS 3.17 and the that wake on AC option disabled), I’ve never seen this behavior.

Editing: I hadn’t used the power on when AC attached option and had mis-remembered what it does. It doesn’t apply to resuming.

Anyway, just for posterity, the steps below are the same, so resume-on-AC-attach does not appear to be a thing on 11th gen (and more recent comments below suggest it can be traced to AMD-specific EC source code anyway - so, misunderstanding corrected).

Just tested now:

  • Unplug charger (from the machine’s USB-C port)
  • Suspend (power button or lid close)
  • Plug charger in
  • Still suspended
  • Unplug, wait, plug in
  • Still suspended (when suspend was byby lid close, “verified” by observing WLAN reconnect on lid open, so timed consistent with laptop suspended throughout the lid closed time)

(Suspend is configured to s2idle on this machine)

Just out of curiosity, what does /proc/acpi/wakeup look like on the AMD system?

FWIW I use this, run from a systemd unit, to disable wakeups from my external keyboard on a gen 11 system:

#!/usr/bin/bash

for device in `tail -n +2 /proc/acpi/wakeup |egrep -v 'PWRB|PXSX' |grep enabled |cut -f 1`; do
  echo "disabling $device"
  sh -c "echo $device > /proc/acpi/wakeup"
done

Disabling everything in /proc/acpi/wakeup didn’t fix the lid issue but here’s the print out

> enzi@ultraportable: ~/projects/ec-patches  
$ cat /proc/acpi/wakeup 
Device  S-state   Status   Sysfs node
GPP0      S4    *disabled
GPP1      S4    *disabled
GPP2      S4    *disabled
GPP5      S4    *disabled
GPP6      S4    *enabled   pci:0000:00:02.2
GPP7      S4    *disabled
GP11      S4    *enabled   pci:0000:00:03.1
SWUS      S4    *disabled
GP12      S4    *enabled   pci:0000:00:04.1
SWUS      S4    *disabled
XHC0      S3    *enabled   pci:0000:c1:00.3
XHC1      S3    *enabled   pci:0000:c1:00.4
XHC2      S3    *enabled   pci:0000:c3:00.0
NHI0      S4    *enabled   pci:0000:c3:00.5
XHC3      S3    *enabled   pci:0000:c3:00.3
NHI1      S4    *enabled   pci:0000:c3:00.6
XHC4      S3    *enabled   pci:0000:c3:00.4

One theory I have is that this code in the EC may be causing an additional interrupt to the host on wake:

When we go from S0i3 to S0ix, the EC will send some dummy key presses to the host so the keyboard will keep working. This may cause the host to wake up to screen on, and stay there.

5 Likes

I think you’re right! I fixed most of my issues with the wakeups using the following rules that I put in the /dev/rules.d/ folder:

/etc/udev/rules.d/20-suspend-fixes.rules

ACTION=="add", SUBSYSTEM=="acpi", DRIVERS=="button", ATTRS{hid}=="PNP0C0D", ATTR{power/wakeup}="disabled"
ACTION=="add", SUBSYSTEM=="serio", DRIVERS=="atkbd", ATTR{power/wakeup}="disabled

The second line disables the keyboard from waking the PC, which fixes the lid waking the machine (along with the first line) AND the AC being plugged in (which sends a keyboard wakeup as well). You lose the keyboard wake-ups but the touchpad and everything else work fine.

I noticed you linked to your GitHub. Is there a guide for consumers to customize and flash their own EC? I haven’t done the research yet.

13 Likes

Seems like it kills lid open wake up too for me.

2 Likes

Try removing the first line and see if it disables wake-on-close but not wake-on-open.

As an aside, how did you track down the particular identifiers to use for the rules? Especially PNP0C0D for the lid?

1 Like

Is there anything like this that can be configured for Windows 11? I’m having an issue with my new laptop where it’s waking up from sleep on its own…

sudo udevadm info -p -a /sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:44/PNP0C09:00/PNP0C0D:00

I found the device by creating a script that tests disabling every result of:

find /sys -wholename "**/power/wakeup"

No clue.

3 Likes

Thank you for this! Using the second rule makes suspend work as expected on Debian Testing. That is, I can close the lid, automatically suspend, unplug and plug power without waking, then open the lid and have the machine wake.

I can also sleep from menu, close the lid and the machine will not wake, just from the second rule. It seems plug/unplug sending keycodes is the problem here.

2 Likes

No such luck here with those udev rules. Plugging in my power adapter still wakes the laptop :confused:

I missed something! There’s a missing quote at the end of the udev rule here and I totally didn’t catch it last night

The full rule is

ACTION=="add", SUBSYSTEM=="acpi", DRIVERS=="button", ATTRS{hid}=="PNP0C0D", ATTR{power/wakeup}="disabled"
ACTION=="add", SUBSYSTEM=="serio", DRIVERS=="atkbd", ATTR{power/wakeup}="disabled"
7 Likes

Echoing the success of others in this thread - adding the second udev rule listed above to disable waking by keyboard keeps the laptop from fully waking up from power plug/unplug. Is this function in the EC necessary for all systems, or is it just a workaround for a specific setup? I ask because I think that this side-effect (waking for power events unnecessarily) is undesirable and am curious if it may be properly fixable further down the line so that we don’t have to just disable waking by keyboard (not the end of the world, but I’d rather have it than not).

4 Likes