diff options
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r-- | drivers/bluetooth/btusb.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 8ff0e162341d..a92811468542 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -328,6 +328,7 @@ static const struct usb_device_id blacklist_table[] = { #define BTUSB_FIRMWARE_LOADED 7 #define BTUSB_FIRMWARE_FAILED 8 #define BTUSB_BOOTING 9 +#define BTUSB_RESET_RESUME 10 struct btusb_data { struct hci_dev *hdev; @@ -2767,8 +2768,15 @@ static int btusb_probe(struct usb_interface *intf, } #ifdef CONFIG_BT_HCIBTUSB_RTL - if (id->driver_info & BTUSB_REALTEK) + if (id->driver_info & BTUSB_REALTEK) { hdev->setup = btrtl_setup_realtek; + + /* Realtek devices lose their updated firmware over suspend, + * but the USB hub doesn't notice any status change. + * Explicitly request a device reset on resume. + */ + set_bit(BTUSB_RESET_RESUME, &data->flags); + } #endif if (id->driver_info & BTUSB_AMP) { @@ -2901,6 +2909,14 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message) btusb_stop_traffic(data); usb_kill_anchored_urbs(&data->tx_anchor); + /* Optionally request a device reset on resume, but only when + * wakeups are disabled. If wakeups are enabled we assume the + * device will stay powered up throughout suspend. + */ + if (test_bit(BTUSB_RESET_RESUME, &data->flags) && + !device_may_wakeup(&data->udev->dev)) + data->udev->reset_resume = 1; + return 0; } |