Skip to content

Commit

Permalink
gpio / ACPI: Move event handling registration to gpiolib irqchip helpers
Browse files Browse the repository at this point in the history
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 <mika.westerberg@linux.intel.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
  • Loading branch information
Mika Westerberg authored and Linus Walleij committed Jul 28, 2014
1 parent 7f87210 commit afa82fa
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 10 deletions.
38 changes: 28 additions & 10 deletions drivers/gpio/gpiolib-acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,19 +221,29 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,

/**
* 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
* chip's interrupt handler. acpi_gpiochip_request_interrupts finds out which
* 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->dev || !chip->to_irq)
return;

if (!chip->to_irq)
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);
Expand All @@ -243,17 +253,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->dev || !chip->to_irq)
return;

if (!chip->to_irq)
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) {
Expand Down Expand Up @@ -525,7 +545,6 @@ void acpi_gpiochip_add(struct gpio_chip *chip)
return;
}

acpi_gpiochip_request_interrupts(acpi_gpio);
acpi_gpiochip_request_regions(acpi_gpio);
}

Expand All @@ -549,7 +568,6 @@ void acpi_gpiochip_remove(struct gpio_chip *chip)
}

acpi_gpiochip_free_regions(acpi_gpio);
acpi_gpiochip_free_interrupts(acpi_gpio);

acpi_detach_data(handle, acpi_gpio_chip_dh);
kfree(acpi_gpio);
Expand Down
4 changes: 4 additions & 0 deletions drivers/gpio/gpiolib.c
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,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++)
Expand Down Expand Up @@ -612,6 +614,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);
Expand Down
9 changes: 9 additions & 0 deletions drivers/gpio/gpiolib.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,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)
Expand Down

0 comments on commit afa82fa

Please sign in to comment.