of/irq: do irq resolution in platform_get_irq
[firefly-linux-kernel-4.4.55.git] / drivers / of / irq.c
index 27212402c53247819cf4edf09e576d2cc69f3136..5aeb89411350a4c98a2d769302e16a8d650d075f 100644 (file)
@@ -216,6 +216,9 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
                                goto fail;
                        }
 
+                       if (!of_device_is_available(newpar))
+                               match = 0;
+
                        /* Get #interrupt-cells and #address-cells of new
                         * parent
                         */
@@ -361,7 +364,7 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
 
                memset(r, 0, sizeof(*r));
                /*
-                * Get optional "interrupts-names" property to add a name
+                * Get optional "interrupt-names" property to add a name
                 * to the resource.
                 */
                of_property_read_string_index(dev, "interrupt-names", index,
@@ -376,6 +379,32 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
 }
 EXPORT_SYMBOL_GPL(of_irq_to_resource);
 
+/**
+ * of_irq_get - Decode a node's IRQ and return it as a Linux irq number
+ * @dev: pointer to device tree node
+ * @index: zero-based index of the irq
+ *
+ * Returns Linux irq number on success, or -EPROBE_DEFER if the irq domain
+ * is not yet created.
+ *
+ */
+int of_irq_get(struct device_node *dev, int index)
+{
+       int rc;
+       struct of_phandle_args oirq;
+       struct irq_domain *domain;
+
+       rc = of_irq_parse_one(dev, index, &oirq);
+       if (rc)
+               return rc;
+
+       domain = irq_find_host(oirq.np);
+       if (!domain)
+               return -EPROBE_DEFER;
+
+       return irq_create_of_mapping(&oirq);
+}
+
 /**
  * of_irq_count - Count the number of IRQs a node uses
  * @dev: pointer to device tree node
@@ -435,7 +464,8 @@ void __init of_irq_init(const struct of_device_id *matches)
        INIT_LIST_HEAD(&intc_parent_list);
 
        for_each_matching_node(np, matches) {
-               if (!of_find_property(np, "interrupt-controller", NULL))
+               if (!of_find_property(np, "interrupt-controller", NULL) ||
+                               !of_device_is_available(np))
                        continue;
                /*
                 * Here, we allocate and populate an intc_desc with the node