Curing zzz insomnia in Void Linux

April 15, 2018 2 minutes

Context

In a vanilla instalation of Void Linux, the easiest way for us to suspend our computer to RAM is via the zzz command. To suspend our computer to disk, there’s the ZZZ command.

Those commands are convenience scripts for interacting with sys/power/state as shown here: https://github.com/voidlinux/void-runit/blob/master/zzz

Problem

After running zzz however, the system went to sleep, but immediately turned itself on again. Such sleep problems cannot be good.

Solution

What can wake-up our computer from a suspended state is listed in the file proc/acpi/wakeup.

In my case it looked something like this:

Device	S-state	  Status   Sysfs node
GPP0	  S4	*disabled  pci:0000:00:01.1
GPP0	  S4	*disabled  pci:0000:01:00.0
GPP1	  S4	*disabled
...
GPP7	  S4	*disabled
GPP8	  S4	*disabled  pci:0000:00:03.1
X161	  S4	*disabled  pci:0000:0b:00.0
GPP9	  S4	*disabled
...
GP17	  S4	*disabled  pci:0000:00:07.1
XHC0	  S4	*enabled   pci:0000:0c:00.3
GP18	  S4	*disabled  pci:0000:00:08.1
PS2K	  S3	*disabled
PS2M	  S3	*disabled
GPP2	  S4	*disabled  pci:0000:00:01.3
AS43	  S4	*enabled   pci:0000:04:00.0
I211	  S4	*enabled   pci:0000:05:00.0
WIBT	  S4	*disabled
...
X413	  S4	*disabled
PTXH	  S4	*enabled   pci:0000:02:00.0

Indeed, there’s a list of things that can wake our computer.

But WTF is XHC0, or I211? Well, those are 4 letter codes for the devices in the motherboard given by the manufacturer. If we want to know what’s what, then we’re better off looking at the Sysfs node column.

For example, the I211 device is in the pci:0000:05:00.0 node. Running lspci | grep 05:00.0 returns the following:

05:00.0 Ethernet controller: Intel Corporation I211 Gigabit Network Connection (rev 03)

Running similar commands for the other devices tells me that some are related to USB devices.

In my case, I only care about the power button, so I’ll disable every device.

To do so, I’ll create a new executable file in /etc/zzz.d/suspend/ with the following contents. The name of the file doesn’t matter.

#!/bin/bash
state_XHC0=`cat /proc/acpi/wakeup | grep XHC0 | cut -f3 | cut -d' ' -f1 | tr -d '*'`
if [ "$state_XHC0" == "enabled" ]
then
        echo XHC0 > /proc/acpi/wakeup
        echo "Disabled XHC0 in /proc/acpi/wakeup"
fi

<<COMMENT
# I copy the previous block for every device which I want to disable, changing XHC0
# to the devices' names. Which in my case were AS43, PTXH, I211.
COMMENT

I check the current state of the devices in the wakeup file as echoing the device name to the file acts as a toggle: if the device was already disabled then doing so will enable it again.