diff options
-rw-r--r-- | kernel/irq/chip.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 63c16d165e78..6f1c7a566b95 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c | |||
@@ -731,7 +731,30 @@ __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, | |||
731 | if (!handle) { | 731 | if (!handle) { |
732 | handle = handle_bad_irq; | 732 | handle = handle_bad_irq; |
733 | } else { | 733 | } else { |
734 | if (WARN_ON(desc->irq_data.chip == &no_irq_chip)) | 734 | struct irq_data *irq_data = &desc->irq_data; |
735 | #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY | ||
736 | /* | ||
737 | * With hierarchical domains we might run into a | ||
738 | * situation where the outermost chip is not yet set | ||
739 | * up, but the inner chips are there. Instead of | ||
740 | * bailing we install the handler, but obviously we | ||
741 | * cannot enable/startup the interrupt at this point. | ||
742 | */ | ||
743 | while (irq_data) { | ||
744 | if (irq_data->chip != &no_irq_chip) | ||
745 | break; | ||
746 | /* | ||
747 | * Bail out if the outer chip is not set up | ||
748 | * and the interrrupt supposed to be started | ||
749 | * right away. | ||
750 | */ | ||
751 | if (WARN_ON(is_chained)) | ||
752 | goto out; | ||
753 | /* Try the parent */ | ||
754 | irq_data = irq_data->parent_data; | ||
755 | } | ||
756 | #endif | ||
757 | if (WARN_ON(!irq_data || irq_data->chip == &no_irq_chip)) | ||
735 | goto out; | 758 | goto out; |
736 | } | 759 | } |
737 | 760 | ||