[linux-yocto] [PATCH 13/15] ARM: axxia: Alloc GIC to be initialized from non-primary core

Charlie Paul cpaul.windriver at gmail.com
Mon Apr 28 17:13:48 PDT 2014


From: Anders Berg <anders.berg at lsi.com>

The condition to only initialize the distributor interface from the primary
core of each cluster could fail when the primary core is not started (e.g. in a
crash kernel started via kexec). In this case, the one and only CPU may be any
core in a cluster.

This change handles this by initializing the GIC distributor interface via the
first CPU calling the init function, by keeping a state which clusters have
been initialized.

Signed-off-by: Anders Berg <anders.berg at lsi.com>
---
 arch/arm/mach-axxia/axxia-gic.c              |   22 ++++++++--------------
 arch/arm/mach-axxia/include/mach/axxia-gic.h |    1 -
 arch/arm/mach-axxia/platsmp.c                |   10 +---------
 3 files changed, 9 insertions(+), 24 deletions(-)

diff --git a/arch/arm/mach-axxia/axxia-gic.c b/arch/arm/mach-axxia/axxia-gic.c
index 8cfed90..53e525a 100644
--- a/arch/arm/mach-axxia/axxia-gic.c
+++ b/arch/arm/mach-axxia/axxia-gic.c
@@ -139,6 +139,7 @@ struct gic_chip_data {
 #endif
 	struct irq_domain *domain;
 	unsigned int gic_irqs;
+	unsigned long dist_init_done;
 };
 
 enum gic_rpc_func_mask {
@@ -572,8 +573,6 @@ static int gic_set_wake(struct irq_data *d, unsigned int on)
 #define gic_set_wake	NULL
 #endif
 
-#ifdef CONFIG_CPU_PM
-
 static u32 get_cluster_id(void)
 {
 	u32 mpidr, cluster;
@@ -591,6 +590,8 @@ static u32 get_cluster_id(void)
 	return cluster;
 }
 
+#ifdef CONFIG_CPU_PM
+
 /*
  * Saves the GIC distributor registers during suspend or idle.  Must be called
  * with interrupts disabled but before powering down the GIC.  After calling
@@ -1057,6 +1058,10 @@ static void __cpuinit gic_dist_init(struct gic_chip_data *gic)
 	u32 enableoff;
 	u32 val;
 
+	/* Initialize the distributor interface once per CPU cluster */
+	if (test_and_set_bit(get_cluster_id(), &gic->dist_init_done))
+		return;
+
 	cpumask = 1 << cpu;
 	cpumask |= cpumask << 8;
 	cpumask |= cpumask << 16;
@@ -1351,21 +1356,10 @@ void __init axxia_gic_init_bases(int irq_start,
 
 void __cpuinit axxia_gic_secondary_init(void)
 {
-	gic_cpu_init(&gic_data);
-}
-
-
-void __cpuinit axxia_gic_secondary_cluster_init(void)
-{
 	struct gic_chip_data *gic = &gic_data;
 
-	/*
-	 * Initialize the GIC distributor and cpu interfaces
-	 * for secondary clusters in the Axxia SoC.
-	 */
-
 	gic_dist_init(gic);
-	gic_cpu_init(gic);
+	gic_cpu_init(&gic_data);
 }
 
 #ifdef CONFIG_OF
diff --git a/arch/arm/mach-axxia/include/mach/axxia-gic.h b/arch/arm/mach-axxia/include/mach/axxia-gic.h
index 9ca0609..af7fbdf 100644
--- a/arch/arm/mach-axxia/include/mach/axxia-gic.h
+++ b/arch/arm/mach-axxia/include/mach/axxia-gic.h
@@ -9,7 +9,6 @@
 #define __AXXIA_GIC_H
 
 void axxia_gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
-void axxia_gic_secondary_cluster_init(void);
 void axxia_gic_secondary_init(void);
 int __init axxia_gic_of_init(struct device_node *node,
 			     struct device_node *parent);
diff --git a/arch/arm/mach-axxia/platsmp.c b/arch/arm/mach-axxia/platsmp.c
index dec7b5b..7975c44 100644
--- a/arch/arm/mach-axxia/platsmp.c
+++ b/arch/arm/mach-axxia/platsmp.c
@@ -80,15 +80,7 @@ void __cpuinit axxia_secondary_init(unsigned int cpu)
 	/* Fixup for cross-cluster SEV */
 	do_fixup_sev();
 
-	/*
-	 * If this isn't the first physical core in a secondary cluster
-	 * then run the standard GIC secondary init routine. Otherwise,
-	 * run the Axxia secondary cluster init routine.
-	 */
-	if (cpu_logical_map(cpu) % 4)
-		axxia_gic_secondary_init();
-	else
-		axxia_gic_secondary_cluster_init();
+	axxia_gic_secondary_init();
 
 	/*
 	 * Let the primary processor know we're out of the
-- 
1.7.9.5



More information about the linux-yocto mailing list