|
@@ -731,7 +731,30 @@ __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
|
|
|
if (!handle) {
|
|
|
handle = handle_bad_irq;
|
|
|
} else {
|
|
|
- if (WARN_ON(desc->irq_data.chip == &no_irq_chip))
|
|
|
+ struct irq_data *irq_data = &desc->irq_data;
|
|
|
+#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
|
|
|
+ /*
|
|
|
+ * With hierarchical domains we might run into a
|
|
|
+ * situation where the outermost chip is not yet set
|
|
|
+ * up, but the inner chips are there. Instead of
|
|
|
+ * bailing we install the handler, but obviously we
|
|
|
+ * cannot enable/startup the interrupt at this point.
|
|
|
+ */
|
|
|
+ while (irq_data) {
|
|
|
+ if (irq_data->chip != &no_irq_chip)
|
|
|
+ break;
|
|
|
+ /*
|
|
|
+ * Bail out if the outer chip is not set up
|
|
|
+ * and the interrrupt supposed to be started
|
|
|
+ * right away.
|
|
|
+ */
|
|
|
+ if (WARN_ON(is_chained))
|
|
|
+ goto out;
|
|
|
+ /* Try the parent */
|
|
|
+ irq_data = irq_data->parent_data;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ if (WARN_ON(!irq_data || irq_data->chip == &no_irq_chip))
|
|
|
goto out;
|
|
|
}
|
|
|
|