[OpenWrt-Devel] [PATCH] cns3xxx: Adopt irq_domain support for cns3xxx gpio driver

Pushpal Sidhu psidhu at gateworks.com
Tue Oct 7 20:25:11 EDT 2014


Have gpio driver adopt irqdomain support so that there are
non-overlapping allocations of irq numbers mapped to gpio's.

Signed-off-by: Pushpal Sidhu <psidhu at gateworks.com>
---
 .../cns3xxx/files/arch/arm/mach-cns3xxx/gpio.c     | 30 +++++++++++++++++-----
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/target/linux/cns3xxx/files/arch/arm/mach-cns3xxx/gpio.c b/target/linux/cns3xxx/files/arch/arm/mach-cns3xxx/gpio.c
index 35434f8..b6e4061 100644
--- a/target/linux/cns3xxx/files/arch/arm/mach-cns3xxx/gpio.c
+++ b/target/linux/cns3xxx/files/arch/arm/mach-cns3xxx/gpio.c
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/gpio.h>
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
 
 #include <asm/mach/irq.h>
 
@@ -45,9 +46,9 @@
 
 struct cns3xxx_gpio_chip {
 	struct gpio_chip    chip;
+	struct irq_domain   *domain;
 	spinlock_t          lock;
 	void __iomem        *base;
-	int                 secondary_irq_base;
 };
 
 static struct cns3xxx_gpio_chip cns3xxx_gpio_chips[2];
@@ -127,7 +128,7 @@ static int cns3xxx_gpio_to_irq(struct gpio_chip *chip, unsigned pin)
 	struct cns3xxx_gpio_chip *cchip =
 		container_of(chip, struct cns3xxx_gpio_chip, chip);
 
-	return cchip->secondary_irq_base + pin;
+	return irq_find_mapping(cchip->domain, pin);
 }
 
 
@@ -152,7 +153,7 @@ static void cns3xxx_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 	for (i = 0; i < 32; i++) {
 		if (reg & (1 << i)) {
 			/* let the generic IRQ layer handle an interrupt */
-			generic_handle_irq(cchip->secondary_irq_base + i);
+			generic_handle_irq(irq_find_mapping(cchip->domain, i));
 		}
 	}
 
@@ -163,7 +164,7 @@ static int cns3xxx_gpio_irq_set_type(struct irq_data *d, u32 irqtype)
 {
 	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
 	struct cns3xxx_gpio_chip *cchip = gc->private;
-	u32 gpio = d->irq - cchip->secondary_irq_base;
+	u32 gpio = d->hwirq;
 	unsigned long flags;
 	u32 method, edges, type;
 
@@ -224,6 +225,7 @@ void __init cns3xxx_gpio_init(int gpio_base, int ngpio,
 	struct irq_chip_generic *gc;
 	struct irq_chip_type *ct;
 	char gc_label[16];
+	int irq_base;
 
 	if (cns3xxx_gpio_chip_count == ARRAY_SIZE(cns3xxx_gpio_chips))
 		return;
@@ -243,7 +245,6 @@ void __init cns3xxx_gpio_init(int gpio_base, int ngpio,
 	cchip->chip.can_sleep = 0;
 	spin_lock_init(&cchip->lock);
 	cchip->base = (void __iomem *)base;
-	cchip->secondary_irq_base = secondary_irq_base;
 
 	BUG_ON(gpiochip_add(&cchip->chip) < 0);
 	cns3xxx_gpio_chip_count++;
@@ -251,11 +252,22 @@ void __init cns3xxx_gpio_init(int gpio_base, int ngpio,
 	/* clear GPIO interrupts */
 	__raw_writel(0xffff, cchip->base + GPIO_INTERRUPT_CLEAR);
 
+	irq_base = irq_alloc_descs(-1, secondary_irq_base, ngpio,
+		numa_node_id());
+	if (irq_base < 0)
+		goto out_irqdesc_free;
+
+	cchip->domain = irq_domain_add_legacy(NULL, ngpio, irq_base, 0,
+		&irq_domain_simple_ops, NULL);
+	if (!cchip->domain)
+		goto out_irqdesc_free;
+
 	/*
 	 * IRQ chip init
 	 */
-	gc = irq_alloc_generic_chip("cns3xxx_gpio_irq", 1, secondary_irq_base,
+	gc = irq_alloc_generic_chip("cns3xxx_gpio_irq", 1, irq_base,
 		cchip->base, handle_edge_irq);
+
 	gc->private = cchip;
 
 	ct = gc->chip_types;
@@ -270,7 +282,11 @@ void __init cns3xxx_gpio_init(int gpio_base, int ngpio,
 
 	irq_setup_generic_chip(gc, IRQ_MSK(ngpio), IRQ_GC_INIT_MASK_CACHE,
 		IRQ_NOREQUEST, 0);
-
 	irq_set_chained_handler(irq, cns3xxx_gpio_irq_handler);
 	irq_set_handler_data(irq, cchip);
+
+	return;
+
+out_irqdesc_free:
+	irq_free_descs(irq_base, ngpio);
 }
-- 
1.9.1
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list