aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYingjoe Chen <yingjoe.chen@mediatek.com>2014-11-06 09:20:15 -0500
committerThomas Gleixner <tglx@linutronix.de>2014-11-23 07:01:46 -0500
commit0cc01abab6412f3a76256bb57ca58dcb94a6edc7 (patch)
tree563060ad84e9d66eb1b8a1ad191b03cb775529fb
parentf8264e34965aaf43203912ed8f7b543c00c8d70f (diff)
irqdomain: Do irq_find_mapping and set_type for hierarchy irqdomain in case OF
It is possible to call irq_create_of_mapping to create/translate the same IRQ from DT for multiple times. Perform irq_find_mapping check and set_type for hierarchy irqdomain in irq_create_of_mapping() to avoid duplicate these functionality in all outer most irqdomain. Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com> Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com> Cc: Bjorn Helgaas <bhelgaas@google.com> Cc: Grant Likely <grant.likely@linaro.org> Cc: Marc Zyngier <marc.zyngier@arm.com> Cc: Yingjoe Chen <yingjoe.chen@mediatek.com> Cc: Yijing Wang <wangyijing@huawei.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--kernel/irq/irqdomain.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 43f3be6fac70..9a61de21933a 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -478,11 +478,6 @@ unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data)
478 return 0; 478 return 0;
479 } 479 }
480 480
481 if (irq_domain_is_hierarchy(domain)) {
482 virq = irq_domain_alloc_irqs(domain, 1, NUMA_NO_NODE, irq_data);
483 return virq <= 0 ? 0 : virq;
484 }
485
486 /* If domain has no translation, then we assume interrupt line */ 481 /* If domain has no translation, then we assume interrupt line */
487 if (domain->ops->xlate == NULL) 482 if (domain->ops->xlate == NULL)
488 hwirq = irq_data->args[0]; 483 hwirq = irq_data->args[0];
@@ -492,10 +487,24 @@ unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data)
492 return 0; 487 return 0;
493 } 488 }
494 489
495 /* Create mapping */ 490 if (irq_domain_is_hierarchy(domain)) {
496 virq = irq_create_mapping(domain, hwirq); 491 /*
497 if (!virq) 492 * If we've already configured this interrupt,
498 return virq; 493 * don't do it again, or hell will break loose.
494 */
495 virq = irq_find_mapping(domain, hwirq);
496 if (virq)
497 return virq;
498
499 virq = irq_domain_alloc_irqs(domain, 1, NUMA_NO_NODE, irq_data);
500 if (virq <= 0)
501 return 0;
502 } else {
503 /* Create mapping */
504 virq = irq_create_mapping(domain, hwirq);
505 if (!virq)
506 return virq;
507 }
499 508
500 /* Set type if specified and different than the current one */ 509 /* Set type if specified and different than the current one */
501 if (type != IRQ_TYPE_NONE && 510 if (type != IRQ_TYPE_NONE &&