From: lorenzo.pieralisi@arm.com (Lorenzo Pieralisi)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v4 7/7] ARM: gic: use a private mapping for CPU target interfaces
Date: Mon, 19 Nov 2012 12:45:06 +0000 [thread overview]
Message-ID: <1353329106-24084-8-git-send-email-lorenzo.pieralisi@arm.com> (raw)
In-Reply-To: <1353329106-24084-1-git-send-email-lorenzo.pieralisi@arm.com>
From: Nicolas Pitre <nicolas.pitre@linaro.org>
The GIC interface numbering does not necessarily follow the logical
CPU numbering, especially for complex topologies such as multi-cluster
systems.
Fortunately we can easily probe the GIC to create a mapping as the
Interrupt Processor Targets Registers for the first 32 interrupts are
read-only, and each field returns a value that always corresponds to
the processor reading the register.
Initially all mappings target all CPUs in case an IPI is required to
boot secondary CPUs. It is refined as those CPUs discover what their
actual mapping is.
Signed-off-by: Nicolas Pitre <nico@linaro.org>
Acked-by: Will Deacon <will.deacon@arm.com>
---
arch/arm/common/gic.c | 45 ++++++++++++++++++++++++++++++++++++---------
1 file changed, 36 insertions(+), 9 deletions(-)
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 50c9eef..2203c92 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -70,6 +70,14 @@ struct gic_chip_data {
static DEFINE_RAW_SPINLOCK(irq_controller_lock);
/*
+ * The GIC mapping of CPU interfaces does not necessarily match
+ * the logical CPU numbering. Let's use a mapping as returned
+ * by the GIC itself.
+ */
+#define NR_GIC_CPU_IF 8
+static u8 gic_cpu_map[NR_GIC_CPU_IF] __read_mostly;
+
+/*
* Supported arch specific GIC irq extension.
* Default make them NULL.
*/
@@ -238,11 +246,11 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
u32 val, mask, bit;
- if (cpu >= 8 || cpu >= nr_cpu_ids)
+ if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids)
return -EINVAL;
mask = 0xff << shift;
- bit = 1 << (cpu_logical_map(cpu) + shift);
+ bit = gic_cpu_map[cpu] << shift;
raw_spin_lock(&irq_controller_lock);
val = readl_relaxed(reg) & ~mask;
@@ -349,11 +357,6 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
u32 cpumask;
unsigned int gic_irqs = gic->gic_irqs;
void __iomem *base = gic_data_dist_base(gic);
- u32 cpu = cpu_logical_map(smp_processor_id());
-
- cpumask = 1 << cpu;
- cpumask |= cpumask << 8;
- cpumask |= cpumask << 16;
writel_relaxed(0, base + GIC_DIST_CTRL);
@@ -366,6 +369,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
/*
* Set all global interrupts to this CPU only.
*/
+ cpumask = readl_relaxed(base + GIC_DIST_TARGET + 0);
for (i = 32; i < gic_irqs; i += 4)
writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
@@ -389,9 +393,25 @@ static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
{
void __iomem *dist_base = gic_data_dist_base(gic);
void __iomem *base = gic_data_cpu_base(gic);
+ unsigned int cpu_mask, cpu = smp_processor_id();
int i;
/*
+ * Get what the GIC says our CPU mask is.
+ */
+ BUG_ON(cpu >= NR_GIC_CPU_IF);
+ cpu_mask = readl_relaxed(dist_base + GIC_DIST_TARGET + 0);
+ gic_cpu_map[cpu] = cpu_mask;
+
+ /*
+ * Clear our mask from the other map entries in case they're
+ * still undefined.
+ */
+ for (i = 0; i < NR_GIC_CPU_IF; i++)
+ if (i != cpu)
+ gic_cpu_map[i] &= ~cpu_mask;
+
+ /*
* Deal with the banked PPI and SGI interrupts - disable all
* PPI interrupts, ensure all SGI interrupts are enabled.
*/
@@ -654,7 +674,7 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
{
irq_hw_number_t hwirq_base;
struct gic_chip_data *gic;
- int gic_irqs, irq_base;
+ int gic_irqs, irq_base, i;
BUG_ON(gic_nr >= MAX_GIC_NR);
@@ -692,6 +712,13 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
}
/*
+ * Initialize the CPU interface map to all CPUs.
+ * It will be refined as each CPU probes its ID.
+ */
+ for (i = 0; i < NR_GIC_CPU_IF; i++)
+ gic_cpu_map[i] = 0xff;
+
+ /*
* For primary GICs, skip over SGIs.
* For secondary GICs, skip over PPIs, too.
*/
@@ -746,7 +773,7 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
/* Convert our logical CPU mask into a physical one. */
for_each_cpu(cpu, mask)
- map |= 1 << cpu_logical_map(cpu);
+ map |= gic_cpu_map[cpu];
/*
* Ensure that stores to Normal memory are visible to the
--
1.7.12
prev parent reply other threads:[~2012-11-19 12:45 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-11-19 12:44 [PATCH v4 0/7] ARM: multi-cluster aware boot protocol Lorenzo Pieralisi
2012-11-19 12:45 ` [PATCH v4 1/7] ARM: kernel: enhance MPIDR macro definitions Lorenzo Pieralisi
2012-11-19 13:44 ` Will Deacon
2012-11-19 15:37 ` Nicolas Pitre
2012-11-19 12:45 ` [PATCH v4 2/7] ARM: kernel: update topology to use new MPIDR macros Lorenzo Pieralisi
2012-11-19 13:45 ` Will Deacon
2012-11-19 15:38 ` Nicolas Pitre
2012-11-19 12:45 ` [PATCH v4 3/7] ARM: kernel: smp_setup_processor_id() updates Lorenzo Pieralisi
2012-11-19 13:45 ` Will Deacon
2012-11-19 12:45 ` [PATCH v4 4/7] ARM: kernel: add device tree init map function Lorenzo Pieralisi
2012-11-19 13:54 ` Mark Rutland
2012-11-19 14:07 ` Lorenzo Pieralisi
2012-11-19 12:45 ` [PATCH v4 5/7] ARM: kernel: add cpu logical map DT init in setup_arch Lorenzo Pieralisi
2012-11-19 12:45 ` [PATCH v4 6/7] ARM: kernel: add logical mappings look-up Lorenzo Pieralisi
2012-11-19 12:45 ` Lorenzo Pieralisi [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1353329106-24084-8-git-send-email-lorenzo.pieralisi@arm.com \
--to=lorenzo.pieralisi@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox