12

I replaced the button battery on the motherboard and now my PC wakes up immediately after suspend. I'm running Ubuntu 20.04.3LTS.

A user at another site stated that this might be due to an inhibitor so I entered the suggested command and got the output shown in this screenshot


I found a partial solution from Ubuntu wakes up after few seconds of sleep

Entering echo EHC1 | sudo tee /proc/acpi/wakeup in the terminal allows suspend to function but I couldn't find a permanent solution.

Do you know how to make this a permanent fix? Thanks.

9
  • Have you set your RTC after replacing the battery? Read man hwclock. Within 2 minutes of an unwanted wakeup, sudo journalctl --since="-5 minutes" will show what is happening.
    – waltinator
    Feb 27, 2022 at 17:52
  • I just reset the RTC but suspend still doesn't work. I also entered the command to show what's happening but the output is so lengthy I was unable to screenshot the entire thing, I don't understand the output, and I don't know how to show the screenshot here in the comments. Mini-Markdown formatting is confusing to me but thanks for your suggestions.
    – Henry
    Mar 1, 2022 at 4:58
  • Don't commit logvomit - posting the whole log (as formatted text, NOT a screenshot). Carefully read each line of the log, skipping the ones clearly unrelated to your problem.
    – waltinator
    Mar 1, 2022 at 5:46
  • Read man pm-is-supported.
    – waltinator
    Mar 1, 2022 at 5:58
  • pastebin.com/gmGXbKzg
    – Henry
    Mar 4, 2022 at 5:24

1 Answer 1

4

I just purchased a new computer, and suspend worked fine when I had it in my office connected to my monitor, but when I moved it to my front room and connected it to my TV, it started exhibiting this same behavior of waking immediately after it went into suspend mode.

I traced the problem down to CEC (Consumer Electronics Control) signaling between the TV and the computer over the HDMI cable. I did a lot of searching, and found a definitive and permanent solution.

Linux has a file /proc/acpi/wakeup that sets the state of devices that can wake up from the suspended state. You can issue the command:

cat /proc/acpi/wakeup

and this will display the different devices that are either enabled or disabled to execute wake from suspend mode. Here’s a partial example:

Device  S-state   Status   Sysfs node
PEG1      S4    *disabled
PEGP      S4    *disabled
PEG2      S4    *disabled
PEGP      S4    *disabled
PEG3      S4    *disabled
PEGP      S4    *disabled
PEG0      S4    *enabled   pci:0000:00:06.0
PEGP      S4    *disabled  pci:0000:01:00.0
SIO1      S3    *disabled  pnp:00:00
RP09      S4    *disabled  pci:0000:00:1d.0
PXSX      S4    *enabled   pci:0000:64:00.0
RP10      S4    *disabled
RP11      S4    *disabled
RP12      S4    *disabled
RP13      S4    *disabled
[etc.]

The first column is the device identifier, and these are set by the manufacturer, and might or might not follow APCI protocol. https://unix.stackexchange.com/questions/236127/acpi-wakeup-4-letters-code-meaning

What the device identifiers refer to is only minimally important. You can get a quick list of those that are enabled by issuing the command:

cat /proc/acpi/wakeup | grep enabled

You can toggle between enabled and disabled state for a device by echoing the device identifier to the file (with root privileges). For instance you can issue the command

sudo sh -c “echo PEG0 > /proc/acpi/wakeup”

and the device PEG0 will be disabled. Issue the command again, and it will be enabled again.

My method was to write a script to disable the enabled devices one by one. Each time I disabled one, I went into suspend mode to see what happened, if it were to reawaken immediately or stay suspended. Once I disabled a device (one which didn’t solve the problem), I left it disabled and moved onto the next one, trying each one by one. In my script file, I just commented out each one as I tested it so it wouldn’t be re-enabled again. Once I found that I had achieved the proper suspend state and it stayed suspended, I went through the previous devices I had disabled and re-enabled them one by one, then going into suspend mode each time to verify it was still working correctly. If I found that suspend reverted to it’s previous mannerism of waking immediately, I disabled that device again and moved on to the next one. I found that there were two devices that had originally been enabled that I had to leave disabled for my suspend state to work correctly.

Now comes the big part. That was all just testing. Linux maintains a directory of files to execute when it goes into suspend state. This directory is

/usr/lib/systemd/system-sleep

Files in this directory have the owner:group of root:root and permissions 755.

Each file will be called in sequence and passed two parameters. The first parameter is the text either “pre” or “post,” depending on whether it is going into suspend mode or waking from it, respectively. The second parameter identifies the suspend state and can be one of “suspend” “hibernate” “hybrid-sleep” or “suspend-then-hibernate.” We are interested in the first parameter only, and only when we are going into suspend mode. The second parameter doesn’t matter – we want the system behavior on waking to be the same regardless.

We want to use this method of disabling a device from waking immediately before going into suspend mode, rather than on system startup, because the system might change the parameters in this wakeup file at some time during operations. This method ensures that the device(s) of interest will be in the proper state on suspend. So we need to create a script file and copy it to this directory. I call mine “disable-some-wake.” The format of this file is:

#! /bin/bash
case $1 in
    pre)
        declare -a devices=(RP09 PXSX) # <-- Add your entries here

        for device in "${devices[@]}"; do
            if $(grep -qw ^${device}.*enabled /proc/acpi/wakeup); then
                echo ${device} > /proc/acpi/wakeup
            fi
        done
    ;;
esac

In this file, we’re only working with the case where we are “pre”-suspend mode. We’ve created an array of devices we want to be disabled, and loop through that array of devices. For each device, we look in the wakeup file to test if it is enabled, and if so, toggle it to be disabled.

Note that the list of devices that works for me might be different than what works for you. Use whatever worked for you in testing. You also can disable additional devices other than those impacted by CEC signals if so desired.

Now copy the file:

sudo cp disable-some-wake /usr/lib/systemd/system-sleep

and change the permissions:

sudo chmod 755 /usr/lib/systemd/system-sleep/disable-some-wake

That’s it. You should be good for all eternity.

4
  • 1
    I've been struggling to find a solution to my problem for like a year and now finally I was able to fix it. Thank you very much!
    – RCRalph
    Jun 10 at 16:21
  • Unfortunately, even after disabling all 3 device wakeup entries (EHC1, EHC2, XHC), the bug persists, so I couldn't apply this method. Btw mind the literary quotes “” in “echo PEG0 > /proc/acpi/wakeup” => use straight quotes "" instead so the command works in terminal.
    – hsandt
    Jul 11 at 9:06
  • 1
    Is it safe to disable all of them? I only ever want my laptop to wake up when I press the power button or open the lid (not a must). Jul 15 at 18:32
  • 1
    @teg_brightly, I think it should be fine, as long as none of those are controlling your power button. Worst case is that you wouldn't be able to wake from sleep, in which case you'd hold the power button until it shuts off completely, and then power up from a cold boot again. Then you'd know to not disable that one case.
    – randyman99
    Jul 20 at 8:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .