From 4d5b94cf653c862ce904064b4218496d8a103bed Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Fri, 25 Jul 2014 09:54:48 +0300 Subject: [PATCH] BACKPORT: gpio / ACPI: Move event handling registration to gpiolib irqchip helpers Since now we have irqchip helpers that the GPIO chip drivers are supposed to use if possible, we can move the registration of ACPI events to happen in these helpers. This seems to be more natural place and might encourage GPIO chip driver writers to take advantage of the irqchip helpers. We make the functions available to GPIO chip drivers via private gpiolib.h, just in case generic irqchip helpers are not suitable. Signed-off-by: Mika Westerberg Signed-off-by: Linus Walleij (cherry picked from commit afa82fab5e136fc64eaf26db9b00c661286e1762) [abrestic: fixed conflict due to introduction of ACPI GPIO operating regions upstream] Signed-off-by: Andrew Bresticker BUG=chrome-os-partner:30840 TEST=builds Change-Id: I12288d5bd8f4b4c69c086341695210bfe709265e Reviewed-on: https://chromium-review.googlesource.com/238912 Reviewed-by: Olof Johansson Tested-by: Andrew Bresticker Commit-Queue: Andrew Bresticker --- drivers/gpio/gpiolib-acpi.c | 36 ++++++++++++++++++++++++++++-------- drivers/gpio/gpiolib.c | 4 ++++ drivers/gpio/gpiolib.h | 9 +++++++++ 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index c758b4daf92b..8c7c65540b7c 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -207,7 +207,7 @@ fail_free_desc: /** * acpi_gpiochip_request_interrupts() - Register isr for gpio chip ACPI events - * @acpi_gpio: ACPI GPIO chip + * @chip: GPIO chip * * ACPI5 platforms can use GPIO signaled ACPI events. These GPIO interrupts are * handled by ACPI event methods which need to be called from the GPIO @@ -215,11 +215,21 @@ fail_free_desc: * gpio pins have acpi event methods and assigns interrupt handlers that calls * the acpi event methods for those pins. */ -static void acpi_gpiochip_request_interrupts(struct acpi_gpio_chip *acpi_gpio) +void acpi_gpiochip_request_interrupts(struct gpio_chip *chip) { - struct gpio_chip *chip = acpi_gpio->chip; + struct acpi_gpio_chip *acpi_gpio; + acpi_handle handle; + acpi_status status; - if (!chip->to_irq) + if (!chip->dev || !chip->to_irq) + return; + + handle = ACPI_HANDLE(chip->dev); + if (!handle) + return; + + status = acpi_get_data(handle, acpi_gpio_chip_dh, (void **)&acpi_gpio); + if (ACPI_FAILURE(status)) return; INIT_LIST_HEAD(&acpi_gpio->events); @@ -229,17 +239,27 @@ static void acpi_gpiochip_request_interrupts(struct acpi_gpio_chip *acpi_gpio) /** * acpi_gpiochip_free_interrupts() - Free GPIO ACPI event interrupts. - * @acpi_gpio: ACPI GPIO chip + * @chip: GPIO chip * * Free interrupts associated with GPIO ACPI event method for the given * GPIO chip. */ -static void acpi_gpiochip_free_interrupts(struct acpi_gpio_chip *acpi_gpio) +void acpi_gpiochip_free_interrupts(struct gpio_chip *chip) { + struct acpi_gpio_chip *acpi_gpio; struct acpi_gpio_event *event, *ep; - struct gpio_chip *chip = acpi_gpio->chip; + acpi_handle handle; + acpi_status status; - if (!chip->to_irq) + if (!chip->dev || !chip->to_irq) + return; + + handle = ACPI_HANDLE(chip->dev); + if (!handle) + return; + + status = acpi_get_data(handle, acpi_gpio_chip_dh, (void **)&acpi_gpio); + if (ACPI_FAILURE(status)) return; list_for_each_entry_safe_reverse(event, ep, &acpi_gpio->events, node) { diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index d5c14744c127..2017734affaa 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1474,6 +1474,8 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) { unsigned int offset; + acpi_gpiochip_free_interrupts(gpiochip); + /* Remove all IRQ mappings and delete the domain */ if (gpiochip->irqdomain) { for (offset = 0; offset < gpiochip->ngpio; offset++) @@ -1567,6 +1569,8 @@ int gpiochip_irqchip_add(struct gpio_chip *gpiochip, gpiochip->irq_base = irq_base; } + acpi_gpiochip_request_interrupts(gpiochip); + return 0; } EXPORT_SYMBOL_GPL(gpiochip_irqchip_add); diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index cf092941a9fd..3b9ac1ed038c 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -29,12 +29,21 @@ struct acpi_gpio_info { void acpi_gpiochip_add(struct gpio_chip *chip); void acpi_gpiochip_remove(struct gpio_chip *chip); +void acpi_gpiochip_request_interrupts(struct gpio_chip *chip); +void acpi_gpiochip_free_interrupts(struct gpio_chip *chip); + struct gpio_desc *acpi_get_gpiod_by_index(struct device *dev, int index, struct acpi_gpio_info *info); #else static inline void acpi_gpiochip_add(struct gpio_chip *chip) { } static inline void acpi_gpiochip_remove(struct gpio_chip *chip) { } +static inline void +acpi_gpiochip_request_interrupts(struct gpio_chip *chip) { } + +static inline void +acpi_gpiochip_free_interrupts(struct gpio_chip *chip) { } + static inline struct gpio_desc * acpi_get_gpiod_by_index(struct device *dev, int index, struct acpi_gpio_info *info)