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