1. Problem
A Bluetooth mouse connected via a USB dongle was freezing for 1-2 seconds intermittently. The cause was Linux USB power management suspending the Bluetooth dongle to save power.
2. Solution
Disable USB autosuspend for the Bluetooth dongle via a udev rule.
Step 1: Identify the Bluetooth Dongle
lsusb | grep -i bluetooth
In our case:
Bus 002 Device 006: ID 0bda:a728 Realtek Semiconductor Corp. Bluetooth Radio
Step 2: Verify udev Attribute Names
udevadm info -a /sys/bus/usb/devices/2-13/ | grep -E "idVendor|idProduct"
This confirmed the device uses ATTR (not ATTRS) for its own attributes.
Step 3: Create the udev Rule
cat > /etc/udev/rules.d/99-bluetooth-dongle.rules << EOF
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="0bda", ATTR{idProduct}=="a728", TEST=="power/control", ATTR{power/control}="on"
EOF
Step 4: Apply the Rule
udevadm control --reload-rules
udevadm trigger
Step 5: Verify
for dev in /sys/bus/usb/devices/*/; do
name=$(cat "$dev/product" 2>/dev/null || echo "unknown")
control=$(cat "$dev/power/control" 2>/dev/null)
echo "$name control=$control"
done | grep -i bluetooth
Expected output:
Bluetooth Radio control=on
3. Troubleshooting: udev Rule Overridden by Power Manager
If the mouse continues to freeze after applying the udev rule, a power management service may be resetting the USB power control back to auto. Check for running power management daemons:
systemctl status tlp
systemctl status power-profiles-daemon
systemctl status tuned
In our case power-profiles-daemon was active and overriding the udev rule. The fix is to create a systemd service that enforces the setting after the daemon starts:
cat > /etc/systemd/system/usb-bluetooth-power.service << 'EOF'
[Unit]
Description=Disable USB autosuspend for Bluetooth dongle
After=power-profiles-daemon.service
[Service]
Type=oneshot
ExecStart=/bin/bash -c 'echo on > /sys/bus/usb/devices/2-13/power/control'
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOF
systemctl enable --now usb-bluetooth-power.service
Verify the service is active and the setting is correct:
systemctl status usb-bluetooth-power.service
cat /sys/bus/usb/devices/2-13/power/control
Expected output: service active (exited) and control=on.
4. Further Fix: Enforcing the Setting with a systemd Timer
If the mouse continues to freeze, power-profiles-daemon is periodically resetting the power control back to auto after boot. A oneshot service only runs once and cannot counter this. The solution is a systemd timer that re-enforces the setting every 30 seconds:
cat > /etc/systemd/system/usb-bluetooth-power.service << 'EOF'
[Unit]
Description=Disable USB autosuspend for Bluetooth dongle
[Service]
Type=oneshot
ExecStart=/bin/bash -c 'echo on > /sys/bus/usb/devices/2-13/power/control'
EOF
cat > /etc/systemd/system/usb-bluetooth-power.timer << 'EOF'
[Unit]
Description=Enforce USB autosuspend off for Bluetooth dongle
[Timer]
OnBootSec=10
OnUnitActiveSec=30s
[Install]
WantedBy=timers.target
EOF
systemctl daemon-reload
systemctl enable --now usb-bluetooth-power.timer
Verify the timer is running:
systemctl status usb-bluetooth-power.timer
5. Notes
- Always verify the correct udev attribute style with
udevadm info -afirst — usingATTRSinstead ofATTRis a common mistake that prevents the rule matching. - Power management daemons such as
power-profiles-daemonandtlpcan override udev rules — use the systemd service workaround if this occurs. - The device path
/sys/bus/usb/devices/2-13/may differ on your system — verify it with the vendor/product ID loop shown in the verification step above. - The same approach applies to any USB device suffering from autosuspend issues.






0 comments:
Post a Comment