|
@@ -19,9 +19,9 @@
|
|
|
*
|
|
|
* Allocate a virq that can be used to send IPI to any CPU in dest mask.
|
|
|
*
|
|
|
- * On success it'll return linux irq number and 0 on failure
|
|
|
+ * On success it'll return linux irq number and error code on failure
|
|
|
*/
|
|
|
-unsigned int irq_reserve_ipi(struct irq_domain *domain,
|
|
|
+int irq_reserve_ipi(struct irq_domain *domain,
|
|
|
const struct cpumask *dest)
|
|
|
{
|
|
|
unsigned int nr_irqs, offset;
|
|
@@ -30,18 +30,18 @@ unsigned int irq_reserve_ipi(struct irq_domain *domain,
|
|
|
|
|
|
if (!domain ||!irq_domain_is_ipi(domain)) {
|
|
|
pr_warn("Reservation on a non IPI domain\n");
|
|
|
- return 0;
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
|
|
|
if (!cpumask_subset(dest, cpu_possible_mask)) {
|
|
|
pr_warn("Reservation is not in possible_cpu_mask\n");
|
|
|
- return 0;
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
|
|
|
nr_irqs = cpumask_weight(dest);
|
|
|
if (!nr_irqs) {
|
|
|
pr_warn("Reservation for empty destination mask\n");
|
|
|
- return 0;
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
|
|
|
if (irq_domain_is_ipi_single(domain)) {
|
|
@@ -72,14 +72,14 @@ unsigned int irq_reserve_ipi(struct irq_domain *domain,
|
|
|
next = cpumask_next(next, dest);
|
|
|
if (next < nr_cpu_ids) {
|
|
|
pr_warn("Destination mask has holes\n");
|
|
|
- return 0;
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
virq = irq_domain_alloc_descs(-1, nr_irqs, 0, NUMA_NO_NODE);
|
|
|
if (virq <= 0) {
|
|
|
pr_warn("Can't reserve IPI, failed to alloc descs\n");
|
|
|
- return 0;
|
|
|
+ return -ENOMEM;
|
|
|
}
|
|
|
|
|
|
virq = __irq_domain_alloc_irqs(domain, virq, nr_irqs, NUMA_NO_NODE,
|
|
@@ -100,7 +100,7 @@ unsigned int irq_reserve_ipi(struct irq_domain *domain,
|
|
|
|
|
|
free_descs:
|
|
|
irq_free_descs(virq, nr_irqs);
|
|
|
- return 0;
|
|
|
+ return -EBUSY;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -108,10 +108,12 @@ free_descs:
|
|
|
* @irq: linux irq number to be destroyed
|
|
|
* @dest: cpumask of cpus which should have the IPI removed
|
|
|
*
|
|
|
- * Return the IPIs allocated with irq_reserve_ipi() to the system destroying
|
|
|
- * all virqs associated with them.
|
|
|
+ * The IPIs allocated with irq_reserve_ipi() are retuerned to the system
|
|
|
+ * destroying all virqs associated with them.
|
|
|
+ *
|
|
|
+ * Return 0 on success or error code on failure.
|
|
|
*/
|
|
|
-void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest)
|
|
|
+int irq_destroy_ipi(unsigned int irq, const struct cpumask *dest)
|
|
|
{
|
|
|
struct irq_data *data = irq_get_irq_data(irq);
|
|
|
struct cpumask *ipimask = data ? irq_data_get_affinity_mask(data) : NULL;
|
|
@@ -119,7 +121,7 @@ void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest)
|
|
|
unsigned int nr_irqs;
|
|
|
|
|
|
if (!irq || !data || !ipimask)
|
|
|
- return;
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
domain = data->domain;
|
|
|
if (WARN_ON(domain == NULL))
|
|
@@ -127,7 +129,7 @@ void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest)
|
|
|
|
|
|
if (!irq_domain_is_ipi(domain)) {
|
|
|
pr_warn("Trying to destroy a non IPI domain!\n");
|
|
|
- return;
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
|
|
|
if (WARN_ON(!cpumask_subset(dest, ipimask)))
|
|
@@ -135,7 +137,7 @@ void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest)
|
|
|
* Must be destroying a subset of CPUs to which this IPI
|
|
|
* was set up to target
|
|
|
*/
|
|
|
- return;
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
if (irq_domain_is_ipi_per_cpu(domain)) {
|
|
|
irq = irq + cpumask_first(dest) - data->common->ipi_offset;
|
|
@@ -145,6 +147,7 @@ void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest)
|
|
|
}
|
|
|
|
|
|
irq_domain_free_irqs(irq, nr_irqs);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
/**
|