From 52044723cd27aed6dad655a3bdf6142a8239ce74 Mon Sep 17 00:00:00 2001 From: Christophe RICARD Date: Wed, 23 Dec 2015 23:25:34 +0100 Subject: [PATCH] ACPI / gpio: Add irq_type when a GPIO is used as an interrupt When a GPIO is used as an interrupt in ACPI, the irq_type was not available for device driver. Make available polarity and triggering information in acpi_find_gpio by renaming acpi_gpio_info field active_low to polarity and adding triggering field (edge/level). For sanity, in gpiolib.c replace info.active_low by "info.polarity == GPIO_ACTIVE_LOW". Set the irq_type if necessary in acpi_dev_gpio_irq_get. Signed-off-by: Christophe Ricard Acked-by: Mika Westerberg Signed-off-by: Rafael J. Wysocki --- drivers/gpio/gpiolib-acpi.c | 33 +++++++++++++++++++++++++++------ drivers/gpio/gpiolib.c | 4 ++-- drivers/gpio/gpiolib.h | 3 ++- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 16a7b6816744..cbbb67a6f1d6 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -417,10 +417,15 @@ static int acpi_find_gpio(struct acpi_resource *ares, void *data) * ActiveLow is only specified for GpioInt resource. If * GpioIo is used then the only way to set the flag is * to use _DSD "gpios" property. + * Note: we expect here: + * - ACPI_ACTIVE_LOW == GPIO_ACTIVE_LOW + * - ACPI_ACTIVE_HIGH == GPIO_ACTIVE_HIGH */ - if (lookup->info.gpioint) - lookup->info.active_low = - agpio->polarity == ACPI_ACTIVE_LOW; + if (lookup->info.gpioint) { + lookup->info.polarity = agpio->polarity; + lookup->info.triggering = agpio->triggering; + } + } return 1; @@ -447,7 +452,7 @@ static int acpi_gpio_resource_lookup(struct acpi_gpio_lookup *lookup, if (info) { *info = lookup->info; if (lookup->active_low) - info->active_low = lookup->active_low; + info->polarity = lookup->active_low; } return 0; } @@ -595,6 +600,7 @@ struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode, int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index) { int idx, i; + unsigned int irq_flags; for (i = 0, idx = 0; idx <= index; i++) { struct acpi_gpio_info info; @@ -603,8 +609,23 @@ int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index) desc = acpi_get_gpiod_by_index(adev, NULL, i, &info); if (IS_ERR(desc)) break; - if (info.gpioint && idx++ == index) - return gpiod_to_irq(desc); + if (info.gpioint && idx++ == index) { + int irq = gpiod_to_irq(desc); + + if (irq < 0) + return irq; + + irq_flags = acpi_dev_get_irq_type(info.triggering, + info.polarity); + + /* Set type if specified and different than the current one */ + if (irq_flags != IRQ_TYPE_NONE && + irq_flags != irq_get_trigger_type(irq)) + irq_set_irq_type(irq, irq_flags); + + return irq; + } + } return -ENOENT; } diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 4e4c3083ae56..5d8d7ab96916 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1879,7 +1879,7 @@ static struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id, return desc; } - if (info.active_low) + if (info.polarity == GPIO_ACTIVE_LOW) *flags |= GPIO_ACTIVE_LOW; return desc; @@ -2217,7 +2217,7 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, desc = acpi_node_get_gpiod(fwnode, propname, 0, &info); if (!IS_ERR(desc)) - active_low = info.active_low; + active_low = info.polarity == GPIO_ACTIVE_LOW; } if (IS_ERR(desc)) diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index 98ab08c0aa2d..5ac3b88a2e0a 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -26,7 +26,8 @@ struct acpi_device; */ struct acpi_gpio_info { bool gpioint; - bool active_low; + int polarity; + int triggering; }; /* gpio suffixes used for ACPI and device tree lookup */ -- 2.34.1