aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Pitre <nicolas.pitre@linaro.org>2012-11-28 18:48:19 -0500
committerNicolas Pitre <nicolas.pitre@linaro.org>2013-05-13 19:03:36 -0400
commite5ec0e38d6b3cca881b125db20dddd50d7eecbbf (patch)
tree5e2286d009c0ec1263467d8ae85cbca82478b9c8
parent3410b145bc6f1fb7a2dd6ee520f0234232bee152 (diff)
downloadvexpress-lsk-e5ec0e38d6b3cca881b125db20dddd50d7eecbbf.tar.gz
ARM: GIC: interface to send a SGI directly
The regular gic_raise_softirq() takes as input a CPU mask which is not adequate when we need to send an IPI to a CPU which is not represented in the kernel to GIC mapping. That is the case with the b.L switcher when GIC migration to the inbound CPU has not yet occurred. Signed-off-by: Nicolas Pitre <nico@linaro.org>
-rw-r--r--drivers/irqchip/irq-gic.c14
-rw-r--r--include/linux/irqchip/arm-gic.h1
2 files changed, 15 insertions, 0 deletions
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index a760f6b1b44..1186096e497 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -666,6 +666,20 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
#ifdef CONFIG_BL_SWITCHER
/*
+ * gic_send_sgi - send a SGI directly to given CPU interface number
+ *
+ * cpu_id: the ID for the destination CPU interface
+ * irq: the IPI number to send a SGI for
+ */
+void gic_send_sgi(unsigned int cpu_id, unsigned int irq)
+{
+ BUG_ON(cpu_id >= NR_GIC_CPU_IF);
+ cpu_id = 1 << cpu_id;
+ /* this always happens on GIC0 */
+ writel_relaxed((cpu_id << 16) | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT);
+}
+
+/*
* gic_get_cpu_id - get the CPU interface ID for the specified CPU
*
* @cpu: the logical CPU number to get the GIC ID for.
diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
index 00795de5dc6..9692a6efd59 100644
--- a/include/linux/irqchip/arm-gic.h
+++ b/include/linux/irqchip/arm-gic.h
@@ -76,6 +76,7 @@ static inline void gic_init(unsigned int nr, int start,
gic_init_bases(nr, start, dist, cpu, 0, NULL);
}
+void gic_send_sgi(unsigned int cpu_id, unsigned int irq);
int gic_get_cpu_id(unsigned int cpu);
void gic_migrate_target(unsigned int new_cpu_id);
unsigned long gic_get_sgir_physaddr(void);