Commit 01292cea authored by Matt Redfearn's avatar Matt Redfearn Committed by Thomas Gleixner

genirq: Make irq_destroy_ipi take a cpumask of IPIs to destroy

Previously irq_destroy_ipi() would destroy IPIs to all CPUs that were
configured by irq_reserve_ipi(). This change makes it possible to
destroy just a subset of the IPIs. This may be useful to remove IPIs to
CPUs that have been hot removed so that the IRQ numbers allocated within
the IPI domain can be re-used.

The original behaviour is restored by passing the complete mask that the
IPI was created with.

There are currently no users of this function that would break from the
API change.
Signed-off-by: default avatarMatt Redfearn <matt.redfearn@imgtec.com>
Cc: linux-mips@linux-mips.org
Cc: jason@lakedaemon.net
Cc: marc.zyngier@arm.com
Cc: ralf@linux-mips.org
Cc: Qais Yousef <qsyousef@gmail.com>
Cc: lisa.parratt@imgtec.com
Cc: jiang.liu@linux.intel.com
Link: http://lkml.kernel.org/r/1461568464-31701-1-git-send-email-matt.redfearn@imgtec.comSigned-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent b75a2bf8
...@@ -348,7 +348,7 @@ int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr, ...@@ -348,7 +348,7 @@ int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr,
/* IPI functions */ /* IPI functions */
unsigned int irq_reserve_ipi(struct irq_domain *domain, unsigned int irq_reserve_ipi(struct irq_domain *domain,
const struct cpumask *dest); const struct cpumask *dest);
void irq_destroy_ipi(unsigned int irq); void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest);
/* V2 interfaces to support hierarchy IRQ domains. */ /* V2 interfaces to support hierarchy IRQ domains. */
extern struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain, extern struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain,
......
...@@ -106,11 +106,12 @@ unsigned int irq_reserve_ipi(struct irq_domain *domain, ...@@ -106,11 +106,12 @@ unsigned int irq_reserve_ipi(struct irq_domain *domain,
/** /**
* irq_destroy_ipi() - unreserve an IPI that was previously allocated * irq_destroy_ipi() - unreserve an IPI that was previously allocated
* @irq: linux irq number to be destroyed * @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 * Return the IPIs allocated with irq_reserve_ipi() to the system destroying
* all virqs associated with them. * all virqs associated with them.
*/ */
void irq_destroy_ipi(unsigned int irq) void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest)
{ {
struct irq_data *data = irq_get_irq_data(irq); struct irq_data *data = irq_get_irq_data(irq);
struct cpumask *ipimask = data ? irq_data_get_affinity_mask(data) : NULL; struct cpumask *ipimask = data ? irq_data_get_affinity_mask(data) : NULL;
...@@ -129,10 +130,19 @@ void irq_destroy_ipi(unsigned int irq) ...@@ -129,10 +130,19 @@ void irq_destroy_ipi(unsigned int irq)
return; return;
} }
if (irq_domain_is_ipi_per_cpu(domain)) if (WARN_ON(!cpumask_subset(dest, ipimask)))
nr_irqs = cpumask_weight(ipimask); /*
else * Must be destroying a subset of CPUs to which this IPI
* was set up to target
*/
return;
if (irq_domain_is_ipi_per_cpu(domain)) {
irq = irq + cpumask_first(dest) - data->common->ipi_offset;
nr_irqs = cpumask_weight(dest);
} else {
nr_irqs = 1; nr_irqs = 1;
}
irq_domain_free_irqs(irq, nr_irqs); irq_domain_free_irqs(irq, nr_irqs);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment