irq_hw_number_t *out_hwirq, unsigned int *out_type);
/* IPI functions */
-unsigned int irq_reserve_ipi(struct irq_domain *domain,
- const struct cpumask *dest);
-void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest);
+int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest);
+int irq_destroy_ipi(unsigned int irq, const struct cpumask *dest);
/* V2 interfaces to support hierarchy IRQ domains. */
extern struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain,
*
* 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;
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)) {
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,
free_descs:
irq_free_descs(virq, nr_irqs);
- return 0;
+ return -EBUSY;
}
/**
* @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;
unsigned int nr_irqs;
if (!irq || !data || !ipimask)
- return;
+ return -EINVAL;
domain = data->domain;
if (WARN_ON(domain == NULL))
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)))
* 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;
}
irq_domain_free_irqs(irq, nr_irqs);
+ return 0;
}
/**