linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/8] of: Handle multi-parent version of msi-parent & msi-map
@ 2015-10-06 17:03 Marc Zyngier
  2015-10-06 17:03 ` [PATCH v2 1/8] of/irq: Add support code for multi-parent version of "msi-parent" Marc Zyngier
                   ` (8 more replies)
  0 siblings, 9 replies; 13+ messages in thread
From: Marc Zyngier @ 2015-10-06 17:03 UTC (permalink / raw)
  To: Rob Herring, Jason Cooper, Thomas Gleixner, Bjorn Helgaas
  Cc: linux-kernel, linux-arm-kernel, linux-pci, Mark Rutland,
	David Daney, Robin Murphy

Now that we have a useable and documented version of msi-parent that
can deal with multiple parenting, we can properly handle it in the
kernel. This leads to a new OF helper, some rework in the PCI and
platform layers, as well as a small patch for the ITS driver, which is
the only thing in the kernel requirering this functionality so far.

On top of that, the msi-map property also offers a new feature, which
is that ability to have a per-device MSI controller (instead of having
a global one). The last four patches enable this.

These patches are on top of David Daney's series:

http://lists.infradead.org/pipermail/linux-arm-kernel/2015-October/373986.html

(of_msi_map_rid is a dependency), and has been tested on 4.3-rc3,
using both platform and PCI MSI devices.

* From the initial version
  - Dropped the of parsing patch
  - Built on top of David's series to reuse of_msi_map_rid
  - New per-device PCI/MSI domain assignment hook
  - Parse msi-map at bus probing time and populate the msi_domain field

Marc Zyngier (8):
  of/irq: Add support code for multi-parent version of "msi-parent"
  of/irq: Use of_msi_get_domain instead of open-coded "msi-parent"
    parsing
  PCI/MSI: Use of_msi_get_domain instead of open-coded "msi-parent"
    parsing
  irqchip/gic-v3-its: Parse new version of msi-parent property
  of/irq: Split of_msi_map_rid to reuse msi-map lookup
  of/irq: Use the msi-map property to provide device-specific MSI domain
  PCI: Add per-device MSI domain hook
  PCI/MSI: Allow the MSI domain to be device-specific

 drivers/irqchip/irq-gic-v3-its-platform-msi.c |  18 ++-
 drivers/of/irq.c                              | 151 ++++++++++++++++++++------
 drivers/pci/msi.c                             |  17 +++
 drivers/pci/of.c                              |  13 +--
 drivers/pci/probe.c                           |  43 +++++++-
 include/linux/msi.h                           |   6 +
 include/linux/of_irq.h                        |  16 +++
 7 files changed, 214 insertions(+), 50 deletions(-)

-- 
2.1.4


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v2 1/8] of/irq: Add support code for multi-parent version of "msi-parent"
  2015-10-06 17:03 [PATCH v2 0/8] of: Handle multi-parent version of msi-parent & msi-map Marc Zyngier
@ 2015-10-06 17:03 ` Marc Zyngier
  2015-10-06 17:03 ` [PATCH v2 2/8] of/irq: Use of_msi_get_domain instead of open-coded "msi-parent" parsing Marc Zyngier
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Marc Zyngier @ 2015-10-06 17:03 UTC (permalink / raw)
  To: Rob Herring, Jason Cooper, Thomas Gleixner, Bjorn Helgaas
  Cc: linux-kernel, linux-arm-kernel, linux-pci, Mark Rutland,
	David Daney, Robin Murphy

Since 126b16e2ad98 ("Docs: dt: add generic MSI bindings"),
the definition of "msi-parent" has evolved, while maintaining
some degree of compatibility. It can now express multiple MSI
controllers as parents, as well as some sideband data being
communicated to the controller.

This patch adds the parsing of the property, iterating over
the multiple parents until a suitable irqdomain is found.
It can also fallback to the original parsing if the old
binding is detected.

This support code gets used in the subsequent patches.

Suggested-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/of/irq.c       | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/of_irq.h |  9 ++++++++
 2 files changed, 68 insertions(+)

diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index c90bd4e..62cfdc2 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -682,3 +682,62 @@ u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in)
 
 	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;
+}
diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
index 8cd9334..62ae6ed 100644
--- a/include/linux/of_irq.h
+++ b/include/linux/of_irq.h
@@ -46,6 +46,9 @@ 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);
 #else
 static inline int of_irq_count(struct device_node *dev)
 {
@@ -64,6 +67,12 @@ 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;
+}
 #endif
 
 #if defined(CONFIG_OF)
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 2/8] of/irq: Use of_msi_get_domain instead of open-coded "msi-parent" parsing
  2015-10-06 17:03 [PATCH v2 0/8] of: Handle multi-parent version of msi-parent & msi-map Marc Zyngier
  2015-10-06 17:03 ` [PATCH v2 1/8] of/irq: Add support code for multi-parent version of "msi-parent" Marc Zyngier
@ 2015-10-06 17:03 ` Marc Zyngier
  2015-10-06 17:03 ` [PATCH v2 3/8] PCI/MSI: " Marc Zyngier
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Marc Zyngier @ 2015-10-06 17:03 UTC (permalink / raw)
  To: Rob Herring, Jason Cooper, Thomas Gleixner, Bjorn Helgaas
  Cc: linux-kernel, linux-arm-kernel, linux-pci, Mark Rutland,
	David Daney, Robin Murphy

Now that we have a function that implements the complexity of the
"msi-parent" property parsing, switch to that.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/of/irq.c | 31 +++++++++++--------------------
 1 file changed, 11 insertions(+), 20 deletions(-)

diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 62cfdc2..89ebc61 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -580,26 +580,6 @@ err:
 }
 
 /**
- * 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)
-{
-	struct device_node *msi_np;
-	struct irq_domain *d;
-
-	msi_np = of_parse_phandle(np, "msi-parent", 0);
-	if (!msi_np)
-		return;
-
-	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);
-}
-
-/**
  * 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.
@@ -741,3 +721,14 @@ struct irq_domain *of_msi_get_domain(struct device *dev,
 
 	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));
+}
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 3/8] PCI/MSI: Use of_msi_get_domain instead of open-coded "msi-parent" parsing
  2015-10-06 17:03 [PATCH v2 0/8] of: Handle multi-parent version of msi-parent & msi-map Marc Zyngier
  2015-10-06 17:03 ` [PATCH v2 1/8] of/irq: Add support code for multi-parent version of "msi-parent" Marc Zyngier
  2015-10-06 17:03 ` [PATCH v2 2/8] of/irq: Use of_msi_get_domain instead of open-coded "msi-parent" parsing Marc Zyngier
@ 2015-10-06 17:03 ` Marc Zyngier
  2015-10-15 20:10   ` Bjorn Helgaas
  2015-10-06 17:03 ` [PATCH v2 4/8] irqchip/gic-v3-its: Parse new version of msi-parent property Marc Zyngier
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 13+ messages in thread
From: Marc Zyngier @ 2015-10-06 17:03 UTC (permalink / raw)
  To: Rob Herring, Jason Cooper, Thomas Gleixner, Bjorn Helgaas
  Cc: linux-kernel, linux-arm-kernel, linux-pci, Mark Rutland,
	David Daney, Robin Murphy

Now that we have a function that implements the complexity of the
"msi-parent" property parsing, switch to that.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/pci/of.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/pci/of.c b/drivers/pci/of.c
index 2e99a50..e112da1 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
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 4/8] irqchip/gic-v3-its: Parse new version of msi-parent property
  2015-10-06 17:03 [PATCH v2 0/8] of: Handle multi-parent version of msi-parent & msi-map Marc Zyngier
                   ` (2 preceding siblings ...)
  2015-10-06 17:03 ` [PATCH v2 3/8] PCI/MSI: " Marc Zyngier
@ 2015-10-06 17:03 ` Marc Zyngier
  2015-10-06 17:04 ` [PATCH v2 5/8] of/irq: Split of_msi_map_rid to reuse msi-map lookup Marc Zyngier
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Marc Zyngier @ 2015-10-06 17:03 UTC (permalink / raw)
  To: Rob Herring, Jason Cooper, Thomas Gleixner, Bjorn Helgaas
  Cc: linux-kernel, linux-arm-kernel, linux-pci, Mark Rutland,
	David Daney, Robin Murphy

Now that 126b16e2ad98 ("Docs: dt: add generic MSI bindings")
has made it into the tree, the time has come to get rid of the
old hack, and to parse msi-parent in its full glory.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its-platform-msi.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
index a865505..589a532 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 == domain->of_node) {
+			if (WARN_ON(args.args_count != 1))
+				return -EINVAL;
+			dev_id = args.args[0];
+			break;
+		}
+	} while (!ret);
+
 	if (ret)
 		return ret;
 
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 5/8] of/irq: Split of_msi_map_rid to reuse msi-map lookup
  2015-10-06 17:03 [PATCH v2 0/8] of: Handle multi-parent version of msi-parent & msi-map Marc Zyngier
                   ` (3 preceding siblings ...)
  2015-10-06 17:03 ` [PATCH v2 4/8] irqchip/gic-v3-its: Parse new version of msi-parent property Marc Zyngier
@ 2015-10-06 17:04 ` Marc Zyngier
  2015-10-06 17:04 ` [PATCH v2 6/8] of/irq: Use the msi-map property to provide device-specific MSI domain Marc Zyngier
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Marc Zyngier @ 2015-10-06 17:04 UTC (permalink / raw)
  To: Rob Herring, Jason Cooper, Thomas Gleixner, Bjorn Helgaas
  Cc: linux-kernel, linux-arm-kernel, linux-pci, Mark Rutland,
	David Daney, Robin Murphy

The msi-map property is also used to identify the MSI controller
as a form of grown-up msi-parent property.

Looking it up is complicated enough, and since of_msi_map_rid
already implements this, let's turn it into an internal utility
function. We'll put that to good use later on.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/of/irq.c | 43 ++++++++++++++++++++++++++++---------------
 1 file changed, 28 insertions(+), 15 deletions(-)

diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 89ebc61..ed64d98 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -579,21 +579,12 @@ err:
 	}
 }
 
-/**
- * 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.
- */
-u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in)
+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;
@@ -643,9 +634,15 @@ u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in)
 
 		msi_controller_node = of_find_node_by_phandle(phandle);
 
-		matched = masked_rid >= rid_base &&
-			masked_rid < rid_base + rid_len &&
-			msi_np == msi_controller_node;
+		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);
@@ -663,6 +660,22 @@ u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in)
 	return rid_out;
 }
 
+/**
+ * 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.
+ */
+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)
 {
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 6/8] of/irq: Use the msi-map property to provide device-specific MSI domain
  2015-10-06 17:03 [PATCH v2 0/8] of: Handle multi-parent version of msi-parent & msi-map Marc Zyngier
                   ` (4 preceding siblings ...)
  2015-10-06 17:04 ` [PATCH v2 5/8] of/irq: Split of_msi_map_rid to reuse msi-map lookup Marc Zyngier
@ 2015-10-06 17:04 ` Marc Zyngier
  2015-10-06 17:04 ` [PATCH v2 7/8] PCI: Add per-device MSI domain hook Marc Zyngier
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Marc Zyngier @ 2015-10-06 17:04 UTC (permalink / raw)
  To: Rob Herring, Jason Cooper, Thomas Gleixner, Bjorn Helgaas
  Cc: linux-kernel, linux-arm-kernel, linux-pci, Mark Rutland,
	David Daney, Robin Murphy

While msi-parent is used to point to the MSI controller that
works for all the devices behind a root complex, it doesn't
allow configurations where each individual device can be routed
to a separate MSI controller.

The msi-map property provides this flexibility (and much more),
so let's add a utility function that parses it, and return the
corresponding MSI domain.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/of/irq.c       | 18 ++++++++++++++++++
 include/linux/of_irq.h |  7 +++++++
 2 files changed, 25 insertions(+)

diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index ed64d98..0baf626d 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -689,6 +689,24 @@ static struct irq_domain *__of_get_msi_domain(struct device_node *np,
 }
 
 /**
+ * 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
diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
index 62ae6ed..65d9692 100644
--- a/include/linux/of_irq.h
+++ b/include/linux/of_irq.h
@@ -49,6 +49,8 @@ extern int of_irq_to_resource_table(struct device_node *dev,
 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)
 {
@@ -73,6 +75,11 @@ static inline struct irq_domain *of_msi_get_domain(struct device *dev,
 {
 	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)
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 7/8] PCI: Add per-device MSI domain hook
  2015-10-06 17:03 [PATCH v2 0/8] of: Handle multi-parent version of msi-parent & msi-map Marc Zyngier
                   ` (5 preceding siblings ...)
  2015-10-06 17:04 ` [PATCH v2 6/8] of/irq: Use the msi-map property to provide device-specific MSI domain Marc Zyngier
@ 2015-10-06 17:04 ` Marc Zyngier
  2015-10-15 20:11   ` Bjorn Helgaas
  2015-10-06 17:04 ` [PATCH v2 8/8] PCI/MSI: Allow the MSI domain to be device-specific Marc Zyngier
  2015-10-15 20:39 ` [PATCH v2 0/8] of: Handle multi-parent version of msi-parent & msi-map Rob Herring
  8 siblings, 1 reply; 13+ messages in thread
From: Marc Zyngier @ 2015-10-06 17:04 UTC (permalink / raw)
  To: Rob Herring, Jason Cooper, Thomas Gleixner, Bjorn Helgaas
  Cc: linux-kernel, linux-arm-kernel, linux-pci, Mark Rutland,
	David Daney, Robin Murphy

So far, we have considered that the MSI domain for a device was
either set via the architecture-dependent pcibios implementation
or inherited from the host bridge.

As we're about to break that assumption, add pci_dev_msi_domain
which is the equivalent of pci_host_bridge_msi_domain, but for
a single device.

Other than moving things around a bit, this patch on its own
has no effect.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/pci/probe.c | 35 ++++++++++++++++++++++++++++++-----
 1 file changed, 30 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 8361d27..7c333f8 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1622,15 +1622,40 @@ 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;
+
+	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)
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 8/8] PCI/MSI: Allow the MSI domain to be device-specific
  2015-10-06 17:03 [PATCH v2 0/8] of: Handle multi-parent version of msi-parent & msi-map Marc Zyngier
                   ` (6 preceding siblings ...)
  2015-10-06 17:04 ` [PATCH v2 7/8] PCI: Add per-device MSI domain hook Marc Zyngier
@ 2015-10-06 17:04 ` Marc Zyngier
  2015-10-15 20:11   ` Bjorn Helgaas
  2015-10-15 20:39 ` [PATCH v2 0/8] of: Handle multi-parent version of msi-parent & msi-map Rob Herring
  8 siblings, 1 reply; 13+ messages in thread
From: Marc Zyngier @ 2015-10-06 17:04 UTC (permalink / raw)
  To: Rob Herring, Jason Cooper, Thomas Gleixner, Bjorn Helgaas
  Cc: linux-kernel, linux-arm-kernel, linux-pci, Mark Rutland,
	David Daney, Robin Murphy

So far, we've always considered that for a given PCI device, its
MSI controller was either set by the architecture-specific
pcibios hook, or simply inherited from the host bridge.

This doesn't cover things like firmware-defined topologies like
msi-map (DT) or IORT (ACPI), which can provide information about
which MSI controller to use on a per-device basis.

This patch adds the necessary hook into the MSI code to allow this
feature, and provides the msi-map functionnality as a first
implementation.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/pci/msi.c   | 17 +++++++++++++++++
 drivers/pci/probe.c |  8 ++++++++
 include/linux/msi.h |  6 ++++++
 3 files changed, 31 insertions(+)

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 81a2798..3daff31 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -1357,4 +1357,21 @@ u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev)
 
 	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/probe.c b/drivers/pci/probe.c
index 7c333f8..f14a970 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1639,6 +1639,14 @@ static struct irq_domain *pci_dev_msi_domain(struct pci_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;
 }
 
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 56e3b76..375be7c 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -294,6 +294,12 @@ irq_hw_number_t pci_msi_domain_calc_hwirq(struct pci_dev *dev,
 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 */
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 3/8] PCI/MSI: Use of_msi_get_domain instead of open-coded "msi-parent" parsing
  2015-10-06 17:03 ` [PATCH v2 3/8] PCI/MSI: " Marc Zyngier
@ 2015-10-15 20:10   ` Bjorn Helgaas
  0 siblings, 0 replies; 13+ messages in thread
From: Bjorn Helgaas @ 2015-10-15 20:10 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Rob Herring, Jason Cooper, Thomas Gleixner, Bjorn Helgaas,
	linux-kernel, linux-arm-kernel, linux-pci, Mark Rutland,
	David Daney, Robin Murphy

On Tue, Oct 06, 2015 at 06:03:58PM +0100, Marc Zyngier wrote:
> Now that we have a function that implements the complexity of the
> "msi-parent" property parsing, switch to that.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Acked-by: Bjorn Helgaas <bhelgaas@google.com>

> ---
>  drivers/pci/of.c | 13 ++++++-------
>  1 file changed, 6 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/pci/of.c b/drivers/pci/of.c
> index 2e99a50..e112da1 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
> -- 
> 2.1.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 7/8] PCI: Add per-device MSI domain hook
  2015-10-06 17:04 ` [PATCH v2 7/8] PCI: Add per-device MSI domain hook Marc Zyngier
@ 2015-10-15 20:11   ` Bjorn Helgaas
  0 siblings, 0 replies; 13+ messages in thread
From: Bjorn Helgaas @ 2015-10-15 20:11 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Rob Herring, Jason Cooper, Thomas Gleixner, Bjorn Helgaas,
	linux-kernel, linux-arm-kernel, linux-pci, Mark Rutland,
	David Daney, Robin Murphy

On Tue, Oct 06, 2015 at 06:04:02PM +0100, Marc Zyngier wrote:
> So far, we have considered that the MSI domain for a device was
> either set via the architecture-dependent pcibios implementation
> or inherited from the host bridge.
> 
> As we're about to break that assumption, add pci_dev_msi_domain
> which is the equivalent of pci_host_bridge_msi_domain, but for
> a single device.
> 
> Other than moving things around a bit, this patch on its own
> has no effect.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Acked-by: Bjorn Helgaas <bhelgaas@google.com>

> ---
>  drivers/pci/probe.c | 35 ++++++++++++++++++++++++++++++-----
>  1 file changed, 30 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 8361d27..7c333f8 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -1622,15 +1622,40 @@ 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;
> +
> +	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)
> -- 
> 2.1.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 8/8] PCI/MSI: Allow the MSI domain to be device-specific
  2015-10-06 17:04 ` [PATCH v2 8/8] PCI/MSI: Allow the MSI domain to be device-specific Marc Zyngier
@ 2015-10-15 20:11   ` Bjorn Helgaas
  0 siblings, 0 replies; 13+ messages in thread
From: Bjorn Helgaas @ 2015-10-15 20:11 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Rob Herring, Jason Cooper, Thomas Gleixner, Bjorn Helgaas,
	linux-kernel, linux-arm-kernel, linux-pci, Mark Rutland,
	David Daney, Robin Murphy

On Tue, Oct 06, 2015 at 06:04:03PM +0100, Marc Zyngier wrote:
> So far, we've always considered that for a given PCI device, its
> MSI controller was either set by the architecture-specific
> pcibios hook, or simply inherited from the host bridge.
> 
> This doesn't cover things like firmware-defined topologies like
> msi-map (DT) or IORT (ACPI), which can provide information about
> which MSI controller to use on a per-device basis.
> 
> This patch adds the necessary hook into the MSI code to allow this
> feature, and provides the msi-map functionnality as a first
> implementation.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Acked-by: Bjorn Helgaas <bhelgaas@google.com>

I assume somebody other than me will merge this series.

> ---
>  drivers/pci/msi.c   | 17 +++++++++++++++++
>  drivers/pci/probe.c |  8 ++++++++
>  include/linux/msi.h |  6 ++++++
>  3 files changed, 31 insertions(+)
> 
> diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
> index 81a2798..3daff31 100644
> --- a/drivers/pci/msi.c
> +++ b/drivers/pci/msi.c
> @@ -1357,4 +1357,21 @@ u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev)
>  
>  	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/probe.c b/drivers/pci/probe.c
> index 7c333f8..f14a970 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -1639,6 +1639,14 @@ static struct irq_domain *pci_dev_msi_domain(struct pci_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;
>  }
>  
> diff --git a/include/linux/msi.h b/include/linux/msi.h
> index 56e3b76..375be7c 100644
> --- a/include/linux/msi.h
> +++ b/include/linux/msi.h
> @@ -294,6 +294,12 @@ irq_hw_number_t pci_msi_domain_calc_hwirq(struct pci_dev *dev,
>  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 */
> -- 
> 2.1.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 0/8] of: Handle multi-parent version of msi-parent & msi-map
  2015-10-06 17:03 [PATCH v2 0/8] of: Handle multi-parent version of msi-parent & msi-map Marc Zyngier
                   ` (7 preceding siblings ...)
  2015-10-06 17:04 ` [PATCH v2 8/8] PCI/MSI: Allow the MSI domain to be device-specific Marc Zyngier
@ 2015-10-15 20:39 ` Rob Herring
  8 siblings, 0 replies; 13+ messages in thread
From: Rob Herring @ 2015-10-15 20:39 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Jason Cooper, Thomas Gleixner, Bjorn Helgaas, linux-kernel,
	linux-arm-kernel, linux-pci, Mark Rutland, David Daney,
	Robin Murphy

On Tue, Oct 6, 2015 at 12:03 PM, Marc Zyngier <marc.zyngier@arm.com> wrote:
> Now that we have a useable and documented version of msi-parent that
> can deal with multiple parenting, we can properly handle it in the
> kernel. This leads to a new OF helper, some rework in the PCI and
> platform layers, as well as a small patch for the ITS driver, which is
> the only thing in the kernel requirering this functionality so far.
>
> On top of that, the msi-map property also offers a new feature, which
> is that ability to have a per-device MSI controller (instead of having
> a global one). The last four patches enable this.
>
> These patches are on top of David Daney's series:
>
> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-October/373986.html
>
> (of_msi_map_rid is a dependency), and has been tested on 4.3-rc3,
> using both platform and PCI MSI devices.
>
> * From the initial version
>   - Dropped the of parsing patch
>   - Built on top of David's series to reuse of_msi_map_rid
>   - New per-device PCI/MSI domain assignment hook
>   - Parse msi-map at bus probing time and populate the msi_domain field
>
> Marc Zyngier (8):
>   of/irq: Add support code for multi-parent version of "msi-parent"
>   of/irq: Use of_msi_get_domain instead of open-coded "msi-parent"
>     parsing
>   PCI/MSI: Use of_msi_get_domain instead of open-coded "msi-parent"
>     parsing
>   irqchip/gic-v3-its: Parse new version of msi-parent property
>   of/irq: Split of_msi_map_rid to reuse msi-map lookup
>   of/irq: Use the msi-map property to provide device-specific MSI domain
>   PCI: Add per-device MSI domain hook
>   PCI/MSI: Allow the MSI domain to be device-specific

For the series:

Acked-by: Rob Herring <robh@kernel.org>

I'm assuming Thomas is taking this and the dependency. It is mostly DT
code so I'm happy take it if you want.

Rob

>
>  drivers/irqchip/irq-gic-v3-its-platform-msi.c |  18 ++-
>  drivers/of/irq.c                              | 151 ++++++++++++++++++++------
>  drivers/pci/msi.c                             |  17 +++
>  drivers/pci/of.c                              |  13 +--
>  drivers/pci/probe.c                           |  43 +++++++-
>  include/linux/msi.h                           |   6 +
>  include/linux/of_irq.h                        |  16 +++
>  7 files changed, 214 insertions(+), 50 deletions(-)
>
> --
> 2.1.4
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2015-10-15 20:40 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-06 17:03 [PATCH v2 0/8] of: Handle multi-parent version of msi-parent & msi-map Marc Zyngier
2015-10-06 17:03 ` [PATCH v2 1/8] of/irq: Add support code for multi-parent version of "msi-parent" Marc Zyngier
2015-10-06 17:03 ` [PATCH v2 2/8] of/irq: Use of_msi_get_domain instead of open-coded "msi-parent" parsing Marc Zyngier
2015-10-06 17:03 ` [PATCH v2 3/8] PCI/MSI: " Marc Zyngier
2015-10-15 20:10   ` Bjorn Helgaas
2015-10-06 17:03 ` [PATCH v2 4/8] irqchip/gic-v3-its: Parse new version of msi-parent property Marc Zyngier
2015-10-06 17:04 ` [PATCH v2 5/8] of/irq: Split of_msi_map_rid to reuse msi-map lookup Marc Zyngier
2015-10-06 17:04 ` [PATCH v2 6/8] of/irq: Use the msi-map property to provide device-specific MSI domain Marc Zyngier
2015-10-06 17:04 ` [PATCH v2 7/8] PCI: Add per-device MSI domain hook Marc Zyngier
2015-10-15 20:11   ` Bjorn Helgaas
2015-10-06 17:04 ` [PATCH v2 8/8] PCI/MSI: Allow the MSI domain to be device-specific Marc Zyngier
2015-10-15 20:11   ` Bjorn Helgaas
2015-10-15 20:39 ` [PATCH v2 0/8] of: Handle multi-parent version of msi-parent & msi-map Rob Herring

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).