gpiolib: acpi: Check if a GPIO is listed in ignore_interrupt earlier
authorHans de Goede <hdegoede@redhat.com>
Sat, 9 Sep 2023 14:18:09 +0000 (16:18 +0200)
committerHans de Goede <hdegoede@redhat.com>
Mon, 11 Sep 2023 11:28:25 +0000 (13:28 +0200)
In some cases where a broken AEI is present for a GPIO and the GPIO
is listed in the ignore_interrupt list to avoid the broken event
handler, the kernel may want to use the GPIO for another purpose.

Before this change trying to use such a GPIO for another purpose would
fail, because the ignore_interrupt list was only checked after
the acpi_request_own_gpiod() call, causing the GPIO to already be
claimed even though it is listed in the ignore_interrupt list.

Fix this by moving the ignore_interrupt list to above
the acpi_request_own_gpiod() call.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Link: https://lore.kernel.org/r/20230909141816.58358-2-hdegoede@redhat.com
drivers/gpio/gpiolib-acpi.c

index fbda452fb4d6afd4154d4f9e219b3b0cfb434e1a..874b4025841b72e655f989c4c24dff542bf1a57e 100644 (file)
@@ -437,6 +437,11 @@ static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares,
        if (!handler)
                return AE_OK;
 
+       if (acpi_gpio_in_ignore_list(ignore_interrupt, dev_name(chip->parent), pin)) {
+               dev_info(chip->parent, "Ignoring interrupt on pin %u\n", pin);
+               return AE_OK;
+       }
+
        desc = acpi_request_own_gpiod(chip, agpio, 0, "ACPI:Event");
        if (IS_ERR(desc)) {
                dev_err(chip->parent,
@@ -461,11 +466,6 @@ static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares,
                goto fail_unlock_irq;
        }
 
-       if (acpi_gpio_in_ignore_list(ignore_interrupt, dev_name(chip->parent), pin)) {
-               dev_info(chip->parent, "Ignoring interrupt on pin %u\n", pin);
-               return AE_OK;
-       }
-
        event = kzalloc(sizeof(*event), GFP_KERNEL);
        if (!event)
                goto fail_unlock_irq;