Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2fd144aa authored by Prakruthi Deepak Heragu's avatar Prakruthi Deepak Heragu Committed by Gerrit - the friendly Code Review server
Browse files

irqdomain: Implement and expose API to clear IRQ mapping for radix tree



The irq_domain_remove() API expects all the irqs of the domain be cleared
before it is called, else it throws a warning. A framework creating a
radix tree to map all the irqs used by its clients cannot be sure if all
the clients cleared their irqs. Thus to avoid this warning, we can use
this API irq_dispose_all_tree_mappings() to ensure that all irqs
belonging to the domain are cleared before the domain is itself removed.

Change-Id: Ied1f20c990aba9d4760091d9ed3d48c3e4f3d5d9
Signed-off-by: default avatarPrakruthi Deepak Heragu <pheragu@codeaurora.org>
parent e99d7055
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@
#include <linux/of.h>
#include <linux/mutex.h>
#include <linux/radix-tree.h>
#include <linux/slab.h>
#include <linux/irq.h>

struct device_node;
struct irq_domain;
@@ -380,6 +382,37 @@ extern unsigned int irq_create_mapping(struct irq_domain *host,
extern unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec);
extern void irq_dispose_mapping(unsigned int virq);

/**
* irq_dispose_all_tree_mappings() - Unmaps all interrupts from a domain
* @domain: domain owning the interrupt range
*
* This routine helps unmap all the interrupts that were mapped to the
* domain using a radix tree.
*/
static inline void irq_dispose_all_tree_mappings(
					struct irq_domain *domain)
{
	struct irq_data **irq_data;
	unsigned int num_irqs = 0;
	unsigned int max_irqs = domain->mapcount;
	unsigned int index = 0;

	if (!max_irqs)
		return;

	irq_data = kcalloc(max_irqs, sizeof(*irq_data), GFP_KERNEL);
	if (!irq_data)
		return;

	rcu_read_lock();
	num_irqs = radix_tree_gang_lookup(&domain->revmap_tree,
					(void **)irq_data, 0, max_irqs);
	rcu_read_unlock();
	for (index = 0; index < num_irqs; index++)
		irq_dispose_mapping(irq_data[index]->irq);
	kfree(irq_data);
}

/**
 * irq_linear_revmap() - Find a linux irq from a hw irq number.
 * @domain: domain owning this hardware interrupt