On 04/16/2013 02:27 PM, Jon Hunter wrote: ... > Right. In the DT case though, if someone does provide the IRQ and GPIO > IDs then at least they would use a different xlate function. Another > option to consider would be defining the #interrupt-cells = <3> where we > would have ... > > cell-#1 --> IRQ domain ID > cell-#2 --> Trigger type > cell-#3 --> GPIO ID > > Then we could have a generic xlate for 3 cells that would also request > the GPIO. Again not sure if people are against a gpio being requested in > the xlate but just an idea. Or given that irq_of_parse_and_map() calls > the xlate, we could have this function call gpio_request() if the > interrupt controller is a gpio and there are 3 cells. So basically some like the following (note I have only included the omap portion in here for an example). The other benefit being no need to re-introduce irq_to_gpio. Jon >From f01ce047075a922969fcbe904b339fe8d03a997b Mon Sep 17 00:00:00 2001 From: Jon Hunter <jon-hunter@xxxxxx> Date: Tue, 16 Apr 2013 09:54:28 -0500 Subject: [PATCH] gpio: add custom xlate for gpio irqs --- drivers/gpio/gpio-omap.c | 3 ++- drivers/gpio/gpiolib-of.c | 24 ++++++++++++++++++++++++ include/linux/of_gpio.h | 1 + 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index d337318..b3d7d43 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -24,6 +24,7 @@ #include <linux/pm.h> #include <linux/of.h> #include <linux/of_device.h> +#include <linux/of_gpio.h> #include <linux/irqdomain.h> #include <linux/gpio.h> #include <linux/platform_data/gpio-omap.h> @@ -1135,7 +1136,7 @@ static int omap_gpio_probe(struct platform_device *pdev) bank->domain = irq_domain_add_linear(node, bank->width, - &irq_domain_simple_ops, NULL); + &of_gpio_irq_domain_ops, NULL); if (!bank->domain) return -ENODEV; diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 5150df6..fc01ec1 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -15,6 +15,8 @@ #include <linux/errno.h> #include <linux/module.h> #include <linux/io.h> +#include <linux/irq.h> +#include <linux/irqdomain.h> #include <linux/gpio.h> #include <linux/of.h> #include <linux/of_address.h> @@ -253,3 +255,25 @@ void of_gpiochip_remove(struct gpio_chip *chip) if (chip->of_node) of_node_put(chip->of_node); } + +int of_gpio_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr, + const u32 *intspec, unsigned int intsize, + unsigned long *out_hwirq, unsigned int *out_type) +{ + int ret; + + if (WARN_ON(intsize < 3)) + return -EINVAL; + + ret = gpio_request_one(intspec[2], GPIOF_IN, NULL); + if (ret) + return ret; + + *out_hwirq = intspec[0]; + *out_type = (intsize > 1) ? intspec[1] : IRQ_TYPE_NONE; + return 0; +} + +const struct irq_domain_ops of_gpio_irq_domain_ops = { + .xlate = of_gpio_irq_domain_xlate, +}; diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h index a83dc6f..ad2b962 100644 --- a/include/linux/of_gpio.h +++ b/include/linux/of_gpio.h @@ -58,6 +58,7 @@ extern void of_gpiochip_remove(struct gpio_chip *gc); extern int of_gpio_simple_xlate(struct gpio_chip *gc, const struct of_phandle_args *gpiospec, u32 *flags); +extern const struct irq_domain_ops of_gpio_irq_domain_ops; #else /* CONFIG_OF_GPIO */ -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html