Linux-ACPI Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH 00/12] ACPI/OF: Upgrade MSI/IOMMU ID mapping APIs
@ 2020-05-21 12:59 Lorenzo Pieralisi
  2020-05-21 12:59 ` [PATCH 01/12] ACPI/IORT: Make iort_match_node_callback walk the ACPI namespace for NC Lorenzo Pieralisi
                   ` (11 more replies)
  0 siblings, 12 replies; 31+ messages in thread
From: Lorenzo Pieralisi @ 2020-05-21 12:59 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Lorenzo Pieralisi, Rob Herring, Rafael J. Wysocki, Hanjun Guo,
	Sudeep Holla, Robin Murphy, Catalin Marinas, Will Deacon,
	Marc Zyngier, iommu, linux-acpi, devicetree, linux-pci,
	Joerg Roedel, Bjorn Helgaas, Makarand Pawagi, Diana Craciun,
	Laurentiu Tudor

Firmware bindings provided in the ACPI IORT table[1] and device tree
bindings define rules to carry out input/output ID mappings - ie
retrieving an IOMMU/MSI controller input ID for a device with a given
ID.

At the moment these firmware bindings are used exclusively for PCI
devices and their requester ID to IOMMU/MSI id mapping but there is
nothing PCI specific in the ACPI and devicetree bindings that prevent
the firmware and kernel from using the firmware bindings to traslate
device IDs for any bus that requires its devices to carry out
input/output id translations.

The Freescale FSL bus is an example whereby the input/output ID
translation kernel code put in place for PCI can be reused for devices
attached to the bus that are not PCI devices.

This series updates the kernel code to make the MSI/IOMMU input/output
ID translation PCI agnostic and apply the resulting changes to the
device ID space provided by the Freescale FSL bus.

[1] http://infocenter.arm.com/help/topic/com.arm.doc.den0049d/DEN0049D_IO_Remapping_Table.pdf

Cc: Rob Herring <robh+dt@kernel.org>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: "Joerg Roedel <joro@8bytes.org>
Cc: Hanjun Guo <guohanjun@huawei.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Marc Zyngier <maz@kernel.org>

Diana Craciun (3):
  of/irq: make of_msi_map_get_device_domain() bus agnostic
  bus/fsl-mc: Refactor the MSI domain creation in the DPRC driver
  bus: fsl-mc: Add ACPI support for fsl-mc

Laurentiu Tudor (1):
  dt-bindings: arm: fsl: Add msi-map device-tree binding for fsl-mc bus

Lorenzo Pieralisi (8):
  ACPI/IORT: Make iort_match_node_callback walk the ACPI namespace for
    NC
  ACPI/IORT: Make iort_get_device_domain IRQ domain agnostic
  ACPI/IORT: Make iort_msi_map_rid() PCI agnostic
  ACPI/IORT: Remove useless PCI bus walk
  ACPI/IORT: Add an input ID to acpi_dma_configure()
  of/iommu: Make of_map_rid() PCI agnostic
  of/device: Add input id to of_dma_configure()
  of/irq: Make of_msi_map_rid() PCI bus agnostic

 .../devicetree/bindings/misc/fsl,qoriq-mc.txt |  30 ++++-
 drivers/acpi/arm64/iort.c                     | 108 ++++++++++++------
 drivers/acpi/scan.c                           |   8 +-
 drivers/bus/fsl-mc/dprc-driver.c              |  31 ++---
 drivers/bus/fsl-mc/fsl-mc-bus.c               |  79 +++++++++----
 drivers/bus/fsl-mc/fsl-mc-msi.c               |  36 ++++--
 drivers/bus/fsl-mc/fsl-mc-private.h           |   6 +-
 drivers/iommu/of_iommu.c                      |  53 ++++++---
 drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c   |  88 +++++++++++++-
 drivers/of/base.c                             |  42 +++----
 drivers/of/device.c                           |   8 +-
 drivers/of/irq.c                              |  34 +++---
 drivers/pci/msi.c                             |   5 +-
 include/acpi/acpi_bus.h                       |   9 +-
 include/linux/acpi.h                          |   7 ++
 include/linux/acpi_iort.h                     |  26 +++--
 include/linux/of.h                            |  17 ++-
 include/linux/of_device.h                     |  16 ++-
 include/linux/of_iommu.h                      |   6 +-
 include/linux/of_irq.h                        |  19 ++-
 20 files changed, 451 insertions(+), 177 deletions(-)

-- 
2.26.1


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

* [PATCH 01/12] ACPI/IORT: Make iort_match_node_callback walk the ACPI namespace for NC
  2020-05-21 12:59 [PATCH 00/12] ACPI/OF: Upgrade MSI/IOMMU ID mapping APIs Lorenzo Pieralisi
@ 2020-05-21 12:59 ` Lorenzo Pieralisi
  2020-05-21 12:59 ` [PATCH 02/12] ACPI/IORT: Make iort_get_device_domain IRQ domain agnostic Lorenzo Pieralisi
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 31+ messages in thread
From: Lorenzo Pieralisi @ 2020-05-21 12:59 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Lorenzo Pieralisi, Will Deacon, Hanjun Guo, Sudeep Holla,
	Catalin Marinas, Robin Murphy, Rafael J. Wysocki, iommu,
	linux-acpi, devicetree, linux-pci, Rob Herring, Joerg Roedel,
	Bjorn Helgaas, Marc Zyngier, Makarand Pawagi, Diana Craciun,
	Laurentiu Tudor

When the iort_match_node_callback is invoked for a named component
the match should be executed upon a device with an ACPI companion.

For devices with no ACPI companion set-up the ACPI device tree must be
walked in order to find the first parent node with a companion set and
check the parent node against the named component entry to check whether
there is a match and therefore an IORT node describing the in/out ID
translation for the device has been found.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Hanjun Guo <guohanjun@huawei.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
---
 drivers/acpi/arm64/iort.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 7d04424189df..7cfd77b5e6e8 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -264,15 +264,31 @@ static acpi_status iort_match_node_callback(struct acpi_iort_node *node,
 
 	if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT) {
 		struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
-		struct acpi_device *adev = to_acpi_device_node(dev->fwnode);
+		struct acpi_device *adev;
 		struct acpi_iort_named_component *ncomp;
+		struct device *nc_dev = dev;
+
+		/*
+		 * Walk the device tree to find a device with an
+		 * ACPI companion; there is no point in scanning
+		 * IORT for a device matching a named component if
+		 * the device does not have an ACPI companion to
+		 * start with.
+		 */
+		do {
+			adev = ACPI_COMPANION(nc_dev);
+			if (adev)
+				break;
+
+			nc_dev = nc_dev->parent;
+		} while (nc_dev);
 
 		if (!adev)
 			goto out;
 
 		status = acpi_get_name(adev->handle, ACPI_FULL_PATHNAME, &buf);
 		if (ACPI_FAILURE(status)) {
-			dev_warn(dev, "Can't get device full path name\n");
+			dev_warn(nc_dev, "Can't get device full path name\n");
 			goto out;
 		}
 
-- 
2.26.1


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

* [PATCH 02/12] ACPI/IORT: Make iort_get_device_domain IRQ domain agnostic
  2020-05-21 12:59 [PATCH 00/12] ACPI/OF: Upgrade MSI/IOMMU ID mapping APIs Lorenzo Pieralisi
  2020-05-21 12:59 ` [PATCH 01/12] ACPI/IORT: Make iort_match_node_callback walk the ACPI namespace for NC Lorenzo Pieralisi
@ 2020-05-21 12:59 ` Lorenzo Pieralisi
  2020-05-21 19:56   ` Bjorn Helgaas
  2020-05-21 12:59 ` [PATCH 03/12] ACPI/IORT: Make iort_msi_map_rid() PCI agnostic Lorenzo Pieralisi
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 31+ messages in thread
From: Lorenzo Pieralisi @ 2020-05-21 12:59 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Lorenzo Pieralisi, Will Deacon, Hanjun Guo, Bjorn Helgaas,
	Sudeep Holla, Catalin Marinas, Robin Murphy, Rafael J. Wysocki,
	Marc Zyngier, iommu, linux-acpi, devicetree, linux-pci,
	Rob Herring, Joerg Roedel, Makarand Pawagi, Diana Craciun,
	Laurentiu Tudor

iort_get_device_domain() is PCI specific but it need not be,
since it can be used to retrieve IRQ domain nexus of any kind
by adding an irq_domain_bus_token input to it.

Make it PCI agnostic by also renaming the requestor ID input
to a more generic ID name.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Hanjun Guo <guohanjun@huawei.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Marc Zyngier <maz@kernel.org>
---
 drivers/acpi/arm64/iort.c | 14 +++++++-------
 drivers/pci/msi.c         |  3 ++-
 include/linux/acpi_iort.h |  7 ++++---
 3 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 7cfd77b5e6e8..8f2a961c1364 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -567,7 +567,6 @@ static struct acpi_iort_node *iort_find_dev_node(struct device *dev)
 		node = iort_get_iort_node(dev->fwnode);
 		if (node)
 			return node;
-
 		/*
 		 * if not, then it should be a platform device defined in
 		 * DSDT/SSDT (with Named Component node in IORT)
@@ -658,13 +657,13 @@ static int __maybe_unused iort_find_its_base(u32 its_id, phys_addr_t *base)
 /**
  * iort_dev_find_its_id() - Find the ITS identifier for a device
  * @dev: The device.
- * @req_id: Device's requester ID
+ * @id: Device's ID
  * @idx: Index of the ITS identifier list.
  * @its_id: ITS identifier.
  *
  * Returns: 0 on success, appropriate error value otherwise
  */
-static int iort_dev_find_its_id(struct device *dev, u32 req_id,
+static int iort_dev_find_its_id(struct device *dev, u32 id,
 				unsigned int idx, int *its_id)
 {
 	struct acpi_iort_its_group *its;
@@ -674,7 +673,7 @@ static int iort_dev_find_its_id(struct device *dev, u32 req_id,
 	if (!node)
 		return -ENXIO;
 
-	node = iort_node_map_id(node, req_id, NULL, IORT_MSI_TYPE);
+	node = iort_node_map_id(node, id, NULL, IORT_MSI_TYPE);
 	if (!node)
 		return -ENXIO;
 
@@ -697,19 +696,20 @@ static int iort_dev_find_its_id(struct device *dev, u32 req_id,
  *
  * Returns: the MSI domain for this device, NULL otherwise
  */
-struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
+struct irq_domain *iort_get_device_domain(struct device *dev, u32 id,
+					  enum irq_domain_bus_token bus_token)
 {
 	struct fwnode_handle *handle;
 	int its_id;
 
-	if (iort_dev_find_its_id(dev, req_id, 0, &its_id))
+	if (iort_dev_find_its_id(dev, id, 0, &its_id))
 		return NULL;
 
 	handle = iort_find_domain_token(its_id);
 	if (!handle)
 		return NULL;
 
-	return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
+	return irq_find_matching_fwnode(handle, bus_token);
 }
 
 static void iort_set_device_domain(struct device *dev,
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 6b43a5455c7a..74a91f52ecc0 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -1558,7 +1558,8 @@ struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev)
 	pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid);
 	dom = of_msi_map_get_device_domain(&pdev->dev, rid);
 	if (!dom)
-		dom = iort_get_device_domain(&pdev->dev, rid);
+		dom = iort_get_device_domain(&pdev->dev, rid,
+					     DOMAIN_BUS_PCI_MSI);
 	return dom;
 }
 #endif /* CONFIG_PCI_MSI_IRQ_DOMAIN */
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 8e7e2ec37f1b..08ec6bd2297f 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -29,7 +29,8 @@ struct fwnode_handle *iort_find_domain_token(int trans_id);
 #ifdef CONFIG_ACPI_IORT
 void acpi_iort_init(void);
 u32 iort_msi_map_rid(struct device *dev, u32 req_id);
-struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id);
+struct irq_domain *iort_get_device_domain(struct device *dev, u32 id,
+					  enum irq_domain_bus_token bus_token);
 void acpi_configure_pmsi_domain(struct device *dev);
 int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id);
 /* IOMMU interface */
@@ -40,8 +41,8 @@ int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head);
 static inline void acpi_iort_init(void) { }
 static inline u32 iort_msi_map_rid(struct device *dev, u32 req_id)
 { return req_id; }
-static inline struct irq_domain *iort_get_device_domain(struct device *dev,
-							u32 req_id)
+static inline struct irq_domain *iort_get_device_domain(
+	struct device *dev, u32 id, enum irq_domain_bus_token bus_token)
 { return NULL; }
 static inline void acpi_configure_pmsi_domain(struct device *dev) { }
 /* IOMMU interface */
-- 
2.26.1


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

* [PATCH 03/12] ACPI/IORT: Make iort_msi_map_rid() PCI agnostic
  2020-05-21 12:59 [PATCH 00/12] ACPI/OF: Upgrade MSI/IOMMU ID mapping APIs Lorenzo Pieralisi
  2020-05-21 12:59 ` [PATCH 01/12] ACPI/IORT: Make iort_match_node_callback walk the ACPI namespace for NC Lorenzo Pieralisi
  2020-05-21 12:59 ` [PATCH 02/12] ACPI/IORT: Make iort_get_device_domain IRQ domain agnostic Lorenzo Pieralisi
@ 2020-05-21 12:59 ` Lorenzo Pieralisi
  2020-05-21 13:00 ` [PATCH 04/12] ACPI/IORT: Remove useless PCI bus walk Lorenzo Pieralisi
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 31+ messages in thread
From: Lorenzo Pieralisi @ 2020-05-21 12:59 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Lorenzo Pieralisi, Will Deacon, Hanjun Guo, Sudeep Holla,
	Catalin Marinas, Robin Murphy, Rafael J. Wysocki, iommu,
	linux-acpi, devicetree, linux-pci, Rob Herring, Joerg Roedel,
	Bjorn Helgaas, Marc Zyngier, Makarand Pawagi, Diana Craciun,
	Laurentiu Tudor

There is nothing PCI specific in iort_msi_map_rid(). Make it
a generic function, iort_msi_map_id() and provide a stub
for iort_msi_map_rid() on top of it to keep current users
unchanged.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Hanjun Guo <guohanjun@huawei.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
---
 drivers/acpi/arm64/iort.c | 12 ++++++------
 include/linux/acpi_iort.h | 12 ++++++++++--
 2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 8f2a961c1364..f346a785e0b5 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -585,22 +585,22 @@ static struct acpi_iort_node *iort_find_dev_node(struct device *dev)
 }
 
 /**
- * iort_msi_map_rid() - Map a MSI requester ID for a device
+ * iort_msi_map_id() - Map a MSI input ID for a device
  * @dev: The device for which the mapping is to be done.
- * @req_id: The device requester ID.
+ * @input_id: The device input ID.
  *
- * Returns: mapped MSI RID on success, input requester ID otherwise
+ * Returns: mapped MSI ID on success, input ID otherwise
  */
-u32 iort_msi_map_rid(struct device *dev, u32 req_id)
+u32 iort_msi_map_id(struct device *dev, u32 input_id)
 {
 	struct acpi_iort_node *node;
 	u32 dev_id;
 
 	node = iort_find_dev_node(dev);
 	if (!node)
-		return req_id;
+		return input_id;
 
-	iort_node_map_id(node, req_id, &dev_id, IORT_MSI_TYPE);
+	iort_node_map_id(node, input_id, &dev_id, IORT_MSI_TYPE);
 	return dev_id;
 }
 
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 08ec6bd2297f..8c71f92b92ef 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -28,7 +28,11 @@ void iort_deregister_domain_token(int trans_id);
 struct fwnode_handle *iort_find_domain_token(int trans_id);
 #ifdef CONFIG_ACPI_IORT
 void acpi_iort_init(void);
-u32 iort_msi_map_rid(struct device *dev, u32 req_id);
+u32 iort_msi_map_id(struct device *dev, u32 id);
+static inline u32 iort_msi_map_rid(struct device *dev, u32 req_id)
+{
+	return iort_msi_map_id(dev, req_id);
+}
 struct irq_domain *iort_get_device_domain(struct device *dev, u32 id,
 					  enum irq_domain_bus_token bus_token);
 void acpi_configure_pmsi_domain(struct device *dev);
@@ -39,8 +43,12 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev);
 int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head);
 #else
 static inline void acpi_iort_init(void) { }
+static inline u32 iort_msi_map_id(struct device *dev, u32 id)
+{ return id; }
 static inline u32 iort_msi_map_rid(struct device *dev, u32 req_id)
-{ return req_id; }
+{
+	return iort_msi_map_id(dev, req_id);
+}
 static inline struct irq_domain *iort_get_device_domain(
 	struct device *dev, u32 id, enum irq_domain_bus_token bus_token)
 { return NULL; }
-- 
2.26.1


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

* [PATCH 04/12] ACPI/IORT: Remove useless PCI bus walk
  2020-05-21 12:59 [PATCH 00/12] ACPI/OF: Upgrade MSI/IOMMU ID mapping APIs Lorenzo Pieralisi
                   ` (2 preceding siblings ...)
  2020-05-21 12:59 ` [PATCH 03/12] ACPI/IORT: Make iort_msi_map_rid() PCI agnostic Lorenzo Pieralisi
@ 2020-05-21 13:00 ` Lorenzo Pieralisi
  2020-05-21 13:00 ` [PATCH 05/12] ACPI/IORT: Add an input ID to acpi_dma_configure() Lorenzo Pieralisi
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 31+ messages in thread
From: Lorenzo Pieralisi @ 2020-05-21 13:00 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Lorenzo Pieralisi, Will Deacon, Hanjun Guo, Sudeep Holla,
	Catalin Marinas, Robin Murphy, Rafael J. Wysocki, iommu,
	linux-acpi, devicetree, linux-pci, Rob Herring, Joerg Roedel,
	Bjorn Helgaas, Marc Zyngier, Makarand Pawagi, Diana Craciun,
	Laurentiu Tudor

The PCI bus domain number (used in the iort_match_node_callback() -
pci_domain_nr() call) is cascaded through the PCI bus hierarchy at PCI
bus enumeration time, therefore there is no need in iort_find_dev_node()
to walk the PCI bus upwards to grab the root bus to be passed to
iort_scan_node(), the device->bus PCI bus pointer will do.

Remove this useless code.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Hanjun Guo <guohanjun@huawei.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
---
 drivers/acpi/arm64/iort.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index f346a785e0b5..ae9e1089d954 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -575,10 +575,7 @@ static struct acpi_iort_node *iort_find_dev_node(struct device *dev)
 				      iort_match_node_callback, dev);
 	}
 
-	/* Find a PCI root bus */
 	pbus = to_pci_dev(dev)->bus;
-	while (!pci_is_root_bus(pbus))
-		pbus = pbus->parent;
 
 	return iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
 			      iort_match_node_callback, &pbus->dev);
-- 
2.26.1


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

* [PATCH 05/12] ACPI/IORT: Add an input ID to acpi_dma_configure()
  2020-05-21 12:59 [PATCH 00/12] ACPI/OF: Upgrade MSI/IOMMU ID mapping APIs Lorenzo Pieralisi
                   ` (3 preceding siblings ...)
  2020-05-21 13:00 ` [PATCH 04/12] ACPI/IORT: Remove useless PCI bus walk Lorenzo Pieralisi
@ 2020-05-21 13:00 ` Lorenzo Pieralisi
  2020-05-21 13:00 ` [PATCH 06/12] of/iommu: Make of_map_rid() PCI agnostic Lorenzo Pieralisi
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 31+ messages in thread
From: Lorenzo Pieralisi @ 2020-05-21 13:00 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Lorenzo Pieralisi, Will Deacon, Hanjun Guo, Sudeep Holla,
	Catalin Marinas, Robin Murphy, Rafael J. Wysocki, iommu,
	linux-acpi, devicetree, linux-pci, Rob Herring, Joerg Roedel,
	Bjorn Helgaas, Marc Zyngier, Makarand Pawagi, Diana Craciun,
	Laurentiu Tudor

Some HW devices are created as child devices of proprietary busses,
that have a bus specific policy definining how the child devices
wires representing the devices ID are translated into IOMMU and
IRQ controllers device IDs.

Current IORT code provides translations for:

- PCI devices, where the device ID is well identified at bus level
  as the requester ID (RID)
- Platform devices that are endpoint devices where the device ID is
  retrieved from the ACPI object IORT mappings (Named components single
  mappings). A platform device is represented in IORT as a named
  component node

For devices that are child devices of proprietary busses the IORT
firmware represents the bus node as a named component node in IORT
and it is up to that named component node to define in/out bus
specific ID translations for the bus child devices that are
allocated and created in a bus specific manner.

In order to make IORT ID translations available for proprietary
bus child devices, the current ACPI (and IORT) code must be
augmented to provide an additional ID parameter to acpi_dma_configure()
representing the child devices input ID. This ID is bus specific
and it is retrieved in bus specific code.

By adding an ID parameter to acpi_dma_configure(), the IORT
code can map the child device ID to an IOMMU stream id through
the IORT named component representing the bus in/out ID mappings.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Hanjun Guo <guohanjun@huawei.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
---
 drivers/acpi/arm64/iort.c | 59 +++++++++++++++++++++++++++++----------
 drivers/acpi/scan.c       |  8 ++++--
 include/acpi/acpi_bus.h   |  9 ++++--
 include/linux/acpi.h      |  7 +++++
 include/linux/acpi_iort.h |  7 +++--
 5 files changed, 67 insertions(+), 23 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index ae9e1089d954..270c1a0cdeff 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -1004,19 +1004,54 @@ static void iort_named_component_init(struct device *dev,
 					   nc->node_flags);
 }
 
+static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
+{
+	struct acpi_iort_node *parent;
+	int err = -ENODEV, i = 0;
+	u32 streamid = 0;
+
+	do {
+
+		parent = iort_node_map_platform_id(node, &streamid,
+						   IORT_IOMMU_TYPE,
+						   i++);
+
+		if (parent)
+			err = iort_iommu_xlate(dev, parent, streamid);
+	} while (parent && !err);
+
+	return err;
+}
+
+static int iort_nc_iommu_map_id(struct device *dev,
+				struct acpi_iort_node *node,
+				const u32 *in_id)
+{
+	struct acpi_iort_node *parent;
+	u32 streamid;
+
+	parent = iort_node_map_id(node, *in_id, &streamid, IORT_IOMMU_TYPE);
+	if (parent)
+		return iort_iommu_xlate(dev, parent, streamid);
+
+	return -ENODEV;
+}
+
+
 /**
- * iort_iommu_configure - Set-up IOMMU configuration for a device.
+ * iort_iommu_configure_id - Set-up IOMMU configuration for a device.
  *
  * @dev: device to configure
+ * @id_in: optional input id const value pointer
  *
  * Returns: iommu_ops pointer on configuration success
  *          NULL on configuration failure
  */
-const struct iommu_ops *iort_iommu_configure(struct device *dev)
+const struct iommu_ops *iort_iommu_configure_id(struct device *dev,
+						const u32 *id_in)
 {
-	struct acpi_iort_node *node, *parent;
+	struct acpi_iort_node *node;
 	const struct iommu_ops *ops;
-	u32 streamid = 0;
 	int err = -ENODEV;
 
 	/*
@@ -1045,21 +1080,13 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
 		if (fwspec && iort_pci_rc_supports_ats(node))
 			fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
 	} else {
-		int i = 0;
-
 		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
 				      iort_match_node_callback, dev);
 		if (!node)
 			return NULL;
 
-		do {
-			parent = iort_node_map_platform_id(node, &streamid,
-							   IORT_IOMMU_TYPE,
-							   i++);
-
-			if (parent)
-				err = iort_iommu_xlate(dev, parent, streamid);
-		} while (parent && !err);
+		err = id_in ? iort_nc_iommu_map_id(dev, node, id_in) :
+			      iort_nc_iommu_map(dev, node);
 
 		if (!err)
 			iort_named_component_init(dev, node);
@@ -1084,6 +1111,7 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
 
 	return ops;
 }
+
 #else
 static inline const struct iommu_ops *iort_fwspec_iommu_ops(struct device *dev)
 { return NULL; }
@@ -1092,7 +1120,8 @@ static inline int iort_add_device_replay(const struct iommu_ops *ops,
 { return 0; }
 int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head)
 { return 0; }
-const struct iommu_ops *iort_iommu_configure(struct device *dev)
+const struct iommu_ops *iort_iommu_configure_id(struct device *dev,
+						const u32 *input_id)
 { return NULL; }
 #endif
 
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 6d3448895382..f252d65ee227 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1448,8 +1448,10 @@ int acpi_dma_get_range(struct device *dev, u64 *dma_addr, u64 *offset,
  * acpi_dma_configure - Set-up DMA configuration for the device.
  * @dev: The pointer to the device
  * @attr: device dma attributes
+ * @input_id: input device id const value pointer
  */
-int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
+int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
+			  const u32 *input_id)
 {
 	const struct iommu_ops *iommu;
 	u64 dma_addr = 0, size = 0;
@@ -1461,7 +1463,7 @@ int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
 
 	iort_dma_setup(dev, &dma_addr, &size);
 
-	iommu = iort_iommu_configure(dev);
+	iommu = iort_iommu_configure_id(dev, input_id);
 	if (PTR_ERR(iommu) == -EPROBE_DEFER)
 		return -EPROBE_DEFER;
 
@@ -1470,7 +1472,7 @@ int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(acpi_dma_configure);
+EXPORT_SYMBOL_GPL(acpi_dma_configure_id);
 
 static void acpi_init_coherency(struct acpi_device *adev)
 {
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index a92bea7184a8..79eb4b9c86f2 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -587,8 +587,13 @@ bool acpi_dma_supported(struct acpi_device *adev);
 enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
 int acpi_dma_get_range(struct device *dev, u64 *dma_addr, u64 *offset,
 		       u64 *size);
-int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
-
+int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
+			   const u32 *input_id);
+static inline int acpi_dma_configure(struct device *dev,
+				     enum dev_dma_attr attr)
+{
+	return acpi_dma_configure_id(dev, attr, NULL);
+}
 struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
 					   u64 address, bool check_children);
 int acpi_is_root_bridge(acpi_handle);
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index d661cd0ee64d..6d2c47489d90 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -905,6 +905,13 @@ static inline int acpi_dma_configure(struct device *dev,
 	return 0;
 }
 
+static inline int acpi_dma_configure_id(struct device *dev,
+					enum dev_dma_attr attr,
+					const u32 *input_id)
+{
+	return 0;
+}
+
 #define ACPI_PTR(_ptr)	(NULL)
 
 static inline void acpi_device_set_enumerated(struct acpi_device *adev)
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 8c71f92b92ef..cb9f079a7358 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -39,7 +39,8 @@ void acpi_configure_pmsi_domain(struct device *dev);
 int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id);
 /* IOMMU interface */
 void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *size);
-const struct iommu_ops *iort_iommu_configure(struct device *dev);
+const struct iommu_ops *iort_iommu_configure_id(struct device *dev,
+						const u32 *id_in);
 int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head);
 #else
 static inline void acpi_iort_init(void) { }
@@ -56,8 +57,8 @@ static inline void acpi_configure_pmsi_domain(struct device *dev) { }
 /* IOMMU interface */
 static inline void iort_dma_setup(struct device *dev, u64 *dma_addr,
 				  u64 *size) { }
-static inline const struct iommu_ops *iort_iommu_configure(
-				      struct device *dev)
+static inline const struct iommu_ops *iort_iommu_configure_id(
+				      struct device *dev, const u32 *id_in)
 { return NULL; }
 static inline
 int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head)
-- 
2.26.1


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

* [PATCH 06/12] of/iommu: Make of_map_rid() PCI agnostic
  2020-05-21 12:59 [PATCH 00/12] ACPI/OF: Upgrade MSI/IOMMU ID mapping APIs Lorenzo Pieralisi
                   ` (4 preceding siblings ...)
  2020-05-21 13:00 ` [PATCH 05/12] ACPI/IORT: Add an input ID to acpi_dma_configure() Lorenzo Pieralisi
@ 2020-05-21 13:00 ` Lorenzo Pieralisi
  2020-05-21 22:47   ` Rob Herring
  2020-05-21 13:00 ` [PATCH 07/12] of/device: Add input id to of_dma_configure() Lorenzo Pieralisi
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 31+ messages in thread
From: Lorenzo Pieralisi @ 2020-05-21 13:00 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Lorenzo Pieralisi, Rob Herring, Joerg Roedel, Robin Murphy,
	Marc Zyngier, iommu, linux-acpi, devicetree, linux-pci,
	Rafael J. Wysocki, Hanjun Guo, Bjorn Helgaas, Sudeep Holla,
	Catalin Marinas, Will Deacon, Makarand Pawagi, Diana Craciun,
	Laurentiu Tudor

There is nothing PCI specific (other than the RID - requester ID)
in the of_map_rid() implementation, so the same function can be
reused for input/output IDs mapping for other busses just as well.

Rename the RID instances/names to a generic "id" tag and provide
an of_map_rid() wrapper function so that we can leave the existing
(and legitimate) callers unchanged.

No functionality change intended.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Marc Zyngier <maz@kernel.org>
---
 drivers/iommu/of_iommu.c |  2 +-
 drivers/of/base.c        | 42 ++++++++++++++++++++--------------------
 include/linux/of.h       | 17 +++++++++++++++-
 3 files changed, 38 insertions(+), 23 deletions(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 20738aacac89..ad96b87137d6 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -145,7 +145,7 @@ static int of_fsl_mc_iommu_init(struct fsl_mc_device *mc_dev,
 	struct of_phandle_args iommu_spec = { .args_count = 1 };
 	int err;
 
-	err = of_map_rid(master_np, mc_dev->icid, "iommu-map",
+	err = of_map_id(master_np, mc_dev->icid, "iommu-map",
 			 "iommu-map-mask", &iommu_spec.np,
 			 iommu_spec.args);
 	if (err)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index ae03b1218b06..e000e17bd602 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2201,15 +2201,15 @@ int of_find_last_cache_level(unsigned int cpu)
 }
 
 /**
- * of_map_rid - Translate a requester ID through a downstream mapping.
+ * of_map_id - Translate a requester ID through a downstream mapping.
  * @np: root complex device node.
- * @rid: device requester ID to map.
+ * @id: device ID to map.
  * @map_name: property name of the map to use.
  * @map_mask_name: optional property name of the mask to use.
  * @target: optional pointer to a target device node.
  * @id_out: optional pointer to receive the translated ID.
  *
- * Given a device requester ID, look up the appropriate implementation-defined
+ * Given a device ID, look up the appropriate implementation-defined
  * platform ID and/or the target device which receives transactions on that
  * ID, as per the "iommu-map" and "msi-map" bindings. Either of @target or
  * @id_out may be NULL if only the other is required. If @target points to
@@ -2219,11 +2219,11 @@ int of_find_last_cache_level(unsigned int cpu)
  *
  * Return: 0 on success or a standard error code on failure.
  */
-int of_map_rid(struct device_node *np, u32 rid,
+int of_map_id(struct device_node *np, u32 id,
 	       const char *map_name, const char *map_mask_name,
 	       struct device_node **target, u32 *id_out)
 {
-	u32 map_mask, masked_rid;
+	u32 map_mask, masked_id;
 	int map_len;
 	const __be32 *map = NULL;
 
@@ -2235,7 +2235,7 @@ int of_map_rid(struct device_node *np, u32 rid,
 		if (target)
 			return -ENODEV;
 		/* Otherwise, no map implies no translation */
-		*id_out = rid;
+		*id_out = id;
 		return 0;
 	}
 
@@ -2255,22 +2255,22 @@ int of_map_rid(struct device_node *np, u32 rid,
 	if (map_mask_name)
 		of_property_read_u32(np, map_mask_name, &map_mask);
 
-	masked_rid = map_mask & rid;
+	masked_id = map_mask & id;
 	for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) {
 		struct device_node *phandle_node;
-		u32 rid_base = be32_to_cpup(map + 0);
+		u32 id_base = be32_to_cpup(map + 0);
 		u32 phandle = be32_to_cpup(map + 1);
 		u32 out_base = be32_to_cpup(map + 2);
-		u32 rid_len = be32_to_cpup(map + 3);
+		u32 id_len = be32_to_cpup(map + 3);
 
-		if (rid_base & ~map_mask) {
-			pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores rid-base (0x%x)\n",
+		if (id_base & ~map_mask) {
+			pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores id-base (0x%x)\n",
 				np, map_name, map_name,
-				map_mask, rid_base);
+				map_mask, id_base);
 			return -EFAULT;
 		}
 
-		if (masked_rid < rid_base || masked_rid >= rid_base + rid_len)
+		if (masked_id < id_base || masked_id >= id_base + id_len)
 			continue;
 
 		phandle_node = of_find_node_by_phandle(phandle);
@@ -2288,20 +2288,20 @@ int of_map_rid(struct device_node *np, u32 rid,
 		}
 
 		if (id_out)
-			*id_out = masked_rid - rid_base + out_base;
+			*id_out = masked_id - id_base + out_base;
 
-		pr_debug("%pOF: %s, using mask %08x, rid-base: %08x, out-base: %08x, length: %08x, rid: %08x -> %08x\n",
-			np, map_name, map_mask, rid_base, out_base,
-			rid_len, rid, masked_rid - rid_base + out_base);
+		pr_debug("%pOF: %s, using mask %08x, id-base: %08x, out-base: %08x, length: %08x, id: %08x -> %08x\n",
+			np, map_name, map_mask, id_base, out_base,
+			id_len, id, masked_id - id_base + out_base);
 		return 0;
 	}
 
-	pr_info("%pOF: no %s translation for rid 0x%x on %pOF\n", np, map_name,
-		rid, target && *target ? *target : NULL);
+	pr_info("%pOF: no %s translation for id 0x%x on %pOF\n", np, map_name,
+		id, target && *target ? *target : NULL);
 
 	/* Bypasses translation */
 	if (id_out)
-		*id_out = rid;
+		*id_out = id;
 	return 0;
 }
-EXPORT_SYMBOL_GPL(of_map_rid);
+EXPORT_SYMBOL_GPL(of_map_id);
diff --git a/include/linux/of.h b/include/linux/of.h
index c669c0a4732f..b7934566a1aa 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -554,10 +554,18 @@ bool of_console_check(struct device_node *dn, char *name, int index);
 
 extern int of_cpu_node_to_id(struct device_node *np);
 
-int of_map_rid(struct device_node *np, u32 rid,
+int of_map_id(struct device_node *np, u32 id,
 	       const char *map_name, const char *map_mask_name,
 	       struct device_node **target, u32 *id_out);
 
+static inline int of_map_rid(struct device_node *np, u32 rid,
+			     const char *map_name,
+			     const char *map_mask_name,
+			     struct device_node **target, u32 *id_out)
+{
+	return of_map_id(np, rid, map_name, map_mask_name, target, id_out);
+}
+
 #else /* CONFIG_OF */
 
 static inline void of_core_init(void)
@@ -978,6 +986,13 @@ static inline int of_cpu_node_to_id(struct device_node *np)
 	return -ENODEV;
 }
 
+static inline int of_map_id(struct device_node *np, u32 id,
+			     const char *map_name, const char *map_mask_name,
+			     struct device_node **target, u32 *id_out)
+{
+	return -EINVAL;
+}
+
 static inline int of_map_rid(struct device_node *np, u32 rid,
 			     const char *map_name, const char *map_mask_name,
 			     struct device_node **target, u32 *id_out)
-- 
2.26.1


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

* [PATCH 07/12] of/device: Add input id to of_dma_configure()
  2020-05-21 12:59 [PATCH 00/12] ACPI/OF: Upgrade MSI/IOMMU ID mapping APIs Lorenzo Pieralisi
                   ` (5 preceding siblings ...)
  2020-05-21 13:00 ` [PATCH 06/12] of/iommu: Make of_map_rid() PCI agnostic Lorenzo Pieralisi
@ 2020-05-21 13:00 ` Lorenzo Pieralisi
  2020-05-21 23:02   ` Rob Herring
  2020-05-21 13:00 ` [PATCH 08/12] of/irq: make of_msi_map_get_device_domain() bus agnostic Lorenzo Pieralisi
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 31+ messages in thread
From: Lorenzo Pieralisi @ 2020-05-21 13:00 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Lorenzo Pieralisi, Rob Herring, Robin Murphy, Joerg Roedel,
	Laurentiu Tudor, iommu, linux-acpi, devicetree, linux-pci,
	Rafael J. Wysocki, Hanjun Guo, Bjorn Helgaas, Sudeep Holla,
	Catalin Marinas, Will Deacon, Marc Zyngier, Makarand Pawagi,
	Diana Craciun

Devices sitting on proprietary busses have a device ID space that
is owned by the respective bus and related firmware bindings. In order
to let the generic OF layer handle the input translations to
an IOMMU id, for such busses the current of_dma_configure() interface
should be extended in order to allow the bus layer to provide the
device input id parameter - that is retrieved/assigned in bus
specific code and firmware.

Augment of_dma_configure() to add an optional input_id parameter,
leaving current functionality unchanged.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Laurentiu Tudor <laurentiu.tudor@nxp.com>
---
 drivers/bus/fsl-mc/fsl-mc-bus.c |  4 ++-
 drivers/iommu/of_iommu.c        | 53 +++++++++++++++++++++------------
 drivers/of/device.c             |  8 +++--
 include/linux/of_device.h       | 16 ++++++++--
 include/linux/of_iommu.h        |  6 ++--
 5 files changed, 60 insertions(+), 27 deletions(-)

diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
index 40526da5c6a6..8ead3f0238f2 100644
--- a/drivers/bus/fsl-mc/fsl-mc-bus.c
+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
@@ -118,11 +118,13 @@ static int fsl_mc_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
 static int fsl_mc_dma_configure(struct device *dev)
 {
 	struct device *dma_dev = dev;
+	struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
+	u32 input_id = mc_dev->icid;
 
 	while (dev_is_fsl_mc(dma_dev))
 		dma_dev = dma_dev->parent;
 
-	return of_dma_configure(dev, dma_dev->of_node, 0);
+	return of_dma_configure_id(dev, dma_dev->of_node, 0, &input_id);
 }
 
 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index ad96b87137d6..4516d5bf6cc9 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -139,25 +139,53 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
 	return err;
 }
 
-static int of_fsl_mc_iommu_init(struct fsl_mc_device *mc_dev,
-				struct device_node *master_np)
+static int of_iommu_configure_dev_id(struct device_node *master_np,
+				     struct device *dev,
+				     const u32 *id)
 {
 	struct of_phandle_args iommu_spec = { .args_count = 1 };
 	int err;
 
-	err = of_map_id(master_np, mc_dev->icid, "iommu-map",
+	err = of_map_id(master_np, *id, "iommu-map",
 			 "iommu-map-mask", &iommu_spec.np,
 			 iommu_spec.args);
 	if (err)
 		return err == -ENODEV ? NO_IOMMU : err;
 
-	err = of_iommu_xlate(&mc_dev->dev, &iommu_spec);
+	err = of_iommu_xlate(dev, &iommu_spec);
 	of_node_put(iommu_spec.np);
 	return err;
 }
 
+static int of_iommu_configure_dev(struct device_node *master_np,
+				  struct device *dev)
+{
+	struct of_phandle_args iommu_spec;
+	int err = NO_IOMMU, idx = 0;
+
+	while (!of_parse_phandle_with_args(master_np, "iommus",
+					   "#iommu-cells",
+					   idx, &iommu_spec)) {
+		err = of_iommu_xlate(dev, &iommu_spec);
+		of_node_put(iommu_spec.np);
+		idx++;
+		if (err)
+			break;
+	}
+
+	return err;
+}
+
+static int of_iommu_configure_device(struct device_node *master_np,
+				     struct device *dev, const u32 *id)
+{
+	return (id) ? of_iommu_configure_dev_id(master_np, dev, id) :
+		      of_iommu_configure_dev(master_np, dev);
+}
+
 const struct iommu_ops *of_iommu_configure(struct device *dev,
-					   struct device_node *master_np)
+					   struct device_node *master_np,
+					   const u32 *id)
 {
 	const struct iommu_ops *ops = NULL;
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
@@ -188,21 +216,8 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
 		pci_request_acs();
 		err = pci_for_each_dma_alias(to_pci_dev(dev),
 					     of_pci_iommu_init, &info);
-	} else if (dev_is_fsl_mc(dev)) {
-		err = of_fsl_mc_iommu_init(to_fsl_mc_device(dev), master_np);
 	} else {
-		struct of_phandle_args iommu_spec;
-		int idx = 0;
-
-		while (!of_parse_phandle_with_args(master_np, "iommus",
-						   "#iommu-cells",
-						   idx, &iommu_spec)) {
-			err = of_iommu_xlate(dev, &iommu_spec);
-			of_node_put(iommu_spec.np);
-			idx++;
-			if (err)
-				break;
-		}
+		err = of_iommu_configure_device(master_np, dev, id);
 
 		fwspec = dev_iommu_fwspec_get(dev);
 		if (!err && fwspec)
diff --git a/drivers/of/device.c b/drivers/of/device.c
index 27203bfd0b22..b439c1e05434 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -78,6 +78,7 @@ int of_device_add(struct platform_device *ofdev)
  * @np:		Pointer to OF node having DMA configuration
  * @force_dma:  Whether device is to be set up by of_dma_configure() even if
  *		DMA capability is not explicitly described by firmware.
+ * @id:		Optional const pointer value input id
  *
  * Try to get devices's DMA configuration from DT and update it
  * accordingly.
@@ -86,7 +87,8 @@ int of_device_add(struct platform_device *ofdev)
  * can use a platform bus notifier and handle BUS_NOTIFY_ADD_DEVICE events
  * to fix up DMA configuration.
  */
-int of_dma_configure(struct device *dev, struct device_node *np, bool force_dma)
+int of_dma_configure_id(struct device *dev, struct device_node *np,
+			bool force_dma, const u32 *id)
 {
 	u64 dma_addr, paddr, size = 0;
 	int ret;
@@ -160,7 +162,7 @@ int of_dma_configure(struct device *dev, struct device_node *np, bool force_dma)
 	dev_dbg(dev, "device is%sdma coherent\n",
 		coherent ? " " : " not ");
 
-	iommu = of_iommu_configure(dev, np);
+	iommu = of_iommu_configure(dev, np, id);
 	if (PTR_ERR(iommu) == -EPROBE_DEFER)
 		return -EPROBE_DEFER;
 
@@ -171,7 +173,7 @@ int of_dma_configure(struct device *dev, struct device_node *np, bool force_dma)
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(of_dma_configure);
+EXPORT_SYMBOL_GPL(of_dma_configure_id);
 
 int of_device_register(struct platform_device *pdev)
 {
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index 8d31e39dd564..07ca187fc5e4 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -55,9 +55,15 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
 	return of_node_get(cpu_dev->of_node);
 }
 
-int of_dma_configure(struct device *dev,
+int of_dma_configure_id(struct device *dev,
 		     struct device_node *np,
-		     bool force_dma);
+		     bool force_dma, const u32 *id);
+static inline int of_dma_configure(struct device *dev,
+				   struct device_node *np,
+				   bool force_dma)
+{
+	return of_dma_configure_id(dev, np, force_dma, NULL);
+}
 #else /* CONFIG_OF */
 
 static inline int of_driver_match_device(struct device *dev,
@@ -106,6 +112,12 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
 	return NULL;
 }
 
+static inline int of_dma_configure_id(struct device *dev,
+				   struct device_node *np,
+				   bool force_dma)
+{
+	return 0;
+}
 static inline int of_dma_configure(struct device *dev,
 				   struct device_node *np,
 				   bool force_dma)
diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
index f3d40dd7bb66..16f4b3e87f20 100644
--- a/include/linux/of_iommu.h
+++ b/include/linux/of_iommu.h
@@ -13,7 +13,8 @@ extern int of_get_dma_window(struct device_node *dn, const char *prefix,
 			     size_t *size);
 
 extern const struct iommu_ops *of_iommu_configure(struct device *dev,
-					struct device_node *master_np);
+					struct device_node *master_np,
+					const u32 *id);
 
 #else
 
@@ -25,7 +26,8 @@ static inline int of_get_dma_window(struct device_node *dn, const char *prefix,
 }
 
 static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
-					 struct device_node *master_np)
+					 struct device_node *master_np,
+					 const u32 *id)
 {
 	return NULL;
 }
-- 
2.26.1


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

* [PATCH 08/12] of/irq: make of_msi_map_get_device_domain() bus agnostic
  2020-05-21 12:59 [PATCH 00/12] ACPI/OF: Upgrade MSI/IOMMU ID mapping APIs Lorenzo Pieralisi
                   ` (6 preceding siblings ...)
  2020-05-21 13:00 ` [PATCH 07/12] of/device: Add input id to of_dma_configure() Lorenzo Pieralisi
@ 2020-05-21 13:00 ` Lorenzo Pieralisi
  2020-05-21 19:57   ` Bjorn Helgaas
  2020-05-21 13:00 ` [PATCH 09/12] dt-bindings: arm: fsl: Add msi-map device-tree binding for fsl-mc bus Lorenzo Pieralisi
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 31+ messages in thread
From: Lorenzo Pieralisi @ 2020-05-21 13:00 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Diana Craciun, Lorenzo Pieralisi, Bjorn Helgaas, Rob Herring,
	Marc Zyngier, iommu, linux-acpi, devicetree, linux-pci,
	Rafael J. Wysocki, Joerg Roedel, Hanjun Guo, Sudeep Holla,
	Robin Murphy, Catalin Marinas, Will Deacon, Makarand Pawagi,
	Laurentiu Tudor

From: Diana Craciun <diana.craciun@oss.nxp.com>

of_msi_map_get_device_domain() is PCI specific but it need not be and
can be easily changed to be bus agnostic in order to be used by other
busses by adding an IRQ domain bus token as an input parameter.

Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Marc Zyngier <maz@kernel.org>
---
 drivers/of/irq.c       | 8 +++++---
 drivers/pci/msi.c      | 2 +-
 include/linux/of_irq.h | 5 +++--
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index a296eaf52a5b..48a40326984f 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -613,18 +613,20 @@ u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in)
  * 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.
+ * @bus_token: Bus token
  *
  * 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 irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 id,
+						u32 bus_token)
 {
 	struct device_node *np = NULL;
 
-	__of_msi_map_rid(dev, &np, rid);
-	return irq_find_matching_host(np, DOMAIN_BUS_PCI_MSI);
+	__of_msi_map_rid(dev, &np, id);
+	return irq_find_matching_host(np, bus_token);
 }
 
 /**
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 74a91f52ecc0..9532e1d12d3f 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -1556,7 +1556,7 @@ struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev)
 	u32 rid = pci_dev_id(pdev);
 
 	pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid);
-	dom = of_msi_map_get_device_domain(&pdev->dev, rid);
+	dom = of_msi_map_get_device_domain(&pdev->dev, rid, DOMAIN_BUS_PCI_MSI);
 	if (!dom)
 		dom = iort_get_device_domain(&pdev->dev, rid,
 					     DOMAIN_BUS_PCI_MSI);
diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
index 1214cabb2247..7142a3722758 100644
--- a/include/linux/of_irq.h
+++ b/include/linux/of_irq.h
@@ -52,7 +52,8 @@ 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);
+							u32 id,
+							u32 bus_token);
 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
@@ -85,7 +86,7 @@ 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)
+						u32 id, u32 bus_token)
 {
 	return NULL;
 }
-- 
2.26.1


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

* [PATCH 09/12] dt-bindings: arm: fsl: Add msi-map device-tree binding for fsl-mc bus
  2020-05-21 12:59 [PATCH 00/12] ACPI/OF: Upgrade MSI/IOMMU ID mapping APIs Lorenzo Pieralisi
                   ` (7 preceding siblings ...)
  2020-05-21 13:00 ` [PATCH 08/12] of/irq: make of_msi_map_get_device_domain() bus agnostic Lorenzo Pieralisi
@ 2020-05-21 13:00 ` Lorenzo Pieralisi
  2020-05-21 23:10   ` Rob Herring
  2020-05-21 13:00 ` [PATCH 10/12] of/irq: Make of_msi_map_rid() PCI bus agnostic Lorenzo Pieralisi
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 31+ messages in thread
From: Lorenzo Pieralisi @ 2020-05-21 13:00 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Laurentiu Tudor, Rob Herring, iommu, linux-acpi, devicetree,
	linux-pci, Rafael J. Wysocki, Joerg Roedel, Hanjun Guo,
	Bjorn Helgaas, Sudeep Holla, Robin Murphy, Catalin Marinas,
	Will Deacon, Marc Zyngier, Makarand Pawagi, Diana Craciun

From: Laurentiu Tudor <laurentiu.tudor@nxp.com>

The existing bindings cannot be used to specify the relationship
between fsl-mc devices and GIC ITSes.

Add a generic binding for mapping fsl-mc devices to GIC ITSes, using
msi-map property.

Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
Cc: Rob Herring <robh+dt@kernel.org>
---
 .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 30 +++++++++++++++++--
 1 file changed, 27 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
index 9134e9bcca56..b0813b2d0493 100644
--- a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
+++ b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
@@ -18,9 +18,9 @@ same hardware "isolation context" and a 10-bit value called an ICID
 the requester.
 
 The generic 'iommus' property is insufficient to describe the relationship
-between ICIDs and IOMMUs, so an iommu-map property is used to define
-the set of possible ICIDs under a root DPRC and how they map to
-an IOMMU.
+between ICIDs and IOMMUs, so the iommu-map and msi-map properties are used
+to define the set of possible ICIDs under a root DPRC and how they map to
+an IOMMU and a GIC ITS respectively.
 
 For generic IOMMU bindings, see
 Documentation/devicetree/bindings/iommu/iommu.txt.
@@ -28,6 +28,9 @@ Documentation/devicetree/bindings/iommu/iommu.txt.
 For arm-smmu binding, see:
 Documentation/devicetree/bindings/iommu/arm,smmu.yaml.
 
+For GICv3 and GIC ITS bindings, see:
+Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml.
+
 Required properties:
 
     - compatible
@@ -119,6 +122,15 @@ Optional properties:
   associated with the listed IOMMU, with the iommu-specifier
   (i - icid-base + iommu-base).
 
+- msi-map: Maps an ICID to a GIC ITS and associated iommu-specifier
+  data.
+
+  The property is an arbitrary number of tuples of
+  (icid-base,iommu,iommu-base,length).
+
+  Any ICID in the interval [icid-base, icid-base + length) is
+  associated with the listed GIC ITS, with the iommu-specifier
+  (i - icid-base + iommu-base).
 Example:
 
         smmu: iommu@5000000 {
@@ -128,6 +140,16 @@ Example:
                ...
         };
 
+	gic: interrupt-controller@6000000 {
+		compatible = "arm,gic-v3";
+		...
+		its: gic-its@6020000 {
+			compatible = "arm,gic-v3-its";
+			msi-controller;
+			...
+		};
+	};
+
         fsl_mc: fsl-mc@80c000000 {
                 compatible = "fsl,qoriq-mc";
                 reg = <0x00000008 0x0c000000 0 0x40>,    /* MC portal base */
@@ -135,6 +157,8 @@ Example:
                 msi-parent = <&its>;
                 /* define map for ICIDs 23-64 */
                 iommu-map = <23 &smmu 23 41>;
+                /* define msi map for ICIDs 23-64 */
+                msi-map = <23 &its 23 41>;
                 #address-cells = <3>;
                 #size-cells = <1>;
 
-- 
2.26.1


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

* [PATCH 10/12] of/irq: Make of_msi_map_rid() PCI bus agnostic
  2020-05-21 12:59 [PATCH 00/12] ACPI/OF: Upgrade MSI/IOMMU ID mapping APIs Lorenzo Pieralisi
                   ` (8 preceding siblings ...)
  2020-05-21 13:00 ` [PATCH 09/12] dt-bindings: arm: fsl: Add msi-map device-tree binding for fsl-mc bus Lorenzo Pieralisi
@ 2020-05-21 13:00 ` Lorenzo Pieralisi
  2020-05-21 23:17   ` Rob Herring
  2020-05-21 13:00 ` [PATCH 11/12] bus/fsl-mc: Refactor the MSI domain creation in the DPRC driver Lorenzo Pieralisi
  2020-05-21 13:00 ` [PATCH 12/12] bus: fsl-mc: Add ACPI support for fsl-mc Lorenzo Pieralisi
  11 siblings, 1 reply; 31+ messages in thread
From: Lorenzo Pieralisi @ 2020-05-21 13:00 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Lorenzo Pieralisi, Rob Herring, Marc Zyngier, iommu, linux-acpi,
	devicetree, linux-pci, Rafael J. Wysocki, Joerg Roedel,
	Hanjun Guo, Bjorn Helgaas, Sudeep Holla, Robin Murphy,
	Catalin Marinas, Will Deacon, Makarand Pawagi, Diana Craciun,
	Laurentiu Tudor

There is nothing PCI bus specific in the of_msi_map_rid()
implementation other than the requester ID tag for the input
ID space. Rename requester ID to a more generic ID so that
the translation code can be used by all busses that require
input/output ID translations.

Leave a wrapper function of_msi_map_rid() in place to keep
existing PCI code mapping requester ID syntactically unchanged.

No functional change intended.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Marc Zyngier <maz@kernel.org>
---
 drivers/of/irq.c       | 28 ++++++++++++++--------------
 include/linux/of_irq.h | 14 ++++++++++++--
 2 files changed, 26 insertions(+), 16 deletions(-)

diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 48a40326984f..25d17b8a1a1a 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -576,43 +576,43 @@ void __init of_irq_init(const struct of_device_id *matches)
 	}
 }
 
-static u32 __of_msi_map_rid(struct device *dev, struct device_node **np,
-			    u32 rid_in)
+static u32 __of_msi_map_id(struct device *dev, struct device_node **np,
+			    u32 id_in)
 {
 	struct device *parent_dev;
-	u32 rid_out = rid_in;
+	u32 id_out = id_in;
 
 	/*
 	 * 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 (!of_map_rid(parent_dev->of_node, rid_in, "msi-map",
-				"msi-map-mask", np, &rid_out))
+		if (!of_map_id(parent_dev->of_node, id_in, "msi-map",
+				"msi-map-mask", np, &id_out))
 			break;
-	return rid_out;
+	return id_out;
 }
 
 /**
- * of_msi_map_rid - Map a MSI requester ID for a device.
+ * of_msi_map_id - Map a MSI 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.
+ * @id_in: unmapped MSI 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.
+ * property.  If found, apply the mapping to @id_in.
  *
- * Returns the mapped MSI requester ID.
+ * Returns the mapped MSI ID.
  */
-u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in)
+u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in)
 {
-	return __of_msi_map_rid(dev, &msi_np, rid_in);
+	return __of_msi_map_id(dev, &msi_np, id_in);
 }
 
 /**
  * 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.
+ * @id: Device ID.
  * @bus_token: Bus token
  *
  * Walk up the device hierarchy looking for devices with a "msi-map"
@@ -625,7 +625,7 @@ struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 id,
 {
 	struct device_node *np = NULL;
 
-	__of_msi_map_rid(dev, &np, id);
+	__of_msi_map_id(dev, &np, id);
 	return irq_find_matching_host(np, bus_token);
 }
 
diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
index 7142a3722758..cf9cb1e545ce 100644
--- a/include/linux/of_irq.h
+++ b/include/linux/of_irq.h
@@ -55,7 +55,12 @@ extern struct irq_domain *of_msi_map_get_device_domain(struct device *dev,
 							u32 id,
 							u32 bus_token);
 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);
+u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in);
+static inline u32 of_msi_map_rid(struct device *dev,
+				 struct device_node *msi_np, u32 rid_in)
+{
+	return of_msi_map_id(dev, msi_np, rid_in);
+}
 #else
 static inline int of_irq_count(struct device_node *dev)
 {
@@ -93,10 +98,15 @@ static inline struct irq_domain *of_msi_map_get_device_domain(struct device *dev
 static inline void of_msi_configure(struct device *dev, struct device_node *np)
 {
 }
+static inline u32 of_msi_map_id(struct device *dev,
+				 struct device_node *msi_np, u32 id_in)
+{
+	return id_in;
+}
 static inline u32 of_msi_map_rid(struct device *dev,
 				 struct device_node *msi_np, u32 rid_in)
 {
-	return rid_in;
+	return of_msi_map_id(dev, msi_np, rid_in);
 }
 #endif
 
-- 
2.26.1


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

* [PATCH 11/12] bus/fsl-mc: Refactor the MSI domain creation in the DPRC driver
  2020-05-21 12:59 [PATCH 00/12] ACPI/OF: Upgrade MSI/IOMMU ID mapping APIs Lorenzo Pieralisi
                   ` (9 preceding siblings ...)
  2020-05-21 13:00 ` [PATCH 10/12] of/irq: Make of_msi_map_rid() PCI bus agnostic Lorenzo Pieralisi
@ 2020-05-21 13:00 ` Lorenzo Pieralisi
  2020-05-21 13:00 ` [PATCH 12/12] bus: fsl-mc: Add ACPI support for fsl-mc Lorenzo Pieralisi
  11 siblings, 0 replies; 31+ messages in thread
From: Lorenzo Pieralisi @ 2020-05-21 13:00 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Diana Craciun, iommu, linux-acpi, devicetree, linux-pci,
	Rob Herring, Rafael J. Wysocki, Joerg Roedel, Hanjun Guo,
	Bjorn Helgaas, Sudeep Holla, Robin Murphy, Catalin Marinas,
	Will Deacon, Marc Zyngier, Makarand Pawagi, Laurentiu Tudor

From: Diana Craciun <diana.craciun@oss.nxp.com>

The DPRC driver is not taking into account the msi-map property
and assumes that the icid is the same as the stream ID. Although
this assumption is correct, generalize the code to include a
translation between icid and streamID.

Furthermore do not just copy the MSI domain from parent (for child
containers), but use the information provided by the msi-map property.

If the msi-map property is missing from the device tree retain the old
behaviour for backward compatibility ie the child DPRC objects
inherit the MSI domain from the parent.

Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
---
 drivers/bus/fsl-mc/dprc-driver.c            | 31 ++++++---------------
 drivers/bus/fsl-mc/fsl-mc-bus.c             |  4 +--
 drivers/bus/fsl-mc/fsl-mc-msi.c             | 31 +++++++++++++--------
 drivers/bus/fsl-mc/fsl-mc-private.h         |  6 ++--
 drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c | 15 +++++++++-
 5 files changed, 47 insertions(+), 40 deletions(-)

diff --git a/drivers/bus/fsl-mc/dprc-driver.c b/drivers/bus/fsl-mc/dprc-driver.c
index c8b1c3842c1a..189bff2115a8 100644
--- a/drivers/bus/fsl-mc/dprc-driver.c
+++ b/drivers/bus/fsl-mc/dprc-driver.c
@@ -592,6 +592,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 	bool mc_io_created = false;
 	bool msi_domain_set = false;
 	u16 major_ver, minor_ver;
+	struct irq_domain *mc_msi_domain;
 
 	if (!is_fsl_mc_bus_dprc(mc_dev))
 		return -EINVAL;
@@ -621,31 +622,15 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
 			return error;
 
 		mc_io_created = true;
+	}
 
-		/*
-		 * Inherit parent MSI domain:
-		 */
-		dev_set_msi_domain(&mc_dev->dev,
-				   dev_get_msi_domain(parent_dev));
-		msi_domain_set = true;
+	mc_msi_domain = fsl_mc_find_msi_domain(&mc_dev->dev);
+	if (!mc_msi_domain) {
+		dev_warn(&mc_dev->dev,
+			 "WARNING: MC bus without interrupt support\n");
 	} else {
-		/*
-		 * This is a root DPRC
-		 */
-		struct irq_domain *mc_msi_domain;
-
-		if (dev_is_fsl_mc(parent_dev))
-			return -EINVAL;
-
-		error = fsl_mc_find_msi_domain(parent_dev,
-					       &mc_msi_domain);
-		if (error < 0) {
-			dev_warn(&mc_dev->dev,
-				 "WARNING: MC bus without interrupt support\n");
-		} else {
-			dev_set_msi_domain(&mc_dev->dev, mc_msi_domain);
-			msi_domain_set = true;
-		}
+		dev_set_msi_domain(&mc_dev->dev, mc_msi_domain);
+		msi_domain_set = true;
 	}
 
 	error = dprc_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id,
diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
index 8ead3f0238f2..824ff77bbe86 100644
--- a/drivers/bus/fsl-mc/fsl-mc-bus.c
+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
@@ -370,8 +370,8 @@ EXPORT_SYMBOL_GPL(fsl_mc_get_version);
 /**
  * fsl_mc_get_root_dprc - function to traverse to the root dprc
  */
-static void fsl_mc_get_root_dprc(struct device *dev,
-				 struct device **root_dprc_dev)
+void fsl_mc_get_root_dprc(struct device *dev,
+			 struct device **root_dprc_dev)
 {
 	if (!dev) {
 		*root_dprc_dev = NULL;
diff --git a/drivers/bus/fsl-mc/fsl-mc-msi.c b/drivers/bus/fsl-mc/fsl-mc-msi.c
index 8b9c66d7c4ff..e7bbff445a83 100644
--- a/drivers/bus/fsl-mc/fsl-mc-msi.c
+++ b/drivers/bus/fsl-mc/fsl-mc-msi.c
@@ -177,23 +177,30 @@ struct irq_domain *fsl_mc_msi_create_irq_domain(struct fwnode_handle *fwnode,
 	return domain;
 }
 
-int fsl_mc_find_msi_domain(struct device *mc_platform_dev,
-			   struct irq_domain **mc_msi_domain)
+struct irq_domain *fsl_mc_find_msi_domain(struct device *dev)
 {
-	struct irq_domain *msi_domain;
-	struct device_node *mc_of_node = mc_platform_dev->of_node;
+	struct irq_domain *msi_domain = NULL;
+	struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
 
-	msi_domain = of_msi_get_domain(mc_platform_dev, mc_of_node,
-				       DOMAIN_BUS_FSL_MC_MSI);
-	if (!msi_domain) {
-		pr_err("Unable to find fsl-mc MSI domain for %pOF\n",
-		       mc_of_node);
+	msi_domain = of_msi_map_get_device_domain(dev, mc_dev->icid,
+						  DOMAIN_BUS_FSL_MC_MSI);
 
-		return -ENOENT;
+	/*
+	 * if the msi-map property is missing assume that all the
+	 * child containers inherit the domain from the parent
+	 */
+	if (!msi_domain) {
+		struct device *root_dprc_dev;
+		struct device *bus_dev;
+
+		fsl_mc_get_root_dprc(dev, &root_dprc_dev);
+		bus_dev = root_dprc_dev->parent;
+		msi_domain = of_msi_get_domain(bus_dev,
+					       bus_dev->of_node,
+					       DOMAIN_BUS_FSL_MC_MSI);
 	}
 
-	*mc_msi_domain = msi_domain;
-	return 0;
+	return msi_domain;
 }
 
 static void fsl_mc_msi_free_descs(struct device *dev)
diff --git a/drivers/bus/fsl-mc/fsl-mc-private.h b/drivers/bus/fsl-mc/fsl-mc-private.h
index 21ca8c756ee7..7a46a12eb747 100644
--- a/drivers/bus/fsl-mc/fsl-mc-private.h
+++ b/drivers/bus/fsl-mc/fsl-mc-private.h
@@ -595,8 +595,7 @@ int fsl_mc_msi_domain_alloc_irqs(struct device *dev,
 
 void fsl_mc_msi_domain_free_irqs(struct device *dev);
 
-int fsl_mc_find_msi_domain(struct device *mc_platform_dev,
-			   struct irq_domain **mc_msi_domain);
+struct irq_domain *fsl_mc_find_msi_domain(struct device *dev);
 
 int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
 			     unsigned int irq_count);
@@ -613,6 +612,9 @@ void fsl_destroy_mc_io(struct fsl_mc_io *mc_io);
 
 bool fsl_mc_is_root_dprc(struct device *dev);
 
+void fsl_mc_get_root_dprc(struct device *dev,
+			 struct device **root_dprc_dev);
+
 struct fsl_mc_device *fsl_mc_device_lookup(struct fsl_mc_obj_desc *obj_desc,
 					   struct fsl_mc_device *mc_bus_dev);
 
diff --git a/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c b/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
index 606efa64adff..a5c8d577e424 100644
--- a/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
@@ -23,6 +23,18 @@ static struct irq_chip its_msi_irq_chip = {
 	.irq_set_affinity = msi_domain_set_affinity
 };
 
+static u32 fsl_mc_msi_domain_get_msi_id(struct irq_domain *domain,
+					struct fsl_mc_device *mc_dev)
+{
+	struct device_node *of_node;
+	u32 out_id;
+
+	of_node = irq_domain_get_of_node(domain);
+	out_id = of_msi_map_id(&mc_dev->dev, of_node, mc_dev->icid);
+
+	return out_id;
+}
+
 static int its_fsl_mc_msi_prepare(struct irq_domain *msi_domain,
 				  struct device *dev,
 				  int nvec, msi_alloc_info_t *info)
@@ -43,7 +55,8 @@ static int its_fsl_mc_msi_prepare(struct irq_domain *msi_domain,
 	 * NOTE: This device id corresponds to the IOMMU stream ID
 	 * associated with the DPRC object (ICID).
 	 */
-	info->scratchpad[0].ul = mc_bus_dev->icid;
+	info->scratchpad[0].ul = fsl_mc_msi_domain_get_msi_id(msi_domain,
+							      mc_bus_dev);
 	msi_info = msi_get_domain_info(msi_domain->parent);
 
 	/* Allocate at least 32 MSIs, and always as a power of 2 */
-- 
2.26.1


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

* [PATCH 12/12] bus: fsl-mc: Add ACPI support for fsl-mc
  2020-05-21 12:59 [PATCH 00/12] ACPI/OF: Upgrade MSI/IOMMU ID mapping APIs Lorenzo Pieralisi
                   ` (10 preceding siblings ...)
  2020-05-21 13:00 ` [PATCH 11/12] bus/fsl-mc: Refactor the MSI domain creation in the DPRC driver Lorenzo Pieralisi
@ 2020-05-21 13:00 ` Lorenzo Pieralisi
  2020-05-21 15:03   ` Laurentiu Tudor
  11 siblings, 1 reply; 31+ messages in thread
From: Lorenzo Pieralisi @ 2020-05-21 13:00 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Diana Craciun, Makarand Pawagi, Laurentiu Tudor, iommu,
	linux-acpi, devicetree, linux-pci, Rob Herring,
	Rafael J. Wysocki, Joerg Roedel, Hanjun Guo, Bjorn Helgaas,
	Sudeep Holla, Robin Murphy, Catalin Marinas, Will Deacon,
	Marc Zyngier

From: Diana Craciun <diana.craciun@oss.nxp.com>

Add ACPI support in the fsl-mc driver. Driver parses MC DSDT table to
extract memory and other resources.

Interrupt (GIC ITS) information is extracted from the MADT table
by drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c.

IORT table is parsed to configure DMA.

Signed-off-by: Makarand Pawagi <makarand.pawagi@nxp.com>
Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
---
 drivers/bus/fsl-mc/fsl-mc-bus.c             | 73 +++++++++++++++-----
 drivers/bus/fsl-mc/fsl-mc-msi.c             | 37 +++++-----
 drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c | 75 ++++++++++++++++++++-
 3 files changed, 150 insertions(+), 35 deletions(-)

diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
index 824ff77bbe86..324d49d6df89 100644
--- a/drivers/bus/fsl-mc/fsl-mc-bus.c
+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
@@ -18,6 +18,8 @@
 #include <linux/bitops.h>
 #include <linux/msi.h>
 #include <linux/dma-mapping.h>
+#include <linux/acpi.h>
+#include <linux/iommu.h>
 
 #include "fsl-mc-private.h"
 
@@ -38,6 +40,7 @@ struct fsl_mc {
 	struct fsl_mc_device *root_mc_bus_dev;
 	u8 num_translation_ranges;
 	struct fsl_mc_addr_translation_range *translation_ranges;
+	void *fsl_mc_regs;
 };
 
 /**
@@ -56,6 +59,10 @@ struct fsl_mc_addr_translation_range {
 	phys_addr_t start_phys_addr;
 };
 
+#define FSL_MC_FAPR	0x28
+#define MC_FAPR_PL	BIT(18)
+#define MC_FAPR_BMT	BIT(17)
+
 /**
  * fsl_mc_bus_match - device to driver matching callback
  * @dev: the fsl-mc device to match against
@@ -124,7 +131,10 @@ static int fsl_mc_dma_configure(struct device *dev)
 	while (dev_is_fsl_mc(dma_dev))
 		dma_dev = dma_dev->parent;
 
-	return of_dma_configure_id(dev, dma_dev->of_node, 0, &input_id);
+	if (dev_of_node(dma_dev))
+		return of_dma_configure_id(dev, dma_dev->of_node, 0, &input_id);
+
+	return acpi_dma_configure_id(dev, DEV_DMA_COHERENT, &input_id);
 }
 
 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
@@ -865,8 +875,11 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
 	struct fsl_mc_io *mc_io = NULL;
 	int container_id;
 	phys_addr_t mc_portal_phys_addr;
-	u32 mc_portal_size;
-	struct resource res;
+	u32 mc_portal_size, mc_stream_id;
+	struct resource *plat_res;
+
+	if (!iommu_present(&fsl_mc_bus_type))
+		return -EPROBE_DEFER;
 
 	mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
 	if (!mc)
@@ -874,19 +887,33 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, mc);
 
+	plat_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	mc->fsl_mc_regs = devm_ioremap_resource(&pdev->dev, plat_res);
+	if (IS_ERR(mc->fsl_mc_regs))
+		return PTR_ERR(mc->fsl_mc_regs);
+
+	if (IS_ENABLED(CONFIG_ACPI) && !dev_of_node(&pdev->dev)) {
+		mc_stream_id = readl(mc->fsl_mc_regs + FSL_MC_FAPR);
+		/*
+		 * HW ORs the PL and BMT bit, places the result in bit 15 of
+		 * the StreamID and ORs in the ICID. Calculate it accordingly.
+		 */
+		mc_stream_id = (mc_stream_id & 0xffff) |
+				((mc_stream_id & (MC_FAPR_PL | MC_FAPR_BMT)) ?
+					0x4000 : 0);
+		error = acpi_dma_configure_id(&pdev->dev, DEV_DMA_COHERENT,
+					      &mc_stream_id);
+		if (error)
+			dev_warn(&pdev->dev, "failed to configure dma: %d.\n",
+				 error);
+	}
+
 	/*
 	 * Get physical address of MC portal for the root DPRC:
 	 */
-	error = of_address_to_resource(pdev->dev.of_node, 0, &res);
-	if (error < 0) {
-		dev_err(&pdev->dev,
-			"of_address_to_resource() failed for %pOF\n",
-			pdev->dev.of_node);
-		return error;
-	}
-
-	mc_portal_phys_addr = res.start;
-	mc_portal_size = resource_size(&res);
+	plat_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mc_portal_phys_addr = plat_res->start;
+	mc_portal_size = resource_size(plat_res);
 	error = fsl_create_mc_io(&pdev->dev, mc_portal_phys_addr,
 				 mc_portal_size, NULL,
 				 FSL_MC_IO_ATOMIC_CONTEXT_PORTAL, &mc_io);
@@ -903,11 +930,13 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
 	dev_info(&pdev->dev, "MC firmware version: %u.%u.%u\n",
 		 mc_version.major, mc_version.minor, mc_version.revision);
 
-	error = get_mc_addr_translation_ranges(&pdev->dev,
-					       &mc->translation_ranges,
-					       &mc->num_translation_ranges);
-	if (error < 0)
-		goto error_cleanup_mc_io;
+	if (dev_of_node(&pdev->dev)) {
+		error = get_mc_addr_translation_ranges(&pdev->dev,
+						&mc->translation_ranges,
+						&mc->num_translation_ranges);
+		if (error < 0)
+			goto error_cleanup_mc_io;
+	}
 
 	error = dprc_get_container_id(mc_io, 0, &container_id);
 	if (error < 0) {
@@ -934,6 +963,7 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
 		goto error_cleanup_mc_io;
 
 	mc->root_mc_bus_dev = mc_bus_dev;
+	mc_bus_dev->dev.fwnode = pdev->dev.fwnode;
 	return 0;
 
 error_cleanup_mc_io:
@@ -967,11 +997,18 @@ static const struct of_device_id fsl_mc_bus_match_table[] = {
 
 MODULE_DEVICE_TABLE(of, fsl_mc_bus_match_table);
 
+static const struct acpi_device_id fsl_mc_bus_acpi_match_table[] = {
+	{"NXP0008", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, fsl_mc_bus_acpi_match_table);
+
 static struct platform_driver fsl_mc_bus_driver = {
 	.driver = {
 		   .name = "fsl_mc_bus",
 		   .pm = NULL,
 		   .of_match_table = fsl_mc_bus_match_table,
+		   .acpi_match_table = fsl_mc_bus_acpi_match_table,
 		   },
 	.probe = fsl_mc_bus_probe,
 	.remove = fsl_mc_bus_remove,
diff --git a/drivers/bus/fsl-mc/fsl-mc-msi.c b/drivers/bus/fsl-mc/fsl-mc-msi.c
index e7bbff445a83..8edadf05cbb7 100644
--- a/drivers/bus/fsl-mc/fsl-mc-msi.c
+++ b/drivers/bus/fsl-mc/fsl-mc-msi.c
@@ -13,6 +13,7 @@
 #include <linux/irq.h>
 #include <linux/irqdomain.h>
 #include <linux/msi.h>
+#include <linux/acpi_iort.h>
 
 #include "fsl-mc-private.h"
 
@@ -179,25 +180,31 @@ struct irq_domain *fsl_mc_msi_create_irq_domain(struct fwnode_handle *fwnode,
 
 struct irq_domain *fsl_mc_find_msi_domain(struct device *dev)
 {
-	struct irq_domain *msi_domain = NULL;
+	struct device *root_dprc_dev;
+	struct device *bus_dev;
+	struct irq_domain *msi_domain;
 	struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
 
-	msi_domain = of_msi_map_get_device_domain(dev, mc_dev->icid,
+	fsl_mc_get_root_dprc(dev, &root_dprc_dev);
+	bus_dev = root_dprc_dev->parent;
+
+	if (bus_dev->of_node) {
+		msi_domain = of_msi_map_get_device_domain(dev,
+						  mc_dev->icid,
 						  DOMAIN_BUS_FSL_MC_MSI);
 
-	/*
-	 * if the msi-map property is missing assume that all the
-	 * child containers inherit the domain from the parent
-	 */
-	if (!msi_domain) {
-		struct device *root_dprc_dev;
-		struct device *bus_dev;
-
-		fsl_mc_get_root_dprc(dev, &root_dprc_dev);
-		bus_dev = root_dprc_dev->parent;
-		msi_domain = of_msi_get_domain(bus_dev,
-					       bus_dev->of_node,
-					       DOMAIN_BUS_FSL_MC_MSI);
+		/*
+		 * if the msi-map property is missing assume that all the
+		 * child containers inherit the domain from the parent
+		 */
+		if (!msi_domain)
+
+			msi_domain = of_msi_get_domain(bus_dev,
+						bus_dev->of_node,
+						DOMAIN_BUS_FSL_MC_MSI);
+	} else {
+		msi_domain = iort_get_device_domain(dev, mc_dev->icid,
+						    DOMAIN_BUS_FSL_MC_MSI);
 	}
 
 	return msi_domain;
diff --git a/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c b/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
index a5c8d577e424..b8b948fb6b2d 100644
--- a/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
@@ -7,6 +7,8 @@
  *
  */
 
+#include <linux/acpi.h>
+#include <linux/acpi_iort.h>
 #include <linux/of_device.h>
 #include <linux/of_address.h>
 #include <linux/irq.h>
@@ -30,7 +32,8 @@ static u32 fsl_mc_msi_domain_get_msi_id(struct irq_domain *domain,
 	u32 out_id;
 
 	of_node = irq_domain_get_of_node(domain);
-	out_id = of_msi_map_id(&mc_dev->dev, of_node, mc_dev->icid);
+	out_id = of_node ? of_msi_map_id(&mc_dev->dev, of_node, mc_dev->icid) :
+			iort_msi_map_id(&mc_dev->dev, mc_dev->icid);
 
 	return out_id;
 }
@@ -79,7 +82,67 @@ static const struct of_device_id its_device_id[] = {
 	{},
 };
 
-static int __init its_fsl_mc_msi_init(void)
+static int __init its_fsl_mc_msi_init_one(struct fwnode_handle *handle,
+					  const char *name)
+{
+	struct irq_domain *parent;
+	struct irq_domain *mc_msi_domain;
+
+	parent = irq_find_matching_fwnode(handle, DOMAIN_BUS_NEXUS);
+	if (!parent || !msi_get_domain_info(parent)) {
+		pr_err("%s: Unable to locate ITS domain\n", name);
+		return -ENXIO;
+	}
+
+	mc_msi_domain = fsl_mc_msi_create_irq_domain(handle,
+						&its_fsl_mc_msi_domain_info,
+						parent);
+	if (!mc_msi_domain)
+		pr_err("ACPIF: unable to create fsl-mc domain\n");
+
+	pr_info("fsl-mc MSI: domain created\n");
+
+	return 0;
+}
+
+static int __init
+its_fsl_mc_msi_parse_madt(union acpi_subtable_headers *header,
+			  const unsigned long end)
+{
+	struct acpi_madt_generic_translator *its_entry;
+	struct fwnode_handle *dom_handle;
+	const char *node_name;
+	int err = -ENXIO;
+
+	its_entry = (struct acpi_madt_generic_translator *)header;
+	node_name = kasprintf(GFP_KERNEL, "ITS@0x%lx",
+			      (long)its_entry->base_address);
+
+	dom_handle = iort_find_domain_token(its_entry->translation_id);
+	if (!dom_handle) {
+		pr_err("%s: Unable to locate ITS domain handle\n", node_name);
+		goto out;
+	}
+
+	err = its_fsl_mc_msi_init_one(dom_handle, node_name);
+	if (!err)
+		pr_info("fsl-mc MSI: %s domain created\n", node_name);
+
+out:
+	kfree(node_name);
+	return err;
+}
+
+
+static int __init its_fsl_mc_acpi_msi_init(void)
+{
+	acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
+			      its_fsl_mc_msi_parse_madt, 0);
+
+	return 0;
+}
+
+static int __init its_fsl_mc_of_msi_init(void)
 {
 	struct device_node *np;
 	struct irq_domain *parent;
@@ -113,4 +176,12 @@ static int __init its_fsl_mc_msi_init(void)
 	return 0;
 }
 
+static int __init its_fsl_mc_msi_init(void)
+{
+	its_fsl_mc_of_msi_init();
+	its_fsl_mc_acpi_msi_init();
+
+	return 0;
+}
+
 early_initcall(its_fsl_mc_msi_init);
-- 
2.26.1


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

* Re: [PATCH 12/12] bus: fsl-mc: Add ACPI support for fsl-mc
  2020-05-21 13:00 ` [PATCH 12/12] bus: fsl-mc: Add ACPI support for fsl-mc Lorenzo Pieralisi
@ 2020-05-21 15:03   ` Laurentiu Tudor
  2020-05-22  5:32     ` Makarand Pawagi
  0 siblings, 1 reply; 31+ messages in thread
From: Laurentiu Tudor @ 2020-05-21 15:03 UTC (permalink / raw)
  To: Lorenzo Pieralisi, linux-arm-kernel
  Cc: Diana Craciun, Makarand Pawagi, iommu, linux-acpi, devicetree,
	linux-pci, Rob Herring, Rafael J. Wysocki, Joerg Roedel,
	Hanjun Guo, Bjorn Helgaas, Sudeep Holla, Robin Murphy,
	Catalin Marinas, Will Deacon, Marc Zyngier

Hi Lorenzo,

On 5/21/2020 4:00 PM, Lorenzo Pieralisi wrote:
> From: Diana Craciun <diana.craciun@oss.nxp.com>
> 
> Add ACPI support in the fsl-mc driver. Driver parses MC DSDT table to
> extract memory and other resources.
> 
> Interrupt (GIC ITS) information is extracted from the MADT table
> by drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c.
> 
> IORT table is parsed to configure DMA.
> 
> Signed-off-by: Makarand Pawagi <makarand.pawagi@nxp.com>
> Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
> Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> ---

The author of this patch should be Makarand. I think I accidentaly broke
it when we exchanged the patches. Very sorry about it.

---
Best Regards, Laurentiu


>  drivers/bus/fsl-mc/fsl-mc-bus.c             | 73 +++++++++++++++-----
>  drivers/bus/fsl-mc/fsl-mc-msi.c             | 37 +++++-----
>  drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c | 75 ++++++++++++++++++++-
>  3 files changed, 150 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
> index 824ff77bbe86..324d49d6df89 100644
> --- a/drivers/bus/fsl-mc/fsl-mc-bus.c
> +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
> @@ -18,6 +18,8 @@
>  #include <linux/bitops.h>
>  #include <linux/msi.h>
>  #include <linux/dma-mapping.h>
> +#include <linux/acpi.h>
> +#include <linux/iommu.h>
>  
>  #include "fsl-mc-private.h"
>  
> @@ -38,6 +40,7 @@ struct fsl_mc {
>  	struct fsl_mc_device *root_mc_bus_dev;
>  	u8 num_translation_ranges;
>  	struct fsl_mc_addr_translation_range *translation_ranges;
> +	void *fsl_mc_regs;
>  };
>  
>  /**
> @@ -56,6 +59,10 @@ struct fsl_mc_addr_translation_range {
>  	phys_addr_t start_phys_addr;
>  };
>  
> +#define FSL_MC_FAPR	0x28
> +#define MC_FAPR_PL	BIT(18)
> +#define MC_FAPR_BMT	BIT(17)
> +
>  /**
>   * fsl_mc_bus_match - device to driver matching callback
>   * @dev: the fsl-mc device to match against
> @@ -124,7 +131,10 @@ static int fsl_mc_dma_configure(struct device *dev)
>  	while (dev_is_fsl_mc(dma_dev))
>  		dma_dev = dma_dev->parent;
>  
> -	return of_dma_configure_id(dev, dma_dev->of_node, 0, &input_id);
> +	if (dev_of_node(dma_dev))
> +		return of_dma_configure_id(dev, dma_dev->of_node, 0, &input_id);
> +
> +	return acpi_dma_configure_id(dev, DEV_DMA_COHERENT, &input_id);
>  }
>  
>  static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
> @@ -865,8 +875,11 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
>  	struct fsl_mc_io *mc_io = NULL;
>  	int container_id;
>  	phys_addr_t mc_portal_phys_addr;
> -	u32 mc_portal_size;
> -	struct resource res;
> +	u32 mc_portal_size, mc_stream_id;
> +	struct resource *plat_res;
> +
> +	if (!iommu_present(&fsl_mc_bus_type))
> +		return -EPROBE_DEFER;
>  
>  	mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
>  	if (!mc)
> @@ -874,19 +887,33 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
>  
>  	platform_set_drvdata(pdev, mc);
>  
> +	plat_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> +	mc->fsl_mc_regs = devm_ioremap_resource(&pdev->dev, plat_res);
> +	if (IS_ERR(mc->fsl_mc_regs))
> +		return PTR_ERR(mc->fsl_mc_regs);
> +
> +	if (IS_ENABLED(CONFIG_ACPI) && !dev_of_node(&pdev->dev)) {
> +		mc_stream_id = readl(mc->fsl_mc_regs + FSL_MC_FAPR);
> +		/*
> +		 * HW ORs the PL and BMT bit, places the result in bit 15 of
> +		 * the StreamID and ORs in the ICID. Calculate it accordingly.
> +		 */
> +		mc_stream_id = (mc_stream_id & 0xffff) |
> +				((mc_stream_id & (MC_FAPR_PL | MC_FAPR_BMT)) ?
> +					0x4000 : 0);
> +		error = acpi_dma_configure_id(&pdev->dev, DEV_DMA_COHERENT,
> +					      &mc_stream_id);
> +		if (error)
> +			dev_warn(&pdev->dev, "failed to configure dma: %d.\n",
> +				 error);
> +	}
> +
>  	/*
>  	 * Get physical address of MC portal for the root DPRC:
>  	 */
> -	error = of_address_to_resource(pdev->dev.of_node, 0, &res);
> -	if (error < 0) {
> -		dev_err(&pdev->dev,
> -			"of_address_to_resource() failed for %pOF\n",
> -			pdev->dev.of_node);
> -		return error;
> -	}
> -
> -	mc_portal_phys_addr = res.start;
> -	mc_portal_size = resource_size(&res);
> +	plat_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	mc_portal_phys_addr = plat_res->start;
> +	mc_portal_size = resource_size(plat_res);
>  	error = fsl_create_mc_io(&pdev->dev, mc_portal_phys_addr,
>  				 mc_portal_size, NULL,
>  				 FSL_MC_IO_ATOMIC_CONTEXT_PORTAL, &mc_io);
> @@ -903,11 +930,13 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
>  	dev_info(&pdev->dev, "MC firmware version: %u.%u.%u\n",
>  		 mc_version.major, mc_version.minor, mc_version.revision);
>  
> -	error = get_mc_addr_translation_ranges(&pdev->dev,
> -					       &mc->translation_ranges,
> -					       &mc->num_translation_ranges);
> -	if (error < 0)
> -		goto error_cleanup_mc_io;
> +	if (dev_of_node(&pdev->dev)) {
> +		error = get_mc_addr_translation_ranges(&pdev->dev,
> +						&mc->translation_ranges,
> +						&mc->num_translation_ranges);
> +		if (error < 0)
> +			goto error_cleanup_mc_io;
> +	}
>  
>  	error = dprc_get_container_id(mc_io, 0, &container_id);
>  	if (error < 0) {
> @@ -934,6 +963,7 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
>  		goto error_cleanup_mc_io;
>  
>  	mc->root_mc_bus_dev = mc_bus_dev;
> +	mc_bus_dev->dev.fwnode = pdev->dev.fwnode;
>  	return 0;
>  
>  error_cleanup_mc_io:
> @@ -967,11 +997,18 @@ static const struct of_device_id fsl_mc_bus_match_table[] = {
>  
>  MODULE_DEVICE_TABLE(of, fsl_mc_bus_match_table);
>  
> +static const struct acpi_device_id fsl_mc_bus_acpi_match_table[] = {
> +	{"NXP0008", 0 },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(acpi, fsl_mc_bus_acpi_match_table);
> +
>  static struct platform_driver fsl_mc_bus_driver = {
>  	.driver = {
>  		   .name = "fsl_mc_bus",
>  		   .pm = NULL,
>  		   .of_match_table = fsl_mc_bus_match_table,
> +		   .acpi_match_table = fsl_mc_bus_acpi_match_table,
>  		   },
>  	.probe = fsl_mc_bus_probe,
>  	.remove = fsl_mc_bus_remove,
> diff --git a/drivers/bus/fsl-mc/fsl-mc-msi.c b/drivers/bus/fsl-mc/fsl-mc-msi.c
> index e7bbff445a83..8edadf05cbb7 100644
> --- a/drivers/bus/fsl-mc/fsl-mc-msi.c
> +++ b/drivers/bus/fsl-mc/fsl-mc-msi.c
> @@ -13,6 +13,7 @@
>  #include <linux/irq.h>
>  #include <linux/irqdomain.h>
>  #include <linux/msi.h>
> +#include <linux/acpi_iort.h>
>  
>  #include "fsl-mc-private.h"
>  
> @@ -179,25 +180,31 @@ struct irq_domain *fsl_mc_msi_create_irq_domain(struct fwnode_handle *fwnode,
>  
>  struct irq_domain *fsl_mc_find_msi_domain(struct device *dev)
>  {
> -	struct irq_domain *msi_domain = NULL;
> +	struct device *root_dprc_dev;
> +	struct device *bus_dev;
> +	struct irq_domain *msi_domain;
>  	struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
>  
> -	msi_domain = of_msi_map_get_device_domain(dev, mc_dev->icid,
> +	fsl_mc_get_root_dprc(dev, &root_dprc_dev);
> +	bus_dev = root_dprc_dev->parent;
> +
> +	if (bus_dev->of_node) {
> +		msi_domain = of_msi_map_get_device_domain(dev,
> +						  mc_dev->icid,
>  						  DOMAIN_BUS_FSL_MC_MSI);
>  
> -	/*
> -	 * if the msi-map property is missing assume that all the
> -	 * child containers inherit the domain from the parent
> -	 */
> -	if (!msi_domain) {
> -		struct device *root_dprc_dev;
> -		struct device *bus_dev;
> -
> -		fsl_mc_get_root_dprc(dev, &root_dprc_dev);
> -		bus_dev = root_dprc_dev->parent;
> -		msi_domain = of_msi_get_domain(bus_dev,
> -					       bus_dev->of_node,
> -					       DOMAIN_BUS_FSL_MC_MSI);
> +		/*
> +		 * if the msi-map property is missing assume that all the
> +		 * child containers inherit the domain from the parent
> +		 */
> +		if (!msi_domain)
> +
> +			msi_domain = of_msi_get_domain(bus_dev,
> +						bus_dev->of_node,
> +						DOMAIN_BUS_FSL_MC_MSI);
> +	} else {
> +		msi_domain = iort_get_device_domain(dev, mc_dev->icid,
> +						    DOMAIN_BUS_FSL_MC_MSI);
>  	}
>  
>  	return msi_domain;
> diff --git a/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c b/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
> index a5c8d577e424..b8b948fb6b2d 100644
> --- a/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
> +++ b/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
> @@ -7,6 +7,8 @@
>   *
>   */
>  
> +#include <linux/acpi.h>
> +#include <linux/acpi_iort.h>
>  #include <linux/of_device.h>
>  #include <linux/of_address.h>
>  #include <linux/irq.h>
> @@ -30,7 +32,8 @@ static u32 fsl_mc_msi_domain_get_msi_id(struct irq_domain *domain,
>  	u32 out_id;
>  
>  	of_node = irq_domain_get_of_node(domain);
> -	out_id = of_msi_map_id(&mc_dev->dev, of_node, mc_dev->icid);
> +	out_id = of_node ? of_msi_map_id(&mc_dev->dev, of_node, mc_dev->icid) :
> +			iort_msi_map_id(&mc_dev->dev, mc_dev->icid);
>  
>  	return out_id;
>  }
> @@ -79,7 +82,67 @@ static const struct of_device_id its_device_id[] = {
>  	{},
>  };
>  
> -static int __init its_fsl_mc_msi_init(void)
> +static int __init its_fsl_mc_msi_init_one(struct fwnode_handle *handle,
> +					  const char *name)
> +{
> +	struct irq_domain *parent;
> +	struct irq_domain *mc_msi_domain;
> +
> +	parent = irq_find_matching_fwnode(handle, DOMAIN_BUS_NEXUS);
> +	if (!parent || !msi_get_domain_info(parent)) {
> +		pr_err("%s: Unable to locate ITS domain\n", name);
> +		return -ENXIO;
> +	}
> +
> +	mc_msi_domain = fsl_mc_msi_create_irq_domain(handle,
> +						&its_fsl_mc_msi_domain_info,
> +						parent);
> +	if (!mc_msi_domain)
> +		pr_err("ACPIF: unable to create fsl-mc domain\n");
> +
> +	pr_info("fsl-mc MSI: domain created\n");
> +
> +	return 0;
> +}
> +
> +static int __init
> +its_fsl_mc_msi_parse_madt(union acpi_subtable_headers *header,
> +			  const unsigned long end)
> +{
> +	struct acpi_madt_generic_translator *its_entry;
> +	struct fwnode_handle *dom_handle;
> +	const char *node_name;
> +	int err = -ENXIO;
> +
> +	its_entry = (struct acpi_madt_generic_translator *)header;
> +	node_name = kasprintf(GFP_KERNEL, "ITS@0x%lx",
> +			      (long)its_entry->base_address);
> +
> +	dom_handle = iort_find_domain_token(its_entry->translation_id);
> +	if (!dom_handle) {
> +		pr_err("%s: Unable to locate ITS domain handle\n", node_name);
> +		goto out;
> +	}
> +
> +	err = its_fsl_mc_msi_init_one(dom_handle, node_name);
> +	if (!err)
> +		pr_info("fsl-mc MSI: %s domain created\n", node_name);
> +
> +out:
> +	kfree(node_name);
> +	return err;
> +}
> +
> +
> +static int __init its_fsl_mc_acpi_msi_init(void)
> +{
> +	acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
> +			      its_fsl_mc_msi_parse_madt, 0);
> +
> +	return 0;
> +}
> +
> +static int __init its_fsl_mc_of_msi_init(void)
>  {
>  	struct device_node *np;
>  	struct irq_domain *parent;
> @@ -113,4 +176,12 @@ static int __init its_fsl_mc_msi_init(void)
>  	return 0;
>  }
>  
> +static int __init its_fsl_mc_msi_init(void)
> +{
> +	its_fsl_mc_of_msi_init();
> +	its_fsl_mc_acpi_msi_init();
> +
> +	return 0;
> +}
> +
>  early_initcall(its_fsl_mc_msi_init);
> 

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

* Re: [PATCH 02/12] ACPI/IORT: Make iort_get_device_domain IRQ domain agnostic
  2020-05-21 12:59 ` [PATCH 02/12] ACPI/IORT: Make iort_get_device_domain IRQ domain agnostic Lorenzo Pieralisi
@ 2020-05-21 19:56   ` Bjorn Helgaas
  0 siblings, 0 replies; 31+ messages in thread
From: Bjorn Helgaas @ 2020-05-21 19:56 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: linux-arm-kernel, Will Deacon, Hanjun Guo, Bjorn Helgaas,
	Sudeep Holla, Catalin Marinas, Robin Murphy, Rafael J. Wysocki,
	Marc Zyngier, iommu, linux-acpi, devicetree, linux-pci,
	Rob Herring, Joerg Roedel, Makarand Pawagi, Diana Craciun,
	Laurentiu Tudor

On Thu, May 21, 2020 at 01:59:58PM +0100, Lorenzo Pieralisi wrote:
> iort_get_device_domain() is PCI specific but it need not be,
> since it can be used to retrieve IRQ domain nexus of any kind
> by adding an irq_domain_bus_token input to it.
> 
> Make it PCI agnostic by also renaming the requestor ID input
> to a more generic ID name.
> 
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: Hanjun Guo <guohanjun@huawei.com>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Robin Murphy <robin.murphy@arm.com>
> Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
> Cc: Marc Zyngier <maz@kernel.org>

Acked-by: Bjorn Helgaas <bhelgaas@google.com>	# pci/msi.c

> ---
>  drivers/acpi/arm64/iort.c | 14 +++++++-------
>  drivers/pci/msi.c         |  3 ++-
>  include/linux/acpi_iort.h |  7 ++++---
>  3 files changed, 13 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index 7cfd77b5e6e8..8f2a961c1364 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -567,7 +567,6 @@ static struct acpi_iort_node *iort_find_dev_node(struct device *dev)
>  		node = iort_get_iort_node(dev->fwnode);
>  		if (node)
>  			return node;
> -
>  		/*
>  		 * if not, then it should be a platform device defined in
>  		 * DSDT/SSDT (with Named Component node in IORT)
> @@ -658,13 +657,13 @@ static int __maybe_unused iort_find_its_base(u32 its_id, phys_addr_t *base)
>  /**
>   * iort_dev_find_its_id() - Find the ITS identifier for a device
>   * @dev: The device.
> - * @req_id: Device's requester ID
> + * @id: Device's ID
>   * @idx: Index of the ITS identifier list.
>   * @its_id: ITS identifier.
>   *
>   * Returns: 0 on success, appropriate error value otherwise
>   */
> -static int iort_dev_find_its_id(struct device *dev, u32 req_id,
> +static int iort_dev_find_its_id(struct device *dev, u32 id,
>  				unsigned int idx, int *its_id)
>  {
>  	struct acpi_iort_its_group *its;
> @@ -674,7 +673,7 @@ static int iort_dev_find_its_id(struct device *dev, u32 req_id,
>  	if (!node)
>  		return -ENXIO;
>  
> -	node = iort_node_map_id(node, req_id, NULL, IORT_MSI_TYPE);
> +	node = iort_node_map_id(node, id, NULL, IORT_MSI_TYPE);
>  	if (!node)
>  		return -ENXIO;
>  
> @@ -697,19 +696,20 @@ static int iort_dev_find_its_id(struct device *dev, u32 req_id,
>   *
>   * Returns: the MSI domain for this device, NULL otherwise
>   */
> -struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
> +struct irq_domain *iort_get_device_domain(struct device *dev, u32 id,
> +					  enum irq_domain_bus_token bus_token)
>  {
>  	struct fwnode_handle *handle;
>  	int its_id;
>  
> -	if (iort_dev_find_its_id(dev, req_id, 0, &its_id))
> +	if (iort_dev_find_its_id(dev, id, 0, &its_id))
>  		return NULL;
>  
>  	handle = iort_find_domain_token(its_id);
>  	if (!handle)
>  		return NULL;
>  
> -	return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
> +	return irq_find_matching_fwnode(handle, bus_token);
>  }
>  
>  static void iort_set_device_domain(struct device *dev,
> diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
> index 6b43a5455c7a..74a91f52ecc0 100644
> --- a/drivers/pci/msi.c
> +++ b/drivers/pci/msi.c
> @@ -1558,7 +1558,8 @@ struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev)
>  	pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid);
>  	dom = of_msi_map_get_device_domain(&pdev->dev, rid);
>  	if (!dom)
> -		dom = iort_get_device_domain(&pdev->dev, rid);
> +		dom = iort_get_device_domain(&pdev->dev, rid,
> +					     DOMAIN_BUS_PCI_MSI);
>  	return dom;
>  }
>  #endif /* CONFIG_PCI_MSI_IRQ_DOMAIN */
> diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
> index 8e7e2ec37f1b..08ec6bd2297f 100644
> --- a/include/linux/acpi_iort.h
> +++ b/include/linux/acpi_iort.h
> @@ -29,7 +29,8 @@ struct fwnode_handle *iort_find_domain_token(int trans_id);
>  #ifdef CONFIG_ACPI_IORT
>  void acpi_iort_init(void);
>  u32 iort_msi_map_rid(struct device *dev, u32 req_id);
> -struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id);
> +struct irq_domain *iort_get_device_domain(struct device *dev, u32 id,
> +					  enum irq_domain_bus_token bus_token);
>  void acpi_configure_pmsi_domain(struct device *dev);
>  int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id);
>  /* IOMMU interface */
> @@ -40,8 +41,8 @@ int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head);
>  static inline void acpi_iort_init(void) { }
>  static inline u32 iort_msi_map_rid(struct device *dev, u32 req_id)
>  { return req_id; }
> -static inline struct irq_domain *iort_get_device_domain(struct device *dev,
> -							u32 req_id)
> +static inline struct irq_domain *iort_get_device_domain(
> +	struct device *dev, u32 id, enum irq_domain_bus_token bus_token)
>  { return NULL; }
>  static inline void acpi_configure_pmsi_domain(struct device *dev) { }
>  /* IOMMU interface */
> -- 
> 2.26.1
> 

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

* Re: [PATCH 08/12] of/irq: make of_msi_map_get_device_domain() bus agnostic
  2020-05-21 13:00 ` [PATCH 08/12] of/irq: make of_msi_map_get_device_domain() bus agnostic Lorenzo Pieralisi
@ 2020-05-21 19:57   ` Bjorn Helgaas
  0 siblings, 0 replies; 31+ messages in thread
From: Bjorn Helgaas @ 2020-05-21 19:57 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: linux-arm-kernel, Diana Craciun, Bjorn Helgaas, Rob Herring,
	Marc Zyngier, iommu, linux-acpi, devicetree, linux-pci,
	Rafael J. Wysocki, Joerg Roedel, Hanjun Guo, Sudeep Holla,
	Robin Murphy, Catalin Marinas, Will Deacon, Makarand Pawagi,
	Laurentiu Tudor

On Thu, May 21, 2020 at 02:00:04PM +0100, Lorenzo Pieralisi wrote:
> From: Diana Craciun <diana.craciun@oss.nxp.com>
> 
> of_msi_map_get_device_domain() is PCI specific but it need not be and
> can be easily changed to be bus agnostic in order to be used by other
> busses by adding an IRQ domain bus token as an input parameter.
> 
> Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Marc Zyngier <maz@kernel.org>

Acked-by: Bjorn Helgaas <bhelgaas@google.com>	# pci/msi.c

> ---
>  drivers/of/irq.c       | 8 +++++---
>  drivers/pci/msi.c      | 2 +-
>  include/linux/of_irq.h | 5 +++--
>  3 files changed, 9 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/of/irq.c b/drivers/of/irq.c
> index a296eaf52a5b..48a40326984f 100644
> --- a/drivers/of/irq.c
> +++ b/drivers/of/irq.c
> @@ -613,18 +613,20 @@ u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in)
>   * 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.
> + * @bus_token: Bus token
>   *
>   * 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 irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 id,
> +						u32 bus_token)
>  {
>  	struct device_node *np = NULL;
>  
> -	__of_msi_map_rid(dev, &np, rid);
> -	return irq_find_matching_host(np, DOMAIN_BUS_PCI_MSI);
> +	__of_msi_map_rid(dev, &np, id);
> +	return irq_find_matching_host(np, bus_token);
>  }
>  
>  /**
> diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
> index 74a91f52ecc0..9532e1d12d3f 100644
> --- a/drivers/pci/msi.c
> +++ b/drivers/pci/msi.c
> @@ -1556,7 +1556,7 @@ struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev)
>  	u32 rid = pci_dev_id(pdev);
>  
>  	pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid);
> -	dom = of_msi_map_get_device_domain(&pdev->dev, rid);
> +	dom = of_msi_map_get_device_domain(&pdev->dev, rid, DOMAIN_BUS_PCI_MSI);
>  	if (!dom)
>  		dom = iort_get_device_domain(&pdev->dev, rid,
>  					     DOMAIN_BUS_PCI_MSI);
> diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
> index 1214cabb2247..7142a3722758 100644
> --- a/include/linux/of_irq.h
> +++ b/include/linux/of_irq.h
> @@ -52,7 +52,8 @@ 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);
> +							u32 id,
> +							u32 bus_token);
>  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
> @@ -85,7 +86,7 @@ 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)
> +						u32 id, u32 bus_token)
>  {
>  	return NULL;
>  }
> -- 
> 2.26.1
> 

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

* Re: [PATCH 06/12] of/iommu: Make of_map_rid() PCI agnostic
  2020-05-21 13:00 ` [PATCH 06/12] of/iommu: Make of_map_rid() PCI agnostic Lorenzo Pieralisi
@ 2020-05-21 22:47   ` Rob Herring
  2020-06-04 14:27     ` Lorenzo Pieralisi
  0 siblings, 1 reply; 31+ messages in thread
From: Rob Herring @ 2020-05-21 22:47 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Joerg Roedel, Robin Murphy, Marc Zyngier, Linux IOMMU,
	linux-acpi, devicetree, PCI, Rafael J. Wysocki, Hanjun Guo,
	Bjorn Helgaas, Sudeep Holla, Catalin Marinas, Will Deacon,
	Makarand Pawagi, Diana Craciun, Laurentiu Tudor

On Thu, May 21, 2020 at 7:00 AM Lorenzo Pieralisi
<lorenzo.pieralisi@arm.com> wrote:
>
> There is nothing PCI specific (other than the RID - requester ID)
> in the of_map_rid() implementation, so the same function can be
> reused for input/output IDs mapping for other busses just as well.
>
> Rename the RID instances/names to a generic "id" tag and provide
> an of_map_rid() wrapper function so that we can leave the existing
> (and legitimate) callers unchanged.

It's not all that clear to a casual observer that RID is a PCI thing,
so I don't know that keeping it buys much. And there's only 3 callers.

> No functionality change intended.
>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Joerg Roedel <joro@8bytes.org>
> Cc: Robin Murphy <robin.murphy@arm.com>
> Cc: Marc Zyngier <maz@kernel.org>
> ---
>  drivers/iommu/of_iommu.c |  2 +-
>  drivers/of/base.c        | 42 ++++++++++++++++++++--------------------
>  include/linux/of.h       | 17 +++++++++++++++-
>  3 files changed, 38 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index 20738aacac89..ad96b87137d6 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -145,7 +145,7 @@ static int of_fsl_mc_iommu_init(struct fsl_mc_device *mc_dev,
>         struct of_phandle_args iommu_spec = { .args_count = 1 };
>         int err;
>
> -       err = of_map_rid(master_np, mc_dev->icid, "iommu-map",
> +       err = of_map_id(master_np, mc_dev->icid, "iommu-map",

I'm not sure this is an improvement because I'd refactor this function
and of_pci_iommu_init() into a single function:

of_bus_iommu_init(struct device *dev, struct device_node *np, u32 id)

Then of_pci_iommu_init() becomes:

of_pci_iommu_init()
{
  return of_bus_iommu_init(info->dev, info->np, alias);
}

And replace of_fsl_mc_iommu_init call with:
err = of_bus_iommu_init(dev, master_np, to_fsl_mc_device(dev)->icid);

>                          "iommu-map-mask", &iommu_spec.np,
>                          iommu_spec.args);
>         if (err)
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index ae03b1218b06..e000e17bd602 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -2201,15 +2201,15 @@ int of_find_last_cache_level(unsigned int cpu)
>  }
>
>  /**
> - * of_map_rid - Translate a requester ID through a downstream mapping.
> + * of_map_id - Translate a requester ID through a downstream mapping.

Still a requester ID?

>   * @np: root complex device node.
> - * @rid: device requester ID to map.
> + * @id: device ID to map.
>   * @map_name: property name of the map to use.
>   * @map_mask_name: optional property name of the mask to use.
>   * @target: optional pointer to a target device node.
>   * @id_out: optional pointer to receive the translated ID.
>   *
> - * Given a device requester ID, look up the appropriate implementation-defined
> + * Given a device ID, look up the appropriate implementation-defined
>   * platform ID and/or the target device which receives transactions on that
>   * ID, as per the "iommu-map" and "msi-map" bindings. Either of @target or
>   * @id_out may be NULL if only the other is required. If @target points to
> @@ -2219,11 +2219,11 @@ int of_find_last_cache_level(unsigned int cpu)
>   *
>   * Return: 0 on success or a standard error code on failure.
>   */
> -int of_map_rid(struct device_node *np, u32 rid,
> +int of_map_id(struct device_node *np, u32 id,
>                const char *map_name, const char *map_mask_name,
>                struct device_node **target, u32 *id_out)
>  {
> -       u32 map_mask, masked_rid;
> +       u32 map_mask, masked_id;
>         int map_len;
>         const __be32 *map = NULL;
>
> @@ -2235,7 +2235,7 @@ int of_map_rid(struct device_node *np, u32 rid,
>                 if (target)
>                         return -ENODEV;
>                 /* Otherwise, no map implies no translation */
> -               *id_out = rid;
> +               *id_out = id;
>                 return 0;
>         }
>
> @@ -2255,22 +2255,22 @@ int of_map_rid(struct device_node *np, u32 rid,
>         if (map_mask_name)
>                 of_property_read_u32(np, map_mask_name, &map_mask);
>
> -       masked_rid = map_mask & rid;
> +       masked_id = map_mask & id;
>         for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) {
>                 struct device_node *phandle_node;
> -               u32 rid_base = be32_to_cpup(map + 0);
> +               u32 id_base = be32_to_cpup(map + 0);
>                 u32 phandle = be32_to_cpup(map + 1);
>                 u32 out_base = be32_to_cpup(map + 2);
> -               u32 rid_len = be32_to_cpup(map + 3);
> +               u32 id_len = be32_to_cpup(map + 3);
>
> -               if (rid_base & ~map_mask) {
> -                       pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores rid-base (0x%x)\n",
> +               if (id_base & ~map_mask) {
> +                       pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores id-base (0x%x)\n",
>                                 np, map_name, map_name,
> -                               map_mask, rid_base);
> +                               map_mask, id_base);
>                         return -EFAULT;
>                 }
>
> -               if (masked_rid < rid_base || masked_rid >= rid_base + rid_len)
> +               if (masked_id < id_base || masked_id >= id_base + id_len)
>                         continue;
>
>                 phandle_node = of_find_node_by_phandle(phandle);
> @@ -2288,20 +2288,20 @@ int of_map_rid(struct device_node *np, u32 rid,
>                 }
>
>                 if (id_out)
> -                       *id_out = masked_rid - rid_base + out_base;
> +                       *id_out = masked_id - id_base + out_base;
>
> -               pr_debug("%pOF: %s, using mask %08x, rid-base: %08x, out-base: %08x, length: %08x, rid: %08x -> %08x\n",
> -                       np, map_name, map_mask, rid_base, out_base,
> -                       rid_len, rid, masked_rid - rid_base + out_base);
> +               pr_debug("%pOF: %s, using mask %08x, id-base: %08x, out-base: %08x, length: %08x, id: %08x -> %08x\n",
> +                       np, map_name, map_mask, id_base, out_base,
> +                       id_len, id, masked_id - id_base + out_base);
>                 return 0;
>         }
>
> -       pr_info("%pOF: no %s translation for rid 0x%x on %pOF\n", np, map_name,
> -               rid, target && *target ? *target : NULL);
> +       pr_info("%pOF: no %s translation for id 0x%x on %pOF\n", np, map_name,
> +               id, target && *target ? *target : NULL);
>
>         /* Bypasses translation */
>         if (id_out)
> -               *id_out = rid;
> +               *id_out = id;
>         return 0;
>  }
> -EXPORT_SYMBOL_GPL(of_map_rid);
> +EXPORT_SYMBOL_GPL(of_map_id);
> diff --git a/include/linux/of.h b/include/linux/of.h
> index c669c0a4732f..b7934566a1aa 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -554,10 +554,18 @@ bool of_console_check(struct device_node *dn, char *name, int index);
>
>  extern int of_cpu_node_to_id(struct device_node *np);
>
> -int of_map_rid(struct device_node *np, u32 rid,
> +int of_map_id(struct device_node *np, u32 id,
>                const char *map_name, const char *map_mask_name,
>                struct device_node **target, u32 *id_out);
>
> +static inline int of_map_rid(struct device_node *np, u32 rid,
> +                            const char *map_name,
> +                            const char *map_mask_name,
> +                            struct device_node **target, u32 *id_out)
> +{
> +       return of_map_id(np, rid, map_name, map_mask_name, target, id_out);
> +}
> +
>  #else /* CONFIG_OF */
>
>  static inline void of_core_init(void)
> @@ -978,6 +986,13 @@ static inline int of_cpu_node_to_id(struct device_node *np)
>         return -ENODEV;
>  }
>
> +static inline int of_map_id(struct device_node *np, u32 id,
> +                            const char *map_name, const char *map_mask_name,
> +                            struct device_node **target, u32 *id_out)
> +{
> +       return -EINVAL;
> +}
> +
>  static inline int of_map_rid(struct device_node *np, u32 rid,
>                              const char *map_name, const char *map_mask_name,
>                              struct device_node **target, u32 *id_out)
> --
> 2.26.1
>

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

* Re: [PATCH 07/12] of/device: Add input id to of_dma_configure()
  2020-05-21 13:00 ` [PATCH 07/12] of/device: Add input id to of_dma_configure() Lorenzo Pieralisi
@ 2020-05-21 23:02   ` Rob Herring
  2020-06-04 14:49     ` Lorenzo Pieralisi
  0 siblings, 1 reply; 31+ messages in thread
From: Rob Herring @ 2020-05-21 23:02 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Robin Murphy, Joerg Roedel, Laurentiu Tudor, Linux IOMMU,
	linux-acpi, devicetree, PCI, Rafael J. Wysocki, Hanjun Guo,
	Bjorn Helgaas, Sudeep Holla, Catalin Marinas, Will Deacon,
	Marc Zyngier, Makarand Pawagi, Diana Craciun

On Thu, May 21, 2020 at 7:00 AM Lorenzo Pieralisi
<lorenzo.pieralisi@arm.com> wrote:
>
> Devices sitting on proprietary busses have a device ID space that
> is owned by the respective bus and related firmware bindings. In order
> to let the generic OF layer handle the input translations to
> an IOMMU id, for such busses the current of_dma_configure() interface
> should be extended in order to allow the bus layer to provide the
> device input id parameter - that is retrieved/assigned in bus
> specific code and firmware.
>
> Augment of_dma_configure() to add an optional input_id parameter,
> leaving current functionality unchanged.
>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Robin Murphy <robin.murphy@arm.com>
> Cc: Joerg Roedel <joro@8bytes.org>
> Cc: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> ---
>  drivers/bus/fsl-mc/fsl-mc-bus.c |  4 ++-
>  drivers/iommu/of_iommu.c        | 53 +++++++++++++++++++++------------
>  drivers/of/device.c             |  8 +++--
>  include/linux/of_device.h       | 16 ++++++++--
>  include/linux/of_iommu.h        |  6 ++--
>  5 files changed, 60 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
> index 40526da5c6a6..8ead3f0238f2 100644
> --- a/drivers/bus/fsl-mc/fsl-mc-bus.c
> +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
> @@ -118,11 +118,13 @@ static int fsl_mc_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
>  static int fsl_mc_dma_configure(struct device *dev)
>  {
>         struct device *dma_dev = dev;
> +       struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
> +       u32 input_id = mc_dev->icid;
>
>         while (dev_is_fsl_mc(dma_dev))
>                 dma_dev = dma_dev->parent;
>
> -       return of_dma_configure(dev, dma_dev->of_node, 0);
> +       return of_dma_configure_id(dev, dma_dev->of_node, 0, &input_id);
>  }
>
>  static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index ad96b87137d6..4516d5bf6cc9 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -139,25 +139,53 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
>         return err;
>  }
>
> -static int of_fsl_mc_iommu_init(struct fsl_mc_device *mc_dev,
> -                               struct device_node *master_np)
> +static int of_iommu_configure_dev_id(struct device_node *master_np,
> +                                    struct device *dev,
> +                                    const u32 *id)

Should have read this patch before #6. I guess you could still make
of_pci_iommu_init() call
of_iommu_configure_dev_id.

Rob

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

* Re: [PATCH 09/12] dt-bindings: arm: fsl: Add msi-map device-tree binding for fsl-mc bus
  2020-05-21 13:00 ` [PATCH 09/12] dt-bindings: arm: fsl: Add msi-map device-tree binding for fsl-mc bus Lorenzo Pieralisi
@ 2020-05-21 23:10   ` Rob Herring
  2020-05-22  9:42     ` Robin Murphy
  0 siblings, 1 reply; 31+ messages in thread
From: Rob Herring @ 2020-05-21 23:10 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Laurentiu Tudor, Linux IOMMU, linux-acpi, devicetree, PCI,
	Rafael J. Wysocki, Joerg Roedel, Hanjun Guo, Bjorn Helgaas,
	Sudeep Holla, Robin Murphy, Catalin Marinas, Will Deacon,
	Marc Zyngier, Makarand Pawagi, Diana Craciun

On Thu, May 21, 2020 at 7:00 AM Lorenzo Pieralisi
<lorenzo.pieralisi@arm.com> wrote:
>
> From: Laurentiu Tudor <laurentiu.tudor@nxp.com>
>
> The existing bindings cannot be used to specify the relationship
> between fsl-mc devices and GIC ITSes.
>
> Add a generic binding for mapping fsl-mc devices to GIC ITSes, using
> msi-map property.
>
> Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> Cc: Rob Herring <robh+dt@kernel.org>
> ---
>  .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 30 +++++++++++++++++--
>  1 file changed, 27 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
> index 9134e9bcca56..b0813b2d0493 100644
> --- a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
> +++ b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
> @@ -18,9 +18,9 @@ same hardware "isolation context" and a 10-bit value called an ICID
>  the requester.
>
>  The generic 'iommus' property is insufficient to describe the relationship
> -between ICIDs and IOMMUs, so an iommu-map property is used to define
> -the set of possible ICIDs under a root DPRC and how they map to
> -an IOMMU.
> +between ICIDs and IOMMUs, so the iommu-map and msi-map properties are used
> +to define the set of possible ICIDs under a root DPRC and how they map to
> +an IOMMU and a GIC ITS respectively.
>
>  For generic IOMMU bindings, see
>  Documentation/devicetree/bindings/iommu/iommu.txt.
> @@ -28,6 +28,9 @@ Documentation/devicetree/bindings/iommu/iommu.txt.
>  For arm-smmu binding, see:
>  Documentation/devicetree/bindings/iommu/arm,smmu.yaml.
>
> +For GICv3 and GIC ITS bindings, see:
> +Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml.
> +
>  Required properties:
>
>      - compatible
> @@ -119,6 +122,15 @@ Optional properties:
>    associated with the listed IOMMU, with the iommu-specifier
>    (i - icid-base + iommu-base).
>
> +- msi-map: Maps an ICID to a GIC ITS and associated iommu-specifier
> +  data.
> +
> +  The property is an arbitrary number of tuples of
> +  (icid-base,iommu,iommu-base,length).

I'm confused because the example has GIC ITS phandle, not an IOMMU.

What is an iommu-base?

> +
> +  Any ICID in the interval [icid-base, icid-base + length) is
> +  associated with the listed GIC ITS, with the iommu-specifier
> +  (i - icid-base + iommu-base).
>  Example:
>
>          smmu: iommu@5000000 {
> @@ -128,6 +140,16 @@ Example:
>                 ...
>          };
>
> +       gic: interrupt-controller@6000000 {
> +               compatible = "arm,gic-v3";
> +               ...
> +               its: gic-its@6020000 {
> +                       compatible = "arm,gic-v3-its";
> +                       msi-controller;
> +                       ...
> +               };
> +       };
> +
>          fsl_mc: fsl-mc@80c000000 {
>                  compatible = "fsl,qoriq-mc";
>                  reg = <0x00000008 0x0c000000 0 0x40>,    /* MC portal base */
> @@ -135,6 +157,8 @@ Example:
>                  msi-parent = <&its>;
>                  /* define map for ICIDs 23-64 */
>                  iommu-map = <23 &smmu 23 41>;
> +                /* define msi map for ICIDs 23-64 */
> +                msi-map = <23 &its 23 41>;

Seeing 23 twice is odd. The numbers to the right of 'its' should be an
ITS number space.

>                  #address-cells = <3>;
>                  #size-cells = <1>;
>
> --
> 2.26.1
>

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

* Re: [PATCH 10/12] of/irq: Make of_msi_map_rid() PCI bus agnostic
  2020-05-21 13:00 ` [PATCH 10/12] of/irq: Make of_msi_map_rid() PCI bus agnostic Lorenzo Pieralisi
@ 2020-05-21 23:17   ` Rob Herring
  2020-06-04 15:08     ` Lorenzo Pieralisi
  0 siblings, 1 reply; 31+ messages in thread
From: Rob Herring @ 2020-05-21 23:17 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Marc Zyngier, Linux IOMMU, linux-acpi, devicetree, PCI,
	Rafael J. Wysocki, Joerg Roedel, Hanjun Guo, Bjorn Helgaas,
	Sudeep Holla, Robin Murphy, Catalin Marinas, Will Deacon,
	Makarand Pawagi, Diana Craciun, Laurentiu Tudor

On Thu, May 21, 2020 at 7:00 AM Lorenzo Pieralisi
<lorenzo.pieralisi@arm.com> wrote:
>
> There is nothing PCI bus specific in the of_msi_map_rid()
> implementation other than the requester ID tag for the input
> ID space. Rename requester ID to a more generic ID so that
> the translation code can be used by all busses that require
> input/output ID translations.
>
> Leave a wrapper function of_msi_map_rid() in place to keep
> existing PCI code mapping requester ID syntactically unchanged.
>
> No functional change intended.
>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Marc Zyngier <maz@kernel.org>
> ---
>  drivers/of/irq.c       | 28 ++++++++++++++--------------
>  include/linux/of_irq.h | 14 ++++++++++++--
>  2 files changed, 26 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/of/irq.c b/drivers/of/irq.c
> index 48a40326984f..25d17b8a1a1a 100644
> --- a/drivers/of/irq.c
> +++ b/drivers/of/irq.c
> @@ -576,43 +576,43 @@ void __init of_irq_init(const struct of_device_id *matches)
>         }
>  }
>
> -static u32 __of_msi_map_rid(struct device *dev, struct device_node **np,
> -                           u32 rid_in)
> +static u32 __of_msi_map_id(struct device *dev, struct device_node **np,
> +                           u32 id_in)
>  {
>         struct device *parent_dev;
> -       u32 rid_out = rid_in;
> +       u32 id_out = id_in;
>
>         /*
>          * 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 (!of_map_rid(parent_dev->of_node, rid_in, "msi-map",
> -                               "msi-map-mask", np, &rid_out))
> +               if (!of_map_id(parent_dev->of_node, id_in, "msi-map",
> +                               "msi-map-mask", np, &id_out))
>                         break;
> -       return rid_out;
> +       return id_out;
>  }
>
>  /**
> - * of_msi_map_rid - Map a MSI requester ID for a device.
> + * of_msi_map_id - Map a MSI 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.
> + * @id_in: unmapped MSI 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.
> + * property.  If found, apply the mapping to @id_in.
>   *
> - * Returns the mapped MSI requester ID.
> + * Returns the mapped MSI ID.
>   */
> -u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in)
> +u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in)
>  {
> -       return __of_msi_map_rid(dev, &msi_np, rid_in);
> +       return __of_msi_map_id(dev, &msi_np, id_in);
>  }
>
>  /**
>   * 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.
> + * @id: Device ID.
>   * @bus_token: Bus token
>   *
>   * Walk up the device hierarchy looking for devices with a "msi-map"
> @@ -625,7 +625,7 @@ struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 id,
>  {
>         struct device_node *np = NULL;
>
> -       __of_msi_map_rid(dev, &np, id);
> +       __of_msi_map_id(dev, &np, id);
>         return irq_find_matching_host(np, bus_token);
>  }
>
> diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
> index 7142a3722758..cf9cb1e545ce 100644
> --- a/include/linux/of_irq.h
> +++ b/include/linux/of_irq.h
> @@ -55,7 +55,12 @@ extern struct irq_domain *of_msi_map_get_device_domain(struct device *dev,
>                                                         u32 id,
>                                                         u32 bus_token);
>  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);
> +u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in);
> +static inline u32 of_msi_map_rid(struct device *dev,
> +                                struct device_node *msi_np, u32 rid_in)
> +{
> +       return of_msi_map_id(dev, msi_np, rid_in);
> +}
>  #else
>  static inline int of_irq_count(struct device_node *dev)
>  {
> @@ -93,10 +98,15 @@ static inline struct irq_domain *of_msi_map_get_device_domain(struct device *dev
>  static inline void of_msi_configure(struct device *dev, struct device_node *np)
>  {
>  }
> +static inline u32 of_msi_map_id(struct device *dev,
> +                                struct device_node *msi_np, u32 id_in)
> +{
> +       return id_in;
> +}
>  static inline u32 of_msi_map_rid(struct device *dev,
>                                  struct device_node *msi_np, u32 rid_in)

Move this out of the ifdef and you only need it declared once.

But again, I think I'd just kill of_msi_map_rid.

>  {
> -       return rid_in;
> +       return of_msi_map_id(dev, msi_np, rid_in);
>  }
>  #endif
>
> --
> 2.26.1
>

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

* RE: [PATCH 12/12] bus: fsl-mc: Add ACPI support for fsl-mc
  2020-05-21 15:03   ` Laurentiu Tudor
@ 2020-05-22  5:32     ` Makarand Pawagi
  2020-05-22  9:53       ` Lorenzo Pieralisi
  0 siblings, 1 reply; 31+ messages in thread
From: Makarand Pawagi @ 2020-05-22  5:32 UTC (permalink / raw)
  To: Laurentiu Tudor, Lorenzo Pieralisi, linux-arm-kernel
  Cc: Diana Madalina Craciun (OSS),
	iommu, linux-acpi, devicetree, linux-pci, Rob Herring,
	Rafael J. Wysocki, Joerg Roedel, Hanjun Guo, Bjorn Helgaas,
	Sudeep Holla, Robin Murphy, Catalin Marinas, Will Deacon,
	Marc Zyngier

Hi Lorenzo,

> -----Original Message-----
> From: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> Sent: Thursday, May 21, 2020 8:33 PM
> To: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>; linux-arm-
> kernel@lists.infradead.org
> Cc: Diana Madalina Craciun (OSS) <diana.craciun@oss.nxp.com>; Makarand
> Pawagi <makarand.pawagi@nxp.com>; iommu@lists.linux-foundation.org;
> linux-acpi@vger.kernel.org; devicetree@vger.kernel.org; linux-
> pci@vger.kernel.org; Rob Herring <robh+dt@kernel.org>; Rafael J. Wysocki
> <rjw@rjwysocki.net>; Joerg Roedel <joro@8bytes.org>; Hanjun Guo
> <guohanjun@huawei.com>; Bjorn Helgaas <bhelgaas@google.com>; Sudeep
> Holla <sudeep.holla@arm.com>; Robin Murphy <robin.murphy@arm.com>;
> Catalin Marinas <catalin.marinas@arm.com>; Will Deacon <will@kernel.org>;
> Marc Zyngier <maz@kernel.org>
> Subject: Re: [PATCH 12/12] bus: fsl-mc: Add ACPI support for fsl-mc
> 
> Hi Lorenzo,
> 
> On 5/21/2020 4:00 PM, Lorenzo Pieralisi wrote:
> > From: Diana Craciun <diana.craciun@oss.nxp.com>
> >
> > Add ACPI support in the fsl-mc driver. Driver parses MC DSDT table to
> > extract memory and other resources.
> >
> > Interrupt (GIC ITS) information is extracted from the MADT table by
> > drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c.
> >
> > IORT table is parsed to configure DMA.
> >
> > Signed-off-by: Makarand Pawagi <makarand.pawagi@nxp.com>
> > Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
> > Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> > ---
> 
> The author of this patch should be Makarand. I think I accidentaly broke it when
> we exchanged the patches. Very sorry about it.
> 
 
Will you be able to correct this or should I post another patch?

> ---
> Best Regards, Laurentiu
> 
> 
> >  drivers/bus/fsl-mc/fsl-mc-bus.c             | 73 +++++++++++++++-----
> >  drivers/bus/fsl-mc/fsl-mc-msi.c             | 37 +++++-----
> >  drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c | 75
> > ++++++++++++++++++++-
> >  3 files changed, 150 insertions(+), 35 deletions(-)
> >
> > diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c
> > b/drivers/bus/fsl-mc/fsl-mc-bus.c index 824ff77bbe86..324d49d6df89
> > 100644
> > --- a/drivers/bus/fsl-mc/fsl-mc-bus.c
> > +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
> > @@ -18,6 +18,8 @@
> >  #include <linux/bitops.h>
> >  #include <linux/msi.h>
> >  #include <linux/dma-mapping.h>
> > +#include <linux/acpi.h>
> > +#include <linux/iommu.h>
> >
> >  #include "fsl-mc-private.h"
> >
> > @@ -38,6 +40,7 @@ struct fsl_mc {
> >  	struct fsl_mc_device *root_mc_bus_dev;
> >  	u8 num_translation_ranges;
> >  	struct fsl_mc_addr_translation_range *translation_ranges;
> > +	void *fsl_mc_regs;
> >  };
> >
> >  /**
> > @@ -56,6 +59,10 @@ struct fsl_mc_addr_translation_range {
> >  	phys_addr_t start_phys_addr;
> >  };
> >
> > +#define FSL_MC_FAPR	0x28
> > +#define MC_FAPR_PL	BIT(18)
> > +#define MC_FAPR_BMT	BIT(17)
> > +
> >  /**
> >   * fsl_mc_bus_match - device to driver matching callback
> >   * @dev: the fsl-mc device to match against @@ -124,7 +131,10 @@
> > static int fsl_mc_dma_configure(struct device *dev)
> >  	while (dev_is_fsl_mc(dma_dev))
> >  		dma_dev = dma_dev->parent;
> >
> > -	return of_dma_configure_id(dev, dma_dev->of_node, 0, &input_id);
> > +	if (dev_of_node(dma_dev))
> > +		return of_dma_configure_id(dev, dma_dev->of_node, 0,
> &input_id);
> > +
> > +	return acpi_dma_configure_id(dev, DEV_DMA_COHERENT, &input_id);
> >  }
> >
> >  static ssize_t modalias_show(struct device *dev, struct
> > device_attribute *attr, @@ -865,8 +875,11 @@ static int
> fsl_mc_bus_probe(struct platform_device *pdev)
> >  	struct fsl_mc_io *mc_io = NULL;
> >  	int container_id;
> >  	phys_addr_t mc_portal_phys_addr;
> > -	u32 mc_portal_size;
> > -	struct resource res;
> > +	u32 mc_portal_size, mc_stream_id;
> > +	struct resource *plat_res;
> > +
> > +	if (!iommu_present(&fsl_mc_bus_type))
> > +		return -EPROBE_DEFER;
> >
> >  	mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
> >  	if (!mc)
> > @@ -874,19 +887,33 @@ static int fsl_mc_bus_probe(struct
> > platform_device *pdev)
> >
> >  	platform_set_drvdata(pdev, mc);
> >
> > +	plat_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> > +	mc->fsl_mc_regs = devm_ioremap_resource(&pdev->dev, plat_res);
> > +	if (IS_ERR(mc->fsl_mc_regs))
> > +		return PTR_ERR(mc->fsl_mc_regs);
> > +
> > +	if (IS_ENABLED(CONFIG_ACPI) && !dev_of_node(&pdev->dev)) {
> > +		mc_stream_id = readl(mc->fsl_mc_regs + FSL_MC_FAPR);
> > +		/*
> > +		 * HW ORs the PL and BMT bit, places the result in bit 15 of
> > +		 * the StreamID and ORs in the ICID. Calculate it accordingly.
> > +		 */
> > +		mc_stream_id = (mc_stream_id & 0xffff) |
> > +				((mc_stream_id & (MC_FAPR_PL |
> MC_FAPR_BMT)) ?
> > +					0x4000 : 0);
> > +		error = acpi_dma_configure_id(&pdev->dev,
> DEV_DMA_COHERENT,
> > +					      &mc_stream_id);
> > +		if (error)
> > +			dev_warn(&pdev->dev, "failed to configure
> dma: %d.\n",
> > +				 error);
> > +	}
> > +
> >  	/*
> >  	 * Get physical address of MC portal for the root DPRC:
> >  	 */
> > -	error = of_address_to_resource(pdev->dev.of_node, 0, &res);
> > -	if (error < 0) {
> > -		dev_err(&pdev->dev,
> > -			"of_address_to_resource() failed for %pOF\n",
> > -			pdev->dev.of_node);
> > -		return error;
> > -	}
> > -
> > -	mc_portal_phys_addr = res.start;
> > -	mc_portal_size = resource_size(&res);
> > +	plat_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +	mc_portal_phys_addr = plat_res->start;
> > +	mc_portal_size = resource_size(plat_res);
> >  	error = fsl_create_mc_io(&pdev->dev, mc_portal_phys_addr,
> >  				 mc_portal_size, NULL,
> >  				 FSL_MC_IO_ATOMIC_CONTEXT_PORTAL,
> &mc_io); @@ -903,11 +930,13 @@
> > static int fsl_mc_bus_probe(struct platform_device *pdev)
> >  	dev_info(&pdev->dev, "MC firmware version: %u.%u.%u\n",
> >  		 mc_version.major, mc_version.minor, mc_version.revision);
> >
> > -	error = get_mc_addr_translation_ranges(&pdev->dev,
> > -					       &mc->translation_ranges,
> > -					       &mc->num_translation_ranges);
> > -	if (error < 0)
> > -		goto error_cleanup_mc_io;
> > +	if (dev_of_node(&pdev->dev)) {
> > +		error = get_mc_addr_translation_ranges(&pdev->dev,
> > +						&mc->translation_ranges,
> > +						&mc-
> >num_translation_ranges);
> > +		if (error < 0)
> > +			goto error_cleanup_mc_io;
> > +	}
> >
> >  	error = dprc_get_container_id(mc_io, 0, &container_id);
> >  	if (error < 0) {
> > @@ -934,6 +963,7 @@ static int fsl_mc_bus_probe(struct platform_device
> *pdev)
> >  		goto error_cleanup_mc_io;
> >
> >  	mc->root_mc_bus_dev = mc_bus_dev;
> > +	mc_bus_dev->dev.fwnode = pdev->dev.fwnode;
> >  	return 0;
> >
> >  error_cleanup_mc_io:
> > @@ -967,11 +997,18 @@ static const struct of_device_id
> > fsl_mc_bus_match_table[] = {
> >
> >  MODULE_DEVICE_TABLE(of, fsl_mc_bus_match_table);
> >
> > +static const struct acpi_device_id fsl_mc_bus_acpi_match_table[] = {
> > +	{"NXP0008", 0 },
> > +	{ }
> > +};
> > +MODULE_DEVICE_TABLE(acpi, fsl_mc_bus_acpi_match_table);
> > +
> >  static struct platform_driver fsl_mc_bus_driver = {
> >  	.driver = {
> >  		   .name = "fsl_mc_bus",
> >  		   .pm = NULL,
> >  		   .of_match_table = fsl_mc_bus_match_table,
> > +		   .acpi_match_table = fsl_mc_bus_acpi_match_table,
> >  		   },
> >  	.probe = fsl_mc_bus_probe,
> >  	.remove = fsl_mc_bus_remove,
> > diff --git a/drivers/bus/fsl-mc/fsl-mc-msi.c
> > b/drivers/bus/fsl-mc/fsl-mc-msi.c index e7bbff445a83..8edadf05cbb7
> > 100644
> > --- a/drivers/bus/fsl-mc/fsl-mc-msi.c
> > +++ b/drivers/bus/fsl-mc/fsl-mc-msi.c
> > @@ -13,6 +13,7 @@
> >  #include <linux/irq.h>
> >  #include <linux/irqdomain.h>
> >  #include <linux/msi.h>
> > +#include <linux/acpi_iort.h>
> >
> >  #include "fsl-mc-private.h"
> >
> > @@ -179,25 +180,31 @@ struct irq_domain
> > *fsl_mc_msi_create_irq_domain(struct fwnode_handle *fwnode,
> >
> >  struct irq_domain *fsl_mc_find_msi_domain(struct device *dev)  {
> > -	struct irq_domain *msi_domain = NULL;
> > +	struct device *root_dprc_dev;
> > +	struct device *bus_dev;
> > +	struct irq_domain *msi_domain;
> >  	struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
> >
> > -	msi_domain = of_msi_map_get_device_domain(dev, mc_dev->icid,
> > +	fsl_mc_get_root_dprc(dev, &root_dprc_dev);
> > +	bus_dev = root_dprc_dev->parent;
> > +
> > +	if (bus_dev->of_node) {
> > +		msi_domain = of_msi_map_get_device_domain(dev,
> > +						  mc_dev->icid,
> >  						  DOMAIN_BUS_FSL_MC_MSI);
> >
> > -	/*
> > -	 * if the msi-map property is missing assume that all the
> > -	 * child containers inherit the domain from the parent
> > -	 */
> > -	if (!msi_domain) {
> > -		struct device *root_dprc_dev;
> > -		struct device *bus_dev;
> > -
> > -		fsl_mc_get_root_dprc(dev, &root_dprc_dev);
> > -		bus_dev = root_dprc_dev->parent;
> > -		msi_domain = of_msi_get_domain(bus_dev,
> > -					       bus_dev->of_node,
> > -					       DOMAIN_BUS_FSL_MC_MSI);
> > +		/*
> > +		 * if the msi-map property is missing assume that all the
> > +		 * child containers inherit the domain from the parent
> > +		 */
> > +		if (!msi_domain)
> > +
> > +			msi_domain = of_msi_get_domain(bus_dev,
> > +						bus_dev->of_node,
> > +						DOMAIN_BUS_FSL_MC_MSI);
> > +	} else {
> > +		msi_domain = iort_get_device_domain(dev, mc_dev->icid,
> > +
> DOMAIN_BUS_FSL_MC_MSI);
> >  	}
> >
> >  	return msi_domain;
> > diff --git a/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
> > b/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
> > index a5c8d577e424..b8b948fb6b2d 100644
> > --- a/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
> > +++ b/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
> > @@ -7,6 +7,8 @@
> >   *
> >   */
> >
> > +#include <linux/acpi.h>
> > +#include <linux/acpi_iort.h>
> >  #include <linux/of_device.h>
> >  #include <linux/of_address.h>
> >  #include <linux/irq.h>
> > @@ -30,7 +32,8 @@ static u32 fsl_mc_msi_domain_get_msi_id(struct
> irq_domain *domain,
> >  	u32 out_id;
> >
> >  	of_node = irq_domain_get_of_node(domain);
> > -	out_id = of_msi_map_id(&mc_dev->dev, of_node, mc_dev->icid);
> > +	out_id = of_node ? of_msi_map_id(&mc_dev->dev, of_node, mc_dev-
> >icid) :
> > +			iort_msi_map_id(&mc_dev->dev, mc_dev->icid);
> >
> >  	return out_id;
> >  }
> > @@ -79,7 +82,67 @@ static const struct of_device_id its_device_id[] = {
> >  	{},
> >  };
> >
> > -static int __init its_fsl_mc_msi_init(void)
> > +static int __init its_fsl_mc_msi_init_one(struct fwnode_handle *handle,
> > +					  const char *name)
> > +{
> > +	struct irq_domain *parent;
> > +	struct irq_domain *mc_msi_domain;
> > +
> > +	parent = irq_find_matching_fwnode(handle, DOMAIN_BUS_NEXUS);
> > +	if (!parent || !msi_get_domain_info(parent)) {
> > +		pr_err("%s: Unable to locate ITS domain\n", name);
> > +		return -ENXIO;
> > +	}
> > +
> > +	mc_msi_domain = fsl_mc_msi_create_irq_domain(handle,
> > +						&its_fsl_mc_msi_domain_info,
> > +						parent);
> > +	if (!mc_msi_domain)
> > +		pr_err("ACPIF: unable to create fsl-mc domain\n");
> > +
> > +	pr_info("fsl-mc MSI: domain created\n");
> > +
> > +	return 0;
> > +}
> > +
> > +static int __init
> > +its_fsl_mc_msi_parse_madt(union acpi_subtable_headers *header,
> > +			  const unsigned long end)
> > +{
> > +	struct acpi_madt_generic_translator *its_entry;
> > +	struct fwnode_handle *dom_handle;
> > +	const char *node_name;
> > +	int err = -ENXIO;
> > +
> > +	its_entry = (struct acpi_madt_generic_translator *)header;
> > +	node_name = kasprintf(GFP_KERNEL, "ITS@0x%lx",
> > +			      (long)its_entry->base_address);
> > +
> > +	dom_handle = iort_find_domain_token(its_entry->translation_id);
> > +	if (!dom_handle) {
> > +		pr_err("%s: Unable to locate ITS domain handle\n",
> node_name);
> > +		goto out;
> > +	}
> > +
> > +	err = its_fsl_mc_msi_init_one(dom_handle, node_name);
> > +	if (!err)
> > +		pr_info("fsl-mc MSI: %s domain created\n", node_name);
> > +
> > +out:
> > +	kfree(node_name);
> > +	return err;
> > +}
> > +
> > +
> > +static int __init its_fsl_mc_acpi_msi_init(void) {
> > +	acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
> > +			      its_fsl_mc_msi_parse_madt, 0);
> > +
> > +	return 0;
> > +}
> > +
> > +static int __init its_fsl_mc_of_msi_init(void)
> >  {
> >  	struct device_node *np;
> >  	struct irq_domain *parent;
> > @@ -113,4 +176,12 @@ static int __init its_fsl_mc_msi_init(void)
> >  	return 0;
> >  }
> >
> > +static int __init its_fsl_mc_msi_init(void) {
> > +	its_fsl_mc_of_msi_init();
> > +	its_fsl_mc_acpi_msi_init();
> > +
> > +	return 0;
> > +}
> > +
> >  early_initcall(its_fsl_mc_msi_init);
> >

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

* Re: [PATCH 09/12] dt-bindings: arm: fsl: Add msi-map device-tree binding for fsl-mc bus
  2020-05-21 23:10   ` Rob Herring
@ 2020-05-22  9:42     ` Robin Murphy
  2020-05-22  9:57       ` Diana Craciun OSS
  2020-05-22 14:02       ` Rob Herring
  0 siblings, 2 replies; 31+ messages in thread
From: Robin Murphy @ 2020-05-22  9:42 UTC (permalink / raw)
  To: Rob Herring, Lorenzo Pieralisi
  Cc: devicetree, Catalin Marinas, Will Deacon, Diana Craciun, PCI,
	Sudeep Holla, Rafael J. Wysocki, Makarand Pawagi, linux-acpi,
	Linux IOMMU, Marc Zyngier, Hanjun Guo, Bjorn Helgaas,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE

On 2020-05-22 00:10, Rob Herring wrote:
> On Thu, May 21, 2020 at 7:00 AM Lorenzo Pieralisi
> <lorenzo.pieralisi@arm.com> wrote:
>>
>> From: Laurentiu Tudor <laurentiu.tudor@nxp.com>
>>
>> The existing bindings cannot be used to specify the relationship
>> between fsl-mc devices and GIC ITSes.
>>
>> Add a generic binding for mapping fsl-mc devices to GIC ITSes, using
>> msi-map property.
>>
>> Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
>> Cc: Rob Herring <robh+dt@kernel.org>
>> ---
>>   .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 30 +++++++++++++++++--
>>   1 file changed, 27 insertions(+), 3 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
>> index 9134e9bcca56..b0813b2d0493 100644
>> --- a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
>> +++ b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
>> @@ -18,9 +18,9 @@ same hardware "isolation context" and a 10-bit value called an ICID
>>   the requester.
>>
>>   The generic 'iommus' property is insufficient to describe the relationship
>> -between ICIDs and IOMMUs, so an iommu-map property is used to define
>> -the set of possible ICIDs under a root DPRC and how they map to
>> -an IOMMU.
>> +between ICIDs and IOMMUs, so the iommu-map and msi-map properties are used
>> +to define the set of possible ICIDs under a root DPRC and how they map to
>> +an IOMMU and a GIC ITS respectively.
>>
>>   For generic IOMMU bindings, see
>>   Documentation/devicetree/bindings/iommu/iommu.txt.
>> @@ -28,6 +28,9 @@ Documentation/devicetree/bindings/iommu/iommu.txt.
>>   For arm-smmu binding, see:
>>   Documentation/devicetree/bindings/iommu/arm,smmu.yaml.
>>
>> +For GICv3 and GIC ITS bindings, see:
>> +Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml.
>> +
>>   Required properties:
>>
>>       - compatible
>> @@ -119,6 +122,15 @@ Optional properties:
>>     associated with the listed IOMMU, with the iommu-specifier
>>     (i - icid-base + iommu-base).
>>
>> +- msi-map: Maps an ICID to a GIC ITS and associated iommu-specifier
>> +  data.
>> +
>> +  The property is an arbitrary number of tuples of
>> +  (icid-base,iommu,iommu-base,length).
> 
> I'm confused because the example has GIC ITS phandle, not an IOMMU.
> 
> What is an iommu-base?

Right, I was already halfway through writing a reply to say that all the 
copy-pasted "iommu" references here should be using the terminology from 
the pci-msi.txt binding instead.

>> +
>> +  Any ICID in the interval [icid-base, icid-base + length) is
>> +  associated with the listed GIC ITS, with the iommu-specifier
>> +  (i - icid-base + iommu-base).
>>   Example:
>>
>>           smmu: iommu@5000000 {
>> @@ -128,6 +140,16 @@ Example:
>>                  ...
>>           };
>>
>> +       gic: interrupt-controller@6000000 {
>> +               compatible = "arm,gic-v3";
>> +               ...
>> +               its: gic-its@6020000 {
>> +                       compatible = "arm,gic-v3-its";
>> +                       msi-controller;
>> +                       ...
>> +               };
>> +       };
>> +
>>           fsl_mc: fsl-mc@80c000000 {
>>                   compatible = "fsl,qoriq-mc";
>>                   reg = <0x00000008 0x0c000000 0 0x40>,    /* MC portal base */
>> @@ -135,6 +157,8 @@ Example:
>>                   msi-parent = <&its>;

Side note: is it right to keep msi-parent here? It rather implies that 
the MC itself has a 'native' Device ID rather than an ICID, which I 
believe is not strictly true. Plus it's extra-confusing that it doesn't 
specify an ID either way, since that makes it look like the legacy PCI 
case that gets treated implicitly as an identity msi-map, which makes no 
sense at all to combine with an actual msi-map.

>>                   /* define map for ICIDs 23-64 */
>>                   iommu-map = <23 &smmu 23 41>;
>> +                /* define msi map for ICIDs 23-64 */
>> +                msi-map = <23 &its 23 41>;
> 
> Seeing 23 twice is odd. The numbers to the right of 'its' should be an
> ITS number space.

On about 99% of systems the values in the SMMU Stream ID and ITS Device 
ID spaces are going to be the same. Nobody's going to bother carrying 
*two* sets of sideband data across the interconnect if they don't have to ;)

Robin.

>>                   #address-cells = <3>;
>>                   #size-cells = <1>;
>>
>> --
>> 2.26.1
>>
> _______________________________________________
> iommu mailing list
> iommu@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu
> 

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

* Re: [PATCH 12/12] bus: fsl-mc: Add ACPI support for fsl-mc
  2020-05-22  5:32     ` Makarand Pawagi
@ 2020-05-22  9:53       ` Lorenzo Pieralisi
  0 siblings, 0 replies; 31+ messages in thread
From: Lorenzo Pieralisi @ 2020-05-22  9:53 UTC (permalink / raw)
  To: Makarand Pawagi
  Cc: Laurentiu Tudor, linux-arm-kernel, Diana Madalina Craciun (OSS),
	iommu, linux-acpi, devicetree, linux-pci, Rob Herring,
	Rafael J. Wysocki, Joerg Roedel, Hanjun Guo, Bjorn Helgaas,
	Sudeep Holla, Robin Murphy, Catalin Marinas, Will Deacon,
	Marc Zyngier

On Fri, May 22, 2020 at 05:32:02AM +0000, Makarand Pawagi wrote:

[...]

> > Subject: Re: [PATCH 12/12] bus: fsl-mc: Add ACPI support for fsl-mc
> > 
> > Hi Lorenzo,
> > 
> > On 5/21/2020 4:00 PM, Lorenzo Pieralisi wrote:
> > > From: Diana Craciun <diana.craciun@oss.nxp.com>
> > >
> > > Add ACPI support in the fsl-mc driver. Driver parses MC DSDT table to
> > > extract memory and other resources.
> > >
> > > Interrupt (GIC ITS) information is extracted from the MADT table by
> > > drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c.
> > >
> > > IORT table is parsed to configure DMA.
> > >
> > > Signed-off-by: Makarand Pawagi <makarand.pawagi@nxp.com>
> > > Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
> > > Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> > > ---
> > 
> > The author of this patch should be Makarand. I think I accidentaly broke it when
> > we exchanged the patches. Very sorry about it.
> > 
>  
> Will you be able to correct this or should I post another patch?

I will update it.

Lorenzo

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

* Re: [PATCH 09/12] dt-bindings: arm: fsl: Add msi-map device-tree binding for fsl-mc bus
  2020-05-22  9:42     ` Robin Murphy
@ 2020-05-22  9:57       ` Diana Craciun OSS
  2020-05-22 14:08         ` Rob Herring
  2020-05-22 14:02       ` Rob Herring
  1 sibling, 1 reply; 31+ messages in thread
From: Diana Craciun OSS @ 2020-05-22  9:57 UTC (permalink / raw)
  To: Robin Murphy, Rob Herring, Lorenzo Pieralisi
  Cc: devicetree, Catalin Marinas, Will Deacon, PCI, Sudeep Holla,
	Rafael J. Wysocki, Makarand Pawagi, linux-acpi, Linux IOMMU,
	Marc Zyngier, Hanjun Guo, Bjorn Helgaas,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE

On 5/22/2020 12:42 PM, Robin Murphy wrote:
> On 2020-05-22 00:10, Rob Herring wrote:
>> On Thu, May 21, 2020 at 7:00 AM Lorenzo Pieralisi
>> <lorenzo.pieralisi@arm.com> wrote:
>>>
>>> From: Laurentiu Tudor <laurentiu.tudor@nxp.com>
>>>
>>> The existing bindings cannot be used to specify the relationship
>>> between fsl-mc devices and GIC ITSes.
>>>
>>> Add a generic binding for mapping fsl-mc devices to GIC ITSes, using
>>> msi-map property.
>>>
>>> Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
>>> Cc: Rob Herring <robh+dt@kernel.org>
>>> ---
>>>   .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 30 
>>> +++++++++++++++++--
>>>   1 file changed, 27 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt 
>>> b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
>>> index 9134e9bcca56..b0813b2d0493 100644
>>> --- a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
>>> +++ b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
>>> @@ -18,9 +18,9 @@ same hardware "isolation context" and a 10-bit 
>>> value called an ICID
>>>   the requester.
>>>
>>>   The generic 'iommus' property is insufficient to describe the 
>>> relationship
>>> -between ICIDs and IOMMUs, so an iommu-map property is used to define
>>> -the set of possible ICIDs under a root DPRC and how they map to
>>> -an IOMMU.
>>> +between ICIDs and IOMMUs, so the iommu-map and msi-map properties 
>>> are used
>>> +to define the set of possible ICIDs under a root DPRC and how they 
>>> map to
>>> +an IOMMU and a GIC ITS respectively.
>>>
>>>   For generic IOMMU bindings, see
>>>   Documentation/devicetree/bindings/iommu/iommu.txt.
>>> @@ -28,6 +28,9 @@ Documentation/devicetree/bindings/iommu/iommu.txt.
>>>   For arm-smmu binding, see:
>>>   Documentation/devicetree/bindings/iommu/arm,smmu.yaml.
>>>
>>> +For GICv3 and GIC ITS bindings, see:
>>> +Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml. 
>>>
>>> +
>>>   Required properties:
>>>
>>>       - compatible
>>> @@ -119,6 +122,15 @@ Optional properties:
>>>     associated with the listed IOMMU, with the iommu-specifier
>>>     (i - icid-base + iommu-base).
>>>
>>> +- msi-map: Maps an ICID to a GIC ITS and associated iommu-specifier
>>> +  data.
>>> +
>>> +  The property is an arbitrary number of tuples of
>>> +  (icid-base,iommu,iommu-base,length).
>>
>> I'm confused because the example has GIC ITS phandle, not an IOMMU.
>>
>> What is an iommu-base?
>
> Right, I was already halfway through writing a reply to say that all 
> the copy-pasted "iommu" references here should be using the 
> terminology from the pci-msi.txt binding instead.

Right, will change it.

>
>>> +
>>> +  Any ICID in the interval [icid-base, icid-base + length) is
>>> +  associated with the listed GIC ITS, with the iommu-specifier
>>> +  (i - icid-base + iommu-base).
>>>   Example:
>>>
>>>           smmu: iommu@5000000 {
>>> @@ -128,6 +140,16 @@ Example:
>>>                  ...
>>>           };
>>>
>>> +       gic: interrupt-controller@6000000 {
>>> +               compatible = "arm,gic-v3";
>>> +               ...
>>> +               its: gic-its@6020000 {
>>> +                       compatible = "arm,gic-v3-its";
>>> +                       msi-controller;
>>> +                       ...
>>> +               };
>>> +       };
>>> +
>>>           fsl_mc: fsl-mc@80c000000 {
>>>                   compatible = "fsl,qoriq-mc";
>>>                   reg = <0x00000008 0x0c000000 0 0x40>,    /* MC 
>>> portal base */
>>> @@ -135,6 +157,8 @@ Example:
>>>                   msi-parent = <&its>;
>
> Side note: is it right to keep msi-parent here? It rather implies that 
> the MC itself has a 'native' Device ID rather than an ICID, which I 
> believe is not strictly true. Plus it's extra-confusing that it 
> doesn't specify an ID either way, since that makes it look like the 
> legacy PCI case that gets treated implicitly as an identity msi-map, 
> which makes no sense at all to combine with an actual msi-map.

Before adding msi-map, the fsl-mc code assumed that ICID and streamID 
are equal and used msi-parent just to get the reference to the ITS node. 
Removing msi-parent will break the backward compatibility of the already 
existing systems. Maybe we should mention that this is legacy and not to 
be used for newer device trees.


>
>>>                   /* define map for ICIDs 23-64 */
>>>                   iommu-map = <23 &smmu 23 41>;
>>> +                /* define msi map for ICIDs 23-64 */
>>> +                msi-map = <23 &its 23 41>;
>>
>> Seeing 23 twice is odd. The numbers to the right of 'its' should be an
>> ITS number space.
>
> On about 99% of systems the values in the SMMU Stream ID and ITS 
> Device ID spaces are going to be the same. Nobody's going to bother 
> carrying *two* sets of sideband data across the interconnect if they 
> don't have to ;)
>
> Robin.

Diana


>
>>>                   #address-cells = <3>;
>>>                   #size-cells = <1>;
>>>
>>> -- 
>>> 2.26.1
>>>
>> _______________________________________________
>> iommu mailing list
>> iommu@lists.linux-foundation.org
>> https://lists.linuxfoundation.org/mailman/listinfo/iommu
>>


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

* Re: [PATCH 09/12] dt-bindings: arm: fsl: Add msi-map device-tree binding for fsl-mc bus
  2020-05-22  9:42     ` Robin Murphy
  2020-05-22  9:57       ` Diana Craciun OSS
@ 2020-05-22 14:02       ` Rob Herring
  2020-05-22 15:38         ` Laurentiu Tudor
  1 sibling, 1 reply; 31+ messages in thread
From: Rob Herring @ 2020-05-22 14:02 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Lorenzo Pieralisi, devicetree, Catalin Marinas, Will Deacon,
	Diana Craciun, PCI, Sudeep Holla, Rafael J. Wysocki,
	Makarand Pawagi, linux-acpi, Linux IOMMU, Marc Zyngier,
	Hanjun Guo, Bjorn Helgaas,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE

On Fri, May 22, 2020 at 3:42 AM Robin Murphy <robin.murphy@arm.com> wrote:
>
> On 2020-05-22 00:10, Rob Herring wrote:
> > On Thu, May 21, 2020 at 7:00 AM Lorenzo Pieralisi
> > <lorenzo.pieralisi@arm.com> wrote:
> >>
> >> From: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> >>
> >> The existing bindings cannot be used to specify the relationship
> >> between fsl-mc devices and GIC ITSes.
> >>
> >> Add a generic binding for mapping fsl-mc devices to GIC ITSes, using
> >> msi-map property.
> >>
> >> Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> >> Cc: Rob Herring <robh+dt@kernel.org>
> >> ---
> >>   .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 30 +++++++++++++++++--
> >>   1 file changed, 27 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
> >> index 9134e9bcca56..b0813b2d0493 100644
> >> --- a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
> >> +++ b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
> >> @@ -18,9 +18,9 @@ same hardware "isolation context" and a 10-bit value called an ICID
> >>   the requester.
> >>
> >>   The generic 'iommus' property is insufficient to describe the relationship
> >> -between ICIDs and IOMMUs, so an iommu-map property is used to define
> >> -the set of possible ICIDs under a root DPRC and how they map to
> >> -an IOMMU.
> >> +between ICIDs and IOMMUs, so the iommu-map and msi-map properties are used
> >> +to define the set of possible ICIDs under a root DPRC and how they map to
> >> +an IOMMU and a GIC ITS respectively.
> >>
> >>   For generic IOMMU bindings, see
> >>   Documentation/devicetree/bindings/iommu/iommu.txt.
> >> @@ -28,6 +28,9 @@ Documentation/devicetree/bindings/iommu/iommu.txt.
> >>   For arm-smmu binding, see:
> >>   Documentation/devicetree/bindings/iommu/arm,smmu.yaml.
> >>
> >> +For GICv3 and GIC ITS bindings, see:
> >> +Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml.
> >> +
> >>   Required properties:
> >>
> >>       - compatible
> >> @@ -119,6 +122,15 @@ Optional properties:
> >>     associated with the listed IOMMU, with the iommu-specifier
> >>     (i - icid-base + iommu-base).
> >>
> >> +- msi-map: Maps an ICID to a GIC ITS and associated iommu-specifier
> >> +  data.
> >> +
> >> +  The property is an arbitrary number of tuples of
> >> +  (icid-base,iommu,iommu-base,length).
> >
> > I'm confused because the example has GIC ITS phandle, not an IOMMU.
> >
> > What is an iommu-base?
>
> Right, I was already halfway through writing a reply to say that all the
> copy-pasted "iommu" references here should be using the terminology from
> the pci-msi.txt binding instead.
>
> >> +
> >> +  Any ICID in the interval [icid-base, icid-base + length) is
> >> +  associated with the listed GIC ITS, with the iommu-specifier
> >> +  (i - icid-base + iommu-base).
> >>   Example:
> >>
> >>           smmu: iommu@5000000 {
> >> @@ -128,6 +140,16 @@ Example:
> >>                  ...
> >>           };
> >>
> >> +       gic: interrupt-controller@6000000 {
> >> +               compatible = "arm,gic-v3";
> >> +               ...
> >> +               its: gic-its@6020000 {
> >> +                       compatible = "arm,gic-v3-its";
> >> +                       msi-controller;
> >> +                       ...
> >> +               };
> >> +       };
> >> +
> >>           fsl_mc: fsl-mc@80c000000 {
> >>                   compatible = "fsl,qoriq-mc";
> >>                   reg = <0x00000008 0x0c000000 0 0x40>,    /* MC portal base */
> >> @@ -135,6 +157,8 @@ Example:
> >>                   msi-parent = <&its>;
>
> Side note: is it right to keep msi-parent here? It rather implies that
> the MC itself has a 'native' Device ID rather than an ICID, which I
> believe is not strictly true. Plus it's extra-confusing that it doesn't
> specify an ID either way, since that makes it look like the legacy PCI
> case that gets treated implicitly as an identity msi-map, which makes no
> sense at all to combine with an actual msi-map.

No, it doesn't make sense from a binding perspective.

>
> >>                   /* define map for ICIDs 23-64 */
> >>                   iommu-map = <23 &smmu 23 41>;
> >> +                /* define msi map for ICIDs 23-64 */
> >> +                msi-map = <23 &its 23 41>;
> >
> > Seeing 23 twice is odd. The numbers to the right of 'its' should be an
> > ITS number space.
>
> On about 99% of systems the values in the SMMU Stream ID and ITS Device
> ID spaces are going to be the same. Nobody's going to bother carrying
> *two* sets of sideband data across the interconnect if they don't have to ;)

I'm referring to the 23 on the left and right, not between the msi and
iommu. If the left and right are the same, then what are we remapping
exactly?

Rob

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

* Re: [PATCH 09/12] dt-bindings: arm: fsl: Add msi-map device-tree binding for fsl-mc bus
  2020-05-22  9:57       ` Diana Craciun OSS
@ 2020-05-22 14:08         ` Rob Herring
  2020-05-22 14:34           ` Robin Murphy
  0 siblings, 1 reply; 31+ messages in thread
From: Rob Herring @ 2020-05-22 14:08 UTC (permalink / raw)
  To: Diana Craciun OSS
  Cc: Robin Murphy, Lorenzo Pieralisi, devicetree, Catalin Marinas,
	Will Deacon, PCI, Sudeep Holla, Rafael J. Wysocki,
	Makarand Pawagi, linux-acpi, Linux IOMMU, Marc Zyngier,
	Hanjun Guo, Bjorn Helgaas,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE

On Fri, May 22, 2020 at 3:57 AM Diana Craciun OSS
<diana.craciun@oss.nxp.com> wrote:
>
> On 5/22/2020 12:42 PM, Robin Murphy wrote:
> > On 2020-05-22 00:10, Rob Herring wrote:
> >> On Thu, May 21, 2020 at 7:00 AM Lorenzo Pieralisi
> >> <lorenzo.pieralisi@arm.com> wrote:
> >>>
> >>> From: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> >>>
> >>> The existing bindings cannot be used to specify the relationship
> >>> between fsl-mc devices and GIC ITSes.
> >>>
> >>> Add a generic binding for mapping fsl-mc devices to GIC ITSes, using
> >>> msi-map property.
> >>>
> >>> Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> >>> Cc: Rob Herring <robh+dt@kernel.org>
> >>> ---
> >>>   .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 30
> >>> +++++++++++++++++--
> >>>   1 file changed, 27 insertions(+), 3 deletions(-)
> >>>
> >>> diff --git a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
> >>> b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
> >>> index 9134e9bcca56..b0813b2d0493 100644
> >>> --- a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
> >>> +++ b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
> >>> @@ -18,9 +18,9 @@ same hardware "isolation context" and a 10-bit
> >>> value called an ICID
> >>>   the requester.
> >>>
> >>>   The generic 'iommus' property is insufficient to describe the
> >>> relationship
> >>> -between ICIDs and IOMMUs, so an iommu-map property is used to define
> >>> -the set of possible ICIDs under a root DPRC and how they map to
> >>> -an IOMMU.
> >>> +between ICIDs and IOMMUs, so the iommu-map and msi-map properties
> >>> are used
> >>> +to define the set of possible ICIDs under a root DPRC and how they
> >>> map to
> >>> +an IOMMU and a GIC ITS respectively.
> >>>
> >>>   For generic IOMMU bindings, see
> >>>   Documentation/devicetree/bindings/iommu/iommu.txt.
> >>> @@ -28,6 +28,9 @@ Documentation/devicetree/bindings/iommu/iommu.txt.
> >>>   For arm-smmu binding, see:
> >>>   Documentation/devicetree/bindings/iommu/arm,smmu.yaml.
> >>>
> >>> +For GICv3 and GIC ITS bindings, see:
> >>> +Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml.
> >>>
> >>> +
> >>>   Required properties:
> >>>
> >>>       - compatible
> >>> @@ -119,6 +122,15 @@ Optional properties:
> >>>     associated with the listed IOMMU, with the iommu-specifier
> >>>     (i - icid-base + iommu-base).
> >>>
> >>> +- msi-map: Maps an ICID to a GIC ITS and associated iommu-specifier
> >>> +  data.
> >>> +
> >>> +  The property is an arbitrary number of tuples of
> >>> +  (icid-base,iommu,iommu-base,length).
> >>
> >> I'm confused because the example has GIC ITS phandle, not an IOMMU.
> >>
> >> What is an iommu-base?
> >
> > Right, I was already halfway through writing a reply to say that all
> > the copy-pasted "iommu" references here should be using the
> > terminology from the pci-msi.txt binding instead.
>
> Right, will change it.
>
> >
> >>> +
> >>> +  Any ICID in the interval [icid-base, icid-base + length) is
> >>> +  associated with the listed GIC ITS, with the iommu-specifier
> >>> +  (i - icid-base + iommu-base).
> >>>   Example:
> >>>
> >>>           smmu: iommu@5000000 {
> >>> @@ -128,6 +140,16 @@ Example:
> >>>                  ...
> >>>           };
> >>>
> >>> +       gic: interrupt-controller@6000000 {
> >>> +               compatible = "arm,gic-v3";
> >>> +               ...
> >>> +               its: gic-its@6020000 {
> >>> +                       compatible = "arm,gic-v3-its";
> >>> +                       msi-controller;
> >>> +                       ...
> >>> +               };
> >>> +       };
> >>> +
> >>>           fsl_mc: fsl-mc@80c000000 {
> >>>                   compatible = "fsl,qoriq-mc";
> >>>                   reg = <0x00000008 0x0c000000 0 0x40>,    /* MC
> >>> portal base */
> >>> @@ -135,6 +157,8 @@ Example:
> >>>                   msi-parent = <&its>;
> >
> > Side note: is it right to keep msi-parent here? It rather implies that
> > the MC itself has a 'native' Device ID rather than an ICID, which I
> > believe is not strictly true. Plus it's extra-confusing that it
> > doesn't specify an ID either way, since that makes it look like the
> > legacy PCI case that gets treated implicitly as an identity msi-map,
> > which makes no sense at all to combine with an actual msi-map.
>
> Before adding msi-map, the fsl-mc code assumed that ICID and streamID
> are equal and used msi-parent just to get the reference to the ITS node.
> Removing msi-parent will break the backward compatibility of the already
> existing systems. Maybe we should mention that this is legacy and not to
> be used for newer device trees.

If ids are 1:1, then the DT should use msi-parent. If there is
remapping, then use msi-map. A given system should use one or the
other. I suppose if some ids are 1:1 and the msi-map was added to add
additional support for ids not 1:1, then you could end up with both.
That's fine in dts files, but examples should reflect the 'right' way.

Rob

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

* Re: [PATCH 09/12] dt-bindings: arm: fsl: Add msi-map device-tree binding for fsl-mc bus
  2020-05-22 14:08         ` Rob Herring
@ 2020-05-22 14:34           ` Robin Murphy
  0 siblings, 0 replies; 31+ messages in thread
From: Robin Murphy @ 2020-05-22 14:34 UTC (permalink / raw)
  To: Rob Herring, Diana Craciun OSS
  Cc: devicetree, Hanjun Guo, Marc Zyngier, Will Deacon, PCI,
	Sudeep Holla, Rafael J. Wysocki, Linux IOMMU, linux-acpi,
	Makarand Pawagi, Catalin Marinas, Bjorn Helgaas,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE

On 2020-05-22 15:08, Rob Herring wrote:
> On Fri, May 22, 2020 at 3:57 AM Diana Craciun OSS
> <diana.craciun@oss.nxp.com> wrote:
>>
>> On 5/22/2020 12:42 PM, Robin Murphy wrote:
>>> On 2020-05-22 00:10, Rob Herring wrote:
>>>> On Thu, May 21, 2020 at 7:00 AM Lorenzo Pieralisi
>>>> <lorenzo.pieralisi@arm.com> wrote:
>>>>>
>>>>> From: Laurentiu Tudor <laurentiu.tudor@nxp.com>
>>>>>
>>>>> The existing bindings cannot be used to specify the relationship
>>>>> between fsl-mc devices and GIC ITSes.
>>>>>
>>>>> Add a generic binding for mapping fsl-mc devices to GIC ITSes, using
>>>>> msi-map property.
>>>>>
>>>>> Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
>>>>> Cc: Rob Herring <robh+dt@kernel.org>
>>>>> ---
>>>>>    .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 30
>>>>> +++++++++++++++++--
>>>>>    1 file changed, 27 insertions(+), 3 deletions(-)
>>>>>
>>>>> diff --git a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
>>>>> b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
>>>>> index 9134e9bcca56..b0813b2d0493 100644
>>>>> --- a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
>>>>> +++ b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
>>>>> @@ -18,9 +18,9 @@ same hardware "isolation context" and a 10-bit
>>>>> value called an ICID
>>>>>    the requester.
>>>>>
>>>>>    The generic 'iommus' property is insufficient to describe the
>>>>> relationship
>>>>> -between ICIDs and IOMMUs, so an iommu-map property is used to define
>>>>> -the set of possible ICIDs under a root DPRC and how they map to
>>>>> -an IOMMU.
>>>>> +between ICIDs and IOMMUs, so the iommu-map and msi-map properties
>>>>> are used
>>>>> +to define the set of possible ICIDs under a root DPRC and how they
>>>>> map to
>>>>> +an IOMMU and a GIC ITS respectively.
>>>>>
>>>>>    For generic IOMMU bindings, see
>>>>>    Documentation/devicetree/bindings/iommu/iommu.txt.
>>>>> @@ -28,6 +28,9 @@ Documentation/devicetree/bindings/iommu/iommu.txt.
>>>>>    For arm-smmu binding, see:
>>>>>    Documentation/devicetree/bindings/iommu/arm,smmu.yaml.
>>>>>
>>>>> +For GICv3 and GIC ITS bindings, see:
>>>>> +Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml.
>>>>>
>>>>> +
>>>>>    Required properties:
>>>>>
>>>>>        - compatible
>>>>> @@ -119,6 +122,15 @@ Optional properties:
>>>>>      associated with the listed IOMMU, with the iommu-specifier
>>>>>      (i - icid-base + iommu-base).
>>>>>
>>>>> +- msi-map: Maps an ICID to a GIC ITS and associated iommu-specifier
>>>>> +  data.
>>>>> +
>>>>> +  The property is an arbitrary number of tuples of
>>>>> +  (icid-base,iommu,iommu-base,length).
>>>>
>>>> I'm confused because the example has GIC ITS phandle, not an IOMMU.
>>>>
>>>> What is an iommu-base?
>>>
>>> Right, I was already halfway through writing a reply to say that all
>>> the copy-pasted "iommu" references here should be using the
>>> terminology from the pci-msi.txt binding instead.
>>
>> Right, will change it.
>>
>>>
>>>>> +
>>>>> +  Any ICID in the interval [icid-base, icid-base + length) is
>>>>> +  associated with the listed GIC ITS, with the iommu-specifier
>>>>> +  (i - icid-base + iommu-base).
>>>>>    Example:
>>>>>
>>>>>            smmu: iommu@5000000 {
>>>>> @@ -128,6 +140,16 @@ Example:
>>>>>                   ...
>>>>>            };
>>>>>
>>>>> +       gic: interrupt-controller@6000000 {
>>>>> +               compatible = "arm,gic-v3";
>>>>> +               ...
>>>>> +               its: gic-its@6020000 {
>>>>> +                       compatible = "arm,gic-v3-its";
>>>>> +                       msi-controller;
>>>>> +                       ...
>>>>> +               };
>>>>> +       };
>>>>> +
>>>>>            fsl_mc: fsl-mc@80c000000 {
>>>>>                    compatible = "fsl,qoriq-mc";
>>>>>                    reg = <0x00000008 0x0c000000 0 0x40>,    /* MC
>>>>> portal base */
>>>>> @@ -135,6 +157,8 @@ Example:
>>>>>                    msi-parent = <&its>;
>>>
>>> Side note: is it right to keep msi-parent here? It rather implies that
>>> the MC itself has a 'native' Device ID rather than an ICID, which I
>>> believe is not strictly true. Plus it's extra-confusing that it
>>> doesn't specify an ID either way, since that makes it look like the
>>> legacy PCI case that gets treated implicitly as an identity msi-map,
>>> which makes no sense at all to combine with an actual msi-map.
>>
>> Before adding msi-map, the fsl-mc code assumed that ICID and streamID
>> are equal and used msi-parent just to get the reference to the ITS node.
>> Removing msi-parent will break the backward compatibility of the already
>> existing systems. Maybe we should mention that this is legacy and not to
>> be used for newer device trees.
> 
> If ids are 1:1, then the DT should use msi-parent. If there is
> remapping, then use msi-map. A given system should use one or the
> other. I suppose if some ids are 1:1 and the msi-map was added to add
> additional support for ids not 1:1, then you could end up with both.
> That's fine in dts files, but examples should reflect the 'right' way.

Is that defined anywhere? The generic MSI binding just has some weaselly 
wording about buses:

"When #msi-cells is non-zero, busses with an msi-parent will require 
additional properties to describe the relationship between devices on 
the bus and the set of MSIs they can potentially generate."

which appears at odds with its own definition of msi-parent as including 
an msi-specifier (or at best very unclear about what value that 
specifier should take in this case).

The PCI MSI binding goes even further and specifically reserves 
msi-parent for cases where there is no sideband data. As far as I'm 
aware, the fact that the ITS driver implements a bodge for the "empty 
msi-parent even though #msi-cells > 0" case is merely a compatibility 
thing for old DTs from before this was really thought through, not an 
officially-specified behaviour.

Robin.

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

* Re: [PATCH 09/12] dt-bindings: arm: fsl: Add msi-map device-tree binding for fsl-mc bus
  2020-05-22 14:02       ` Rob Herring
@ 2020-05-22 15:38         ` Laurentiu Tudor
  0 siblings, 0 replies; 31+ messages in thread
From: Laurentiu Tudor @ 2020-05-22 15:38 UTC (permalink / raw)
  To: Rob Herring, Robin Murphy
  Cc: devicetree, Hanjun Guo, Catalin Marinas, PCI, Sudeep Holla,
	Rafael J. Wysocki, Linux IOMMU, linux-acpi, Makarand Pawagi,
	Marc Zyngier, Diana Craciun, Bjorn Helgaas, Will Deacon,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE

On 5/22/2020 5:02 PM, Rob Herring wrote:
> On Fri, May 22, 2020 at 3:42 AM Robin Murphy <robin.murphy@arm.com> wrote:
>>
>> On 2020-05-22 00:10, Rob Herring wrote:
>>> On Thu, May 21, 2020 at 7:00 AM Lorenzo Pieralisi
>>> <lorenzo.pieralisi@arm.com> wrote:
>>>>
>>>> From: Laurentiu Tudor <laurentiu.tudor@nxp.com>
>>>>
>>>> The existing bindings cannot be used to specify the relationship
>>>> between fsl-mc devices and GIC ITSes.
>>>>
>>>> Add a generic binding for mapping fsl-mc devices to GIC ITSes, using
>>>> msi-map property.
>>>>
>>>> Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
>>>> Cc: Rob Herring <robh+dt@kernel.org>
>>>> ---
>>>>   .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 30 +++++++++++++++++--
>>>>   1 file changed, 27 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
>>>> index 9134e9bcca56..b0813b2d0493 100644
>>>> --- a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
>>>> +++ b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
>>>> @@ -18,9 +18,9 @@ same hardware "isolation context" and a 10-bit value called an ICID
>>>>   the requester.
>>>>
>>>>   The generic 'iommus' property is insufficient to describe the relationship
>>>> -between ICIDs and IOMMUs, so an iommu-map property is used to define
>>>> -the set of possible ICIDs under a root DPRC and how they map to
>>>> -an IOMMU.
>>>> +between ICIDs and IOMMUs, so the iommu-map and msi-map properties are used
>>>> +to define the set of possible ICIDs under a root DPRC and how they map to
>>>> +an IOMMU and a GIC ITS respectively.
>>>>
>>>>   For generic IOMMU bindings, see
>>>>   Documentation/devicetree/bindings/iommu/iommu.txt.
>>>> @@ -28,6 +28,9 @@ Documentation/devicetree/bindings/iommu/iommu.txt.
>>>>   For arm-smmu binding, see:
>>>>   Documentation/devicetree/bindings/iommu/arm,smmu.yaml.
>>>>
>>>> +For GICv3 and GIC ITS bindings, see:
>>>> +Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml.
>>>> +
>>>>   Required properties:
>>>>
>>>>       - compatible
>>>> @@ -119,6 +122,15 @@ Optional properties:
>>>>     associated with the listed IOMMU, with the iommu-specifier
>>>>     (i - icid-base + iommu-base).
>>>>
>>>> +- msi-map: Maps an ICID to a GIC ITS and associated iommu-specifier
>>>> +  data.
>>>> +
>>>> +  The property is an arbitrary number of tuples of
>>>> +  (icid-base,iommu,iommu-base,length).
>>>
>>> I'm confused because the example has GIC ITS phandle, not an IOMMU.
>>>
>>> What is an iommu-base?
>>
>> Right, I was already halfway through writing a reply to say that all the
>> copy-pasted "iommu" references here should be using the terminology from
>> the pci-msi.txt binding instead.
>>
>>>> +
>>>> +  Any ICID in the interval [icid-base, icid-base + length) is
>>>> +  associated with the listed GIC ITS, with the iommu-specifier
>>>> +  (i - icid-base + iommu-base).
>>>>   Example:
>>>>
>>>>           smmu: iommu@5000000 {
>>>> @@ -128,6 +140,16 @@ Example:
>>>>                  ...
>>>>           };
>>>>
>>>> +       gic: interrupt-controller@6000000 {
>>>> +               compatible = "arm,gic-v3";
>>>> +               ...
>>>> +               its: gic-its@6020000 {
>>>> +                       compatible = "arm,gic-v3-its";
>>>> +                       msi-controller;
>>>> +                       ...
>>>> +               };
>>>> +       };
>>>> +
>>>>           fsl_mc: fsl-mc@80c000000 {
>>>>                   compatible = "fsl,qoriq-mc";
>>>>                   reg = <0x00000008 0x0c000000 0 0x40>,    /* MC portal base */
>>>> @@ -135,6 +157,8 @@ Example:
>>>>                   msi-parent = <&its>;
>>
>> Side note: is it right to keep msi-parent here? It rather implies that
>> the MC itself has a 'native' Device ID rather than an ICID, which I
>> believe is not strictly true. Plus it's extra-confusing that it doesn't
>> specify an ID either way, since that makes it look like the legacy PCI
>> case that gets treated implicitly as an identity msi-map, which makes no
>> sense at all to combine with an actual msi-map.
> 
> No, it doesn't make sense from a binding perspective.
> 
>>
>>>>                   /* define map for ICIDs 23-64 */
>>>>                   iommu-map = <23 &smmu 23 41>;
>>>> +                /* define msi map for ICIDs 23-64 */
>>>> +                msi-map = <23 &its 23 41>;
>>>
>>> Seeing 23 twice is odd. The numbers to the right of 'its' should be an
>>> ITS number space.
>>
>> On about 99% of systems the values in the SMMU Stream ID and ITS Device
>> ID spaces are going to be the same. Nobody's going to bother carrying
>> *two* sets of sideband data across the interconnect if they don't have to ;)
> 
> I'm referring to the 23 on the left and right, not between the msi and
> iommu. If the left and right are the same, then what are we remapping
> exactly?
> 

I also insisted a lot on keeping things simple and don't do any kind of
translation but Robin convinced me that this is not such a great idea.
The truth is that the hardware can be configured in such a way that the
assumption that icid -> streamid mapping is 1:1 no longer holds.
It just happens that we currently setup the hw to have 1:1 mappings.

P.S. No idea why, but somehow I got dropped from the thread. Weird.

---
Best Regards, Laurentiu

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

* Re: [PATCH 06/12] of/iommu: Make of_map_rid() PCI agnostic
  2020-05-21 22:47   ` Rob Herring
@ 2020-06-04 14:27     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 31+ messages in thread
From: Lorenzo Pieralisi @ 2020-06-04 14:27 UTC (permalink / raw)
  To: Rob Herring
  Cc: moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Joerg Roedel, Robin Murphy, Marc Zyngier, Linux IOMMU,
	linux-acpi, devicetree, PCI, Rafael J. Wysocki, Hanjun Guo,
	Bjorn Helgaas, Sudeep Holla, Catalin Marinas, Will Deacon,
	Makarand Pawagi, Diana Craciun, Laurentiu Tudor

On Thu, May 21, 2020 at 04:47:19PM -0600, Rob Herring wrote:
> On Thu, May 21, 2020 at 7:00 AM Lorenzo Pieralisi
> <lorenzo.pieralisi@arm.com> wrote:
> >
> > There is nothing PCI specific (other than the RID - requester ID)
> > in the of_map_rid() implementation, so the same function can be
> > reused for input/output IDs mapping for other busses just as well.
> >
> > Rename the RID instances/names to a generic "id" tag and provide
> > an of_map_rid() wrapper function so that we can leave the existing
> > (and legitimate) callers unchanged.
> 
> It's not all that clear to a casual observer that RID is a PCI thing,
> so I don't know that keeping it buys much. And there's only 3 callers.

Yes I agree - I think we can remove the _rid interface.

> > No functionality change intended.
> >
> > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> > Cc: Rob Herring <robh+dt@kernel.org>
> > Cc: Joerg Roedel <joro@8bytes.org>
> > Cc: Robin Murphy <robin.murphy@arm.com>
> > Cc: Marc Zyngier <maz@kernel.org>
> > ---
> >  drivers/iommu/of_iommu.c |  2 +-
> >  drivers/of/base.c        | 42 ++++++++++++++++++++--------------------
> >  include/linux/of.h       | 17 +++++++++++++++-
> >  3 files changed, 38 insertions(+), 23 deletions(-)
> >
> > diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> > index 20738aacac89..ad96b87137d6 100644
> > --- a/drivers/iommu/of_iommu.c
> > +++ b/drivers/iommu/of_iommu.c
> > @@ -145,7 +145,7 @@ static int of_fsl_mc_iommu_init(struct fsl_mc_device *mc_dev,
> >         struct of_phandle_args iommu_spec = { .args_count = 1 };
> >         int err;
> >
> > -       err = of_map_rid(master_np, mc_dev->icid, "iommu-map",
> > +       err = of_map_id(master_np, mc_dev->icid, "iommu-map",
> 
> I'm not sure this is an improvement because I'd refactor this function
> and of_pci_iommu_init() into a single function:
> 
> of_bus_iommu_init(struct device *dev, struct device_node *np, u32 id)
> 
> Then of_pci_iommu_init() becomes:
> 
> of_pci_iommu_init()
> {
>   return of_bus_iommu_init(info->dev, info->np, alias);
> }
> 
> And replace of_fsl_mc_iommu_init call with:
> err = of_bus_iommu_init(dev, master_np, to_fsl_mc_device(dev)->icid);

I will follow up on this on patch 7.

> >                          "iommu-map-mask", &iommu_spec.np,
> >                          iommu_spec.args);
> >         if (err)
> > diff --git a/drivers/of/base.c b/drivers/of/base.c
> > index ae03b1218b06..e000e17bd602 100644
> > --- a/drivers/of/base.c
> > +++ b/drivers/of/base.c
> > @@ -2201,15 +2201,15 @@ int of_find_last_cache_level(unsigned int cpu)
> >  }
> >
> >  /**
> > - * of_map_rid - Translate a requester ID through a downstream mapping.
> > + * of_map_id - Translate a requester ID through a downstream mapping.
> 
> Still a requester ID?

Fixed, thanks.

Lorenzo

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

* Re: [PATCH 07/12] of/device: Add input id to of_dma_configure()
  2020-05-21 23:02   ` Rob Herring
@ 2020-06-04 14:49     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 31+ messages in thread
From: Lorenzo Pieralisi @ 2020-06-04 14:49 UTC (permalink / raw)
  To: Rob Herring
  Cc: moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Robin Murphy, Joerg Roedel, Laurentiu Tudor, Linux IOMMU,
	linux-acpi, devicetree, PCI, Rafael J. Wysocki, Hanjun Guo,
	Bjorn Helgaas, Sudeep Holla, Catalin Marinas, Will Deacon,
	Marc Zyngier, Makarand Pawagi, Diana Craciun

On Thu, May 21, 2020 at 05:02:20PM -0600, Rob Herring wrote:
> On Thu, May 21, 2020 at 7:00 AM Lorenzo Pieralisi
> <lorenzo.pieralisi@arm.com> wrote:
> >
> > Devices sitting on proprietary busses have a device ID space that
> > is owned by the respective bus and related firmware bindings. In order
> > to let the generic OF layer handle the input translations to
> > an IOMMU id, for such busses the current of_dma_configure() interface
> > should be extended in order to allow the bus layer to provide the
> > device input id parameter - that is retrieved/assigned in bus
> > specific code and firmware.
> >
> > Augment of_dma_configure() to add an optional input_id parameter,
> > leaving current functionality unchanged.
> >
> > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> > Cc: Rob Herring <robh+dt@kernel.org>
> > Cc: Robin Murphy <robin.murphy@arm.com>
> > Cc: Joerg Roedel <joro@8bytes.org>
> > Cc: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> > ---
> >  drivers/bus/fsl-mc/fsl-mc-bus.c |  4 ++-
> >  drivers/iommu/of_iommu.c        | 53 +++++++++++++++++++++------------
> >  drivers/of/device.c             |  8 +++--
> >  include/linux/of_device.h       | 16 ++++++++--
> >  include/linux/of_iommu.h        |  6 ++--
> >  5 files changed, 60 insertions(+), 27 deletions(-)
> >
> > diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
> > index 40526da5c6a6..8ead3f0238f2 100644
> > --- a/drivers/bus/fsl-mc/fsl-mc-bus.c
> > +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
> > @@ -118,11 +118,13 @@ static int fsl_mc_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
> >  static int fsl_mc_dma_configure(struct device *dev)
> >  {
> >         struct device *dma_dev = dev;
> > +       struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
> > +       u32 input_id = mc_dev->icid;
> >
> >         while (dev_is_fsl_mc(dma_dev))
> >                 dma_dev = dma_dev->parent;
> >
> > -       return of_dma_configure(dev, dma_dev->of_node, 0);
> > +       return of_dma_configure_id(dev, dma_dev->of_node, 0, &input_id);
> >  }
> >
> >  static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
> > diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> > index ad96b87137d6..4516d5bf6cc9 100644
> > --- a/drivers/iommu/of_iommu.c
> > +++ b/drivers/iommu/of_iommu.c
> > @@ -139,25 +139,53 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
> >         return err;
> >  }
> >
> > -static int of_fsl_mc_iommu_init(struct fsl_mc_device *mc_dev,
> > -                               struct device_node *master_np)
> > +static int of_iommu_configure_dev_id(struct device_node *master_np,
> > +                                    struct device *dev,
> > +                                    const u32 *id)
> 
> Should have read this patch before #6. I guess you could still make
> of_pci_iommu_init() call
> of_iommu_configure_dev_id.

Yes that makes sense, I will update it.

Thanks,
Lorenzo

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

* Re: [PATCH 10/12] of/irq: Make of_msi_map_rid() PCI bus agnostic
  2020-05-21 23:17   ` Rob Herring
@ 2020-06-04 15:08     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 31+ messages in thread
From: Lorenzo Pieralisi @ 2020-06-04 15:08 UTC (permalink / raw)
  To: Rob Herring
  Cc: devicetree, Sudeep Holla, Catalin Marinas, Will Deacon,
	Diana Craciun, Marc Zyngier, Joerg Roedel, Hanjun Guo,
	Rafael J. Wysocki, Makarand Pawagi, linux-acpi, Linux IOMMU, PCI,
	Bjorn Helgaas, Robin Murphy,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Laurentiu Tudor

On Thu, May 21, 2020 at 05:17:27PM -0600, Rob Herring wrote:
> On Thu, May 21, 2020 at 7:00 AM Lorenzo Pieralisi
> <lorenzo.pieralisi@arm.com> wrote:
> >
> > There is nothing PCI bus specific in the of_msi_map_rid()
> > implementation other than the requester ID tag for the input
> > ID space. Rename requester ID to a more generic ID so that
> > the translation code can be used by all busses that require
> > input/output ID translations.
> >
> > Leave a wrapper function of_msi_map_rid() in place to keep
> > existing PCI code mapping requester ID syntactically unchanged.
> >
> > No functional change intended.
> >
> > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> > Cc: Rob Herring <robh+dt@kernel.org>
> > Cc: Marc Zyngier <maz@kernel.org>
> > ---
> >  drivers/of/irq.c       | 28 ++++++++++++++--------------
> >  include/linux/of_irq.h | 14 ++++++++++++--
> >  2 files changed, 26 insertions(+), 16 deletions(-)
> >
> > diff --git a/drivers/of/irq.c b/drivers/of/irq.c
> > index 48a40326984f..25d17b8a1a1a 100644
> > --- a/drivers/of/irq.c
> > +++ b/drivers/of/irq.c
> > @@ -576,43 +576,43 @@ void __init of_irq_init(const struct of_device_id *matches)
> >         }
> >  }
> >
> > -static u32 __of_msi_map_rid(struct device *dev, struct device_node **np,
> > -                           u32 rid_in)
> > +static u32 __of_msi_map_id(struct device *dev, struct device_node **np,
> > +                           u32 id_in)
> >  {
> >         struct device *parent_dev;
> > -       u32 rid_out = rid_in;
> > +       u32 id_out = id_in;
> >
> >         /*
> >          * 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 (!of_map_rid(parent_dev->of_node, rid_in, "msi-map",
> > -                               "msi-map-mask", np, &rid_out))
> > +               if (!of_map_id(parent_dev->of_node, id_in, "msi-map",
> > +                               "msi-map-mask", np, &id_out))
> >                         break;
> > -       return rid_out;
> > +       return id_out;
> >  }
> >
> >  /**
> > - * of_msi_map_rid - Map a MSI requester ID for a device.
> > + * of_msi_map_id - Map a MSI 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.
> > + * @id_in: unmapped MSI 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.
> > + * property.  If found, apply the mapping to @id_in.
> >   *
> > - * Returns the mapped MSI requester ID.
> > + * Returns the mapped MSI ID.
> >   */
> > -u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in)
> > +u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in)
> >  {
> > -       return __of_msi_map_rid(dev, &msi_np, rid_in);
> > +       return __of_msi_map_id(dev, &msi_np, id_in);
> >  }
> >
> >  /**
> >   * 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.
> > + * @id: Device ID.
> >   * @bus_token: Bus token
> >   *
> >   * Walk up the device hierarchy looking for devices with a "msi-map"
> > @@ -625,7 +625,7 @@ struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 id,
> >  {
> >         struct device_node *np = NULL;
> >
> > -       __of_msi_map_rid(dev, &np, id);
> > +       __of_msi_map_id(dev, &np, id);
> >         return irq_find_matching_host(np, bus_token);
> >  }
> >
> > diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
> > index 7142a3722758..cf9cb1e545ce 100644
> > --- a/include/linux/of_irq.h
> > +++ b/include/linux/of_irq.h
> > @@ -55,7 +55,12 @@ extern struct irq_domain *of_msi_map_get_device_domain(struct device *dev,
> >                                                         u32 id,
> >                                                         u32 bus_token);
> >  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);
> > +u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in);
> > +static inline u32 of_msi_map_rid(struct device *dev,
> > +                                struct device_node *msi_np, u32 rid_in)
> > +{
> > +       return of_msi_map_id(dev, msi_np, rid_in);
> > +}
> >  #else
> >  static inline int of_irq_count(struct device_node *dev)
> >  {
> > @@ -93,10 +98,15 @@ static inline struct irq_domain *of_msi_map_get_device_domain(struct device *dev
> >  static inline void of_msi_configure(struct device *dev, struct device_node *np)
> >  {
> >  }
> > +static inline u32 of_msi_map_id(struct device *dev,
> > +                                struct device_node *msi_np, u32 id_in)
> > +{
> > +       return id_in;
> > +}
> >  static inline u32 of_msi_map_rid(struct device *dev,
> >                                  struct device_node *msi_np, u32 rid_in)
> 
> Move this out of the ifdef and you only need it declared once.
> 
> But again, I think I'd just kill of_msi_map_rid.

Yes I don't think there is a clear benefit in keeping the _rid
interface.

Thanks,
Lorenzo

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

end of thread, back to index

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-21 12:59 [PATCH 00/12] ACPI/OF: Upgrade MSI/IOMMU ID mapping APIs Lorenzo Pieralisi
2020-05-21 12:59 ` [PATCH 01/12] ACPI/IORT: Make iort_match_node_callback walk the ACPI namespace for NC Lorenzo Pieralisi
2020-05-21 12:59 ` [PATCH 02/12] ACPI/IORT: Make iort_get_device_domain IRQ domain agnostic Lorenzo Pieralisi
2020-05-21 19:56   ` Bjorn Helgaas
2020-05-21 12:59 ` [PATCH 03/12] ACPI/IORT: Make iort_msi_map_rid() PCI agnostic Lorenzo Pieralisi
2020-05-21 13:00 ` [PATCH 04/12] ACPI/IORT: Remove useless PCI bus walk Lorenzo Pieralisi
2020-05-21 13:00 ` [PATCH 05/12] ACPI/IORT: Add an input ID to acpi_dma_configure() Lorenzo Pieralisi
2020-05-21 13:00 ` [PATCH 06/12] of/iommu: Make of_map_rid() PCI agnostic Lorenzo Pieralisi
2020-05-21 22:47   ` Rob Herring
2020-06-04 14:27     ` Lorenzo Pieralisi
2020-05-21 13:00 ` [PATCH 07/12] of/device: Add input id to of_dma_configure() Lorenzo Pieralisi
2020-05-21 23:02   ` Rob Herring
2020-06-04 14:49     ` Lorenzo Pieralisi
2020-05-21 13:00 ` [PATCH 08/12] of/irq: make of_msi_map_get_device_domain() bus agnostic Lorenzo Pieralisi
2020-05-21 19:57   ` Bjorn Helgaas
2020-05-21 13:00 ` [PATCH 09/12] dt-bindings: arm: fsl: Add msi-map device-tree binding for fsl-mc bus Lorenzo Pieralisi
2020-05-21 23:10   ` Rob Herring
2020-05-22  9:42     ` Robin Murphy
2020-05-22  9:57       ` Diana Craciun OSS
2020-05-22 14:08         ` Rob Herring
2020-05-22 14:34           ` Robin Murphy
2020-05-22 14:02       ` Rob Herring
2020-05-22 15:38         ` Laurentiu Tudor
2020-05-21 13:00 ` [PATCH 10/12] of/irq: Make of_msi_map_rid() PCI bus agnostic Lorenzo Pieralisi
2020-05-21 23:17   ` Rob Herring
2020-06-04 15:08     ` Lorenzo Pieralisi
2020-05-21 13:00 ` [PATCH 11/12] bus/fsl-mc: Refactor the MSI domain creation in the DPRC driver Lorenzo Pieralisi
2020-05-21 13:00 ` [PATCH 12/12] bus: fsl-mc: Add ACPI support for fsl-mc Lorenzo Pieralisi
2020-05-21 15:03   ` Laurentiu Tudor
2020-05-22  5:32     ` Makarand Pawagi
2020-05-22  9:53       ` Lorenzo Pieralisi

Linux-ACPI Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-acpi/0 linux-acpi/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-acpi linux-acpi/ https://lore.kernel.org/linux-acpi \
		linux-acpi@vger.kernel.org
	public-inbox-index linux-acpi

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-acpi


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git