[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