summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQais Yousef <qais.yousef@imgtec.com>2015-12-08 08:20:20 -0500
committerThomas Gleixner <tglx@linutronix.de>2016-02-25 04:56:56 -0500
commitf9bce791ae2a1a10a965b30427f5507c1a77669f (patch)
tree73095b50502e126c58b16a05cfba733fee8648df
parentd17bf24e695290d3fe7943aca52ab48098a10653 (diff)
genirq: Add a new function to get IPI reverse mapping
When dealing with coprocessors we need to find out the actual hwirqs values to pass on to the firmware so that it knows what it needs to use to receive IPIs from and send IPIs to Linux cpus. [ tglx: Fixed the single hwirq IPI case. The hardware irq number does not change due to the cpu number ] Signed-off-by: Qais Yousef <qais.yousef@imgtec.com> Cc: <jason@lakedaemon.net> Cc: <marc.zyngier@arm.com> Cc: <jiang.liu@linux.intel.com> Cc: <ralf@linux-mips.org> Cc: <linux-mips@linux-mips.org> Cc: <lisa.parratt@imgtec.com> Cc: Qais Yousef <qsyousef@gmail.com> Link: http://lkml.kernel.org/r/1449580830-23652-10-git-send-email-qais.yousef@imgtec.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--include/linux/irq.h1
-rw-r--r--kernel/irq/ipi.c34
2 files changed, 35 insertions, 0 deletions
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 95f4f66f95f3..10273dce058a 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -942,5 +942,6 @@ static inline u32 irq_reg_readl(struct irq_chip_generic *gc,
942 942
943/* Contrary to Linux irqs, for hardware irqs the irq number 0 is valid */ 943/* Contrary to Linux irqs, for hardware irqs the irq number 0 is valid */
944#define INVALID_HWIRQ (~0UL) 944#define INVALID_HWIRQ (~0UL)
945irq_hw_number_t ipi_get_hwirq(unsigned int irq, unsigned int cpu);
945 946
946#endif /* _LINUX_IRQ_H */ 947#endif /* _LINUX_IRQ_H */
diff --git a/kernel/irq/ipi.c b/kernel/irq/ipi.c
index 340af273429c..6f34f2930bc0 100644
--- a/kernel/irq/ipi.c
+++ b/kernel/irq/ipi.c
@@ -135,3 +135,37 @@ void irq_destroy_ipi(unsigned int irq)
135 135
136 irq_domain_free_irqs(irq, nr_irqs); 136 irq_domain_free_irqs(irq, nr_irqs);
137} 137}
138
139/**
140 * ipi_get_hwirq - Get the hwirq associated with an IPI to a cpu
141 * @irq: linux irq number
142 * @cpu: the target cpu
143 *
144 * When dealing with coprocessors IPI, we need to inform the coprocessor of
145 * the hwirq it needs to use to receive and send IPIs.
146 *
147 * Returns hwirq value on success and INVALID_HWIRQ on failure.
148 */
149irq_hw_number_t ipi_get_hwirq(unsigned int irq, unsigned int cpu)
150{
151 struct irq_data *data = irq_get_irq_data(irq);
152 struct cpumask *ipimask = data ? irq_data_get_affinity_mask(data) : NULL;
153
154 if (!data || !ipimask || cpu > nr_cpu_ids)
155 return INVALID_HWIRQ;
156
157 if (!cpumask_test_cpu(cpu, ipimask))
158 return INVALID_HWIRQ;
159
160 /*
161 * Get the real hardware irq number if the underlying implementation
162 * uses a seperate irq per cpu. If the underlying implementation uses
163 * a single hardware irq for all cpus then the IPI send mechanism
164 * needs to take care of this.
165 */
166 if (irq_domain_is_ipi_per_cpu(data->domain))
167 data = irq_get_irq_data(irq + cpu - data->common->ipi_offset);
168
169 return data ? irqd_to_hwirq(data) : INVALID_HWIRQ;
170}
171EXPORT_SYMBOL_GPL(ipi_get_hwirq);