Skip to content

Commit e49312f

Browse files
committed
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 <[email protected]> Signed-off-by: Anup Patel <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 0ee1578 commit e49312f

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

kernel/irq/irqdomain.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ static int irq_domain_alloc_irqs_locked(struct irq_domain *domain, int irq_base,
2929
unsigned int nr_irqs, int node, void *arg,
3030
bool realloc, const struct irq_affinity_desc *affinity);
3131
static void irq_domain_check_hierarchy(struct irq_domain *domain);
32+
static void irq_domain_free_one_irq(struct irq_domain *domain, unsigned int virq);
3233

3334
struct irqchip_fwid {
3435
struct fwnode_handle fwnode;
@@ -858,8 +859,13 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec)
858859
}
859860

860861
if (irq_domain_is_hierarchy(domain)) {
861-
virq = irq_domain_alloc_irqs_locked(domain, -1, 1, NUMA_NO_NODE,
862-
fwspec, false, NULL);
862+
if (irq_domain_is_msi_device(domain)) {
863+
mutex_unlock(&domain->root->mutex);
864+
virq = msi_device_domain_alloc_wired(domain, hwirq, type);
865+
mutex_lock(&domain->root->mutex);
866+
} else
867+
virq = irq_domain_alloc_irqs_locked(domain, -1, 1, NUMA_NO_NODE,
868+
fwspec, false, NULL);
863869
if (virq <= 0) {
864870
virq = 0;
865871
goto out;
@@ -914,7 +920,7 @@ void irq_dispose_mapping(unsigned int virq)
914920
return;
915921

916922
if (irq_domain_is_hierarchy(domain)) {
917-
irq_domain_free_irqs(virq, 1);
923+
irq_domain_free_one_irq(domain, virq);
918924
} else {
919925
irq_domain_disassociate(domain, virq);
920926
irq_free_desc(virq);
@@ -1755,6 +1761,14 @@ void irq_domain_free_irqs(unsigned int virq, unsigned int nr_irqs)
17551761
irq_free_descs(virq, nr_irqs);
17561762
}
17571763

1764+
static void irq_domain_free_one_irq(struct irq_domain *domain, unsigned int virq)
1765+
{
1766+
if (irq_domain_is_msi_device(domain))
1767+
msi_device_domain_free_wired(domain, virq);
1768+
else
1769+
irq_domain_free_irqs(virq, 1);
1770+
}
1771+
17581772
/**
17591773
* irq_domain_alloc_irqs_parent - Allocate interrupts from parent domain
17601774
* @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,
19071921
return -EINVAL;
19081922
}
19091923

1910-
static void irq_domain_check_hierarchy(struct irq_domain *domain)
1911-
{
1912-
}
1924+
static void irq_domain_check_hierarchy(struct irq_domain *domain) { }
1925+
static void irq_domain_free_one_irq(struct irq_domain *domain, unsigned int virq) { }
1926+
19131927
#endif /* CONFIG_IRQ_DOMAIN_HIERARCHY */
19141928

19151929
#ifdef CONFIG_GENERIC_IRQ_DEBUGFS

0 commit comments

Comments
 (0)