summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/pci/pci-msi.txt220
-rw-r--r--drivers/irqchip/irq-gic-v3-its-pci-msi.c4
-rw-r--r--drivers/irqchip/irq-gic-v3-its-platform-msi.c18
-rw-r--r--drivers/of/irq.c185
-rw-r--r--drivers/pci/msi.c49
-rw-r--r--drivers/pci/of.c13
-rw-r--r--drivers/pci/probe.c43
-rw-r--r--include/linux/msi.h7
-rw-r--r--include/linux/of_irq.h23
9 files changed, 534 insertions, 28 deletions
diff --git a/Documentation/devicetree/bindings/pci/pci-msi.txt b/Documentation/devicetree/bindings/pci/pci-msi.txt
new file mode 100644
index 000000000000..9b3cc817d181
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/pci-msi.txt
@@ -0,0 +1,220 @@
+This document describes the generic device tree binding for describing the
+relationship between PCI devices and MSI controllers.
+
+Each PCI device under a root complex is uniquely identified by its Requester ID
+(AKA RID). A Requester ID is a triplet of a Bus number, Device number, and
+Function number.
+
+For the purpose of this document, when treated as a numeric value, a RID is
+formatted such that:
+
+* Bits [15:8] are the Bus number.
+* Bits [7:3] are the Device number.
+* Bits [2:0] are the Function number.
+* Any other bits required for padding must be zero.
+
+MSIs may be distinguished in part through the use of sideband data accompanying
+writes. In the case of PCI devices, this sideband data may be derived from the
+Requester ID. A mechanism is required to associate a device with both the MSI
+controllers it can address, and the sideband data that will be associated with
+its writes to those controllers.
+
+For generic MSI bindings, see
+Documentation/devicetree/bindings/interrupt-controller/msi.txt.
+
+
+PCI root complex
+================
+
+Optional properties
+-------------------
+
+- msi-map: Maps a Requester ID to an MSI controller and associated
+ msi-specifier data. The property is an arbitrary number of tuples of
+ (rid-base,msi-controller,msi-base,length), where:
+
+ * rid-base is a single cell describing the first RID matched by the entry.
+
+ * msi-controller is a single phandle to an MSI controller
+
+ * msi-base is an msi-specifier describing the msi-specifier produced for the
+ first RID matched by the entry.
+
+ * length is a single cell describing how many consecutive RIDs are matched
+ following the rid-base.
+
+ Any RID r in the interval [rid-base, rid-base + length) is associated with
+ the listed msi-controller, with the msi-specifier (r - rid-base + msi-base).
+
+- msi-map-mask: A mask to be applied to each Requester ID prior to being mapped
+ to an msi-specifier per the msi-map property.
+
+- msi-parent: Describes the MSI parent of the root complex itself. Where
+ the root complex and MSI controller do not pass sideband data with MSI
+ writes, this property may be used to describe the MSI controller(s)
+ used by PCI devices under the root complex, if defined as such in the
+ binding for the root complex.
+
+
+Example (1)
+===========
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ msi: msi-controller@a {
+ reg = <0xa 0x1>;
+ compatible = "vendor,some-controller";
+ msi-controller;
+ #msi-cells = <1>;
+ };
+
+ pci: pci@f {
+ reg = <0xf 0x1>;
+ compatible = "vendor,pcie-root-complex";
+ device_type = "pci";
+
+ /*
+ * The sideband data provided to the MSI controller is
+ * the RID, identity-mapped.
+ */
+ msi-map = <0x0 &msi_a 0x0 0x10000>,
+ };
+};
+
+
+Example (2)
+===========
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ msi: msi-controller@a {
+ reg = <0xa 0x1>;
+ compatible = "vendor,some-controller";
+ msi-controller;
+ #msi-cells = <1>;
+ };
+
+ pci: pci@f {
+ reg = <0xf 0x1>;
+ compatible = "vendor,pcie-root-complex";
+ device_type = "pci";
+
+ /*
+ * The sideband data provided to the MSI controller is
+ * the RID, masked to only the device and function bits.
+ */
+ msi-map = <0x0 &msi_a 0x0 0x100>,
+ msi-map-mask = <0xff>
+ };
+};
+
+
+Example (3)
+===========
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ msi: msi-controller@a {
+ reg = <0xa 0x1>;
+ compatible = "vendor,some-controller";
+ msi-controller;
+ #msi-cells = <1>;
+ };
+
+ pci: pci@f {
+ reg = <0xf 0x1>;
+ compatible = "vendor,pcie-root-complex";
+ device_type = "pci";
+
+ /*
+ * The sideband data provided to the MSI controller is
+ * the RID, but the high bit of the bus number is
+ * ignored.
+ */
+ msi-map = <0x0000 &msi 0x0000 0x8000>,
+ <0x8000 &msi 0x0000 0x8000>;
+ };
+};
+
+
+Example (4)
+===========
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ msi: msi-controller@a {
+ reg = <0xa 0x1>;
+ compatible = "vendor,some-controller";
+ msi-controller;
+ #msi-cells = <1>;
+ };
+
+ pci: pci@f {
+ reg = <0xf 0x1>;
+ compatible = "vendor,pcie-root-complex";
+ device_type = "pci";
+
+ /*
+ * The sideband data provided to the MSI controller is
+ * the RID, but the high bit of the bus number is
+ * negated.
+ */
+ msi-map = <0x0000 &msi 0x8000 0x8000>,
+ <0x8000 &msi 0x0000 0x8000>;
+ };
+};
+
+
+Example (5)
+===========
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ msi_a: msi-controller@a {
+ reg = <0xa 0x1>;
+ compatible = "vendor,some-controller";
+ msi-controller;
+ #msi-cells = <1>;
+ };
+
+ msi_b: msi-controller@b {
+ reg = <0xb 0x1>;
+ compatible = "vendor,some-controller";
+ msi-controller;
+ #msi-cells = <1>;
+ };
+
+ msi_c: msi-controller@c {
+ reg = <0xc 0x1>;
+ compatible = "vendor,some-controller";
+ msi-controller;
+ #msi-cells = <1>;
+ };
+
+ pci: pci@c {
+ reg = <0xf 0x1>;
+ compatible = "vendor,pcie-root-complex";
+ device_type = "pci";
+
+ /*
+ * The sideband data provided to MSI controller a is the
+ * RID, but the high bit of the bus number is negated.
+ * The sideband data provided to MSI controller b is the
+ * RID, identity-mapped.
+ * MSI controller c is not addressable.
+ */
+ msi-map = <0x0000 &msi_a 0x8000 0x08000>,
+ <0x8000 &msi_a 0x0000 0x08000>,
+ <0x0000 &msi_b 0x0000 0x10000>;
+ };
+};
diff --git a/drivers/irqchip/irq-gic-v3-its-pci-msi.c b/drivers/irqchip/irq-gic-v3-its-pci-msi.c
index 693c2f9ae898..aee60ed025dc 100644
--- a/drivers/irqchip/irq-gic-v3-its-pci-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-pci-msi.c
@@ -42,7 +42,6 @@ static struct irq_chip its_msi_irq_chip = {
struct its_pci_alias {
struct pci_dev *pdev;
- u32 dev_id;
u32 count;
};
@@ -60,7 +59,6 @@ static int its_get_pci_alias(struct pci_dev *pdev, u16 alias, void *data)
{
struct its_pci_alias *dev_alias = data;
- dev_alias->dev_id = alias;
if (pdev != dev_alias->pdev)
dev_alias->count += its_pci_msi_vec_count(pdev);
@@ -86,7 +84,7 @@ static int its_pci_msi_prepare(struct irq_domain *domain, struct device *dev,
pci_for_each_dma_alias(pdev, its_get_pci_alias, &dev_alias);
/* ITS specific DeviceID, as the core ITS ignores dev. */
- info->scratchpad[0].ul = dev_alias.dev_id;
+ info->scratchpad[0].ul = pci_msi_domain_get_msi_rid(domain, pdev);
return msi_info->ops->msi_prepare(domain->parent,
dev, dev_alias.count, info);
diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
index 960a8166a6c0..470b4aa7d62c 100644
--- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
@@ -29,13 +29,25 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
{
struct msi_domain_info *msi_info;
u32 dev_id;
- int ret;
+ int ret, index = 0;
msi_info = msi_get_domain_info(domain->parent);
/* Suck the DeviceID out of the msi-parent property */
- ret = of_property_read_u32_index(dev->of_node, "msi-parent",
- 1, &dev_id);
+ do {
+ struct of_phandle_args args;
+
+ ret = of_parse_phandle_with_args(dev->of_node,
+ "msi-parent", "#msi-cells",
+ index, &args);
+ if (args.np == irq_domain_get_of_node(domain)) {
+ if (WARN_ON(args.args_count != 1))
+ return -EINVAL;
+ dev_id = args.args[0];
+ break;
+ }
+ } while (!ret);
+
if (ret)
return ret;
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 55317fa9c9dc..0baf626da56a 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -579,22 +579,187 @@ err:
}
}
+static u32 __of_msi_map_rid(struct device *dev, struct device_node **np,
+ u32 rid_in)
+{
+ struct device *parent_dev;
+ struct device_node *msi_controller_node;
+ struct device_node *msi_np = *np;
+ u32 map_mask, masked_rid, rid_base, msi_base, rid_len, phandle;
+ int msi_map_len;
+ bool matched;
+ u32 rid_out = rid_in;
+ const __be32 *msi_map = NULL;
+
+ /*
+ * Walk up the device parent links looking for one with a
+ * "msi-map" property.
+ */
+ for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent) {
+ if (!parent_dev->of_node)
+ continue;
+
+ msi_map = of_get_property(parent_dev->of_node,
+ "msi-map", &msi_map_len);
+ if (!msi_map)
+ continue;
+
+ if (msi_map_len % (4 * sizeof(__be32))) {
+ dev_err(parent_dev, "Error: Bad msi-map length: %d\n",
+ msi_map_len);
+ return rid_out;
+ }
+ /* We have a good parent_dev and msi_map, let's use them. */
+ break;
+ }
+ if (!msi_map)
+ return rid_out;
+
+ /* The default is to select all bits. */
+ map_mask = 0xffffffff;
+
+ /*
+ * Can be overridden by "msi-map-mask" property. If
+ * of_property_read_u32() fails, the default is used.
+ */
+ of_property_read_u32(parent_dev->of_node, "msi-map-mask", &map_mask);
+
+ masked_rid = map_mask & rid_in;
+ matched = false;
+ while (!matched && msi_map_len >= 4 * sizeof(__be32)) {
+ rid_base = be32_to_cpup(msi_map + 0);
+ phandle = be32_to_cpup(msi_map + 1);
+ msi_base = be32_to_cpup(msi_map + 2);
+ rid_len = be32_to_cpup(msi_map + 3);
+
+ msi_controller_node = of_find_node_by_phandle(phandle);
+
+ matched = (masked_rid >= rid_base &&
+ masked_rid < rid_base + rid_len);
+ if (msi_np)
+ matched &= msi_np == msi_controller_node;
+
+ if (matched && !msi_np) {
+ *np = msi_np = msi_controller_node;
+ break;
+ }
+
+ of_node_put(msi_controller_node);
+ msi_map_len -= 4 * sizeof(__be32);
+ msi_map += 4;
+ }
+ if (!matched)
+ return rid_out;
+
+ rid_out = masked_rid + msi_base;
+ dev_dbg(dev,
+ "msi-map at: %s, using mask %08x, rid-base: %08x, msi-base: %08x, length: %08x, rid: %08x -> %08x\n",
+ dev_name(parent_dev), map_mask, rid_base, msi_base,
+ rid_len, rid_in, rid_out);
+
+ return rid_out;
+}
+
/**
- * of_msi_configure - Set the msi_domain field of a device
- * @dev: device structure to associate with an MSI irq domain
- * @np: device node for that device
+ * of_msi_map_rid - Map a MSI requester ID for a device.
+ * @dev: device for which the mapping is to be done.
+ * @msi_np: device node of the expected msi controller.
+ * @rid_in: unmapped MSI requester ID for the device.
+ *
+ * Walk up the device hierarchy looking for devices with a "msi-map"
+ * property. If found, apply the mapping to @rid_in.
+ *
+ * Returns the mapped MSI requester ID.
*/
-void of_msi_configure(struct device *dev, struct device_node *np)
+u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in)
+{
+ return __of_msi_map_rid(dev, &msi_np, rid_in);
+}
+
+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_map_get_device_domain - Use msi-map to find the relevant MSI domain
+ * @dev: device for which the mapping is to be done.
+ * @rid: Requester ID for the device.
+ *
+ * Walk up the device hierarchy looking for devices with a "msi-map"
+ * property.
+ *
+ * Returns: the MSI domain for this device (or NULL on failure)
+ */
+struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 rid)
+{
+ struct device_node *np = NULL;
+
+ __of_msi_map_rid(dev, &np, rid);
+ return __of_get_msi_domain(np, DOMAIN_BUS_PCI_MSI);
+}
+
+/**
+ * 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)
- return;
+ 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;
+ }
- d = irq_find_matching_host(msi_np, DOMAIN_BUS_PLATFORM_MSI);
- if (!d)
- d = irq_find_host(msi_np);
- dev_set_msi_domain(dev, 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;
+}
+
+/**
+ * of_msi_configure - Set the msi_domain field of a device
+ * @dev: device structure to associate with an MSI irq domain
+ * @np: device node for that device
+ */
+void of_msi_configure(struct device *dev, struct device_node *np)
+{
+ dev_set_msi_domain(dev,
+ of_msi_get_domain(dev, np, DOMAIN_BUS_PLATFORM_MSI));
}
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index ddd59fe786f8..4cd6f3abcecf 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -20,6 +20,7 @@
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/irqdomain.h>
+#include <linux/of_irq.h>
#include "pci.h"
@@ -1327,4 +1328,52 @@ struct irq_domain *pci_msi_create_default_irq_domain(struct fwnode_handle *fwnod
return domain;
}
+
+static int get_msi_id_cb(struct pci_dev *pdev, u16 alias, void *data)
+{
+ u32 *pa = data;
+
+ *pa = alias;
+ return 0;
+}
+/**
+ * pci_msi_domain_get_msi_rid - Get the MSI requester id (RID)
+ * @domain: The interrupt domain
+ * @pdev: The PCI device.
+ *
+ * The RID for a device is formed from the alias, with a firmware
+ * supplied mapping applied
+ *
+ * Returns: The RID.
+ */
+u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev)
+{
+ struct device_node *of_node;
+ u32 rid = 0;
+
+ pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid);
+
+ of_node = irq_domain_get_of_node(domain);
+ if (of_node)
+ rid = of_msi_map_rid(&pdev->dev, of_node, rid);
+
+ return rid;
+}
+
+/**
+ * pci_msi_get_device_domain - Get the MSI domain for a given PCI device
+ * @pdev: The PCI device
+ *
+ * Use the firmware data to find a device-specific MSI domain
+ * (i.e. not one that is ste as a default).
+ *
+ * Returns: The coresponding MSI domain or NULL if none has been found.
+ */
+struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev)
+{
+ u32 rid = 0;
+
+ pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid);
+ return of_msi_map_get_device_domain(&pdev->dev, rid);
+}
#endif /* CONFIG_PCI_MSI_IRQ_DOMAIN */
diff --git a/drivers/pci/of.c b/drivers/pci/of.c
index 2e99a500cb83..e112da11630e 100644
--- a/drivers/pci/of.c
+++ b/drivers/pci/of.c
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/of.h>
+#include <linux/of_irq.h>
#include <linux/of_pci.h>
#include "pci.h"
@@ -64,27 +65,25 @@ struct device_node * __weak pcibios_get_phb_of_node(struct pci_bus *bus)
struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus)
{
#ifdef CONFIG_IRQ_DOMAIN
- struct device_node *np;
struct irq_domain *d;
if (!bus->dev.of_node)
return NULL;
/* Start looking for a phandle to an MSI controller. */
- np = of_parse_phandle(bus->dev.of_node, "msi-parent", 0);
+ d = of_msi_get_domain(&bus->dev, bus->dev.of_node, DOMAIN_BUS_PCI_MSI);
+ if (d)
+ return d;
/*
* If we don't have an msi-parent property, look for a domain
* directly attached to the host bridge.
*/
- if (!np)
- np = bus->dev.of_node;
-
- d = irq_find_matching_host(np, DOMAIN_BUS_PCI_MSI);
+ d = irq_find_matching_host(bus->dev.of_node, DOMAIN_BUS_PCI_MSI);
if (d)
return d;
- return irq_find_host(np);
+ return irq_find_host(bus->dev.of_node);
#else
return NULL;
#endif
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 8361d27e5eca..f14a970b61fa 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1622,15 +1622,48 @@ static void pci_init_capabilities(struct pci_dev *dev)
pci_enable_acs(dev);
}
+/*
+ * This is the equivalent of pci_host_bridge_msi_domain that acts on
+ * devices. Firmware interfaces that can select the MSI domain on a
+ * per-device basis should be called from here.
+ */
+static struct irq_domain *pci_dev_msi_domain(struct pci_dev *dev)
+{
+ struct irq_domain *d;
+
+ /*
+ * If a domain has been set through the pcibios_add_device
+ * callback, then this is the one (platform code knows best).
+ */
+ d = dev_get_msi_domain(&dev->dev);
+ if (d)
+ return d;
+
+ /*
+ * Let's see if we have a firmware interface able to provide
+ * the domain.
+ */
+ d = pci_msi_get_device_domain(dev);
+ if (d)
+ return d;
+
+ return NULL;
+}
+
static void pci_set_msi_domain(struct pci_dev *dev)
{
+ struct irq_domain *d;
+
/*
- * If no domain has been set through the pcibios_add_device
- * callback, inherit the default from the bus device.
+ * If the platform or firmware interfaces cannot supply a
+ * device-specific MSI domain, then inherit the default domain
+ * from the host bridge itself.
*/
- if (!dev_get_msi_domain(&dev->dev))
- dev_set_msi_domain(&dev->dev,
- dev_get_msi_domain(&dev->bus->dev));
+ d = pci_dev_msi_domain(dev);
+ if (!d)
+ d = dev_get_msi_domain(&dev->bus->dev);
+
+ dev_set_msi_domain(&dev->dev, d);
}
void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 32a24b9a9556..0b4460374020 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -294,6 +294,13 @@ irq_hw_number_t pci_msi_domain_calc_hwirq(struct pci_dev *dev,
struct msi_desc *desc);
int pci_msi_domain_check_cap(struct irq_domain *domain,
struct msi_domain_info *info, struct device *dev);
+u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev);
+struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev);
+#else
+static inline struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev)
+{
+ return NULL;
+}
#endif /* CONFIG_PCI_MSI_IRQ_DOMAIN */
#endif /* LINUX_MSI_H */
diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
index 4bcbd586a672..65d969246a4d 100644
--- a/include/linux/of_irq.h
+++ b/include/linux/of_irq.h
@@ -46,6 +46,11 @@ extern int of_irq_get(struct device_node *dev, int index);
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);
+extern struct irq_domain *of_msi_map_get_device_domain(struct device *dev,
+ u32 rid);
#else
static inline int of_irq_count(struct device_node *dev)
{
@@ -64,6 +69,17 @@ static inline int of_irq_to_resource_table(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;
+}
+static inline struct irq_domain *of_msi_map_get_device_domain(struct device *dev,
+ u32 rid)
+{
+ return NULL;
+}
#endif
#if defined(CONFIG_OF)
@@ -75,6 +91,7 @@ static inline int of_irq_to_resource_table(struct device_node *dev,
extern unsigned int irq_of_parse_and_map(struct device_node *node, int index);
extern struct device_node *of_irq_find_parent(struct device_node *child);
extern void of_msi_configure(struct device *dev, struct device_node *np);
+u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in);
#else /* !CONFIG_OF */
static inline unsigned int irq_of_parse_and_map(struct device_node *dev,
@@ -87,6 +104,12 @@ static inline void *of_irq_find_parent(struct device_node *child)
{
return NULL;
}
+
+static inline u32 of_msi_map_rid(struct device *dev,
+ struct device_node *msi_np, u32 rid_in)
+{
+ return rid_in;
+}
#endif /* !CONFIG_OF */
#endif /* __OF_IRQ_H */