|
@@ -21,6 +21,7 @@
|
|
|
*
|
|
|
*/
|
|
|
|
|
|
+#include <linux/dmi.h>
|
|
|
#include <linux/module.h>
|
|
|
#include <linux/usb.h>
|
|
|
#include <linux/usb/quirks.h>
|
|
@@ -379,6 +380,21 @@ static const struct usb_device_id blacklist_table[] = {
|
|
|
{ } /* Terminating entry */
|
|
|
};
|
|
|
|
|
|
+/* The Bluetooth USB module build into some devices needs to be reset on resume,
|
|
|
+ * this is a problem with the platform (likely shutting off all power) not with
|
|
|
+ * the module itself. So we use a DMI list to match known broken platforms.
|
|
|
+ */
|
|
|
+static const struct dmi_system_id btusb_needs_reset_resume_table[] = {
|
|
|
+ {
|
|
|
+ /* Lenovo Yoga 920 (QCA Rome device 0cf3:e300) */
|
|
|
+ .matches = {
|
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
|
|
+ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 920"),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {}
|
|
|
+};
|
|
|
+
|
|
|
#define BTUSB_MAX_ISOC_FRAMES 10
|
|
|
|
|
|
#define BTUSB_INTR_RUNNING 0
|
|
@@ -2945,6 +2961,9 @@ static int btusb_probe(struct usb_interface *intf,
|
|
|
hdev->send = btusb_send_frame;
|
|
|
hdev->notify = btusb_notify;
|
|
|
|
|
|
+ if (dmi_check_system(btusb_needs_reset_resume_table))
|
|
|
+ interface_to_usbdev(intf)->quirks |= USB_QUIRK_RESET_RESUME;
|
|
|
+
|
|
|
#ifdef CONFIG_PM
|
|
|
err = btusb_config_oob_wake(hdev);
|
|
|
if (err)
|
|
@@ -3031,12 +3050,6 @@ static int btusb_probe(struct usb_interface *intf,
|
|
|
if (id->driver_info & BTUSB_QCA_ROME) {
|
|
|
data->setup_on_usb = btusb_setup_qca;
|
|
|
hdev->set_bdaddr = btusb_set_bdaddr_ath3012;
|
|
|
-
|
|
|
- /* QCA Rome devices lose their updated firmware over suspend,
|
|
|
- * but the USB hub doesn't notice any status change.
|
|
|
- * explicitly request a device reset on resume.
|
|
|
- */
|
|
|
- interface_to_usbdev(intf)->quirks |= USB_QUIRK_RESET_RESUME;
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_BT_HCIBTUSB_RTL
|