ARM tegra: gpio: Correct gpio interrupt init sequence
Daehyoung Ko [Sat, 1 Oct 2011 00:42:49 +0000 (17:42 -0700)]
It is possible for GPIO interrupt to occur when registering handler
since set_irq_chained_handler enables GPIO interrupt. Thus
all relevant variables are required to be initialized
before calling set_irq_chained_handler.

Also add initialization of interrupt status register.

Bug 884569

Reviewed-on: http://git-master/r/58218
(cherry picked from commit e03fe4cc1bf06fa6c32c0520e2ba31f009f9301d)

Change-Id: Ic76f95215b61d6e091ae1cfa11522f8af9c3eecd
Reviewed-on: http://git-master/r/60475
Reviewed-by: Daehyoung Ko <dko@nvidia.com>
Tested-by: Daehyoung Ko <dko@nvidia.com>
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>

Rebase-Id: R5340918dccc1a8b1d95c5b629cc985f44d45fb67

arch/arm/mach-tegra/irq.c
drivers/gpio/gpio-tegra.c

index 73a7261..21f7c9c 100644 (file)
@@ -194,6 +194,7 @@ void __init tegra_init_irq(void)
                void __iomem *ictlr = ictlr_reg_base[i];
                writel(~0, ictlr + ICTLR_CPU_IER_CLR);
                writel(0, ictlr + ICTLR_CPU_IEP_CLASS);
+               writel(~0, ictlr + ICTLR_CPU_IEP_FIR_CLR);
        }
 
        gic_arch_extn.irq_ack = tegra_ack;
index 0beefa1..5219746 100644 (file)
@@ -412,6 +412,7 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev)
                for (j = 0; j < 4; j++) {
                        int gpio = tegra_gpio_compose(i, j, 0);
                        tegra_gpio_writel(0x00, GPIO_INT_ENB(gpio));
+                       tegra_gpio_writel(0x00, GPIO_INT_STA(gpio));
                }
        }
 
@@ -437,11 +438,12 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev)
        for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) {
                bank = &tegra_gpio_banks[i];
 
-               irq_set_chained_handler(bank->irq, tegra_gpio_irq_handler);
-               irq_set_handler_data(bank->irq, bank);
-
                for (j = 0; j < 4; j++)
                        spin_lock_init(&bank->lvl_lock[j]);
+
+               irq_set_handler_data(bank->irq, bank);
+               irq_set_chained_handler(bank->irq, tegra_gpio_irq_handler);
+
        }
 
        return 0;