Skip to content

Commit 5adc409

Browse files
jwrdegoederafaeljw
authored andcommitted
ACPI: x86: Introduce an acpi_quirk_skip_gpio_event_handlers() helper
x86 ACPI boards which ship with only Android as their factory image usually have pretty broken ACPI tables, relying on everything being hardcoded in the factory kernel image and often disabling parts of the ACPI enumeration kernel code to avoid the broken tables causing issues. Part of this broken ACPI code is that sometimes these boards have _AEI ACPI GPIO event handlers which are broken. So far this has been dealt with in the platform/x86/x86-android-tablets.c module, which contains various workarounds for these devices, by it calling acpi_gpiochip_free_interrupts() on gpiochip-s with troublesome handlers to disable the handlers. But in some cases this is too late, if the handlers are of the edge type then gpiolib-acpi.c's code will already have run them at boot. This can cause issues such as GPIOs ending up as owned by "ACPI:OpRegion", making them unavailable for drivers which actually need them. Boards with these broken ACPI tables are already listed in drivers/acpi/x86/utils.c for e.g. acpi_quirk_skip_i2c_client_enumeration(). Extend the quirks mechanism for a new acpi_quirk_skip_gpio_event_handlers() helper, this re-uses the DMI-ids rather then having to duplicate the same DMI table in gpiolib-acpi.c . Also add the new ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS quirk to existing boards with troublesome ACPI gpio event handlers, so that the current acpi_gpiochip_free_interrupts() hack can be removed from x86-android-tablets.c . Signed-off-by: Hans de Goede <[email protected]> Acked-by: Andy Shevchenko <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent fe15c26 commit 5adc409

File tree

3 files changed

+29
-3
lines changed

3 files changed

+29
-3
lines changed

drivers/acpi/x86/utils.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ bool force_storage_d3(void)
251251
#define ACPI_QUIRK_UART1_TTY_UART2_SKIP BIT(1)
252252
#define ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY BIT(2)
253253
#define ACPI_QUIRK_USE_ACPI_AC_AND_BATTERY BIT(3)
254+
#define ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS BIT(4)
254255

255256
static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {
256257
/*
@@ -286,15 +287,17 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {
286287
},
287288
.driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
288289
ACPI_QUIRK_UART1_TTY_UART2_SKIP |
289-
ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
290+
ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY |
291+
ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS),
290292
},
291293
{
292294
.matches = {
293295
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
294296
DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"),
295297
},
296298
.driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
297-
ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
299+
ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY |
300+
ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS),
298301
},
299302
{
300303
/* Lenovo Yoga Tablet 2 1050F/L */
@@ -336,7 +339,8 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {
336339
DMI_MATCH(DMI_PRODUCT_NAME, "M890BAP"),
337340
},
338341
.driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
339-
ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
342+
ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY |
343+
ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS),
340344
},
341345
{
342346
/* Whitelabel (sold as various brands) TM800A550L */
@@ -413,6 +417,20 @@ int acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *s
413417
return 0;
414418
}
415419
EXPORT_SYMBOL_GPL(acpi_quirk_skip_serdev_enumeration);
420+
421+
bool acpi_quirk_skip_gpio_event_handlers(void)
422+
{
423+
const struct dmi_system_id *dmi_id;
424+
long quirks;
425+
426+
dmi_id = dmi_first_match(acpi_quirk_skip_dmi_ids);
427+
if (!dmi_id)
428+
return false;
429+
430+
quirks = (unsigned long)dmi_id->driver_data;
431+
return (quirks & ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS);
432+
}
433+
EXPORT_SYMBOL_GPL(acpi_quirk_skip_gpio_event_handlers);
416434
#endif
417435

418436
/* Lists of PMIC ACPI HIDs with an (often better) native charger driver */

drivers/gpio/gpiolib-acpi.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,9 @@ void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
536536
if (ACPI_FAILURE(status))
537537
return;
538538

539+
if (acpi_quirk_skip_gpio_event_handlers())
540+
return;
541+
539542
acpi_walk_resources(handle, METHOD_NAME__AEI,
540543
acpi_gpiochip_alloc_event, acpi_gpio);
541544

include/acpi/acpi_bus.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,7 @@ static inline bool acpi_quirk_skip_acpi_ac_and_battery(void)
657657
#if IS_ENABLED(CONFIG_X86_ANDROID_TABLETS)
658658
bool acpi_quirk_skip_i2c_client_enumeration(struct acpi_device *adev);
659659
int acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *skip);
660+
bool acpi_quirk_skip_gpio_event_handlers(void);
660661
#else
661662
static inline bool acpi_quirk_skip_i2c_client_enumeration(struct acpi_device *adev)
662663
{
@@ -668,6 +669,10 @@ acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *skip)
668669
*skip = false;
669670
return 0;
670671
}
672+
static inline bool acpi_quirk_skip_gpio_event_handlers(void)
673+
{
674+
return false;
675+
}
671676
#endif
672677

673678
#ifdef CONFIG_PM

0 commit comments

Comments
 (0)