irqchip/gic: Only allow the primary GIC to set the CPU map
[deliverable/linux.git] / drivers / irqchip / irq-gic.c
index 4dd88264dff55c0c95efd813c82fe762d7216263..84fc622d030920d39d8ac5e72c2f7477d8120266 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/interrupt.h>
 #include <linux/percpu.h>
 #include <linux/slab.h>
+#include <linux/irqchip.h>
 #include <linux/irqchip/chained_irq.h>
 #include <linux/irqchip/arm-gic.h>
 #include <linux/irqchip/arm-gic-acpi.h>
@@ -48,7 +49,6 @@
 #include <asm/smp_plat.h>
 
 #include "irq-gic-common.h"
-#include "irqchip.h"
 
 union gic_base {
        void __iomem *common_base;
@@ -288,8 +288,8 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
 
 static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
 {
-       struct gic_chip_data *chip_data = irq_get_handler_data(irq);
-       struct irq_chip *chip = irq_get_chip(irq);
+       struct gic_chip_data *chip_data = irq_desc_get_handler_data(desc);
+       struct irq_chip *chip = irq_desc_get_chip(desc);
        unsigned int cascade_irq, gic_irq;
        unsigned long status;
 
@@ -324,16 +324,17 @@ static struct irq_chip gic_chip = {
 #endif
        .irq_get_irqchip_state  = gic_irq_get_irqchip_state,
        .irq_set_irqchip_state  = gic_irq_set_irqchip_state,
-       .flags                  = IRQCHIP_SET_TYPE_MASKED,
+       .flags                  = IRQCHIP_SET_TYPE_MASKED |
+                                 IRQCHIP_SKIP_SET_WAKE |
+                                 IRQCHIP_MASK_ON_SUSPEND,
 };
 
 void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
 {
        if (gic_nr >= MAX_GIC_NR)
                BUG();
-       if (irq_set_handler_data(irq, &gic_data[gic_nr]) != 0)
-               BUG();
-       irq_set_chained_handler(irq, gic_handle_cascade_irq);
+       irq_set_chained_handler_and_data(irq, gic_handle_cascade_irq,
+                                        &gic_data[gic_nr]);
 }
 
 static u8 gic_get_cpumask(struct gic_chip_data *gic)
@@ -401,19 +402,26 @@ static void gic_cpu_init(struct gic_chip_data *gic)
        int i;
 
        /*
-        * Get what the GIC says our CPU mask is.
+        * Setting up the CPU map is only relevant for the primary GIC
+        * because any nested/secondary GICs do not directly interface
+        * with the CPU(s).
         */
-       BUG_ON(cpu >= NR_GIC_CPU_IF);
-       cpu_mask = gic_get_cpumask(gic);
-       gic_cpu_map[cpu] = cpu_mask;
+       if (gic == &gic_data[0]) {
+               /*
+                * Get what the GIC says our CPU mask is.
+                */
+               BUG_ON(cpu >= NR_GIC_CPU_IF);
+               cpu_mask = gic_get_cpumask(gic);
+               gic_cpu_map[cpu] = cpu_mask;
 
-       /*
-        * Clear our mask from the other map entries in case they're
-        * still undefined.
-        */
-       for (i = 0; i < NR_GIC_CPU_IF; i++)
-               if (i != cpu)
-                       gic_cpu_map[i] &= ~cpu_mask;
+               /*
+                * Clear our mask from the other map entries in case they're
+                * still undefined.
+                */
+               for (i = 0; i < NR_GIC_CPU_IF; i++)
+                       if (i != cpu)
+                               gic_cpu_map[i] &= ~cpu_mask;
+       }
 
        gic_cpu_config(dist_base, NULL);
 
@@ -880,11 +888,6 @@ static const struct irq_domain_ops gic_irq_domain_ops = {
        .xlate = gic_irq_domain_xlate,
 };
 
-void gic_set_irqchip_flags(unsigned long flags)
-{
-       gic_chip.flags |= flags;
-}
-
 void __init gic_init_bases(unsigned int gic_nr, int irq_start,
                           void __iomem *dist_base, void __iomem *cpu_base,
                           u32 percpu_offset, struct device_node *node)
@@ -929,13 +932,6 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
                gic_set_base_accessor(gic, gic_get_common_base);
        }
 
-       /*
-        * Initialize the CPU interface map to all CPUs.
-        * It will be refined as each CPU probes its ID.
-        */
-       for (i = 0; i < NR_GIC_CPU_IF; i++)
-               gic_cpu_map[i] = 0xff;
-
        /*
         * Find out how many interrupts are supported.
         * The GIC only supports up to 1020 interrupt sources.
@@ -981,6 +977,13 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
                return;
 
        if (gic_nr == 0) {
+               /*
+                * Initialize the CPU interface map to all CPUs.
+                * It will be refined as each CPU probes its ID.
+                * This is only necessary for the primary GIC.
+                */
+               for (i = 0; i < NR_GIC_CPU_IF; i++)
+                       gic_cpu_map[i] = 0xff;
 #ifdef CONFIG_SMP
                set_smp_cross_call(gic_raise_softirq);
                register_cpu_notifier(&gic_cpu_notifier);
This page took 0.025919 seconds and 5 git commands to generate.