]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/irqchip/irq-gic-v3.c
Merge branch 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorri...
[linux.git] / drivers / irqchip / irq-gic-v3.c
index d5912f1ec8848d19ff93161102d6690eb7bb43d2..8f87f40c946092ae0c709db458d56ef1f79c9672 100644 (file)
@@ -348,48 +348,45 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
 {
        u32 irqnr;
 
-       do {
-               irqnr = gic_read_iar();
+       irqnr = gic_read_iar();
 
-               if (likely(irqnr > 15 && irqnr < 1020) || irqnr >= 8192) {
-                       int err;
+       if (likely(irqnr > 15 && irqnr < 1020) || irqnr >= 8192) {
+               int err;
 
-                       if (static_branch_likely(&supports_deactivate_key))
+               if (static_branch_likely(&supports_deactivate_key))
+                       gic_write_eoir(irqnr);
+               else
+                       isb();
+
+               err = handle_domain_irq(gic_data.domain, irqnr, regs);
+               if (err) {
+                       WARN_ONCE(true, "Unexpected interrupt received!\n");
+                       if (static_branch_likely(&supports_deactivate_key)) {
+                               if (irqnr < 8192)
+                                       gic_write_dir(irqnr);
+                       } else {
                                gic_write_eoir(irqnr);
-                       else
-                               isb();
-
-                       err = handle_domain_irq(gic_data.domain, irqnr, regs);
-                       if (err) {
-                               WARN_ONCE(true, "Unexpected interrupt received!\n");
-                               if (static_branch_likely(&supports_deactivate_key)) {
-                                       if (irqnr < 8192)
-                                               gic_write_dir(irqnr);
-                               } else {
-                                       gic_write_eoir(irqnr);
-                               }
                        }
-                       continue;
                }
-               if (irqnr < 16) {
-                       gic_write_eoir(irqnr);
-                       if (static_branch_likely(&supports_deactivate_key))
-                               gic_write_dir(irqnr);
+               return;
+       }
+       if (irqnr < 16) {
+               gic_write_eoir(irqnr);
+               if (static_branch_likely(&supports_deactivate_key))
+                       gic_write_dir(irqnr);
 #ifdef CONFIG_SMP
-                       /*
-                        * Unlike GICv2, we don't need an smp_rmb() here.
-                        * The control dependency from gic_read_iar to
-                        * the ISB in gic_write_eoir is enough to ensure
-                        * that any shared data read by handle_IPI will
-                        * be read after the ACK.
-                        */
-                       handle_IPI(irqnr, regs);
+               /*
+                * Unlike GICv2, we don't need an smp_rmb() here.
+                * The control dependency from gic_read_iar to
+                * the ISB in gic_write_eoir is enough to ensure
+                * that any shared data read by handle_IPI will
+                * be read after the ACK.
+                */
+               handle_IPI(irqnr, regs);
 #else
-                       WARN_ONCE(true, "Unexpected SGI received!\n");
+               WARN_ONCE(true, "Unexpected SGI received!\n");
 #endif
-                       continue;
-               }
-       } while (irqnr != ICC_IAR1_EL1_SPURIOUS);
+       }
 }
 
 static void __init gic_dist_init(void)
@@ -653,7 +650,9 @@ early_param("irqchip.gicv3_nolpi", gicv3_nolpi_cfg);
 
 static int gic_dist_supports_lpis(void)
 {
-       return !!(readl_relaxed(gic_data.dist_base + GICD_TYPER) & GICD_TYPER_LPIS) && !gicv3_nolpi;
+       return (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) &&
+               !!(readl_relaxed(gic_data.dist_base + GICD_TYPER) & GICD_TYPER_LPIS) &&
+               !gicv3_nolpi);
 }
 
 static void gic_cpu_init(void)
@@ -673,10 +672,6 @@ static void gic_cpu_init(void)
 
        gic_cpu_config(rbase, gic_redist_wait_for_rwp);
 
-       /* Give LPIs a spin */
-       if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis())
-               its_cpu_init();
-
        /* initialise system registers */
        gic_cpu_sys_reg_init();
 }
@@ -689,6 +684,10 @@ static void gic_cpu_init(void)
 static int gic_starting_cpu(unsigned int cpu)
 {
        gic_cpu_init();
+
+       if (gic_dist_supports_lpis())
+               its_cpu_init();
+
        return 0;
 }
 
@@ -1127,14 +1126,16 @@ static int __init gic_init_bases(void __iomem *dist_base,
 
        gic_update_vlpi_properties();
 
-       if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis())
-               its_init(handle, &gic_data.rdists, gic_data.domain);
-
        gic_smp_init();
        gic_dist_init();
        gic_cpu_init();
        gic_cpu_pm_init();
 
+       if (gic_dist_supports_lpis()) {
+               its_init(handle, &gic_data.rdists, gic_data.domain);
+               its_cpu_init();
+       }
+
        return 0;
 
 out_free: