Skip to content

Instantly share code, notes, and snippets.

@nullconfig
Last active June 16, 2026 20:40
Show Gist options
  • Select an option

  • Save nullconfig/742469c0cf820618d9bae272e6d92965 to your computer and use it in GitHub Desktop.

Select an option

Save nullconfig/742469c0cf820618d9bae272e6d92965 to your computer and use it in GitHub Desktop.
Power & USB Wakeup Guide

Power & USB Wakeup — CachyOS Setup Guide

No-sleep, no-hibernate configuration for a gaming/streaming desktop: CPU locked to performance mode, USB autosuspend disabled system-wide, hibernate masked, automatic suspend triggers disabled, and target USB devices configured to wake the system from sleep — persistent across reboots and port-agnostic.

Tested on: Arch Linux (CachyOS), systemd 256.x, Linux 6.x


What This Achieves

  • CPU stays at full performance frequency — no scaling down under low load
  • USB devices never autosuspend — no reconnect delays or input dropout between inputs
  • Hibernate is permanently disabled — system cannot accidentally write RAM to disk and power off
  • Automatic suspend via idle timer and sleep keys is disabled
  • Specific USB devices (keyboard, mouse, etc.) can wake the system from sleep regardless of which physical port they are plugged into

Prerequisites

  • power-profiles-daemon installed and running (ships with CachyOS desktop)
  • Root or sudo access

Verify power-profiles-daemon is active:

systemctl is-active power-profiles-daemon
# Expected: active

If not installed:

sudo pacman -S power-profiles-daemon
sudo systemctl enable --now power-profiles-daemon

Step 1 — Set CPU to Performance Mode

power-profiles-daemon manages the CPU power profile and persists the setting across reboots automatically. One command is all that is needed.

powerprofilesctl set performance

Verify:

powerprofilesctl
# Expected: performance profile marked with *
# * performance:
#     Driver:     amd-pstate / intel_pstate
#     Degraded:   no

Do not set the governor directly with cpupower frequency-set -g performance. While it takes effect immediately, power-profiles-daemon overrides it on the next profile switch or reboot. powerprofilesctl is the persistent path when the daemon is running.

power-profiles-daemon and tlp cannot coexist. If tlp is installed it will fight over the governor and win. Check: systemctl is-active tlp. If active, disable and remove it: sudo systemctl disable --now tlp && sudo pacman -R tlp.


Step 2 — Disable USB Autosuspend

USB autosuspend causes input devices to drop off briefly when idle, producing missed keystrokes and input lag on wakeup. Disabling it system-wide via kernel parameter is the most reliable method — it applies before udev runs and covers all USB devices without per-device rules.

Find the Limine config file:

find /boot /etc -name "limine.conf" 2>/dev/null
# Typically: /boot/limine.conf

Edit the config and append usbcore.autosuspend=-1 to the CMDLINE= line of each boot entry:

CMDLINE=root=PARTUUID=... quiet splash ... usbcore.autosuspend=-1

Limine reads its config directly on boot — no regeneration step needed. The change takes effect after the next reboot. Verify it loaded:

cat /proc/cmdline | grep autosuspend
# Expected: ... usbcore.autosuspend=-1 ...

Step 3 — Disable Hibernate

Masking the hibernate targets prevents systemd from ever hibernating the system, regardless of what requests it — logind, the desktop environment, or direct systemctl hibernate calls.

sudo systemctl mask hibernate.target hybrid-sleep.target

Masking is stronger than disabling. It creates a symlink to /dev/null so the unit cannot be started even if explicitly requested.

Verify:

systemctl status hibernate.target hybrid-sleep.target | grep Loaded
# Expected: Loaded: masked (/dev/null; bad)

Step 4 — Disable Automatic Suspend (logind)

logind handles suspend requests from idle timers, the desktop environment, and hardware sleep keys. Editing /etc/systemd/logind.conf overrides all of these.

/etc/systemd/logind.conf — add or edit these lines under [Login]:

[Login]
HandleSuspendKey=ignore
HandleHibernateKey=ignore
IdleAction=ignore

Apply without rebooting:

sudo systemctl restart systemd-logind

HandlePowerKey is intentionally left at its default (poweroff). Only the sleep and hibernate keys are ignored. The power button still shuts the system down cleanly.

This does not mask suspend.target itself. Running systemctl suspend manually or via script will still work. If you need to block that entirely, also run: sudo systemctl mask suspend.target

Desktop environment power managers override logind. KDE Plasma, GNOME, and XFCE have their own idle/suspend settings that take priority over logind.conf. Disable suspend in the desktop power manager settings as well, or the desktop will request suspend through its own path and logind will honour it regardless of what IdleAction is set to.


Step 5 — USB Wakeup (persistent, port-agnostic)

The kernel resets each USB device's power/wakeup attribute to disabled on every boot. A udev rule re-enables it on every add event, matched by USB vendor and product ID. Because the match uses the device's hardware identity rather than its physical port path, the rule works regardless of which USB port the device is plugged into.

5a — Find Device IDs

lsusb

Example output:

Bus 001 Device 002: ID 046d:c52b Logitech, Inc. Unifying Receiver
Bus 001 Device 003: ID 1b1c:1b4f Corsair Gaming K70 RGB MK.2
Bus 002 Device 004: ID 093a:2510 Pixart Imaging, Inc. Optical Mouse

The ID field is idVendor:idProduct. Note these for each device you want to wake the system.

Check the current wakeup state of all connected USB devices:

sh -c '
for f in /sys/bus/usb/devices/*/power/wakeup; do
    dir=${f%/power/wakeup}
    v=$(cat "$dir/idVendor" 2>/dev/null)
    [ -z "$v" ] && continue
    printf "[%s:%s] %-30s %s\n" "$v" \
        "$(cat "$dir/idProduct" 2>/dev/null)" \
        "$(cat "$dir/product" 2>/dev/null)" \
        "$(cat "$f" 2>/dev/null)"
done
' | sort

Devices showing disabled with no power/wakeup file at all cannot be made to wake the system in software — the hardware does not support it.

5b — Create the Wakeup Rule

sudo nano /etc/udev/rules.d/90-usb-wakeup.rules

/etc/udev/rules.d/90-usb-wakeup.rules

# USB wakeup — matched by vendor:product ID, fires on every device connect event.
# Port-agnostic: works regardless of which physical USB port the device is plugged into.

# Logitech Unifying Receiver (keyboard/mouse dongle)
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c52b", ATTR{power/wakeup}="enabled"

# Corsair K70 keyboard
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b4f", ATTR{power/wakeup}="enabled"

Replace vendor/product IDs with your own devices from Step 5a. Add one line per device.

5c — Apply Without Rebooting

sudo udevadm control --reload-rules && sudo udevadm trigger

5d — Verify

sh -c '
for f in /sys/bus/usb/devices/*/power/wakeup; do
    dir=${f%/power/wakeup}
    v=$(cat "$dir/idVendor" 2>/dev/null)
    [ -z "$v" ] && continue
    printf "[%s:%s] %-30s %s\n" "$v" \
        "$(cat "$dir/idProduct" 2>/dev/null)" \
        "$(cat "$dir/product" 2>/dev/null)" \
        "$(cat "$f" 2>/dev/null)"
done
' | sort

Target devices should now show enabled. If a device still shows disabled after triggering, replug it to force a fresh add event with the new rules active.

USB wakeup requires BIOS support. In your UEFI firmware settings, look for "USB Wake Support", "Power On By USB", or an equivalent option and ensure it is enabled. Without this, setting power/wakeup=enabled on the device has no effect — the hardware will not signal the system to wake.

USB hubs in the path also need wakeup enabled. If a device is connected through an external USB hub, add a rule for the hub as well (same format, using the hub's vendor/product ID from lsusb). Internal USB hubs on the motherboard are typically handled by the BIOS setting.


Verification

Run after setup or after each reboot to confirm everything is in effect:

# 1. Performance profile active
powerprofilesctl | grep -E "\*|performance"

# 2. CPU governor — all cores should report "performance"
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor | sort -u

# 3. Hibernate targets masked
systemctl status hibernate.target hybrid-sleep.target | grep Loaded

# 4. USB autosuspend kernel parameter present
cat /proc/cmdline | grep autosuspend

# 5. USB wakeup — target devices showing "enabled"
sh -c '
for f in /sys/bus/usb/devices/*/power/wakeup; do
    dir=${f%/power/wakeup}
    v=$(cat "$dir/idVendor" 2>/dev/null)
    [ -z "$v" ] && continue
    printf "[%s:%s] %-30s %s\n" "$v" \
        "$(cat "$dir/idProduct" 2>/dev/null)" \
        "$(cat "$dir/product" 2>/dev/null)" \
        "$(cat "$f" 2>/dev/null)"
done
' | sort

# 6. logind idle action disabled
systemctl show systemd-logind | grep IdleAction

Troubleshooting

CPU governor shows schedutil or powersave despite performance profile being set Another power management tool is overriding the governor. Check for conflicts:

systemctl list-units --type=service | grep -E "tuned|thermald|cpupower|tlp"

power-profiles-daemon and tlp cannot coexist — if tlp is active, remove it. tuned can also conflict; disable any profile it has set before using powerprofilesctl.

Hibernate option still visible in desktop power menu after masking The desktop session caches capabilities at login. Log out and back in — the mask takes effect immediately for systemd but the session manager re-queries it only at session start.

USB devices still show disabled after running udevadm trigger Test the rule against a specific device to see what udev sees:

# Step 1 — get the sysfs path for your target device (use bus/device numbers from lsusb)
udevadm info --query=path --name=/dev/bus/usb/001/002

# Step 2 — pass the returned path to udevadm test, e.g.:
udevadm test /sys/bus/usb/devices/1-1 2>&1 | grep -i wakeup

If the rule is not matching, confirm ATTR{idVendor} and ATTR{idProduct} values are lowercase hex exactly as lsusb reports them (e.g., 046d not 046D).

Device has no power/wakeup file in sysfs

ls /sys/bus/usb/devices/*/power/wakeup 2>/dev/null

If the file does not exist for a device, the hardware does not support software-controlled wakeup and no udev rule can enable it.

System suspends automatically despite logind changes The desktop environment power manager is overriding logind. Common culprits:

systemctl --user list-units | grep -E "power|sleep|idle"

Disable suspend in the desktop's power management settings directly (KDE: System Settings → Power Management; GNOME: Settings → Power; XFCE: Power Manager). The desktop manager takes priority over logind.conf for idle-triggered suspension.

usbcore.autosuspend=-1 present in cmdline but devices still autosuspend A udev rule or userspace tool is re-enabling autosuspend after boot. Check for rules that write to power/autosuspend:

grep -r autosuspend /etc/udev/rules.d/ /usr/lib/udev/rules.d/ 2>/dev/null

File Inventory

File Purpose
/etc/udev/rules.d/90-usb-wakeup.rules Enables wakeup for named USB devices on every connect
/etc/systemd/logind.conf Disables idle suspend and hardware sleep keys
/boot/limine.conf usbcore.autosuspend=-1 kernel parameter (append to CMDLINE=)

Power profile (powerprofilesctl set performance) is persisted by power-profiles-daemon internally — no config file to manage manually.

Hibernate mask (systemctl mask) is persisted by systemd in /etc/systemd/system/ as symlinks to /dev/null — no manual file to manage.

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