Curing zzz insomnia in Void Linux
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.