Skip to content

Commit

Permalink
arm: davinci: Fix low level gpio irq handlers' argument
Browse files Browse the repository at this point in the history
Commit 7416401 ("arm: davinci: Fix fallout from generic irq chip
conversion") introduced a bug, causing low level interrupt handlers to
get a bogus irq number as an argument. The gpio irq handler falsely
assumes that the handler data is the irq base number and that is no
longer true.

Set the irq handler data to be a pointer to the corresponding gpio
controller. The chained irq handler can then use it to extract both the
irq base number and the gpio registers structure.

Signed-off-by: Ido Yariv <ido@wizery.com>
CC: Thomas Gleixner <tglx@linutronix.de>
[nsekhar@ti.com: renamed "ctl" to "d", simplified indexing logic for chips and
took care of odd bank handling in irq handler]
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
  • Loading branch information
Ido Yariv authored and Sekhar Nori committed Jul 12, 2011
1 parent 620917d commit f299bb9
Showing 1 changed file with 16 additions and 5 deletions.
21 changes: 16 additions & 5 deletions arch/arm/mach-davinci/gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,10 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
{
struct davinci_gpio_regs __iomem *g;
u32 mask = 0xffff;
struct davinci_gpio_controller *d;

g = (__force struct davinci_gpio_regs __iomem *) irq_desc_get_handler_data(desc);
d = (struct davinci_gpio_controller *)irq_desc_get_handler_data(desc);
g = (struct davinci_gpio_regs __iomem *)d->regs;

/* we only care about one bank */
if (irq & 1)
Expand All @@ -274,11 +276,14 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
if (!status)
break;
__raw_writel(status, &g->intstat);
if (irq & 1)
status >>= 16;

/* now demux them to the right lowlevel handler */
n = (int)irq_get_handler_data(irq);
n = d->irq_base;
if (irq & 1) {
n += 16;
status >>= 16;
}

while (status) {
res = ffs(status);
n += res;
Expand Down Expand Up @@ -424,7 +429,13 @@ static int __init davinci_gpio_irq_setup(void)

/* set up all irqs in this bank */
irq_set_chained_handler(bank_irq, gpio_irq_handler);
irq_set_handler_data(bank_irq, (__force void *)g);

/*
* Each chip handles 32 gpios, and each irq bank consists of 16
* gpio irqs. Pass the irq bank's corresponding controller to
* the chained irq handler.
*/
irq_set_handler_data(bank_irq, &chips[gpio / 32]);

for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) {
irq_set_chip(irq, &gpio_irqchip);
Expand Down

0 comments on commit f299bb9

Please sign in to comment.