[PATCH 08/16] ARM: bL_platsmp.c: make sure the GIC interface of a dying CPU is disabled
Nicolas Pitre
nicolas.pitre at linaro.org
Wed Jan 9 19:20:43 EST 2013
Otherwise there might be some interrupts or IPIs becoming pending and the
CPU will not enter low power mode when doing a WFI. The effect of this
is a CPU that loops back into the kernel, go through the first man
election, signals itself as alive, and prevent the cluster from being
shut down.
This could benefit from a better solution.
Signed-off-by: Nicolas Pitre <nico at linaro.org>
---
arch/arm/common/bL_platsmp.c | 1 +
arch/arm/common/gic.c | 6 ++++++
arch/arm/include/asm/hardware/gic.h | 2 ++
3 files changed, 9 insertions(+)
diff --git a/arch/arm/common/bL_platsmp.c b/arch/arm/common/bL_platsmp.c
index 0ae44123bf..6a3b251b97 100644
--- a/arch/arm/common/bL_platsmp.c
+++ b/arch/arm/common/bL_platsmp.c
@@ -68,6 +68,7 @@ static void __ref bL_cpu_die(unsigned int cpu)
pcpu = mpidr & 0xff;
pcluster = (mpidr >> 8) & 0xff;
bL_set_entry_vector(pcpu, pcluster, NULL);
+ gic_cpu_if_down();
bL_cpu_power_down();
}
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 36ae03a3f5..760e8f4ca1 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -428,6 +428,12 @@ static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
writel_relaxed(1, base + GIC_CPU_CTRL);
}
+void gic_cpu_if_down(void)
+{
+ void __iomem *cpu_base = gic_data_cpu_base(&gic_data[0]);
+ writel_relaxed(0, cpu_base + GIC_CPU_CTRL);
+}
+
#ifdef CONFIG_CPU_PM
/*
* Saves the GIC distributor registers during suspend or idle. Must be called
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
index 4b1ce6cd47..2a7605492d 100644
--- a/arch/arm/include/asm/hardware/gic.h
+++ b/arch/arm/include/asm/hardware/gic.h
@@ -46,6 +46,8 @@ void gic_handle_irq(struct pt_regs *regs);
void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
+void gic_cpu_if_down(void);
+
static inline void gic_init(unsigned int nr, int start,
void __iomem *dist , void __iomem *cpu)
{
--
1.8.0
More information about the linux-arm-kernel
mailing list