2

I cannot suspend / sleep while bluetooth is active. There is no error message in the syslog.

However, after rfkill block bluetooth I can sucessfully sleep / suspend.

I use a bluetooth mouse so permanently disabling bluetooth is not an option.

How can I sleep / suspend while still having bluetooth functionality?

5

Cause

Kernel Bug 200039 - BT advertising packet wakes up the system from S3 and suspend-to-idle.

This affects Intel (8087:0aaa) and Atheros (0cf3:e005)(0cf3:e007) bluetooth:

  • Acer Swift SF314-55
  • Asus UX333FA
  • Asus UX433FN
  • Asus UX533FD

Workaround

A workaround is to automatically deauthorise the bluetooth USB device before sleep/suspend, and then reauthorise upon wake.

For systemd work-around is to use the following:

/etc/systemd/system/bluetooth-disable-before-sleep.service (note the CHANGE ME lines):

[Unit]
Description=disable bluetooth for systemd sleep/suspend targets
Before=sleep.target
Before=suspend.target
Before=hybrid-sleep.target
Before=suspend-then-hibernate.target
StopWhenUnneeded=yes

[Service]
Type=oneshot
RemainAfterExit=yes

# Usage: bluetooth-sleep (start|stop) <vendor> <product>
# Get values from `lsusb`:
# eg: Bus 001 Device 003: ID 8087:0aaa Intel Corp.
# Usage: bluetooth-sleep (start|stop) 8087 0aaa

##### CHANGE ME: (the two hex values at end of next line) ###
ExecStart=/usr/local/bin/bluetooth-sleep start 8087 0aaa
##### CHANGE ME: (the two hex values at end of next line) ###
ExecStop=/usr/local/bin/bluetooth-sleep  stop  8087 0aaa

[Install]
WantedBy=sleep.target
WantedBy=suspend.target
WantedBy=hybrid-sleep.target
WantedBy=suspend-then-hibernate.target

/usr/local/bin/bluetooth-sleep:

#!/bin/bash

# Disable bluetooth given first argument "start"
# Re-enable bluetooth given first argument "stop"
# Expects vendor and product as 2nd and 3rd arguments

set -eu

usage() {
  script_name=${0##*/}
  printf '%s: de-authorise bluetooth during sleep/suspend\n' "$script_name" >&2
  printf 'Usage: %s (start|stop) <vendor> <product>\n' "$script_name" >&2
  exit 1
}

case "${1:-}" in
  start) value=0 ;;
  stop)  value=1 ;;
  *)     usage   ;;
esac

[ $# -ne 3 ] && usage
vendor=$2
product=$3

shopt -s nullglob
for dir in /sys/bus/usb/devices/*; do
  if [[ -L "$dir" && -f $dir/idVendor && -f $dir/idProduct &&
        $(cat "$dir/idVendor")  == "$vendor" &&
        $(cat "$dir/idProduct") == "$product" ]]; then
    echo "$value" > "$dir/authorized"
    echo "echo $value > $dir/authorized"
  fi
done

Credit to this post.

3
  • 1
    Thanks! Looks like it is working. Don't forget to remove ### CHANGE ME ### as comments also treated as command line arguments. Though running /usr/local/bin/bluetooth-sleep stop 8087 0029 or echo 0 > /sys/bus/usb/devices/1-14/authorized manually works unstable on my system. Bluetooth may suddenly stop working after disabling and re-enabling device, echo with stream redirect may block forever preventing sleep job from completion, after that even systemctl reboot may stop working. Looks like there's some another hardware or kernel/module bugs :( – Stanislav Mamontov Aug 9 '20 at 8:24
  • Cheers @StanislavMamontov, I moved the # CHANGE MEs to a separate line. – Tom Hale Aug 13 '20 at 10:02
  • I had to disable this "fix", it was a bit unstable on my laptop (BT device on my thinkpad is USB 8087:0029). But it looks like the problem is gone after recent updates! – Stanislav Mamontov Aug 14 '20 at 16:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.