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 -a first — using ATTRS instead of ATTR is a common mistake that prevents the rule matching.
  • Power management daemons such as power-profiles-daemon and tlp can 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.