diff options
Diffstat (limited to 'drivers/of/irq.c')
-rw-r--r-- | drivers/of/irq.c | 27 |
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 | ||
474 | struct of_intc_desc { | 474 | struct 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 | */ |
487 | void __init of_irq_init(const struct of_device_id *matches) | 488 | void __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; |