[PATCH v2 1/6] arm: davinci: Fix low level gpio irq handlers' argument
Nori, Sekhar
nsekhar at ti.com
Mon Jul 11 07:58:44 EDT 2011
Hi Ido,
On Sun, Jul 10, 2011 at 18:44:34, Ido Yariv wrote:
> 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.
>
> Fix this by converting gpio_irq_handler's bank_irq argument to the
> corresponding irq base number.
>
> Signed-off-by: Ido Yariv <ido at wizery.com>
> CC: Thomas Gleixner <tglx at linutronix.de>
> ---
> arch/arm/mach-davinci/gpio.c | 32 ++++++++++++++++++++++++++++----
> 1 files changed, 28 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c
> index e722139..ff43e2a 100644
> --- a/arch/arm/mach-davinci/gpio.c
> +++ b/arch/arm/mach-davinci/gpio.c
> @@ -249,16 +249,40 @@ static struct irq_chip gpio_irqchip = {
> .flags = IRQCHIP_SET_TYPE_MASKED,
> };
>
> +static inline int bankirq_to_irqbase(unsigned int bank_irq)
> +{
> + int gpio;
> + int index;
> +
> + /* Each irq bank consists of up to 16 irqs */
> + gpio = 16 * (bank_irq - davinci_soc_info.gpio_irq);
> +
> + /* Each controller controls 32 GPIOs */
> + index = gpio / 32;
> +
> + if (unlikely(!davinci_soc_info.gpio_ctlrs))
> + return -EINVAL;
> +
> + if (unlikely(index >= davinci_soc_info.gpio_ctlrs_num))
> + return -EINVAL;
> +
> + return davinci_soc_info.gpio_ctlrs[index].irq_base;
> +}
> +
> static void
> -gpio_irq_handler(unsigned irq, struct irq_desc *desc)
> +gpio_irq_handler(unsigned bank_irq, struct irq_desc *desc)
> {
> struct davinci_gpio_regs __iomem *g;
> u32 mask = 0xffff;
> + int irqbase = bankirq_to_irqbase(bank_irq);
> +
> + if (unlikely(irqbase < 0))
> + return;
>
> g = (__force struct davinci_gpio_regs __iomem *) irq_desc_get_handler_data(desc);
>
> /* we only care about one bank */
> - if (irq & 1)
> + if (bank_irq & 1)
> mask <<= 16;
>
> /* temporarily mask (level sensitive) parent IRQ */
> @@ -274,11 +298,11 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
> if (!status)
> break;
> __raw_writel(status, &g->intstat);
> - if (irq & 1)
> + if (bank_irq & 1)
> status >>= 16;
>
> /* now demux them to the right lowlevel handler */
> - n = (int)irq_get_handler_data(irq);
> + n = irqbase;
> while (status) {
> res = ffs(status);
> n += res;
Thanks for the bug fix.
How about setting the handler data for bank IRQ in
davinci_gpio_irq_setup() to &chips[bank]?
chips[bank].regs should give you the register base address
(g) and chips[bank].irq_base should give you 'n'.
Also please drop the rename of irq to bank_irq as it is not
central to the bug fix.
If you spin in soon enough, we may make it to v3.0
Thanks,
Sekhar
More information about the linux-arm-kernel
mailing list