Added muxed support for the EMIF controller's interrupts
IRQ_EMIF_EMWAIT_TIMEOUT
IRQ_EMIF_EMWAIT_RISE
This will enable nand erase to be interrupt driven.
Added non-muxed low gpio interrupt support
Moved/independently wrote muxed gpio interrupts from gpio.c to irq.c
I didn't look at the moved gpio.c code too closely so
this needs more testing before applying

Signed-off-by: Troy Kisky <[EMAIL PROTECTED]>
---
 arch/arm/mach-davinci/gpio.c        |  128 -------------
 arch/arm/mach-davinci/irq.c         |  353 +++++++++++++++++++++++++++++------
 include/asm-arm/arch-davinci/gpio.h |    5 +-
 include/asm-arm/arch-davinci/irqs.h |   12 +-
 4 files changed, 311 insertions(+), 187 deletions(-)
 mode change 100644 => 100755 arch/arm/mach-davinci/irq.c

diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c
index cb7b607..665fc2a 100644
--- a/arch/arm/mach-davinci/gpio.c
+++ b/arch/arm/mach-davinci/gpio.c
@@ -130,103 +130,6 @@ int gpio_direction_output(unsigned gpio, int value)
 }
 EXPORT_SYMBOL(gpio_direction_output);
 
-/*
- * We expect irqs will normally be set up as input pins, but they can also be
- * used as output pins ... which is convenient for testing.
- *
- * NOTE:  GPIO0..GPIO7 also have direct INTC hookups, which work in addition
- * to their GPIOBNK0 irq (but with a bit less overhead).  But we don't have
- * a good way to hook those up ...
- *
- * All those INTC hookups (GPIO0..GPIO7 plus five IRQ banks) can also
- * serve as EDMA event triggers.
- */
-
-static void gpio_irq_disable(unsigned irq)
-{
-       struct gpio_controller *__iomem g = get_irq_chip_data(irq);
-       u32 mask = __gpio_mask(irq_to_gpio(irq));
-
-       __raw_writel(mask, &g->clr_falling);
-       __raw_writel(mask, &g->clr_rising);
-}
-
-static void gpio_irq_enable(unsigned irq)
-{
-       struct gpio_controller *__iomem g = get_irq_chip_data(irq);
-       u32 mask = __gpio_mask(irq_to_gpio(irq));
-
-       if (irq_desc[irq].status & IRQ_TYPE_EDGE_FALLING)
-               __raw_writel(mask, &g->set_falling);
-       if (irq_desc[irq].status & IRQ_TYPE_EDGE_RISING)
-               __raw_writel(mask, &g->set_rising);
-}
-
-static int gpio_irq_type(unsigned irq, unsigned trigger)
-{
-       struct gpio_controller *__iomem g = get_irq_chip_data(irq);
-       u32 mask = __gpio_mask(irq_to_gpio(irq));
-
-       if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
-               return -EINVAL;
-
-       irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK;
-       irq_desc[irq].status |= trigger;
-
-       __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING)
-                    ? &g->set_falling : &g->clr_falling);
-       __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING)
-                    ? &g->set_rising : &g->clr_rising);
-       return 0;
-}
-
-static struct irq_chip gpio_irqchip = {
-       .name           = "GPIO",
-       .enable         = gpio_irq_enable,
-       .disable        = gpio_irq_disable,
-       .set_type       = gpio_irq_type,
-};
-
-static void
-gpio_irq_handler(unsigned irq, struct irq_desc *desc)
-{
-       struct gpio_controller *__iomem g = get_irq_chip_data(irq);
-       u32 mask = 0xffff;
-
-       /* we only care about one bank */
-       if (irq & 1)
-               mask <<= 16;
-
-       /* temporarily mask (level sensitive) parent IRQ */
-       desc->chip->ack(irq);
-       while (1) {
-               u32             status;
-               struct irq_desc *gpio;
-               int             n;
-               int             res;
-
-               /* ack any irqs */
-               status = __raw_readl(&g->intstat) & mask;
-               if (!status)
-                       break;
-               __raw_writel(status, &g->intstat);
-               if (irq & 1)
-                       status >>= 16;
-
-               /* now demux them to the right lowlevel handler */
-               n = (int)get_irq_data(irq);
-               gpio = &irq_desc[n];
-               while (status) {
-                       res = ffs(status);
-                       n += res;
-                       gpio += res;
-                       desc_handle_irq(n - 1, gpio - 1);
-                       status >>= res;
-               }
-       }
-       desc->chip->unmask(irq);
-       /* now it may re-trigger */
-}
 
 /*
  * NOTE:  for suspend/resume, probably best to make a sysdev (and class)
@@ -238,7 +141,6 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 
 static int __init davinci_gpio_irq_setup(void)
 {
-       unsigned        gpio, irq, bank;
        struct clk      *clk;
 
        clk = clk_get(NULL, "gpio");
@@ -250,36 +152,6 @@ static int __init davinci_gpio_irq_setup(void)
 
        clk_enable(clk);
 
-       for (gpio = 0, irq = gpio_to_irq(0), bank = IRQ_GPIOBNK0;
-            gpio < DAVINCI_N_GPIO; bank++) {
-               struct gpio_controller  *__iomem g = gpio2controller(gpio);
-               unsigned                i;
-
-               __raw_writel(~0, &g->clr_falling);
-               __raw_writel(~0, &g->clr_rising);
-
-               /* set up all irqs in this bank */
-               set_irq_chained_handler(bank, gpio_irq_handler);
-               set_irq_chip_data(bank, g);
-               set_irq_data(bank, (void *)irq);
-
-               for (i = 0; i < 16 && gpio < DAVINCI_N_GPIO;
-                    i++, irq++, gpio++) {
-                       set_irq_chip(irq, &gpio_irqchip);
-                       set_irq_chip_data(irq, g);
-                       set_irq_handler(irq, handle_simple_irq);
-                       set_irq_flags(irq, IRQF_VALID);
-               }
-       }
-
-       /* BINTEN -- per-bank interrupt enable. genirq would also let these
-        * bits be set/cleared dynamically.
-        */
-       __raw_writel(0x1f, (void *__iomem)
-                    IO_ADDRESS(DAVINCI_GPIO_BASE + 0x08));
-
-       printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));
-
        return 0;
 }
 
diff --git a/arch/arm/mach-davinci/irq.c b/arch/arm/mach-davinci/irq.c
old mode 100644
new mode 100755
index 51371f1..a6fb85d
--- a/arch/arm/mach-davinci/irq.c
+++ b/arch/arm/mach-davinci/irq.c
@@ -2,6 +2,7 @@
  * Interrupt handler for DaVinci boards.
  *
  * Copyright (C) 2006 Texas Instruments.
+ * 2007 Boundary Devices. Troy Kisky <[EMAIL PROTECTED]>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,8 +27,7 @@
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/mach/irq.h>
-
-#define IRQ_BIT(irq)           ((irq) & 0x1f)
+#include <asm/arch/gpio.h>
 
 #define FIQ_REG0_OFFSET                0x0000
 #define FIQ_REG1_OFFSET                0x0004
@@ -40,6 +40,13 @@
 #define IRQ_INTPRI0_REG_OFFSET 0x0030
 #define IRQ_INTPRI7_REG_OFFSET 0x004C
 
+#define GPIO_MAX 70
+#ifdef DEBUG
+#define dbg(format, arg...) printk(KERN_DEBUG format "\n" , ## arg)
+#else
+#define dbg(format, arg...) do {} while (0)
+#endif
+
 static inline unsigned int davinci_irq_readl(int offset)
 {
        return davinci_readl(DAVINCI_ARM_INTC_BASE + offset);
@@ -51,66 +58,271 @@ static inline void davinci_irq_writel(unsigned long value, 
int offset)
 }
 
 /* Disable interrupt */
-static void davinci_mask_irq(unsigned int irq)
+static void davinci_mask_irq0(unsigned int irq)
 {
-       unsigned int mask;
-       u32 l;
+       u32 l = davinci_irq_readl(IRQ_ENT_REG0_OFFSET);
+       l &= ~(1 << irq);
+       davinci_irq_writel(l, IRQ_ENT_REG0_OFFSET);
+}
+/* Disable interrupt */
+static void davinci_mask_irq1(unsigned int irq)
+{
+       u32 l = davinci_irq_readl(IRQ_ENT_REG1_OFFSET);
+       l &= ~(1 << (irq&0x1f));
+       davinci_irq_writel(l, IRQ_ENT_REG1_OFFSET);
+}
 
-       mask = 1 << IRQ_BIT(irq);
+/* Enable interrupt */
+static void davinci_unmask_irq0(unsigned int irq)
+{
+       u32 l = davinci_irq_readl(IRQ_ENT_REG0_OFFSET);
+       l |= (1 << irq);
+       davinci_irq_writel(l, IRQ_ENT_REG0_OFFSET);
+}
+/* Enable interrupt */
+static void davinci_unmask_irq1(unsigned int irq)
+{
+       u32 l = davinci_irq_readl(IRQ_ENT_REG1_OFFSET);
+       l |= (1 << (irq&0x1f));
+       davinci_irq_writel(l, IRQ_ENT_REG1_OFFSET);
+}
 
-       if (irq > 31) {
-               l = davinci_irq_readl(IRQ_ENT_REG1_OFFSET);
-               l &= ~mask;
-               davinci_irq_writel(l, IRQ_ENT_REG1_OFFSET);
-       } else {
-               l = davinci_irq_readl(IRQ_ENT_REG0_OFFSET);
-               l &= ~mask;
-               davinci_irq_writel(l, IRQ_ENT_REG0_OFFSET);
-       }
+/* EOI interrupt */
+static void davinci_ack_irq0(unsigned int irq)
+{
+       davinci_irq_writel((1 << irq), IRQ_REG0_OFFSET);
+}
+/* EOI interrupt */
+static void davinci_ack_irq1(unsigned int irq)
+{
+       davinci_irq_writel((1 << (irq&0x1f)), IRQ_REG1_OFFSET);
 }
 
-/* Enable interrupt */
-static void davinci_unmask_irq(unsigned int irq)
+static struct irq_chip davinci_irq_chip_0 = {
+       .name   = "AINTC0",
+       .ack    = davinci_ack_irq0,
+       .mask   = davinci_mask_irq0,
+       .unmask = davinci_unmask_irq0,
+};
+static struct irq_chip davinci_irq_chip_1 = {
+       .name   = "AINTC1",
+       .ack    = davinci_ack_irq1,
+       .mask   = davinci_mask_irq1,
+       .unmask = davinci_unmask_irq1,
+};
+
+/* ---------------------------------------------  */
+static long GPIO_IRQ_rising_edge[3];
+static long GPIO_IRQ_falling_edge[3];
+static long GPIO_IRQ_mask[3];
+
+static int davinci_gpio_irq_set_type(unsigned int irq, unsigned int type)
 {
-       unsigned int mask;
-       u32 l;
+       int gp = IRQ_TO_GPIO(irq);
+       int idx = gp >> 5;
+       int mask = 1<<(gp&0x1f);
+       struct gpio_controller  *__iomem g = __gpio_to_controller(gp);
 
-       mask = 1 << IRQ_BIT(irq);
+       if (type == IRQT_PROBE) {
+               unsigned int dir;
+           /* Don't mess with enabled GPIOs using preconfigured edges or
+              GPIOs set to output during probe */
+               dir = __raw_readl(&g->dir);     /* 1 means input */
+               if ((GPIO_IRQ_rising_edge[idx] | GPIO_IRQ_falling_edge[idx] |
+                               ~dir) & mask)
+                       return 0;
+               type = __IRQT_RISEDGE | __IRQT_FALEDGE;
+       }
 
-       if (irq > 31) {
-               l = davinci_irq_readl(IRQ_ENT_REG1_OFFSET);
-               l |= mask;
-               davinci_irq_writel(l, IRQ_ENT_REG1_OFFSET);
+       {
+               unsigned int dir;
+               unsigned long flags;
+               local_irq_save(flags);
+               /* 1 means input, make sure gp is an input */
+               dir = __raw_readl(&g->dir);
+               __raw_writel(dir|mask, &g->dir);
+               local_irq_restore(flags);
+       }
+       if (type & __IRQT_RISEDGE) {
+               __set_bit(gp, GPIO_IRQ_rising_edge);
        } else {
-               l = davinci_irq_readl(IRQ_ENT_REG0_OFFSET);
-               l |= mask;
-               davinci_irq_writel(l, IRQ_ENT_REG0_OFFSET);
+               __clear_bit(gp, GPIO_IRQ_rising_edge);
        }
+
+       if (type & __IRQT_FALEDGE) {
+               __set_bit(gp, GPIO_IRQ_falling_edge);
+       } else {
+               __clear_bit(gp, GPIO_IRQ_falling_edge);
+       }
+
+       if (GPIO_IRQ_mask[idx] & mask) {
+               __raw_writel(mask, (GPIO_IRQ_rising_edge[idx]&mask)?
+                               &g->set_rising : &g->clr_rising);
+               __raw_writel(mask, (GPIO_IRQ_falling_edge[idx]&mask)?
+                               &g->set_falling : &g->clr_falling);
+       }
+       return 0;
 }
 
-/* EOI interrupt */
-static void davinci_ack_irq(unsigned int irq)
+/*
+ * GPIO IRQs must be acknowledged.  This is for GPIO 0-7.
+ */
+static void davinci_ack_low_gpio(unsigned int irq)
+{
+       int gp = irq - IRQ_GPIO0;
+       struct gpio_controller  *__iomem g = __gpio_to_controller(0);
+       __raw_writel((1 << gp), &g->intstat);
+       davinci_irq_writel((1 << (irq&0x1f)), IRQ_REG1_OFFSET);
+       dbg("irq davinci_ack_low_gpio");
+}
+
+static struct irq_chip davinci_low_gpio_chip = {
+       .name           = "low gpio",
+       .ack            = davinci_ack_low_gpio,
+       .mask           = davinci_mask_irq1,
+       .unmask         = davinci_unmask_irq1,
+       .set_type       = davinci_gpio_irq_set_type,
+};
+/* ---------------------------------------------  */
+/*
+ * Demux handler for GPIO>=8 edge detect interrupts
+ */
+static void davinci_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
 {
+       int index = irq-IRQ_GPIOBNK0;
+       /* 16 bits/bank */
+       struct gpio_controller  *__iomem g = __gpio_to_controller(index<<4);
        unsigned int mask;
+       do {
+               int irqBase;
+               davinci_irq_writel((1 << (irq&0x1f)), IRQ_REG1_OFFSET);
+               mask = __raw_readl(&g->intstat);
+               /* remove status bits not relevent to this interrrupt */
+               mask &= (index&1)? 0xffff0000 : ((index)? 0xffff : 0xff00);
+               dbg("irq davinci_gpio_demux_handler, irq=%i, mask=0x%08x",
+                       irq, mask);
+
+               if (!mask)
+                       break;
+               /* acknowledge changes */
+               __raw_writel(mask, &g->intstat);
+               irqBase = IRQ_GPIO(8)-8 + ((index&~0x1)<<4);
+               do {
+                       /* subtract 1 because ffs will
+                        * return 1-32 instead of 0-31
+                        */
+                       int i = ffs(mask) - 1;
+                       desc_handle_irq(irqBase+i, irq_desc+irqBase+i);
+                       mask &= ~(1<<i);
+               } while (mask);
+       } while (1);
+}
 
-       mask = 1 << IRQ_BIT(irq);
+static void davinci_ack_muxed_gpio(unsigned int irq)
+{
+       int gp = irq - (IRQ_GPIO(8)-8);
+       int mask = 1<<(gp&0x1f);
+       struct gpio_controller  *__iomem g = __gpio_to_controller(gp);
+       __raw_writel(mask, &g->intstat);
+       dbg("irq=%i gp=%i mask=%x davinci_ack_muxed_gpio", irq, gp, mask);
+}
 
-       if (irq > 31)
-               davinci_irq_writel(mask, IRQ_REG1_OFFSET);
-       else
-               davinci_irq_writel(mask, IRQ_REG0_OFFSET);
+static void davinci_mask_muxed_gpio(unsigned int irq)
+{
+       int gp = irq - (IRQ_GPIO(8)-8);
+       int mask = 1<<(gp&0x1f);
+       struct gpio_controller  *__iomem g = __gpio_to_controller(gp);
+       __clear_bit(gp, GPIO_IRQ_mask);
+       __raw_writel(mask, &g->clr_rising);
+       __raw_writel(mask, &g->clr_falling);
+       dbg("irq=%i gp=%i mask=%x davinci_mask_muxed_gpio", irq, gp, mask);
 }
 
-static struct irq_chip davinci_irq_chip_0 = {
-       .name   = "AINTC",
-       .ack    = davinci_ack_irq,
-       .mask   = davinci_mask_irq,
-       .unmask = davinci_unmask_irq,
+static void davinci_unmask_muxed_gpio(unsigned int irq)
+{
+       int gp = irq - (IRQ_GPIO(8)-8);
+       int mask = 1<<(gp&0x1f);
+       int idx = gp >> 5;
+       struct gpio_controller  *__iomem g = __gpio_to_controller(gp);
+       __set_bit(gp, GPIO_IRQ_mask);
+       if (GPIO_IRQ_rising_edge[idx] & mask)
+               __raw_writel(mask, &g->set_rising);
+       if (GPIO_IRQ_falling_edge[idx] & mask)
+               __raw_writel(mask, &g->set_falling);
+       dbg("irq=%i gp=%i mask=%x davinci_unmask_muxed_gpio %c%c",
+               irq, gp, mask, (GPIO_IRQ_rising_edge[idx] & mask)?'r':' ',
+               (GPIO_IRQ_falling_edge[idx] & mask)?'f':' ');
+}
+static struct irq_chip davinci_muxed_gpio_chip = {
+       .name           = "muxed gpio",
+       .ack            = davinci_ack_muxed_gpio,
+       .mask           = davinci_mask_muxed_gpio,
+       .unmask         = davinci_unmask_muxed_gpio,
+       .set_type       = davinci_gpio_irq_set_type,
 };
+/* ---------------------------------------------  */
+/* EMIF Register offsets */
+#define EMIF_EIMR      0x44
+#define EMIF_EIMSR     0x48
+#define EMIF_EIMCR     0x4c
+
+#define read_emif(offset) __raw_readl( \
+       IO_ADDRESS(DAVINCI_ASYNC_EMIF_CNTRL_BASE+offset))
+#define write_emif(val, offset) __raw_writel(val, \
+       IO_ADDRESS(DAVINCI_ASYNC_EMIF_CNTRL_BASE+offset))
+/*
+ * Demux handler for emif interrupts
+ */
+static void davinci_emif_demux_handler(unsigned int irq, struct irq_desc *desc)
+{
+       unsigned int mask;
 
+       do {
+               davinci_irq_writel((1 << irq), IRQ_REG0_OFFSET);
+               mask = read_emif(EMIF_EIMR) & 0x5;
+               if (!mask)
+                       break;
+               write_emif(mask, EMIF_EIMR);    /* acknowledge changes */
+               if (mask & 1)
+                       desc_handle_irq(IRQ_EMIF_EMWAIT_TIMEOUT,
+                               irq_desc+IRQ_EMIF_EMWAIT_TIMEOUT);
+               if (mask & 4)
+                       desc_handle_irq(IRQ_EMIF_EMWAIT_RISE,
+                               irq_desc+IRQ_EMIF_EMWAIT_RISE);
+       } while (1);
+}
+
+static void davinci_ack_muxed_emif(unsigned int irq)
+{
+       unsigned int mask = (irq == IRQ_EMIF_EMWAIT_TIMEOUT)? 1 :
+               ((irq == IRQ_EMIF_EMWAIT_RISE)? 4 : 0);
+       if (mask)
+               write_emif(mask, EMIF_EIMR);
+}
+static void davinci_mask_muxed_emif(unsigned int irq)
+{
+       unsigned int mask = (irq == IRQ_EMIF_EMWAIT_TIMEOUT)? 1 :
+               ((irq == IRQ_EMIF_EMWAIT_RISE)? 4 : 0);
+       if (mask)
+               write_emif(mask, EMIF_EIMCR);
+}
+static void davinci_unmask_muxed_emif(unsigned int irq)
+{
+       unsigned int mask = (irq == IRQ_EMIF_EMWAIT_TIMEOUT)? 1 :
+               ((irq == IRQ_EMIF_EMWAIT_RISE)? 4 : 0);
+       if (mask)
+               write_emif(mask, EMIF_EIMSR);
+}
+static struct irq_chip davinci_muxed_emif_chip = {
+       .name           = "muxed emif",
+       .ack            = davinci_ack_muxed_emif,
+       .mask           = davinci_mask_muxed_emif,
+       .unmask         = davinci_unmask_muxed_emif,
+};
+/* ---------------------------------------------  */
 
 /* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
-static const u8 default_priorities[DAVINCI_N_AINTC_IRQ] __initdata = {
+static const u8 default_priorities[64] __initdata = {
        [IRQ_VDINT0]            = 2,
        [IRQ_VDINT1]            = 6,
        [IRQ_VDINT2]            = 6,
@@ -180,15 +392,10 @@ static const u8 default_priorities[DAVINCI_N_AINTC_IRQ] 
__initdata = {
 /* ARM Interrupt Controller Initialization */
 void __init davinci_irq_init(void)
 {
+       int irq;
        unsigned i;
        const u8 *priority = default_priorities;
 
-       /* Clear all interrupt requests */
-       davinci_irq_writel(~0x0, FIQ_REG0_OFFSET);
-       davinci_irq_writel(~0x0, FIQ_REG1_OFFSET);
-       davinci_irq_writel(~0x0, IRQ_REG0_OFFSET);
-       davinci_irq_writel(~0x0, IRQ_REG1_OFFSET);
-
        /* Disable all interrupts */
        davinci_irq_writel(0x0, IRQ_ENT_REG0_OFFSET);
        davinci_irq_writel(0x0, IRQ_ENT_REG1_OFFSET);
@@ -205,7 +412,8 @@ void __init davinci_irq_init(void)
        davinci_irq_writel(~0x0, IRQ_REG0_OFFSET);
        davinci_irq_writel(~0x0, IRQ_REG1_OFFSET);
 
-       for (i = IRQ_INTPRI0_REG_OFFSET; i <= IRQ_INTPRI7_REG_OFFSET; i += 4) {
+       for (i = IRQ_INTPRI0_REG_OFFSET;
+                       i <= IRQ_INTPRI7_REG_OFFSET; i += 4) {
                unsigned        j;
                u32             pri;
 
@@ -215,12 +423,49 @@ void __init davinci_irq_init(void)
        }
 
        /* set up genirq dispatch for ARM INTC */
-       for (i = 0; i < DAVINCI_N_AINTC_IRQ; i++) {
-               set_irq_chip(i, &davinci_irq_chip_0);
-               set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
-                if (i != IRQ_TINT1_TINT34)
-                        set_irq_handler(i, handle_edge_irq);
-                else
-                        set_irq_handler(i, handle_level_irq);
+       for (irq = 0; irq < 32; irq++) {
+               set_irq_chip(irq, &davinci_irq_chip_0);
+               set_irq_handler(irq, handle_edge_irq);
+               if (irq == IRQ_AEMIFINT)
+                       set_irq_chained_handler(irq,
+                               davinci_emif_demux_handler);
+               set_irq_flags(irq, IRQF_VALID);
+       }
+
+       for (irq = 32; irq < IRQ_GPIO0; irq++) {
+               set_irq_chip(irq, &davinci_irq_chip_1);
+               set_irq_handler(irq, (irq == IRQ_TINT1_TINT34)?
+                               handle_level_irq : handle_edge_irq);
+               set_irq_flags(irq, IRQF_VALID);
+       }
+       for (irq = IRQ_GPIO(0); irq <= IRQ_GPIO(7); irq++) {
+               set_irq_chip(irq, &davinci_low_gpio_chip);
+               set_irq_handler(irq, handle_edge_irq);
+               set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+       }
+       /* Install handler for GPIO>=8 edge detect interrupts */
+       for (irq = IRQ_GPIOBNK0; irq <= IRQ_GPIOBNK4; irq++)  {
+               set_irq_chip(irq, &davinci_irq_chip_1);
+               set_irq_handler(irq, handle_edge_irq);
+               set_irq_chained_handler(irq, davinci_gpio_demux_handler);
+               set_irq_flags(irq, IRQF_VALID);
+       }
+       for (irq = IRQ_GPIOBNK4+1; irq < 64; irq++) {
+               set_irq_chip(irq, &davinci_irq_chip_1);
+               set_irq_handler(irq, handle_edge_irq);
+               set_irq_flags(irq, IRQF_VALID);
+       }
+       for (irq = IRQ_EMIF_EMWAIT_TIMEOUT;
+                       irq <= IRQ_EMIF_EMWAIT_RISE; irq++) {
+               set_irq_chip(irq, &davinci_muxed_emif_chip);
+               set_irq_handler(irq, handle_edge_irq);
+               set_irq_flags(irq, IRQF_VALID);
+       }
+       for (irq = IRQ_GPIO(8); irq <= IRQ_GPIO(GPIO_MAX); irq++) {
+               set_irq_chip(irq, &davinci_muxed_gpio_chip);
+               set_irq_handler(irq, handle_edge_irq);
+               set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
        }
+       /* enable interrupts for all banks */
+       __raw_writel(0x1f, IO_ADDRESS(DAVINCI_GPIO_BASE + 0x08));
 }
diff --git a/include/asm-arm/arch-davinci/gpio.h 
b/include/asm-arm/arch-davinci/gpio.h
index 15ecadd..fd02756 100644
--- a/include/asm-arm/arch-davinci/gpio.h
+++ b/include/asm-arm/arch-davinci/gpio.h
@@ -12,6 +12,7 @@
 
 #ifndef        __DAVINCI_GPIO_H
 #define        __DAVINCI_GPIO_H
+#include <asm/arch/irqs.h>
 
 #include <linux/io.h>
 #include <asm/hardware.h>
@@ -148,12 +149,12 @@ extern void gpio_free(unsigned gpio);
 
 static inline int gpio_to_irq(unsigned gpio)
 {
-       return DAVINCI_N_AINTC_IRQ + gpio;
+       return IRQ_GPIO(gpio);
 }
 
 static inline int irq_to_gpio(unsigned irq)
 {
-       return irq - DAVINCI_N_AINTC_IRQ;
+       return IRQ_TO_GPIO(irq);
 }
 
 #endif                         /* __DAVINCI_GPIO_H */
diff --git a/include/asm-arm/arch-davinci/irqs.h 
b/include/asm-arm/arch-davinci/irqs.h
index f4c5ca6..38661ca 100644
--- a/include/asm-arm/arch-davinci/irqs.h
+++ b/include/asm-arm/arch-davinci/irqs.h
@@ -95,11 +95,17 @@
 #define IRQ_COMMRX       62
 #define IRQ_EMUINT       63
 
-#define DAVINCI_N_AINTC_IRQ    64
+
+#define ARCH_TIMER_IRQ IRQ_TINT1_TINT34
 #define DAVINCI_N_GPIO         71
 
-#define NR_IRQS                        (DAVINCI_N_AINTC_IRQ + DAVINCI_N_GPIO)
+#define IRQ_EMIF_EMWAIT_TIMEOUT 64
+#define IRQ_EMIF_EMWAIT_RISE 65
 
-#define ARCH_TIMER_IRQ IRQ_TINT1_TINT34
+#define IRQ_GPIO8     66
+#define IRQ_GPIO(x) ((x < 8)? IRQ_GPIO0+x : IRQ_GPIO8-8+x)
+#define IRQ_TO_GPIO(irq) ((irq < IRQ_GPIO(8))? \
+               irq - IRQ_GPIO(0) : irq - (IRQ_GPIO(8)-8))
 
+#define NR_IRQS                  (IRQ_GPIO(70) + 1)
 #endif /* __ASM_ARCH_IRQS_H */
-- 
1.5.4

_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to