]> Pileus Git - ~andy/linux/blobdiff - arch/arm/mach-tegra/irq.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/apm
[~andy/linux] / arch / arm / mach-tegra / irq.c
index 4e1afcd54faedd71ffb04276d78c9f025bc4b407..2f5bd2db8e1faa78a69cedd1bfdc144bec47b615 100644 (file)
 #define ICTLR_COP_IER_CLR      0x38
 #define ICTLR_COP_IEP_CLASS    0x3c
 
-#define NUM_ICTLRS 4
 #define FIRST_LEGACY_IRQ 32
 
+static int num_ictlrs;
+
 static void __iomem *ictlr_reg_base[] = {
        IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE),
        IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE),
        IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE),
        IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE),
+       IO_ADDRESS(TEGRA_QUINARY_ICTLR_BASE),
 };
 
 static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg)
@@ -60,7 +62,7 @@ static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg)
        u32 mask;
 
        BUG_ON(irq < FIRST_LEGACY_IRQ ||
-               irq >= FIRST_LEGACY_IRQ + NUM_ICTLRS * 32);
+               irq >= FIRST_LEGACY_IRQ + num_ictlrs * 32);
 
        base = ictlr_reg_base[(irq - FIRST_LEGACY_IRQ) / 32];
        mask = BIT((irq - FIRST_LEGACY_IRQ) % 32);
@@ -113,8 +115,18 @@ static int tegra_retrigger(struct irq_data *d)
 void __init tegra_init_irq(void)
 {
        int i;
+       void __iomem *distbase;
+
+       distbase = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE);
+       num_ictlrs = readl_relaxed(distbase + GIC_DIST_CTR) & 0x1f;
+
+       if (num_ictlrs > ARRAY_SIZE(ictlr_reg_base)) {
+               WARN(1, "Too many (%d) interrupt controllers found. Maximum is %d.",
+                       num_ictlrs, ARRAY_SIZE(ictlr_reg_base));
+               num_ictlrs = ARRAY_SIZE(ictlr_reg_base);
+       }
 
-       for (i = 0; i < NUM_ICTLRS; i++) {
+       for (i = 0; i < num_ictlrs; i++) {
                void __iomem *ictlr = ictlr_reg_base[i];
                writel(~0, ictlr + ICTLR_CPU_IER_CLR);
                writel(0, ictlr + ICTLR_CPU_IEP_CLASS);
@@ -131,6 +143,6 @@ void __init tegra_init_irq(void)
         * initialized elsewhere under DT.
         */
        if (!of_have_populated_dt())
-               gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE),
+               gic_init(0, 29, distbase,
                        IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
 }