|
@@ -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;
|
|
|
}
|
|
|
|