]> git.karo-electronics.de Git - linux-beck.git/blobdiff - arch/arm/common/gic.c
Merge branches 'x86-fixes-for-linus', 'perf-fixes-for-linus' and 'sched-fixes-for...
[linux-beck.git] / arch / arm / common / gic.c
index 772f95f1aecddf49ada9ceea0caa5295d22c9613..e6388dcd8cfa2cf5f7a31ee59a6728bda377f89c 100644 (file)
@@ -146,9 +146,15 @@ static int gic_set_cpu(unsigned int irq, const struct cpumask *mask_val)
        unsigned int shift = (irq % 4) * 8;
        unsigned int cpu = cpumask_first(mask_val);
        u32 val;
+       struct irq_desc *desc;
 
        spin_lock(&irq_controller_lock);
-       irq_desc[irq].node = cpu;
+       desc = irq_to_desc(irq);
+       if (desc == NULL) {
+               spin_unlock(&irq_controller_lock);
+               return -EINVAL;
+       }
+       desc->node = cpu;
        val = readl(reg) & ~(0xff << shift);
        val |= 1 << (cpu + shift);
        writel(val, reg);
@@ -210,7 +216,7 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
 void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
                          unsigned int irq_start)
 {
-       unsigned int max_irq, i;
+       unsigned int gic_irqs, irq_limit, i;
        u32 cpumask = 1 << smp_processor_id();
 
        if (gic_nr >= MAX_GIC_NR)
@@ -226,47 +232,49 @@ void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
 
        /*
         * Find out how many interrupts are supported.
-        */
-       max_irq = readl(base + GIC_DIST_CTR) & 0x1f;
-       max_irq = (max_irq + 1) * 32;
-
-       /*
         * The GIC only supports up to 1020 interrupt sources.
-        * Limit this to either the architected maximum, or the
-        * platform maximum.
         */
-       if (max_irq > max(1020, NR_IRQS))
-               max_irq = max(1020, NR_IRQS);
+       gic_irqs = readl(base + GIC_DIST_CTR) & 0x1f;
+       gic_irqs = (gic_irqs + 1) * 32;
+       if (gic_irqs > 1020)
+               gic_irqs = 1020;
 
        /*
         * Set all global interrupts to be level triggered, active low.
         */
-       for (i = 32; i < max_irq; i += 16)
+       for (i = 32; i < gic_irqs; i += 16)
                writel(0, base + GIC_DIST_CONFIG + i * 4 / 16);
 
        /*
         * Set all global interrupts to this CPU only.
         */
-       for (i = 32; i < max_irq; i += 4)
+       for (i = 32; i < gic_irqs; i += 4)
                writel(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
 
        /*
         * Set priority on all global interrupts.
         */
-       for (i = 32; i < max_irq; i += 4)
+       for (i = 32; i < gic_irqs; i += 4)
                writel(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4);
 
        /*
         * Disable all interrupts.  Leave the PPI and SGIs alone
         * as these enables are banked registers.
         */
-       for (i = 32; i < max_irq; i += 32)
+       for (i = 32; i < gic_irqs; i += 32)
                writel(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);
 
+       /*
+        * Limit number of interrupts registered to the platform maximum
+        */
+       irq_limit = gic_data[gic_nr].irq_offset + gic_irqs;
+       if (WARN_ON(irq_limit > NR_IRQS))
+               irq_limit = NR_IRQS;
+
        /*
         * Setup the Linux IRQ subsystem.
         */
-       for (i = irq_start; i < gic_data[gic_nr].irq_offset + max_irq; i++) {
+       for (i = irq_start; i < irq_limit; i++) {
                set_irq_chip(i, &gic_chip);
                set_irq_chip_data(i, &gic_data[gic_nr]);
                set_irq_handler(i, handle_level_irq);