< Power management

Power management/Wakeup triggers

Wakeup triggers are event sources that can wake the system from any of the hardware power-saving states. The obvious example is the power or suspend button, the Wake-on-LAN functionality or the lid switch in laptop systems. Wakeup triggers can be controlled through various kernel interfaces listed below. There is no unified interface covering all possible triggers.

Wakeup trigger interfaces

/proc/acpi/wakeup

Reading the /proc/acpi/wakeup file yields list of ACPI-registered wakeup sources with corresponding sysfs IDs where available. Writing an entry from the Device column to the file toggles its state. For example, to disable waking on opening the laptop lid, run:

# echo "LID" > /proc/acpi/wakeup

/sys/module/acpi/parameters/ec_no_wakeup

This file represents the value of ACPI kernel module option ec_no_wakeup, which controls passing the wakeup triggers from embedded controller when the system is in the suspend-to-idle (s2idle) power state . On modern laptops embedded controller wakeups can cause excessive battery drain in some cases.

/sys/devices/

Each sysfs device that supports wakeup contains the file wakeup in a device's power subdirectory. The file contains wakeup trigger's status and can be written to as well. Bus controllers as well as endpoint devices can be capable of waking up the system. For example, to disable wakeups from the first USB controller (bus), run:

# echo "disabled" > /sys/bus/usb/devices/usb1/power/wakeup

An endpoint device should be able to wake the device if the trigger is enabled regardless of the controller's setting, however this might be hardware-dependent.

Program PowerTOP interfaces with sysfs, but it only lists wakeup triggers of networking and USB devices by reading /sys/class/net/ and (containing symlinks to ).

/sys/class/wakeup/*

Almost all wakeup triggers can be found in the directory, which contains symlinks to all relevant devices. This is useful for finding possible wakeup triggers by going through subdirectories. Some of the triggers can correspond to virtual devices while hardware-related wakeup triggers are the ones that contain at least one of these files:

/sys/class/wakeup/*/device/physical_node/power/wakeup
/sys/class/wakeup/*/device/power/wakeup

Some of wakeup triggers in also provide a link to the cryptic /proc/acpi/wakeup names where the following file is present:

/sys/class/wakeup/*/device/path

Persistent settings

The one-time methods should suffice for setting the /proc/acpi/wakeup states and kernel parameter while the event-driven approach with udev is the reliable way to configure the sysfs devices.

One-time with systemd

The ec_no_wakeups ACPI kernel module option can be set at boot as described in the article. The standard solution to set the sysfs values at boot are systemd services such as in this troubleshooting case. Another systemd-based manager for /proc/acpi/wakeup is .

Some systems can override some of the ACPI wakeup triggers upon power state transition(s) in what is more of a bug rather than a feature. If the hardware is overriding triggers at predictable times that can still be solved with appropriately crafted systemd units. The sleep.target is a generic target covering all different suspended states that might be helpful in this case, but there is no generic .

This method only works reliably with sysfs devices that are connected all the time.

Event-driven with udev

Setting the wakeup trigger status with udev rules is an event-driven method that works reliably any time the devices with wakeup triggers are connected. The key is to detect an addition of a new device () in a rule and set the wakeup trigger status with . If the hardware is resetting this setting, udev can try to circumvent it by reapplying rules upon every device change (). A device tree with possible parameters for matching a particular device found in sysfs can be obtained with .

A representative common example here would be a Logitech Unifying USB receiver. Its wakeup trigger should be enabled by default and if that is not desired, a solution could be an udev rule, as follows:

The reverse case to enable the necessary trigger(s) is described in the udev article.

udev triggers so early in the device enumeration that disabling wakeup trigger with the method above causes (some?) disabled triggers to not be listed in . That might be dependent on whether the device was already present at boot and needs further clarification.

Troubleshooting

List device and/or bus trees

These auxiliary commands can be helpful when trying to understand all wakeup triggers of a certain system, to aid with udev rule writing or general wakeup source troubleshooting:

# lshw -businfo -numeric
# lspci -DPPnn
# lsusb -tvv

Instantaneous wakeups from suspend

For some Intel Haswell systems with the LynxPoint and LynxPoint-LP chipset, instantaneous wakeups after suspend are reported. They are linked to erroneous BIOS ACPI implementations and how the module interprets it during boot. As a work-around reported affected systems are added to a denylist (named ) by the kernel case-by-case .

Instantaneous resume may happen, for example, if a USB device is plugged during suspend and ACPI wakeup triggers are enabled. A viable work-around for such a system, if it is not on the denylist yet, is to disable the wakeup triggers. An example to disable wakeup through USB is described as follows .

To view the current configuration:

$ cat /proc/acpi/wakeup
Device  S-state   Status   Sysfs node
...
EHC1      S3    *enabled  pci:0000:00:1d.0
EHC2      S3    *enabled  pci:0000:00:1a.0
XHC       S3    *enabled  pci:0000:00:14.0
...

The relevant devices are , and (for USB 3.0). To toggle their state you have to echo the device name to the file as root:

# echo EHC1 > /proc/acpi/wakeup
# echo EHC2 > /proc/acpi/wakeup
# echo XHC > /proc/acpi/wakeup

This should result in suspension working again. However, this settings are only temporary and need to be set at every boot. To automate this, see systemd-tmpfiles or BBS thread for possible solutions.

nouveau driver

If the nouveau driver is used, the reason for instantaneous wakeups may be a bug in the driver, which sometimes prevents GPU from suspending. A possible workaround is unloading the kernel module right before going to sleep and loading it back after wakeup. To do this, create the following script:

The first echo line unbinds from the framebuffer console driver (). Usually it is as in this example, but it may also be another vtcon*. See which one of them is a frame buffer device .

gollark: (this is because humans cannot reasoning under uncertainty)
gollark: It's fiiiiiiiine, I rounded the chances of them doing so off to zero.
gollark: Oh, and they still didn't get round to explaining the creepiness thing.
gollark: They can't kill me because that would be mean.
gollark: Anyway, we hit *those* limits ages ago, so we achieve our high clocks by extending the processors out into arbitrarily many orthogonal dimensions, ignoring the "speed of light", and patterning the logic gates directly onto underlying physical laws.
This article is issued from Archlinux. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.