|
21 | 21 | *
|
22 | 22 | */
|
23 | 23 |
|
| 24 | +#include <linux/dmi.h> |
24 | 25 | #include <linux/module.h>
|
25 | 26 | #include <linux/usb.h>
|
26 | 27 | #include <linux/usb/quirks.h>
|
@@ -379,6 +380,21 @@ static const struct usb_device_id blacklist_table[] = {
|
379 | 380 | { } /* Terminating entry */
|
380 | 381 | };
|
381 | 382 |
|
| 383 | +/* The Bluetooth USB module build into some devices needs to be reset on resume, |
| 384 | + * this is a problem with the platform (likely shutting off all power) not with |
| 385 | + * the module itself. So we use a DMI list to match known broken platforms. |
| 386 | + */ |
| 387 | +static const struct dmi_system_id btusb_needs_reset_resume_table[] = { |
| 388 | + { |
| 389 | + /* Lenovo Yoga 920 (QCA Rome device 0cf3:e300) */ |
| 390 | + .matches = { |
| 391 | + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
| 392 | + DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 920"), |
| 393 | + }, |
| 394 | + }, |
| 395 | + {} |
| 396 | +}; |
| 397 | + |
382 | 398 | #define BTUSB_MAX_ISOC_FRAMES 10
|
383 | 399 |
|
384 | 400 | #define BTUSB_INTR_RUNNING 0
|
@@ -2945,6 +2961,9 @@ static int btusb_probe(struct usb_interface *intf,
|
2945 | 2961 | hdev->send = btusb_send_frame;
|
2946 | 2962 | hdev->notify = btusb_notify;
|
2947 | 2963 |
|
| 2964 | + if (dmi_check_system(btusb_needs_reset_resume_table)) |
| 2965 | + interface_to_usbdev(intf)->quirks |= USB_QUIRK_RESET_RESUME; |
| 2966 | + |
2948 | 2967 | #ifdef CONFIG_PM
|
2949 | 2968 | err = btusb_config_oob_wake(hdev);
|
2950 | 2969 | if (err)
|
@@ -3031,12 +3050,6 @@ static int btusb_probe(struct usb_interface *intf,
|
3031 | 3050 | if (id->driver_info & BTUSB_QCA_ROME) {
|
3032 | 3051 | data->setup_on_usb = btusb_setup_qca;
|
3033 | 3052 | hdev->set_bdaddr = btusb_set_bdaddr_ath3012;
|
3034 |
| - |
3035 |
| - /* QCA Rome devices lose their updated firmware over suspend, |
3036 |
| - * but the USB hub doesn't notice any status change. |
3037 |
| - * explicitly request a device reset on resume. |
3038 |
| - */ |
3039 |
| - interface_to_usbdev(intf)->quirks |= USB_QUIRK_RESET_RESUME; |
3040 | 3053 | }
|
3041 | 3054 |
|
3042 | 3055 | #ifdef CONFIG_BT_HCIBTUSB_RTL
|
|
0 commit comments