return rid_out;
}
+
+static struct irq_domain *__of_get_msi_domain(struct device_node *np,
+ enum irq_domain_bus_token token)
+{
+ struct irq_domain *d;
+
+ d = irq_find_matching_host(np, token);
+ if (!d)
+ d = irq_find_host(np);
+
+ return d;
+}
+
+/**
+ * of_msi_get_domain - Use msi-parent to find the relevant MSI domain
+ * @dev: device for which the domain is requested
+ * @np: device node for @dev
+ * @token: bus type for this 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).
+ */
+struct irq_domain *of_msi_get_domain(struct device *dev,
+ struct device_node *np,
+ enum irq_domain_bus_token token)
+{
+ struct device_node *msi_np;
+ struct irq_domain *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 = __of_get_msi_domain(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 = __of_get_msi_domain(args.np, token);
+ if (d)
+ return d;
+
+ of_node_put(args.np);
+ index++;
+ }
+ }
+
+ return NULL;
+}
extern int of_irq_get_byname(struct device_node *dev, const char *name);
extern int of_irq_to_resource_table(struct device_node *dev,
struct resource *res, int nr_irqs);
+extern struct irq_domain *of_msi_get_domain(struct device *dev,
+ struct device_node *np,
+ enum irq_domain_bus_token token);
#else
static inline int of_irq_count(struct device_node *dev)
{
{
return 0;
}
+static inline struct irq_domain *of_msi_get_domain(struct device *dev,
+ struct device_node *np,
+ enum irq_domain_bus_token token)
+{
+ return NULL;
+}
#endif
#if defined(CONFIG_OF)