summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2022-02-23 14:31:50 +0100
committerHans de Goede <hdegoede@redhat.com>2022-03-02 11:43:45 +0100
commit7fa7dfafe40a75e93a5f59bcb4e382d0af436ace (patch)
treeb3b8f992e3b5d44a9e99d88c0b2e5fe05c71cbe4 /drivers
parentf97afae4d78097f7c854fa4890c6536582fd7e1e (diff)
downloadlinux-7fa7dfafe40a75e93a5f59bcb4e382d0af436ace.tar.bz2
platform/x86: x86-android-tablets: Fix EBUSY error when requesting IOAPIC IRQs
Sometimes IRQs used by GPIOs in direct-IRQ mode are already registered because they are used as ACPI "Interrupt () {}" resource for one of the many bogus I2C devices present in the broken DSDTs of Android x86 tablets. This is an issue if the existing (bogus) ACPI resource uses different trigger settings then what is being requested, leading to an -EBUSY error return of acpi_register_gsi(). Fix this by calling acpi_unregister_gsi() first, so that the acpi_register_gsi() is allowed to change the trigger settings. In cases where the GSI has not been registered yet the acpi_unregister_gsi() is a no-op. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Link: https://lore.kernel.org/r/20220223133153.730337-3-hdegoede@redhat.com
Diffstat (limited to 'drivers')
-rw-r--r--drivers/platform/x86/x86-android-tablets.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/platform/x86/x86-android-tablets.c b/drivers/platform/x86/x86-android-tablets.c
index f280c82d5ba5..61e526e048c3 100644
--- a/drivers/platform/x86/x86-android-tablets.c
+++ b/drivers/platform/x86/x86-android-tablets.c
@@ -89,6 +89,12 @@ static int x86_acpi_irq_helper_get(const struct x86_acpi_irq_data *data)
switch (data->type) {
case X86_ACPI_IRQ_TYPE_APIC:
+ /*
+ * The DSDT may already reference the GSI in a device skipped by
+ * acpi_quirk_skip_i2c_client_enumeration(). Unregister the GSI
+ * to avoid EBUSY errors in this case.
+ */
+ acpi_unregister_gsi(data->index);
irq = acpi_register_gsi(NULL, data->index, data->trigger, data->polarity);
if (irq < 0)
pr_err("error %d getting APIC IRQ %d\n", irq, data->index);