Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save y8a5y/63993ac88263483af165e737ac2f375f to your computer and use it in GitHub Desktop.

Select an option

Save y8a5y/63993ac88263483af165e737ac2f375f to your computer and use it in GitHub Desktop.
find the bloody device who wakes up your laptop from sleep

context: my laptop recently started to fail staying in sleep mode, waking up instantly after sleep.

note: I've tackeled a quite similar subject in this gist.

I've agregated many posts from various places online to make a hopefully easy way to find the culprit and permanently disabling it, without side effect nor hacks.

  1. list your devices that have the authority to wake up your computer:
grep enable /proc/acpi/wakeup

You should get a somewhat short list like this:

FOO0	  S4	*enabled   pci:0000:00:05.0
FOO1	  S4	*enabled   pci:0000:00:05.1
BAR0	  S3	*enabled   pci:0000:00:07.0
BAZ0	  S3	*enabled   pci:0000:00:d1.0
...
PWRB	  S4	*enabled   platform:PNP0C0C:00

If you glanced at my other gist I mentioned earlier, you should remember that the columns are Device, S-state (sleep state), Status and Sysfs node respectively.

The S-state refers to the different existing System Sleep States. Knowing that, you may think that the column indicates the mode the devices has authority to trigger a wake up. In my observation, it does jack-shit, but I may have made you click on kernel documentation so it's a win in my book!

More seriously, here comes the tidious part: you need to check each device, using their 4 characters "device code" (first column), to pin point which one makes your computer insomniac. If you got a large number of devices listed, you can check in batches (don't worry I'll show you at the end, but don't skip! read the following first to not mess things up).

Just know that the device PWRB if the computer power button, you can leave him alone since he can't be our culprit.

Now lets see how you can actually expose the mischievous bastard. Again, if you read my other gist you already know about /etc/tmpfiles.d/ (see systemd-tmpfiles).

Create a new conf file inside /etc/tmpfiles.d/, as always try to name it something easy to understand (mine was disable-device-preventing-sleep.conf), then put the following inside:

#  Path              Mode UID  GID  Age Argument
w+ /proc/acpi/wakeup -    -    -    -   <device code>

After that, I can run sudo systemd-tmpfiles --create to apply the new config. Changes take effect immediately, no need to reboot.

Try to put you computer to sleep: if it worked, congrats! you found the bastard; if not, it's between the remaining devices.

Before you try the next device in the list, you need to re-run the sudo systemd-tmpfiles --create to undo the change, no need to modify anything in the file yet.

Then, you can change the device code in the file, run the command again, and try to sleep one more time.

Did not work? run again to revert the change, then repeat the procedure for the next device, then the one after... until sleep works as intended.

When sleep is working OK: you're done! Congrats! Keep the file as is in case the change get reverted by something (prehaps an update), tho it will unlikely be needed.


I'll now go over how you can test devices by batch, and how to actually find the name of the culprit device.

As an example, lets say after running grep enable /proc/acpi/wakeup you got 8 devices in the list:

FOO0	  S4	*enabled   pci:0000:00:05.0
FOO1	  S4	*enabled   pci:0000:00:05.1
FOO2	  S3	*enabled   pci:0000:00:05.2
FOO3	  S3	*enabled   pci:0000:00:05.3
BAR0	  S3	*enabled   pci:0000:00:07.4
BAR1	  S4	*enabled   pci:0000:00:07.8
BAZ0	  S4	*enabled   pci:0000:00:d1.0
BAZ1	  S3	*enabled   pci:0000:00:d2.0

To try in batch you first need to understand that each line in the conf file act as an on-off switch. So to try the first 4 devices at once, the conf file should look like this:

#  Path              Mode UID  GID  Age Argument
w+ /proc/acpi/wakeup -    -    -    -   FOO0
w+ /proc/acpi/wakeup -    -    -    -   FOO1
w+ /proc/acpi/wakeup -    -    -    -   FOO2
w+ /proc/acpi/wakeup -    -    -    -   FOO3

Run sudo systemd-tmpfiles --create then try to sleep. If it worked, I know the culprit is between devices nb 1 and 4; conversely, I then know it's between nb 5 and 8.

Lets say it did not work. As explained before, re-run the command to revert the change. Then, knowing it's between BAR0, BAR1, BAZ0 and BAZ1, you can just put BAR0 and BAR1 in the conf before trying again.

This time it worked, I now know it's between BAR0 and BAR1! re-run to revert change, remove one of the two before trying again.

If it work, you're done! it was BAR0! If not, you're sure it's BAR1: revert one last time, change the file, run the command and you should be all set!

Finding the real name of the device is pretty straight forward. Run udevadm info --tree and scroll for three hours until you see the Sysfs node of the culprit (the last column mentioned earlier), and you should find its real name somewhere (usually next to ID_MODEL_FROM_DATABASE).

To find it more easily, pipe the output of the command to a text editor with search capability, like so:

# with kwrite
udevadm info --tree | kwrite -i

# with nano
udevadm info --tree | nano -

Then search for the Sysfs node (e.g. 00:1c.0) and the ID_MODEL_FROM_DATABASE should be close. If you want, you can rename the conf file to reflect this new discovery.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment