Stopping my laptop spontaneously resuming immediately after Suspend to RAM
February 8, 2016 2 Comments
If I selected ‘Suspend to RAM’ via the Desktop Environment in the Gentoo Linux installation on my Clevo W230SS laptop, the laptop did suspend but then immediately resumed automatically. The same thing happened if I suspended the laptop using either of the following commands from the command line:
root # pm-suspend
user $ qdbus org.kde.Solid.PowerManagement /org/freedesktop/PowerManagement Suspend
This behaviour was annoying, as it meant I had to shut down the laptop completely when I was not at my desk for a long time, rather than just being able to suspend the laptop.
Problem 1: USB devices
I usually have several USB devices connected to my laptop when I am at home or in the office, and I began to suspect that these USB connections were somehow causing Linux to resume as soon as it had suspended. Searching the Web turned up a Q&A page that seemed to confirm my suspicion: Why does my laptop resume immediately after suspend? I installed the utility acpitool
mentioned on that Web page and used it with the ‘-w
‘ option to check which wakeup-capable USB devices were currently enabled in my installation:
root # acpitool -w
Device S-state Status Sysfs node
---------------------------------------
1. RP01 S4 *disabled pci:0000:00:1c.0
2. PXSX S4 *disabled
3. RP02 S4 *disabled
4. PXSX S4 *disabled
5. RP03 S4 *disabled pci:0000:00:1c.2
6. PXSX S4 *disabled pci:0000:03:00.0
7. RP04 S4 *disabled pci:0000:00:1c.3
8. PXSX S4 *disabled pci:0000:04:00.0
9. *disabled platform:rtsx_pci_sdmmc.0
10. *disabled platform:rtsx_pci_ms.0
11. RLAN S4 *disabled
12. RP05 S4 *disabled
13. PXSX S4 *disabled
14. RP06 S4 *disabled
15. PXSX S4 *disabled
16. RP07 S4 *disabled
17. PXSX S4 *disabled
18. RP08 S4 *disabled
19. PXSX S4 *disabled
20. GLAN S4 *disabled
21. EHC1 S3 *enabled pci:0000:00:1d.0
22. EHC2 S3 *enabled pci:0000:00:1a.0
23. XHC S3 *disabled pci:0000:00:14.0
24. HDEF S4 *disabled pci:0000:00:1b.0
25. PEG0 S4 *disabled pci:0000:00:01.0
26. PEGP S4 *disabled pci:0000:01:00.0
27. PEGA S4 *disabled
28. PWRB S3 *enabled platform:PNP0C0C:0
^C
root #
(I had to use Ctrl-C to get back to the command prompt.)
I then used the command ‘acpitool -W <device number>
‘ on each of the three enabled devices (21, 22 and 28 above) in order to find out which of them needed to be disabled in order for my laptop to remain suspended when I suspended it. I found that I only needed to disable devices EHC1 (pci:0000:00:1d.0) and EHC2 (pci:0000:00:1a.0) to be able to suspend the laptop successfully:
root # acpitool -W 21 | grep 21
Changed status for wakeup device #21 (EHC1)
21. EHC1 S3 *disabled pci:0000:00:1d.0
^C
root # acpitool -W 22 | grep 22
Changed status for wakeup device #22 (EHC2)
22. EHC2 S3 *disabled pci:0000:00:1a.0
^C
root # pm-suspend
In this laptop these two devices are two internal USB root hubs:
user $ lsusb -t
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/2p, 480M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/8p, 480M
|__ Port 2: Dev 3, If 0, Class=Hub, Driver=hub/4p, 480M
|__ Port 1: Dev 4, If 0, Class=Mass Storage, Driver=usb-storage, 480M
|__ Port 3: Dev 5, If 0, Class=Mass Storage, Driver=usb-storage, 480M
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/2p, 480M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/6p, 480M
|__ Port 2: Dev 3, If 0, Class=Hub, Driver=hub/4p, 480M
|__ Port 1: Dev 6, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
|__ Port 4: Dev 7, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
|__ Port 4: Dev 7, If 1, Class=Human Interface Device, Driver=usbhid, 1.5M
|__ Port 3: Dev 4, If 0, Class=Wireless, Driver=btusb, 12M
|__ Port 3: Dev 4, If 1, Class=Wireless, Driver=btusb, 12M
|__ Port 4: Dev 5, If 0, Class=Video, Driver=uvcvideo, 480M
|__ Port 4: Dev 5, If 1, Class=Video, Driver=uvcvideo, 480M
The next challenge was to find out how to disable and re-enable the two devices automatically when I suspend and resume the installation. Further searching of the Web turned up another Q&A page which pointed me in the right direction: How to run a script when suspending/resuming?. It turns out that you need to put a script of the following form in the directory /etc/pm/sleep.d/
:
#!/bin/bash case "$1" in suspend) # executed on suspend ;; resume) # executed on resume ;; *) ;; esac
If you want the script to run when hibernating and thawing, the tests would be for ‘hibernate
‘ and ‘thaw
‘ instead of ‘suspend
‘ and ‘resume
‘.
The thread [SOLVED] Computer immediately resumes after suspend in the KDE Forums almost gave me the solution I needed. I created a file /etc/pm/sleep.d/01-toggle-usb-hubs
containing the following:
#!/bin/sh # username=fitzcarraldo userhome=/home/$username export XAUTHORITY="$userhome/.Xauthority" export DISPLAY=":0" # case "$1" in suspend|hibernate) # Unbind ehci-pci for the device 0000:00:1a.0 echo -n "0000:00:1a.0" | tee /sys/bus/pci/drivers/ehci-pci/unbind # Unbind ehci-pci for the device 0000:00:1d.0 echo -n "0000:00:1d.0" | tee /sys/bus/pci/drivers/ehci-pci/unbind ;; resume|thaw) # Bind ehci-pci for the device 0000:00:1a.0 echo -n "0000:00:1a.0" | tee /sys/bus/pci/drivers/ehci-pci/bind # Bind ehci-pci for the device 0000:00:1d.0 echo -n "0000:00:1d.0" | tee /sys/bus/pci/drivers/ehci-pci/bind ;; *) exit $NA ;; esac
I obtained the device details from the output of the ‘acpitools -w
‘ command listed earlier and by looking in the directory /sys/bus/pci/drivers/ehci-pci
:
root # ls /sys/bus/pci/drivers/ehci-pci
0000:00:1a.0 0000:00:1d.0 bind new_id remove_id uevent unbind
Notice that the script tests for either ‘suspend
‘ or ‘hibernate
‘ to disable the two devices, and tests for either ‘resume
‘ or ‘thaw
‘ to enable the two devices.
I made the script executable:
root # chmod +x /etc/pm/sleep.d/01-toggle-usb-hubs
Problem 2: Blank X Windows display due to NVIDIA closed-source driver bug
However, a problem remained: My laptop has an NVIDIA GPU and, when resuming from suspension, the X Windows display (Virtual Terminal 7) was a blank screen with only the mouse pointer visible. Now, it so happens that I also experience this behaviour if I switch from Virtual Terminal 7 to e.g. Virtual Terminal 1 (Ctrl-Alt-F1) and then switch back to Virtual Terminal 7 (Ctrl-Alt-F7). Apparently this is due to a bug in the closed-source NVIDIA driver (I am currently using Gentoo package x11-drivers/nvidia-drivers-358.16-r1
). However, if I first disable compositing before switching to another virtual terminal, the X Windows display on Virtual Terminal 7 is still visible when I switch back to Virtual Terminal 7. It turns out there is a known bug in the NVIDIA closed-source driver, as explained in the following KDE bug report and thread in the NVIDIA CUDA ZONE Forums:
KDE Bugtracking System Bug No. 344326 – Black or corrupted screen on resume from suspend
As the suggested work-around is to disable compositing before suspending to RAM, I created a script /etc/pm/sleep.d/02-toggle-compositing
containing the following:
#!/bin/sh # username=fitzcarraldo userhome=/home/$username export XAUTHORITY="$userhome/.Xauthority" export DISPLAY=":0" # case "$1" in suspend|hibernate) su $username -c "qdbus org.kde.kwin /KWin toggleCompositing" & ;; resume|thaw) su $username -c "qdbus org.kde.kwin /KWin toggleCompositing" & ;; *) exit $NA ;; esac
As I have KDE 4 on this laptop, I made the script use the command ‘qdbus org.kde.kwin /KWin toggleCompositing
‘ to disable/enable compositing, so replace that command with the appropriate command if you are not using KDE 4.
I made the script executable:
root # chmod +x /etc/pm/sleep.d/02-toggle-compositing
Now both the scripts in the directory /etc/pm/sleep.d/
run when I suspend or resume the laptop, and everything works as expected. Mission accomplished! 🙂
Now that I am using KDE Plasma 5 instead of KDE 4, the script
/etc/pm/sleep.d/02-toggle-compositing
needs to be changed to the following:Pingback: Gentoo Linux: A work-around to be able to Resume from Suspend to RAM when using the NVIDIA closed-source driver | Fitzcarraldo's Blog