]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
irqchip/mips-gic: Replace open coded online CPU iterations
authorPaul Burton <paulburton@kernel.org>
Mon, 28 Oct 2024 17:59:23 +0000 (18:59 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Wed, 30 Oct 2024 14:41:18 +0000 (15:41 +0100)
Several places in the MIPS GIC driver iterate over the online CPUs to
operate on the CPU's GIC local register block, accessed via the GIC's
other/redirect register block.

Abstract the process of iterating over online CPUs & configuring the
other/redirect region to access their registers through a new
for_each_online_cpu_gic() macro and convert all usage sites over.

Signed-off-by: Paul Burton <paulburton@kernel.org>
Signed-off-by: Chao-ying Fu <cfu@wavecomp.com>
Signed-off-by: Dragan Mladjenovic <dragan.mladjenovic@syrmia.com>
Signed-off-by: Aleksandar Rikalo <arikalo@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Serge Semin <fancer.lancer@gmail.com>
Tested-by: Gregory CLEMENT <gregory.clement@bootlin.com>
Link: https://lore.kernel.org/all/20241028175935.51250-2-arikalo@gmail.com
drivers/irqchip/irq-mips-gic.c

index 76253e864f23049b0bd8246465690741654bafe2..6c7a7d2f0438570be6649fad24ee7d4a5f77ba01 100644 (file)
@@ -66,6 +66,44 @@ static struct gic_all_vpes_chip_data {
        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;
@@ -350,37 +388,27 @@ static struct irq_chip gic_local_irq_controller = {
 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)
@@ -469,7 +497,6 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq,
                              irq_hw_number_t hwirq)
 {
        struct gic_all_vpes_chip_data *cd;
-       unsigned long flags;
        unsigned int intr;
        int err, cpu;
        u32 map;
@@ -533,12 +560,8 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq,
        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;
 }