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 fa525e1..a0e3099 100644 (file)
@@ -202,6 +202,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 2347894..59480bd 100644 (file)
@@ -482,6 +482,7 @@ static int 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));
                }
        }
 
@@ -505,11 +506,12 @@ static int tegra_gpio_probe(struct platform_device *pdev)
        for (i = 0; i < tegra_gpio_bank_count; 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;