Wakeup from suspend, wireless Bluetooth / RF keyboard, udev and Ubuntu12.10

Finally got my HTPC wireless controls to wake-up it from suspend. I'm using PS3 BD Bluetooth remote with Trust Bluetooth 3.0 USB receiver (Atheros AR3011) and Logitech Wireless K400r with Logitech Unifying Receiver.



This is actually quite simple. We just need to make sure USB ports are are shown as "enabled" in /proc/acpi/wakeup and also set /sys/bus/usb/devices/*/power/wakeup to enabled state. How to automate it while still supporting hot plugging with processes starting up and drivers loading in more or less random order is more tricky.

I'm using following script as /etc/rc.local to enable wakeup with USB ports.
#!/bin/bash
# /etc/rc.local
#
# Enable USB wakeup, part 1
grep -e "USB.*disabled" /proc/acpi/wakeup |\
while read line; do
echo $line >/proc/acpi/wakeup
done
#
# Enable USB wakeup, part 2
for i in /sys/bus/usb/devices/*/power/wakeup; do echo "enabled" > $i; done
#
# Exit with success
exit 0

We still need udev rule to handle devices appearing after rc.local has been executed. You can try to create rule that would target only your USB hid and bluetooth devices, but that's real minefield. There's so many race conditions with udev that it's simply not worth the trouble. Besides by nature all Linux solutions are supposed to be hacks, right?
#!/bin/bash
# /etc/usbwakeup-fixup.sh
(sleep 3; for i in /sys/bus/usb/devices/*/power/wakeup; do echo "enabled" > $i; done) &

# /etc/udev/rules.d/10-usb-wakeup.rules
ACTION=="add", SUBSYSTEM=="usb", IMPORT{program}="/bin/bash -c /etc/usbwakeup-fixup.sh"

Downside of this approach is that usb wakeup is enabled for all usb devices supporting it. Also usbwakeup-fixup.sh script is executed for every USB device plugged in.

Make sure scripts are executable (chmod a+x /etc/rc.local /etc/usbwakeup-fixup.sh).

P.S. "udevadm" has some neat features to debug udev madness. For example "udevadm info --attribute-walk --name=/dev/usb/hiddev0" and "udevadm monitor --property" can be useful.

Comments

  1. On your udev rule there is a typo, /etc/usbwakeup-fixup.sh is the correct file name

    ReplyDelete

Post a Comment

Got something to say?!