[PATCH 3/5] gpio/omap: Add DT support to GPIO driver
Jon Hunter
jon-hunter at ti.com
Tue Apr 16 17:57:02 EDT 2013
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 at ti.com>
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
More information about the linux-arm-kernel
mailing list