This references an irq_desc if already mapped interrupt requested to map again. This happends for PCI legacy interrupts where 4 interrupts are shared among all devices on the same PCI host bus adapter. >From now on, the users shall call irq_dispose_mapping() for every irq_create_fwspec_mapping(). Most (all?) users do not bother with disposing though so it is not very likely to break many things. Signed-off-by: Alexey Kardashevskiy <aik@xxxxxxxxx> --- kernel/irq/irqdomain.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index a0a81cc6c524..07f4bde87de5 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -663,7 +663,9 @@ unsigned int irq_create_mapping(struct irq_domain *domain, /* Check if mapping already exists */ virq = irq_find_mapping(domain, hwirq); if (virq) { + desc = irq_to_desc(virq); pr_debug("-> existing mapping on virq %d\n", virq); + kobject_get(&desc->kobj); return virq; } @@ -762,6 +764,7 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec) irq_hw_number_t hwirq; unsigned int type = IRQ_TYPE_NONE; int virq; + struct irq_desc *desc; if (fwspec->fwnode) { domain = irq_find_matching_fwspec(fwspec, DOMAIN_BUS_WIRED); @@ -798,8 +801,11 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec) * current trigger type then we are done so return the * interrupt number. */ - if (type == IRQ_TYPE_NONE || type == irq_get_trigger_type(virq)) + if (type == IRQ_TYPE_NONE || type == irq_get_trigger_type(virq)) { + desc = irq_to_desc(virq); + kobject_get(&desc->kobj); return virq; + } /* * If the trigger type has not been set yet, then set @@ -811,6 +817,8 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec) return 0; irqd_set_trigger_type(irq_data, type); + desc = irq_to_desc(virq); + kobject_get(&desc->kobj); return virq; } -- 2.17.1