26

I disabled most of my entries in /proc/acpi/wakeup/ to make sure only the power button and the laptop lid can resume my system, not the mouse or keyboard. The problem is: every time I reboot, the settings are reset for some reason.

Is there a way to make these changes permanent? There are some workaround out there that just put the commands into a script hooked to some wakeup routine, but is there really no other solution?

I'm using a Debian/Gnome Windows 10 dual boot laptop

3
  • Can you set it in the bios? Or uefi as it probably is now..
    – Guy
    Commented Jan 19, 2018 at 12:49
  • Nope I checked all my BIOS settings and found nothing helpful there
    – piegames
    Commented Jan 19, 2018 at 14:44
  • 1
    old question, but for people looking for a modern solution, you can use systemd-tmpfiles (as explained there : wiki.archlinux.org/index.php/…)
    – tbrugere
    Commented Apr 29, 2021 at 10:15

10 Answers 10

26
+50

For a USB mouse or keyboard, you can use a udev rule to make the setting permanent. First, look up the PCI vendor ID of your mouse/keyboard using lsusb. For my mouse, it's 046d:

Bus 001 Device 006: ID 046d:c52b Logitech, Inc. Unifying Receiver

Then create a "rules" file like my /etc/udev/rules.d/logitech.rules, only replace "046d" with the vendor ID of your own device:

ACTION=="add", SUBSYSTEM=="usb", DRIVERS=="usb", ATTRS{idVendor}=="046d", ATTR{power/wakeup}="disabled"
4
  • 2
    I believe this is the correct answer. And it is preferable for modern systems unlike the /etc/rc.local solution suggested below.
    – scrutari
    Commented Dec 4, 2020 at 19:41
  • 1
    It could help to reload the rule: udevadm control --reload-rules
    – sanmai
    Commented May 17, 2021 at 0:15
  • 3
    I think you should use ATTRS{idProduct}=="c52b" there, too, in case there are more than one product from the same vendor.
    – jarno
    Commented Nov 2, 2021 at 18:04
  • I have an issue with this kind of rule.
    – jarno
    Commented Nov 4, 2021 at 20:50
7

The preferred way to do this is by creating a service with systemd.
Adding script in rc.local is the deprecated way.

  1. Create a script file wherever you wish. Ex: ~/scripts/disable-devices-as-wakeup.sh.

    #!/bin/bash
    
    declare -a devices=(XHC OCH1 USB1 USB2) # <-- Add your entries here
    for device in "${devices[@]}"; do
        if grep -qw ^$device.*enabled /proc/acpi/wakeup; then
            sudo sh -c "echo $device > /proc/acpi/wakeup"
        fi
    done
    
  2. Test it by executing it from the terminal.

  3. If everything is okay then let's make a service.

    $ touch ~/scripts/disable-devices-as-wakeup.service
    

    ~/scripts/disable-devices-as-wakeup.service -

    [Unit]
    Description=Disable devices as wakeup
    
    [Service]
    ExecStart=/home/username/scripts/disable-devices-as-wakeup.sh
    Type=oneshot
    
    [Install]
    WantedBy=multi-user.target
    
  4. Copy or move the service to /etc/systemd/system/.

    $ sudo cp ~/scripts/disable-devices-as-wakeup.service /etc/systemd/system/
    
  5. Enable the service.

    $ systemctl enable disable-devices-as-wakeup.service
    
  6. Restart the OS and check the status.

    $ systemctl status disable-devices-as-wakeup.service
    

Detailed explanation found here.

1
  • 1
    If you have a SELinux enabled distro (like fedora) be sure to 1. create the Service directly under /etc/systemd/system/ and not copy it there 2. create the script not under your home directory, but i.e. under /usr/local/bin/ Otherwise you will have problems with the SELinux context. Either Systemd will not find your service file or it won't execute the script because Systemd isn't permitted to execute files lying in home directories.
    – Gero
    Commented Jul 25, 2021 at 10:39
2

Eric Garrido has a script in /etc/rc.local that echo's those devices that are allowed to wake up his system, to /proc/acpi/wakeup.

for i in `/bin/grep USB /proc/acpi/wakeup | /usr/bin/awk '{print $1}'`; 
do 
    echo $i > /proc/acpi/wakeup; 
done
4
  • The /etc/rc.local is much shorter! Commented May 17, 2021 at 14:10
  • @JeremyBoden, much shorter than ... ? Commented May 21, 2021 at 9:10
  • 1
    ;) Much shorter than a set of Systemd scripts. I wrote one set of 3 to run a single command weekly [fstrim] but I would have to look at the man pages and run some find commands if I wanted to modify anything. Why can't Systemd put everything in /etc? I've got stuff in /etc, /home, /usr and /var! Commented May 21, 2021 at 13:20
  • 2
    @JeremyBoden don't ask me, I wouldn't touch systemd with a stick. Commented May 21, 2021 at 13:50
2

acpitool can be used for this apt install acpitool

And then

sudo acpitool -W [some number]

where some number is device id from /proc/acpi/wakeup

maciej@michal:~$ sudo acpitool -W 22
  Changed status for wakeup device #22 (UHC6)

   Device   S-state   Status   Sysfs node
  ---------------------------------------
  1. PCE2     S4    *disabled  pci:0000:00:02.0
  2. PCE3     S4    *disabled
  3. PCE4     S4    *disabled  pci:0000:00:04.0
  4. RLAN     S4    *enabled   pci:0000:02:00.0
  5. PCE5     S4    *disabled
  6. PCE6     S4    *disabled
  7. PCE7     S4    *disabled  pci:0000:00:07.0
  8. PCE9     S4    *disabled
  9. PCEA     S4    *disabled
  10. PCEB    S4    *disabled
  11. PCEC    S4    *disabled
  12. SBAZ    S4    *disabled  pci:0000:00:14.2
  13. PS2K    S4    *disabled
  14. PS2M    S4    *disabled
  15. UAR1    S4    *disabled  pnp:00:03
  16. P0PC    S4    *disabled  pci:0000:00:14.4
  17. UHC1    S4    *disabled  pci:0000:00:12.0
  18. UHC2    S4    *disabled  pci:0000:00:12.1
  19. UHC3    S4    *disabled  pci:0000:00:12.2
  20. USB4    S4    *disabled  pci:0000:00:13.0
  21. UHC5    S4    *disabled  pci:0000:00:13.1
  22. UHC6    S4    *disabled  pci:0000:00:13.2
  23. UHC7    S4    *enabled   pci:0000:00:14.5
1
  • 5
    It was asked for a permanent solution. This one is only temporary. Commented Jun 1, 2019 at 10:36
1

I decided to create script in /usr/lib/systemd/system-sleep/

according to man page systemd will run it just before suspend.

0

The /proc is a virtual file system containing runtime system info. So its content resets on reboot.

// Edit: Setup a udev rule or create a script echoing the right values to the /proc/acpi/wakeup/ on start up.

7
  • 1
    So, how exactly do I set OHC1 to disabled in /proc/acpi/wakeup?
    – piegames
    Commented Jan 18, 2018 at 9:34
  • Sorry, @piegames, this seems to require a script triggered on startup (in your case via systemd). The script really just needs to echo the values to /proc/acpi/wakeup. This should give you the idea: linuxconfig.org/…
    – Yuri
    Commented Jan 18, 2018 at 20:48
  • The systemd service unit running a script did the job for me. Please update your answer so that it also works without the links.
    – piegames
    Commented Jan 23, 2018 at 22:41
  • 7
    /proc/acpi/wakeup is not a child of /proc/sys, sysctl doesn't work here.
    – Nova
    Commented Feb 12, 2019 at 19:50
  • 1
    Please update the answer to reflect the @Erik's comment above. Thank you.
    – scrutari
    Commented Dec 4, 2020 at 19:34
0

You might be able to get away with a crontab on reboot if the entry only reverses on reboot.

On startup, the following crontab will reverse the entry XHC.

@reboot /bin/sh -c '/bin/echo XHC > /proc/acpi/wakeup'

0

The script file in Hrishikesh Kadam's answer is good, but rather than incorporating it in a service, I dropped it in a directory that is run by the system as it is entering suspend mode, so the updates to /proc/apci/wakeup are fresh as the system is going into suspend mode and a service isn't necessary. In my case, I named the file disable-some-wake. The format of the file is:

#! /bin/bash
case $1 in
    pre)
        declare -a devices=(RP09 PXSX) # <-- Add your entries here

        for device in "${devices[@]}"; do
            if $(grep -qw ^${device}.*enabled /proc/acpi/wakeup); then
                echo ${device} > /proc/acpi/wakeup
            fi
        done
    ;;
esac

The pre case specifies that this is pre-suspend. Now drop it into the directory:

sudo cp disable-some-wake /usr/lib/systemd/system-sleep

and change the permissions:

sudo chmod 755 /usr/lib/systemd/system-sleep/disable-some-wake

That’s it. No need to start a service or reboot your system.

0
# cat /etc/systemd/system/acpi-wake.service 
[Unit]
Description=ACPI Wake Service
Before=sleep.target

[Service]
Type=oneshot
ExecStart=/bin/sh -c "for i in $(cat /proc/acpi/wakeup| grep enabled| awk '{print $1}'| xargs); do [ $i != PBTN ] && echo $i| tee /proc/acpi/wakeup; done"

[Install]
WantedBy=sleep.target

# ln -s /etc/systemd/system/acpi-wake.service  /etc/systemd/system/sleep.target.wants/acpi-wake.service

# systemctl daemon-reload
0

The systemd way:

Create /etc/tmpfiles.d/disable-bluetooth-wake-from-sleep.conf:

#    Path                  Mode UID  GID  Age Argument
w+   /proc/acpi/wakeup     -    -    -    -   OCH1
w+   /proc/acpi/wakeup     -    -    -    -   XHCI

# It is possible to write multiple lines to the same file, either with \n in the argument
# or using the w+ type on multiple lines (including the first one) for appending

Apply the changes without reboot:

sudo systemd-tmpfiles --create

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .