bool    mask;
 } gic_all_vpes_chip_data[GIC_NUM_LOCAL_INTRS];
 
+static int __gic_with_next_online_cpu(int prev)
+{
+       unsigned int cpu;
+
+       /* Discover the next online CPU */
+       cpu = cpumask_next(prev, cpu_online_mask);
+
+       /* If there isn't one, we're done */
+       if (cpu >= nr_cpu_ids)
+               return cpu;
+
+       /*
+        * Move the access lock to the next CPU's GIC local register block.
+        *
+        * Set GIC_VL_OTHER. Since the caller holds gic_lock nothing can
+        * clobber the written value.
+        */
+       write_gic_vl_other(mips_cm_vp_id(cpu));
+
+       return cpu;
+}
+
+/**
+ * for_each_online_cpu_gic() - Iterate over online CPUs, access local registers
+ * @cpu: An integer variable to hold the current CPU number
+ * @gic_lock: A pointer to raw spin lock used as a guard
+ *
+ * Iterate over online CPUs & configure the other/redirect register region to
+ * access each CPUs GIC local register block, which can be accessed from the
+ * loop body using read_gic_vo_*() or write_gic_vo_*() accessor functions or
+ * their derivatives.
+ */
+#define for_each_online_cpu_gic(cpu, gic_lock)         \
+       guard(raw_spinlock_irqsave)(gic_lock);          \
+       for ((cpu) = __gic_with_next_online_cpu(-1);    \
+            (cpu) < nr_cpu_ids;                        \
+            (cpu) = __gic_with_next_online_cpu(cpu))
+
 static void gic_clear_pcpu_masks(unsigned int intr)
 {
        unsigned int i;
 static void gic_mask_local_irq_all_vpes(struct irq_data *d)
 {
        struct gic_all_vpes_chip_data *cd;
-       unsigned long flags;
        int intr, cpu;
 
        intr = GIC_HWIRQ_TO_LOCAL(d->hwirq);
        cd = irq_data_get_irq_chip_data(d);
        cd->mask = false;
 
-       raw_spin_lock_irqsave(&gic_lock, flags);
-       for_each_online_cpu(cpu) {
-               write_gic_vl_other(mips_cm_vp_id(cpu));
+       for_each_online_cpu_gic(cpu, &gic_lock)
                write_gic_vo_rmask(BIT(intr));
-       }
-       raw_spin_unlock_irqrestore(&gic_lock, flags);
 }
 
 static void gic_unmask_local_irq_all_vpes(struct irq_data *d)
 {
        struct gic_all_vpes_chip_data *cd;
-       unsigned long flags;
        int intr, cpu;
 
        intr = GIC_HWIRQ_TO_LOCAL(d->hwirq);
        cd = irq_data_get_irq_chip_data(d);
        cd->mask = true;
 
-       raw_spin_lock_irqsave(&gic_lock, flags);
-       for_each_online_cpu(cpu) {
-               write_gic_vl_other(mips_cm_vp_id(cpu));
+       for_each_online_cpu_gic(cpu, &gic_lock)
                write_gic_vo_smask(BIT(intr));
-       }
-       raw_spin_unlock_irqrestore(&gic_lock, flags);
 }
 
 static void gic_all_vpes_irq_cpu_online(void)
                              irq_hw_number_t hwirq)
 {
        struct gic_all_vpes_chip_data *cd;
-       unsigned long flags;
        unsigned int intr;
        int err, cpu;
        u32 map;
        if (!gic_local_irq_is_routable(intr))
                return -EPERM;
 
-       raw_spin_lock_irqsave(&gic_lock, flags);
-       for_each_online_cpu(cpu) {
-               write_gic_vl_other(mips_cm_vp_id(cpu));
+       for_each_online_cpu_gic(cpu, &gic_lock)
                write_gic_vo_map(mips_gic_vx_map_reg(intr), map);
-       }
-       raw_spin_unlock_irqrestore(&gic_lock, flags);
 
        return 0;
 }