]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
irqchip/mips-gic: Setup defaults in each cluster
authorChao-ying Fu <cfu@wavecomp.com>
Mon, 28 Oct 2024 17:59:25 +0000 (18:59 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Wed, 30 Oct 2024 14:41:18 +0000 (15:41 +0100)
In multi-cluster MIPS I6500 systems, there is a GIC per cluster.

The default shared interrupt setup configured in gic_of_init() applies only
to the GIC in the cluster containing the boot CPU, leaving the GICs of
other clusters unconfigured.

Configure the other clusters as well.

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-4-arikalo@gmail.com
drivers/irqchip/irq-mips-gic.c

index 29bdfdce2123e207c757297b70ccd5b964759704..d93a076620c7c16a5d73ca0e3ed438f7e59f17e9 100644 (file)
@@ -764,7 +764,7 @@ static int gic_cpu_startup(unsigned int cpu)
 static int __init gic_of_init(struct device_node *node,
                              struct device_node *parent)
 {
-       unsigned int cpu_vec, i, gicconfig;
+       unsigned int cpu_vec, i, gicconfig, cl, nclusters;
        unsigned long reserved;
        phys_addr_t gic_base;
        struct resource res;
@@ -845,11 +845,29 @@ static int __init gic_of_init(struct device_node *node,
 
        board_bind_eic_interrupt = &gic_bind_eic_interrupt;
 
-       /* Setup defaults */
-       for (i = 0; i < gic_shared_intrs; i++) {
-               change_gic_pol(i, GIC_POL_ACTIVE_HIGH);
-               change_gic_trig(i, GIC_TRIG_LEVEL);
-               write_gic_rmask(i);
+       /*
+        * Initialise each cluster's GIC shared registers to sane default
+        * values.
+        * Otherwise, the IPI set up will be erased if we move code
+        * to gic_cpu_startup for each cpu.
+        */
+       nclusters = mips_cps_numclusters();
+       for (cl = 0; cl < nclusters; cl++) {
+               if (cl == cpu_cluster(&current_cpu_data)) {
+                       for (i = 0; i < gic_shared_intrs; i++) {
+                               change_gic_pol(i, GIC_POL_ACTIVE_HIGH);
+                               change_gic_trig(i, GIC_TRIG_LEVEL);
+                               write_gic_rmask(i);
+                       }
+               } else {
+                       mips_cm_lock_other(cl, 0, 0, CM_GCR_Cx_OTHER_BLOCK_GLOBAL);
+                       for (i = 0; i < gic_shared_intrs; i++) {
+                               change_gic_redir_pol(i, GIC_POL_ACTIVE_HIGH);
+                               change_gic_redir_trig(i, GIC_TRIG_LEVEL);
+                               write_gic_redir_rmask(i);
+                       }
+                       mips_cm_unlock_other();
+               }
        }
 
        return cpuhp_setup_state(CPUHP_AP_IRQ_MIPS_GIC_STARTING,