blob: ef363d87c42e8c01d0072aef9d3361f3f2f685ff [file] [log] [blame]
From 60c59196f7164af18826c4e78be3c6f3b41ae963 Mon Sep 17 00:00:00 2001
From: Nicolas Pitre <nicolas.pitre@linaro.org>
Date: Wed, 28 Nov 2012 18:48:19 -0500
Subject: 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>
(cherry picked from commit 14d2ca615a85e2dbc744c12c296affd35f119fa7)
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
Conflicts:
drivers/irqchip/irq-gic.c
include/linux/irqchip/arm-gic.h
---
drivers/irqchip/irq-gic.c | 14 ++++++++++++++
include/linux/irqchip/arm-gic.h | 1 +
2 files changed, 15 insertions(+)
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index d87bbc03263a..70e4a3080029 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -674,6 +674,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_migrate_target - migrate IRQs to another CPU interface
*
* @new_cpu_id: the CPU target ID to migrate IRQs to
diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
index f829e00795b3..442f016df62c 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);
void gic_migrate_target(unsigned int new_cpu_id);
unsigned long gic_get_sgir_physaddr(void);
--
1.8.5.rc3