]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/gpio/gpiolib-acpi.c
Merge remote-tracking branch 'pm/linux-next'
[karo-tx-linux.git] / drivers / gpio / gpiolib-acpi.c
index 69a83626f1aed1ef78bbd6c25a2ffe3208d69274..16a7b68167444bba93e24d3d59769f0a08d55440 100644 (file)
@@ -304,7 +304,6 @@ void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
        if (ACPI_FAILURE(status))
                return;
 
-       INIT_LIST_HEAD(&acpi_gpio->events);
        acpi_walk_resources(handle, "_AEI",
                            acpi_gpiochip_request_interrupt, acpi_gpio);
 }
@@ -668,6 +667,25 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
                                break;
                        }
                }
+
+               /*
+                * The same GPIO can be shared between operation region and
+                * event but only if the access here is ACPI_READ. In that
+                * case we "borrow" the event GPIO instead.
+                */
+               if (!found && agpio->sharable == ACPI_SHARED &&
+                    function == ACPI_READ) {
+                       struct acpi_gpio_event *event;
+
+                       list_for_each_entry(event, &achip->events, node) {
+                               if (event->pin == pin) {
+                                       desc = event->desc;
+                                       found = true;
+                                       break;
+                               }
+                       }
+               }
+
                if (!found) {
                        desc = gpiochip_request_own_desc(chip, pin,
                                                         "ACPI:OpRegion");
@@ -784,6 +802,7 @@ void acpi_gpiochip_add(struct gpio_chip *chip)
        }
 
        acpi_gpio->chip = chip;
+       INIT_LIST_HEAD(&acpi_gpio->events);
 
        status = acpi_attach_data(handle, acpi_gpio_chip_dh, acpi_gpio);
        if (ACPI_FAILURE(status)) {