genirq/irqdomain: Reroute device MSI create_mapping
Reroute interrupt allocation in irq_create_fwspec_mapping() if the domain is a MSI device domain. This is required to convert the support for wire to MSI bridges to per device MSI domains. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Anup Patel <apatel@ventanamicro.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/r/20240127161753.114685-13-apatel@ventanamicro.com
This commit is contained in:
parent
0ee1578b00
commit
e49312fe09
@ -29,6 +29,7 @@ static int irq_domain_alloc_irqs_locked(struct irq_domain *domain, int irq_base,
|
||||
unsigned int nr_irqs, int node, void *arg,
|
||||
bool realloc, const struct irq_affinity_desc *affinity);
|
||||
static void irq_domain_check_hierarchy(struct irq_domain *domain);
|
||||
static void irq_domain_free_one_irq(struct irq_domain *domain, unsigned int virq);
|
||||
|
||||
struct irqchip_fwid {
|
||||
struct fwnode_handle fwnode;
|
||||
@ -858,8 +859,13 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec)
|
||||
}
|
||||
|
||||
if (irq_domain_is_hierarchy(domain)) {
|
||||
virq = irq_domain_alloc_irqs_locked(domain, -1, 1, NUMA_NO_NODE,
|
||||
fwspec, false, NULL);
|
||||
if (irq_domain_is_msi_device(domain)) {
|
||||
mutex_unlock(&domain->root->mutex);
|
||||
virq = msi_device_domain_alloc_wired(domain, hwirq, type);
|
||||
mutex_lock(&domain->root->mutex);
|
||||
} else
|
||||
virq = irq_domain_alloc_irqs_locked(domain, -1, 1, NUMA_NO_NODE,
|
||||
fwspec, false, NULL);
|
||||
if (virq <= 0) {
|
||||
virq = 0;
|
||||
goto out;
|
||||
@ -914,7 +920,7 @@ void irq_dispose_mapping(unsigned int virq)
|
||||
return;
|
||||
|
||||
if (irq_domain_is_hierarchy(domain)) {
|
||||
irq_domain_free_irqs(virq, 1);
|
||||
irq_domain_free_one_irq(domain, virq);
|
||||
} else {
|
||||
irq_domain_disassociate(domain, virq);
|
||||
irq_free_desc(virq);
|
||||
@ -1755,6 +1761,14 @@ void irq_domain_free_irqs(unsigned int virq, unsigned int nr_irqs)
|
||||
irq_free_descs(virq, nr_irqs);
|
||||
}
|
||||
|
||||
static void irq_domain_free_one_irq(struct irq_domain *domain, unsigned int virq)
|
||||
{
|
||||
if (irq_domain_is_msi_device(domain))
|
||||
msi_device_domain_free_wired(domain, virq);
|
||||
else
|
||||
irq_domain_free_irqs(virq, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* irq_domain_alloc_irqs_parent - Allocate interrupts from parent domain
|
||||
* @domain: Domain below which interrupts must be allocated
|
||||
@ -1907,9 +1921,9 @@ static int irq_domain_alloc_irqs_locked(struct irq_domain *domain, int irq_base,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void irq_domain_check_hierarchy(struct irq_domain *domain)
|
||||
{
|
||||
}
|
||||
static void irq_domain_check_hierarchy(struct irq_domain *domain) { }
|
||||
static void irq_domain_free_one_irq(struct irq_domain *domain, unsigned int virq) { }
|
||||
|
||||
#endif /* CONFIG_IRQ_DOMAIN_HIERARCHY */
|
||||
|
||||
#ifdef CONFIG_GENERIC_IRQ_DEBUGFS
|
||||
|
Loading…
Reference in New Issue
Block a user