12
12
#include <linux/acpi.h>
13
13
#include <linux/pci.h>
14
14
#include <linux/usb/hcd.h>
15
+ #include <linux/dmi.h>
15
16
16
17
#include "hub.h"
17
18
@@ -142,6 +143,19 @@ int usb_acpi_set_power_state(struct usb_device *hdev, int index, bool enable)
142
143
}
143
144
EXPORT_SYMBOL_GPL (usb_acpi_set_power_state );
144
145
146
+ static const struct dmi_system_id intel_icl_broken_acpi [] = {
147
+ {
148
+ .ident = "ICL RVP" ,
149
+ .matches = {
150
+ DMI_MATCH (DMI_SYS_VENDOR , "Intel Corporation" ),
151
+ DMI_MATCH (DMI_PRODUCT_NAME , "Ice Lake Client Platform" ),
152
+ },
153
+ },
154
+
155
+ { }
156
+ };
157
+ static bool acpi_connection_type_broken ;
158
+
145
159
/*
146
160
* Private to usb-acpi, all the core needs to know is that
147
161
* port_dev->location is non-zero when it has been set by the firmware.
@@ -157,6 +171,12 @@ usb_acpi_get_connect_type(struct usb_port *port_dev, acpi_handle *handle)
157
171
struct acpi_pld_info * pld = NULL ;
158
172
acpi_status status ;
159
173
174
+ /* Work around unknown ACPI instruction error on ICL RVP BIOSes. */
175
+ if (acpi_connection_type_broken ) {
176
+ port_dev -> connect_type = USB_PORT_CONNECT_TYPE_UNKNOWN ;
177
+ return ;
178
+ }
179
+
160
180
/*
161
181
* According to 9.14 in ACPI Spec 6.2. _PLD indicates whether usb port
162
182
* is user visible and _UPC indicates whether it is connectable. If
@@ -321,6 +341,11 @@ static struct acpi_bus_type usb_acpi_bus = {
321
341
322
342
int usb_acpi_register (void )
323
343
{
344
+ if (dmi_check_system (intel_icl_broken_acpi )) {
345
+ pr_info ("USB ACPI connection type broken.\n" );
346
+ acpi_connection_type_broken = true;
347
+ }
348
+
324
349
return register_acpi_bus_type (& usb_acpi_bus );
325
350
}
326
351
0 commit comments