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 <a...@ozlabs.ru>
---
 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

Reply via email to