aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of/irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/of/irq.c')
-rw-r--r--drivers/of/irq.c27
1 files changed, 13 insertions, 14 deletions
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 4fa916dffc91..706e3ff67f8b 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -473,6 +473,7 @@ EXPORT_SYMBOL_GPL(of_irq_to_resource_table);
473 473
474struct of_intc_desc { 474struct of_intc_desc {
475 struct list_head list; 475 struct list_head list;
476 of_irq_init_cb_t irq_init_cb;
476 struct device_node *dev; 477 struct device_node *dev;
477 struct device_node *interrupt_parent; 478 struct device_node *interrupt_parent;
478}; 479};
@@ -486,6 +487,7 @@ struct of_intc_desc {
486 */ 487 */
487void __init of_irq_init(const struct of_device_id *matches) 488void __init of_irq_init(const struct of_device_id *matches)
488{ 489{
490 const struct of_device_id *match;
489 struct device_node *np, *parent = NULL; 491 struct device_node *np, *parent = NULL;
490 struct of_intc_desc *desc, *temp_desc; 492 struct of_intc_desc *desc, *temp_desc;
491 struct list_head intc_desc_list, intc_parent_list; 493 struct list_head intc_desc_list, intc_parent_list;
@@ -493,10 +495,15 @@ void __init of_irq_init(const struct of_device_id *matches)
493 INIT_LIST_HEAD(&intc_desc_list); 495 INIT_LIST_HEAD(&intc_desc_list);
494 INIT_LIST_HEAD(&intc_parent_list); 496 INIT_LIST_HEAD(&intc_parent_list);
495 497
496 for_each_matching_node(np, matches) { 498 for_each_matching_node_and_match(np, matches, &match) {
497 if (!of_find_property(np, "interrupt-controller", NULL) || 499 if (!of_find_property(np, "interrupt-controller", NULL) ||
498 !of_device_is_available(np)) 500 !of_device_is_available(np))
499 continue; 501 continue;
502
503 if (WARN(!match->data, "of_irq_init: no init function for %s\n",
504 match->compatible))
505 continue;
506
500 /* 507 /*
501 * Here, we allocate and populate an of_intc_desc with the node 508 * Here, we allocate and populate an of_intc_desc with the node
502 * pointer, interrupt-parent device_node etc. 509 * pointer, interrupt-parent device_node etc.
@@ -507,6 +514,7 @@ void __init of_irq_init(const struct of_device_id *matches)
507 goto err; 514 goto err;
508 } 515 }
509 516
517 desc->irq_init_cb = match->data;
510 desc->dev = of_node_get(np); 518 desc->dev = of_node_get(np);
511 desc->interrupt_parent = of_irq_find_parent(np); 519 desc->interrupt_parent = of_irq_find_parent(np);
512 if (desc->interrupt_parent == np) 520 if (desc->interrupt_parent == np)
@@ -526,27 +534,18 @@ void __init of_irq_init(const struct of_device_id *matches)
526 * The assumption is that NULL parent means a root controller. 534 * The assumption is that NULL parent means a root controller.
527 */ 535 */
528 list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) { 536 list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
529 const struct of_device_id *match;
530 int ret; 537 int ret;
531 of_irq_init_cb_t irq_init_cb;
532 538
533 if (desc->interrupt_parent != parent) 539 if (desc->interrupt_parent != parent)
534 continue; 540 continue;
535 541
536 list_del(&desc->list); 542 list_del(&desc->list);
537 match = of_match_node(matches, desc->dev);
538 if (WARN(!match->data,
539 "of_irq_init: no init function for %s\n",
540 match->compatible)) {
541 kfree(desc);
542 continue;
543 }
544 543
545 pr_debug("of_irq_init: init %s @ %p, parent %p\n", 544 pr_debug("of_irq_init: init %s (%p), parent %p\n",
546 match->compatible, 545 desc->dev->full_name,
547 desc->dev, desc->interrupt_parent); 546 desc->dev, desc->interrupt_parent);
548 irq_init_cb = (of_irq_init_cb_t)match->data; 547 ret = desc->irq_init_cb(desc->dev,
549 ret = irq_init_cb(desc->dev, desc->interrupt_parent); 548 desc->interrupt_parent);
550 if (ret) { 549 if (ret) {
551 kfree(desc); 550 kfree(desc);
552 continue; 551 continue;