genirq: Add error code reporting to irq_{reserve,destroy}_ipi
[cascardo/linux.git] / kernel / irq / ipi.c
index bedc995..c427422 100644 (file)
@@ -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;
 }
 
 /**