Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gpio / ACPI: register to ACPI events automatically

Instead of asking each driver to register to ACPI events we can just call
acpi_gpiochip_register_interrupts() for each chip that has an ACPI handle.
The function checks chip->to_irq and if it is set to NULL (a GPIO driver
that doesn't do interrupts) the function does nothing.

We also add the a new header drivers/gpio/gpiolib.h that is used for
functions internal to gpiolib and add ACPI GPIO chip registering functions
to that header.

Once that is done we can remove call to acpi_gpiochip_register_interrupts()
from its only user, pinctrl-baytrail.c

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Mika Westerberg and committed by
Linus Walleij
664e3e5a 87875655

+39 -14
+12 -4
drivers/gpio/gpiolib-acpi.c
··· 94 94 * gpio pins have acpi event methods and assigns interrupt handlers that calls 95 95 * the acpi event methods for those pins. 96 96 */ 97 - void acpi_gpiochip_request_interrupts(struct gpio_chip *chip) 97 + static void acpi_gpiochip_request_interrupts(struct gpio_chip *chip) 98 98 { 99 99 struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL}; 100 100 struct acpi_resource *res; ··· 192 192 irq); 193 193 } 194 194 } 195 - EXPORT_SYMBOL(acpi_gpiochip_request_interrupts); 196 195 197 196 /** 198 197 * acpi_gpiochip_free_interrupts() - Free GPIO _EVT ACPI event interrupts. ··· 202 203 * The remaining ACPI event interrupts associated with the chip are freed 203 204 * automatically. 204 205 */ 205 - void acpi_gpiochip_free_interrupts(struct gpio_chip *chip) 206 + static void acpi_gpiochip_free_interrupts(struct gpio_chip *chip) 206 207 { 207 208 acpi_handle handle; 208 209 acpi_status status; ··· 229 230 acpi_detach_data(handle, acpi_gpio_evt_dh); 230 231 kfree(evt_pins); 231 232 } 232 - EXPORT_SYMBOL(acpi_gpiochip_free_interrupts); 233 233 234 234 struct acpi_gpio_lookup { 235 235 struct acpi_gpio_info info; ··· 308 310 return lookup.desc ? lookup.desc : ERR_PTR(-ENOENT); 309 311 } 310 312 EXPORT_SYMBOL_GPL(acpi_get_gpiod_by_index); 313 + 314 + void acpi_gpiochip_add(struct gpio_chip *chip) 315 + { 316 + acpi_gpiochip_request_interrupts(chip); 317 + } 318 + 319 + void acpi_gpiochip_remove(struct gpio_chip *chip) 320 + { 321 + acpi_gpiochip_free_interrupts(chip); 322 + }
+4
drivers/gpio/gpiolib.c
··· 16 16 #include <linux/acpi.h> 17 17 #include <linux/gpio/driver.h> 18 18 19 + #include "gpiolib.h" 20 + 19 21 #define CREATE_TRACE_POINTS 20 22 #include <trace/events/gpio.h> 21 23 ··· 1228 1226 #endif 1229 1227 1230 1228 of_gpiochip_add(chip); 1229 + acpi_gpiochip_add(chip); 1231 1230 1232 1231 if (status) 1233 1232 goto fail; ··· 1270 1267 1271 1268 gpiochip_remove_pin_ranges(chip); 1272 1269 of_gpiochip_remove(chip); 1270 + acpi_gpiochip_remove(chip); 1273 1271 1274 1272 for (id = 0; id < chip->ngpio; id++) { 1275 1273 if (test_bit(FLAG_REQUESTED, &chip->desc[id].flags)) {
+23
drivers/gpio/gpiolib.h
··· 1 + /* 2 + * Internal GPIO functions. 3 + * 4 + * Copyright (C) 2013, Intel Corporation 5 + * Author: Mika Westerberg <mika.westerberg@linux.intel.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 as 9 + * published by the Free Software Foundation. 10 + */ 11 + 12 + #ifndef GPIOLIB_H 13 + #define GPIOLIB_H 14 + 15 + #ifdef CONFIG_ACPI 16 + void acpi_gpiochip_add(struct gpio_chip *chip); 17 + void acpi_gpiochip_remove(struct gpio_chip *chip); 18 + #else 19 + static inline void acpi_gpiochip_add(struct gpio_chip *chip) { } 20 + static inline void acpi_gpiochip_remove(struct gpio_chip *chip) { } 21 + #endif 22 + 23 + #endif /* GPIOLIB_H */
-4
drivers/pinctrl/pinctrl-baytrail.c
··· 29 29 #include <linux/gpio.h> 30 30 #include <linux/irqdomain.h> 31 31 #include <linux/acpi.h> 32 - #include <linux/acpi_gpio.h> 33 32 #include <linux/platform_device.h> 34 33 #include <linux/seq_file.h> 35 34 #include <linux/io.h> ··· 484 485 485 486 irq_set_handler_data(hwirq, vg); 486 487 irq_set_chained_handler(hwirq, byt_gpio_irq_handler); 487 - 488 - /* Register interrupt handlers for gpio signaled acpi events */ 489 - acpi_gpiochip_request_interrupts(gc); 490 488 } 491 489 492 490 pm_runtime_enable(dev);
-6
include/linux/acpi_gpio.h
··· 21 21 22 22 struct gpio_desc *acpi_get_gpiod_by_index(struct device *dev, int index, 23 23 struct acpi_gpio_info *info); 24 - void acpi_gpiochip_request_interrupts(struct gpio_chip *chip); 25 - void acpi_gpiochip_free_interrupts(struct gpio_chip *chip); 26 - 27 24 #else /* CONFIG_GPIO_ACPI */ 28 25 29 26 static inline struct gpio_desc * ··· 29 32 { 30 33 return ERR_PTR(-ENOSYS); 31 34 } 32 - 33 - static inline void acpi_gpiochip_request_interrupts(struct gpio_chip *chip) { } 34 - static inline void acpi_gpiochip_free_interrupts(struct gpio_chip *chip) { } 35 35 36 36 #endif /* CONFIG_GPIO_ACPI */ 37 37