aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKai-Chuan Hsieh <kai.chiuan@gmail.com>2017-04-04 15:32:36 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-04-12 06:41:22 -0400
commit71f38c11cdb87f0372cbedb599c08d7915fdd448 (patch)
treef4178dba89d8efb24d447480697b366a27b46c59
parent4dc1eb47fbea4018715f017ff83b77e1a8d79f62 (diff)
platform/x86: asus-wmi: Set specified XUSB2PR value for X550LB
[ Upstream commit 8023eff10e7b0327898f17f0b553d2e45c71cef3 ] The bluetooth adapter Atheros AR3012 can't be enumerated and make the bluetooth function broken. T: Bus=02 Lev=01 Prnt=01 Port=05 Cnt=02 Dev#= 5 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=13d3 ProdID=3362 Rev=00.02 S: Manufacturer=Atheros Communications S: Product=Bluetooth USB Host Controller S: SerialNumber=Alaska Day 2006 C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb The error is: usb 2-6: device not accepting address 7, error -62 usb usb2-port6: unable to enumerate USB device It is caused by adapter's connected port is mapped to xHC controller, but the xHCI is not supported by the usb device. The output of 'sudo lspci -nnxxx -s 00:14.0': 00:14.0 USB controller [0c03]: Intel Corporation 8 Series USB xHCI HC [8086:9c31] (rev 04) 00: 86 80 31 9c 06 04 90 02 04 30 03 0c 00 00 00 00 10: 04 00 a0 f7 00 00 00 00 00 00 00 00 00 00 00 00 20: 00 00 00 00 00 00 00 00 00 00 00 00 43 10 1f 20 30: 00 00 00 00 70 00 00 00 00 00 00 00 0b 01 00 00 40: fd 01 36 80 89 c6 0f 80 00 00 00 00 00 00 00 00 50: 5f 2e ce 0f 00 00 00 00 00 00 00 00 00 00 00 00 60: 30 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 70: 01 80 c2 c1 08 00 00 00 00 00 00 00 00 00 00 00 80: 05 00 87 00 0c a0 e0 fe 00 00 00 00 a1 41 00 00 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a0: 00 01 04 00 00 00 00 00 00 00 00 00 00 00 00 00 b0: 0f 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 c0: 03 c0 30 00 00 00 00 00 03 0c 00 00 00 00 00 00 d0: f9 01 00 00 f9 01 00 00 0f 00 00 00 0f 00 00 00 e0: 00 08 00 00 00 00 00 00 00 00 00 00 d8 d8 00 00 f0: 00 00 00 00 00 00 00 00 b1 0f 04 08 00 00 00 00 By referencing Intel Platform Controller Hub(PCH) datasheet, the xHC USB 2.0 Port Routing(XUSB2PR) at offset 0xD0-0xD3h decides the setting of mapping the port to EHCI controller or xHC controller. And the port mapped to xHC will enable xHCI during bus resume. The setting of disabling bluetooth adapter's connected port is 0x000001D9. The value can be obtained by few times 1 bit flip operation. The suited configuration should have the 'lsusb -t' result with bluetooth using ehci: /: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M /: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/9p, 480M |__ Port 5: Dev 2, If 0, Class=Video, Driver=uvcvideo, 480M |__ Port 5: Dev 2, If 1, Class=Video, Driver=uvcvideo, 480M /: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/2p, 480M |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/8p, 480M |__ Port 6: Dev 3, If 0, Class=Wireless, Driver=btusb, 12M |__ Port 6: Dev 3, If 1, Class=Wireless, Driver=btusb, 12M Signed-off-by: Kai-Chuan Hsieh <kai.chiuan@gmail.com> Acked-by: Corentin Chary <corentin.chary@gmail.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> [andy: resolve merge conflict in asus-wmi.h] Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Sasha Levin <alexander.levin@verizon.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/platform/x86/asus-nb-wmi.c13
-rw-r--r--drivers/platform/x86/asus-wmi.c29
-rw-r--r--drivers/platform/x86/asus-wmi.h1
3 files changed, 43 insertions, 0 deletions
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index 6032b7085582..6eb2837f6b89 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -116,6 +116,10 @@ static struct quirk_entry quirk_asus_ux303ub = {
116 .wmi_backlight_native = true, 116 .wmi_backlight_native = true,
117}; 117};
118 118
119static struct quirk_entry quirk_asus_x550lb = {
120 .xusb2pr = 0x01D9,
121};
122
119static int dmi_matched(const struct dmi_system_id *dmi) 123static int dmi_matched(const struct dmi_system_id *dmi)
120{ 124{
121 quirks = dmi->driver_data; 125 quirks = dmi->driver_data;
@@ -407,6 +411,15 @@ static const struct dmi_system_id asus_quirks[] = {
407 }, 411 },
408 .driver_data = &quirk_asus_ux303ub, 412 .driver_data = &quirk_asus_ux303ub,
409 }, 413 },
414 {
415 .callback = dmi_matched,
416 .ident = "ASUSTeK COMPUTER INC. X550LB",
417 .matches = {
418 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
419 DMI_MATCH(DMI_PRODUCT_NAME, "X550LB"),
420 },
421 .driver_data = &quirk_asus_x550lb,
422 },
410 {}, 423 {},
411}; 424};
412 425
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index ce6ca31a2d09..43cb680adbb4 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -156,6 +156,9 @@ MODULE_LICENSE("GPL");
156#define ASUS_FAN_CTRL_MANUAL 1 156#define ASUS_FAN_CTRL_MANUAL 1
157#define ASUS_FAN_CTRL_AUTO 2 157#define ASUS_FAN_CTRL_AUTO 2
158 158
159#define USB_INTEL_XUSB2PR 0xD0
160#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31
161
159struct bios_args { 162struct bios_args {
160 u32 arg0; 163 u32 arg0;
161 u32 arg1; 164 u32 arg1;
@@ -1080,6 +1083,29 @@ exit:
1080 return result; 1083 return result;
1081} 1084}
1082 1085
1086static void asus_wmi_set_xusb2pr(struct asus_wmi *asus)
1087{
1088 struct pci_dev *xhci_pdev;
1089 u32 orig_ports_available;
1090 u32 ports_available = asus->driver->quirks->xusb2pr;
1091
1092 xhci_pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
1093 PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI,
1094 NULL);
1095
1096 if (!xhci_pdev)
1097 return;
1098
1099 pci_read_config_dword(xhci_pdev, USB_INTEL_XUSB2PR,
1100 &orig_ports_available);
1101
1102 pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR,
1103 cpu_to_le32(ports_available));
1104
1105 pr_info("set USB_INTEL_XUSB2PR old: 0x%04x, new: 0x%04x\n",
1106 orig_ports_available, ports_available);
1107}
1108
1083/* 1109/*
1084 * Hwmon device 1110 * Hwmon device
1085 */ 1111 */
@@ -2087,6 +2113,9 @@ static int asus_wmi_add(struct platform_device *pdev)
2087 if (asus->driver->quirks->wmi_backlight_native) 2113 if (asus->driver->quirks->wmi_backlight_native)
2088 acpi_video_set_dmi_backlight_type(acpi_backlight_native); 2114 acpi_video_set_dmi_backlight_type(acpi_backlight_native);
2089 2115
2116 if (asus->driver->quirks->xusb2pr)
2117 asus_wmi_set_xusb2pr(asus);
2118
2090 if (acpi_video_get_backlight_type() == acpi_backlight_vendor) { 2119 if (acpi_video_get_backlight_type() == acpi_backlight_vendor) {
2091 err = asus_wmi_backlight_init(asus); 2120 err = asus_wmi_backlight_init(asus);
2092 if (err && err != -ENODEV) 2121 if (err && err != -ENODEV)
diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h
index 0e19014e9f54..fdff626c3b51 100644
--- a/drivers/platform/x86/asus-wmi.h
+++ b/drivers/platform/x86/asus-wmi.h
@@ -53,6 +53,7 @@ struct quirk_entry {
53 * and let the ACPI interrupt to send out the key event. 53 * and let the ACPI interrupt to send out the key event.
54 */ 54 */
55 int no_display_toggle; 55 int no_display_toggle;
56 u32 xusb2pr;
56 57
57 bool (*i8042_filter)(unsigned char data, unsigned char str, 58 bool (*i8042_filter)(unsigned char data, unsigned char str,
58 struct serio *serio); 59 struct serio *serio);