]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - kernel/irq/ipi.c
genirq: Add a new function to get IPI reverse mapping
[karo-tx-linux.git] / kernel / irq / ipi.c
index 340af273429ce22cdd02da2b6938d1d465cdeed3..6f34f2930bc06146c0201ab1796525c074d4d8b2 100644 (file)
@@ -135,3 +135,37 @@ void irq_destroy_ipi(unsigned int irq)
 
        irq_domain_free_irqs(irq, nr_irqs);
 }
+
+/**
+ * ipi_get_hwirq - Get the hwirq associated with an IPI to a cpu
+ * @irq:       linux irq number
+ * @cpu:       the target cpu
+ *
+ * When dealing with coprocessors IPI, we need to inform the coprocessor of
+ * the hwirq it needs to use to receive and send IPIs.
+ *
+ * Returns hwirq value on success and INVALID_HWIRQ on failure.
+ */
+irq_hw_number_t ipi_get_hwirq(unsigned int irq, unsigned int cpu)
+{
+       struct irq_data *data = irq_get_irq_data(irq);
+       struct cpumask *ipimask = data ? irq_data_get_affinity_mask(data) : NULL;
+
+       if (!data || !ipimask || cpu > nr_cpu_ids)
+               return INVALID_HWIRQ;
+
+       if (!cpumask_test_cpu(cpu, ipimask))
+               return INVALID_HWIRQ;
+
+       /*
+        * Get the real hardware irq number if the underlying implementation
+        * uses a seperate irq per cpu. If the underlying implementation uses
+        * a single hardware irq for all cpus then the IPI send mechanism
+        * needs to take care of this.
+        */
+       if (irq_domain_is_ipi_per_cpu(data->domain))
+               data = irq_get_irq_data(irq + cpu - data->common->ipi_offset);
+
+       return data ? irqd_to_hwirq(data) : INVALID_HWIRQ;
+}
+EXPORT_SYMBOL_GPL(ipi_get_hwirq);