diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 873b642f4ad8..c0709837d831 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -781,7 +781,8 @@ struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 rid) * @np: device node for @dev * @token: bus type for this domain * - * Parse the msi-parent property and returns the corresponding MSI domain. + * Parse the msi-parent property (both the simple and the complex + * versions), and returns the corresponding MSI domain. * * Returns: the MSI domain for this device (or NULL on failure). */ @@ -789,14 +790,33 @@ struct irq_domain *of_msi_get_domain(struct device *dev, struct device_node *np, enum irq_domain_bus_token token) { - struct of_phandle_iterator it; + struct device_node *msi_np; struct irq_domain *d; - int err; - of_for_each_phandle(&it, err, np, "msi-parent", "#msi-cells", 0) { - d = irq_find_matching_host(it.node, token); - if (d) - return d; + /* Check for a single msi-parent property */ + msi_np = of_parse_phandle(np, "msi-parent", 0); + if (msi_np && !of_property_read_bool(msi_np, "#msi-cells")) { + d = irq_find_matching_host(msi_np, token); + if (!d) + of_node_put(msi_np); + return d; + } + + if (token == DOMAIN_BUS_PLATFORM_MSI) { + /* Check for the complex msi-parent version */ + struct of_phandle_args args; + int index = 0; + + while (!of_parse_phandle_with_args(np, "msi-parent", + "#msi-cells", + index, &args)) { + d = irq_find_matching_host(args.np, token); + if (d) + return d; + + of_node_put(args.np); + index++; + } } return NULL;