All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V11 00/11] IOMMU probe deferral support
@ 2017-04-10 11:20   ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:20 UTC (permalink / raw)
  To: robin.murphy, will.deacon, joro, lorenzo.pieralisi, iommu,
	linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh
  Cc: sricharan

This series calls the dma ops configuration for the devices
at a generic place so that it works for all busses.
The dma_configure_ops for a device is now called during
the device_attach callback just before the probe of the
bus/driver is called. Similarly dma_deconfigure is called during
device/driver_detach path.

pci_bus_add_devices    (platform/amba)(_device_create/driver_register)
       |                         |
pci_bus_add_device     (device_add/driver_register)
       |                         |
device_attach           device_initial_probe
       |                         |
__device_attach_driver    __device_attach_driver
       |
driver_probe_device
       |
really_probe
       |
dma_configure

Similarly on the device/driver_unregister path __device_release_driver is
called which inturn calls dma_deconfigure.

Rebased the series against mainline 4.11-rc5. Applies and builds cleanly
against iommu-next and with 3-way merge applies on top of linux-next
as well (patch #8), because of "ACPI platform MSI support" from
Hanjun being merged.
  
* Tested with platform and pci devices for probe deferral
  and reprobe on arm64 based platform.

Previous post of this series [8]. 

Please note that, i have kept the tested/acked tags intact from V8
because V9/10/11 were for more fixes that was added, so the original
tags that was given for the functional testing remains the same.

 [V11]
     * No functional changes.

     * Rebased on top of 4.11-rc6.

     * Dropped patch#3 from V10, as a result have to make
       a change in patch#7 to return a 'non-void' to fix a
       build warning.

     * Added Robin's and Rob's tags.

 [V10]
     * Rebased on top of 4.11-rc5.
 
     * Fixed coherent_dma_mask 64bit overflow issue [8]
       for OF. The fix for OF was added as a separate
       patch#6, since the issue is true even without probe deferral,
       but gets reproduced with the probe deferral series.
       Added Lorenzo's ACPI fix for coherent_dma_mask overflow
       and the fix for dma_configure getting called more than
       once for the same device.

     * Also fixed an build issue caught by kbuild robot for
       m68k arch. The issue was dma_(de)configure was not
       getting defined for !CONFIG_HAS_DMA, so fixed that as well.

 [V9]
     * Rebased on top of 4.11-rc1.

     * Merged Robin's fixes for legacy binding issue,
       pci devices with no iommu-map property and deferencing
       of_iommu_table after init.
     
 [V8]
     * Picked up all the acks and tested tags from Marek and
       Hanjun for DT and ACPI patches respectively, since
       no functional changes was done.

     * Addressed Minor comments Sinan and Bjorn.

     * Added Robin's fix for fixing the deferencing NULL for
       of_iommu_table after init in patch #2.

     * Rebased it on top of linux-next

 [V7]
     * Updated the subject and commit log for patch #6 as per
       comments from Lorenzo. No functional changes.

 [V6]
     * Fixed a bug in dma_configure function pointed out by
       Robin.
     * Reordered the patches as per comments from Robin and
       Lorenzo.
     * Added Tags.

 [V5]
     * Reworked the pci configuration code hanging outside and
       pushed it to dma_configure as in PATCH#5,6,7.
       Also added a couple of patches that Lorenzo provided for
       correcting the Probe deferring mechanism in case of
       ACPI devices from here [5].

 [V4]
     * Took the reworked patches [2] from Robin's branch and
       rebased on top of Lorenzo's ACPI IORT ARM support series [3].

     * Added the patches for moving the dma ops configuration of
       acpi based devices to probe time as well.
 [V3]
     * Removed the patch to split dma_masks/dma_ops configuration
       separately based on review comments that both masks and ops are
       required only during the device probe time.

     * Reworked the series based on Generic DT bindings series.

     * Added call to iommu's remove_device in the cleanup path for arm and
       arm64.

     * Removed the notifier trick in arm64 to handle early device
       registration.

     * Added reset of dma_ops in cleanup path for arm based on comments.

     * Fixed the pci_iommu_configure path and tested with PCI device as
       well.
 
     * Fixed a bug to return the correct iommu_ops from patch 7 [4] in
       last post.

     * Fixed few other cosmetic comments.
  
 [V2]
     * Updated the Initial post to call dma_configure/deconfigure from
       generic code
 
     * Added iommu add_device callback from of_iommu_configure path

 [V1]
     * Initial post from Laurent Pinchart [1]

[1] http://lists.linuxfoundation.org/pipermail/iommu/2015-May/013016.html
[2] http://www.linux-arm.org/git?p=linux-rm.git;a=shortlog;h=refs/heads/iommu/defer
[3] https://lkml.org/lkml/2016/11/21/141
[4] https://www.mail-archive.com/iommu@xxxxxxxxxxxxxxxxxxxxxxxxxx/msg13940.html
[5] git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git iommu/probe-deferral
[6] http://www.spinics.net/lists/linux-pci/msg57992.html
[7] https://www.spinics.net/lists/arm-kernel/msg556209.html
[8] http://lkml.iu.edu/hypermail/linux/kernel/1704.0/01557.html

Laurent Pinchart (2):
  of: dma: Make of_dma_deconfigure() public
  iommu: of: Handle IOMMU lookup failure with deferred probing or error

Lorenzo Pieralisi (2):
  ACPI/IORT: Add function to check SMMUs drivers presence
  ACPI/IORT: Remove linker section for IORT entries probing

Robin Murphy (3):
  iommu/of: Refactor of_iommu_configure() for error handling
  iommu/of: Prepare for deferred IOMMU configuration
  iommu/arm-smmu: Clean up early-probing workarounds

Sricharan R (4):
  of: device: Fix overflow of coherent_dma_mask
  of/acpi: Configure dma operations at probe time for platform/amba/pci
    bus devices
  drivers: acpi: Handle IOMMU lookup failure with deferred probing or
    error
  arm64: dma-mapping: Remove the notifier trick to handle early setting
    of dma_ops

 arch/arm64/mm/dma-mapping.c       | 142 +++++---------------------------------
 drivers/acpi/arm64/iort.c         |  48 ++++++++++++-
 drivers/acpi/glue.c               |   5 --
 drivers/acpi/scan.c               |  11 ++-
 drivers/base/dd.c                 |   9 +++
 drivers/base/dma-mapping.c        |  41 +++++++++++
 drivers/iommu/arm-smmu-v3.c       |  46 +-----------
 drivers/iommu/arm-smmu.c          | 110 +++++++++++++----------------
 drivers/iommu/of_iommu.c          | 126 ++++++++++++++++++++++++---------
 drivers/of/device.c               |  23 +++++-
 drivers/of/platform.c             |  10 +--
 drivers/pci/probe.c               |  28 --------
 include/acpi/acpi_bus.h           |   2 +-
 include/asm-generic/vmlinux.lds.h |   1 -
 include/linux/acpi.h              |   7 +-
 include/linux/acpi_iort.h         |   3 -
 include/linux/dma-mapping.h       |  12 ++++
 include/linux/of_device.h         |  10 ++-
 18 files changed, 312 insertions(+), 322 deletions(-)

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 00/11] IOMMU probe deferral support
@ 2017-04-10 11:20   ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:20 UTC (permalink / raw)
  To: linux-arm-kernel

This series calls the dma ops configuration for the devices
at a generic place so that it works for all busses.
The dma_configure_ops for a device is now called during
the device_attach callback just before the probe of the
bus/driver is called. Similarly dma_deconfigure is called during
device/driver_detach path.

pci_bus_add_devices    (platform/amba)(_device_create/driver_register)
       |                         |
pci_bus_add_device     (device_add/driver_register)
       |                         |
device_attach           device_initial_probe
       |                         |
__device_attach_driver    __device_attach_driver
       |
driver_probe_device
       |
really_probe
       |
dma_configure

Similarly on the device/driver_unregister path __device_release_driver is
called which inturn calls dma_deconfigure.

Rebased the series against mainline 4.11-rc5. Applies and builds cleanly
against iommu-next and with 3-way merge applies on top of linux-next
as well (patch #8), because of "ACPI platform MSI support" from
Hanjun being merged.
  
* Tested with platform and pci devices for probe deferral
  and reprobe on arm64 based platform.

Previous post of this series [8]. 

Please note that, i have kept the tested/acked tags intact from V8
because V9/10/11 were for more fixes that was added, so the original
tags that was given for the functional testing remains the same.

 [V11]
     * No functional changes.

     * Rebased on top of 4.11-rc6.

     * Dropped patch#3 from V10, as a result have to make
       a change in patch#7 to return a 'non-void' to fix a
       build warning.

     * Added Robin's and Rob's tags.

 [V10]
     * Rebased on top of 4.11-rc5.
 
     * Fixed coherent_dma_mask 64bit overflow issue [8]
       for OF. The fix for OF was added as a separate
       patch#6, since the issue is true even without probe deferral,
       but gets reproduced with the probe deferral series.
       Added Lorenzo's ACPI fix for coherent_dma_mask overflow
       and the fix for dma_configure getting called more than
       once for the same device.

     * Also fixed an build issue caught by kbuild robot for
       m68k arch. The issue was dma_(de)configure was not
       getting defined for !CONFIG_HAS_DMA, so fixed that as well.

 [V9]
     * Rebased on top of 4.11-rc1.

     * Merged Robin's fixes for legacy binding issue,
       pci devices with no iommu-map property and deferencing
       of_iommu_table after init.
     
 [V8]
     * Picked up all the acks and tested tags from Marek and
       Hanjun for DT and ACPI patches respectively, since
       no functional changes was done.

     * Addressed Minor comments Sinan and Bjorn.

     * Added Robin's fix for fixing the deferencing NULL for
       of_iommu_table after init in patch #2.

     * Rebased it on top of linux-next

 [V7]
     * Updated the subject and commit log for patch #6 as per
       comments from Lorenzo. No functional changes.

 [V6]
     * Fixed a bug in dma_configure function pointed out by
       Robin.
     * Reordered the patches as per comments from Robin and
       Lorenzo.
     * Added Tags.

 [V5]
     * Reworked the pci configuration code hanging outside and
       pushed it to dma_configure as in PATCH#5,6,7.
       Also added a couple of patches that Lorenzo provided for
       correcting the Probe deferring mechanism in case of
       ACPI devices from here [5].

 [V4]
     * Took the reworked patches [2] from Robin's branch and
       rebased on top of Lorenzo's ACPI IORT ARM support series [3].

     * Added the patches for moving the dma ops configuration of
       acpi based devices to probe time as well.
 [V3]
     * Removed the patch to split dma_masks/dma_ops configuration
       separately based on review comments that both masks and ops are
       required only during the device probe time.

     * Reworked the series based on Generic DT bindings series.

     * Added call to iommu's remove_device in the cleanup path for arm and
       arm64.

     * Removed the notifier trick in arm64 to handle early device
       registration.

     * Added reset of dma_ops in cleanup path for arm based on comments.

     * Fixed the pci_iommu_configure path and tested with PCI device as
       well.
 
     * Fixed a bug to return the correct iommu_ops from patch 7 [4] in
       last post.

     * Fixed few other cosmetic comments.
  
 [V2]
     * Updated the Initial post to call dma_configure/deconfigure from
       generic code
 
     * Added iommu add_device callback from of_iommu_configure path

 [V1]
     * Initial post from Laurent Pinchart [1]

[1] http://lists.linuxfoundation.org/pipermail/iommu/2015-May/013016.html
[2] http://www.linux-arm.org/git?p=linux-rm.git;a=shortlog;h=refs/heads/iommu/defer
[3] https://lkml.org/lkml/2016/11/21/141
[4] https://www.mail-archive.com/iommu at xxxxxxxxxxxxxxxxxxxxxxxxxx/msg13940.html
[5] git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git iommu/probe-deferral
[6] http://www.spinics.net/lists/linux-pci/msg57992.html
[7] https://www.spinics.net/lists/arm-kernel/msg556209.html
[8] http://lkml.iu.edu/hypermail/linux/kernel/1704.0/01557.html

Laurent Pinchart (2):
  of: dma: Make of_dma_deconfigure() public
  iommu: of: Handle IOMMU lookup failure with deferred probing or error

Lorenzo Pieralisi (2):
  ACPI/IORT: Add function to check SMMUs drivers presence
  ACPI/IORT: Remove linker section for IORT entries probing

Robin Murphy (3):
  iommu/of: Refactor of_iommu_configure() for error handling
  iommu/of: Prepare for deferred IOMMU configuration
  iommu/arm-smmu: Clean up early-probing workarounds

Sricharan R (4):
  of: device: Fix overflow of coherent_dma_mask
  of/acpi: Configure dma operations at probe time for platform/amba/pci
    bus devices
  drivers: acpi: Handle IOMMU lookup failure with deferred probing or
    error
  arm64: dma-mapping: Remove the notifier trick to handle early setting
    of dma_ops

 arch/arm64/mm/dma-mapping.c       | 142 +++++---------------------------------
 drivers/acpi/arm64/iort.c         |  48 ++++++++++++-
 drivers/acpi/glue.c               |   5 --
 drivers/acpi/scan.c               |  11 ++-
 drivers/base/dd.c                 |   9 +++
 drivers/base/dma-mapping.c        |  41 +++++++++++
 drivers/iommu/arm-smmu-v3.c       |  46 +-----------
 drivers/iommu/arm-smmu.c          | 110 +++++++++++++----------------
 drivers/iommu/of_iommu.c          | 126 ++++++++++++++++++++++++---------
 drivers/of/device.c               |  23 +++++-
 drivers/of/platform.c             |  10 +--
 drivers/pci/probe.c               |  28 --------
 include/acpi/acpi_bus.h           |   2 +-
 include/asm-generic/vmlinux.lds.h |   1 -
 include/linux/acpi.h              |   7 +-
 include/linux/acpi_iort.h         |   3 -
 include/linux/dma-mapping.h       |  12 ++++
 include/linux/of_device.h         |  10 ++-
 18 files changed, 312 insertions(+), 322 deletions(-)

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 01/11] iommu/of: Refactor of_iommu_configure() for error handling
  2017-04-10 11:20   ` Sricharan R
  (?)
@ 2017-04-10 11:20     ` Sricharan R
  -1 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:20 UTC (permalink / raw)
  To: robin.murphy, will.deacon, joro, lorenzo.pieralisi, iommu,
	linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh
  Cc: sricharan

From: Robin Murphy <robin.murphy@arm.com>

In preparation for some upcoming cleverness, rework the control flow in
of_iommu_configure() to minimise duplication and improve the propogation
of errors. It's also as good a time as any to switch over from the
now-just-a-compatibility-wrapper of_iommu_get_ops() to using the generic
IOMMU instance interface directly.

Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 drivers/iommu/of_iommu.c | 83 +++++++++++++++++++++++++++++++-----------------
 1 file changed, 53 insertions(+), 30 deletions(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 2683e9f..8f4e599 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -96,6 +96,28 @@ int of_get_dma_window(struct device_node *dn, const char *prefix, int index,
 }
 EXPORT_SYMBOL_GPL(of_get_dma_window);
 
+static const struct iommu_ops
+*of_iommu_xlate(struct device *dev, struct of_phandle_args *iommu_spec)
+{
+	const struct iommu_ops *ops;
+	struct fwnode_handle *fwnode = &iommu_spec->np->fwnode;
+	int err;
+
+	ops = iommu_ops_from_fwnode(fwnode);
+	if (!ops || !ops->of_xlate)
+		return NULL;
+
+	err = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
+	if (err)
+		return ERR_PTR(err);
+
+	err = ops->of_xlate(dev, iommu_spec);
+	if (err)
+		return ERR_PTR(err);
+
+	return ops;
+}
+
 static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
 {
 	struct of_phandle_args *iommu_spec = data;
@@ -105,10 +127,11 @@ static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
 }
 
 static const struct iommu_ops
-*of_pci_iommu_configure(struct pci_dev *pdev, struct device_node *bridge_np)
+*of_pci_iommu_init(struct pci_dev *pdev, struct device_node *bridge_np)
 {
 	const struct iommu_ops *ops;
 	struct of_phandle_args iommu_spec;
+	int err;
 
 	/*
 	 * Start by tracing the RID alias down the PCI topology as
@@ -123,56 +146,56 @@ static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
 	 * bus into the system beyond, and which IOMMU it ends up at.
 	 */
 	iommu_spec.np = NULL;
-	if (of_pci_map_rid(bridge_np, iommu_spec.args[0], "iommu-map",
-			   "iommu-map-mask", &iommu_spec.np, iommu_spec.args))
-		return NULL;
+	err = of_pci_map_rid(bridge_np, iommu_spec.args[0], "iommu-map",
+			     "iommu-map-mask", &iommu_spec.np,
+			     iommu_spec.args);
+	if (err)
+		return err == -ENODEV ? NULL : ERR_PTR(err);
 
-	ops = iommu_ops_from_fwnode(&iommu_spec.np->fwnode);
-	if (!ops || !ops->of_xlate ||
-	    iommu_fwspec_init(&pdev->dev, &iommu_spec.np->fwnode, ops) ||
-	    ops->of_xlate(&pdev->dev, &iommu_spec))
-		ops = NULL;
+	ops = of_iommu_xlate(&pdev->dev, &iommu_spec);
 
 	of_node_put(iommu_spec.np);
 	return ops;
 }
 
-const struct iommu_ops *of_iommu_configure(struct device *dev,
-					   struct device_node *master_np)
+static const struct iommu_ops
+*of_platform_iommu_init(struct device *dev, struct device_node *np)
 {
 	struct of_phandle_args iommu_spec;
-	struct device_node *np;
 	const struct iommu_ops *ops = NULL;
 	int idx = 0;
 
-	if (dev_is_pci(dev))
-		return of_pci_iommu_configure(to_pci_dev(dev), master_np);
-
 	/*
 	 * We don't currently walk up the tree looking for a parent IOMMU.
 	 * See the `Notes:' section of
 	 * Documentation/devicetree/bindings/iommu/iommu.txt
 	 */
-	while (!of_parse_phandle_with_args(master_np, "iommus",
-					   "#iommu-cells", idx,
-					   &iommu_spec)) {
-		np = iommu_spec.np;
-		ops = iommu_ops_from_fwnode(&np->fwnode);
-
-		if (!ops || !ops->of_xlate ||
-		    iommu_fwspec_init(dev, &np->fwnode, ops) ||
-		    ops->of_xlate(dev, &iommu_spec))
-			goto err_put_node;
-
-		of_node_put(np);
+	while (!of_parse_phandle_with_args(np, "iommus", "#iommu-cells",
+					   idx, &iommu_spec)) {
+		ops = of_iommu_xlate(dev, &iommu_spec);
+		of_node_put(iommu_spec.np);
 		idx++;
+		if (IS_ERR_OR_NULL(ops))
+			break;
 	}
 
 	return ops;
+}
+
+const struct iommu_ops *of_iommu_configure(struct device *dev,
+					   struct device_node *master_np)
+{
+	const struct iommu_ops *ops;
+
+	if (!master_np)
+		return NULL;
+
+	if (dev_is_pci(dev))
+		ops = of_pci_iommu_init(to_pci_dev(dev), master_np);
+	else
+		ops = of_platform_iommu_init(dev, master_np);
 
-err_put_node:
-	of_node_put(np);
-	return NULL;
+	return IS_ERR(ops) ? NULL : ops;
 }
 
 static int __init of_iommu_init(void)
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 01/11] iommu/of: Refactor of_iommu_configure() for error handling
@ 2017-04-10 11:20     ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:20 UTC (permalink / raw)
  To: robin.murphy, will.deacon, joro, lorenzo.pieralisi, iommu,
	linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh
  Cc: sricharan

From: Robin Murphy <robin.murphy@arm.com>

In preparation for some upcoming cleverness, rework the control flow in
of_iommu_configure() to minimise duplication and improve the propogation
of errors. It's also as good a time as any to switch over from the
now-just-a-compatibility-wrapper of_iommu_get_ops() to using the generic
IOMMU instance interface directly.

Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 drivers/iommu/of_iommu.c | 83 +++++++++++++++++++++++++++++++-----------------
 1 file changed, 53 insertions(+), 30 deletions(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 2683e9f..8f4e599 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -96,6 +96,28 @@ int of_get_dma_window(struct device_node *dn, const char *prefix, int index,
 }
 EXPORT_SYMBOL_GPL(of_get_dma_window);
 
+static const struct iommu_ops
+*of_iommu_xlate(struct device *dev, struct of_phandle_args *iommu_spec)
+{
+	const struct iommu_ops *ops;
+	struct fwnode_handle *fwnode = &iommu_spec->np->fwnode;
+	int err;
+
+	ops = iommu_ops_from_fwnode(fwnode);
+	if (!ops || !ops->of_xlate)
+		return NULL;
+
+	err = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
+	if (err)
+		return ERR_PTR(err);
+
+	err = ops->of_xlate(dev, iommu_spec);
+	if (err)
+		return ERR_PTR(err);
+
+	return ops;
+}
+
 static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
 {
 	struct of_phandle_args *iommu_spec = data;
@@ -105,10 +127,11 @@ static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
 }
 
 static const struct iommu_ops
-*of_pci_iommu_configure(struct pci_dev *pdev, struct device_node *bridge_np)
+*of_pci_iommu_init(struct pci_dev *pdev, struct device_node *bridge_np)
 {
 	const struct iommu_ops *ops;
 	struct of_phandle_args iommu_spec;
+	int err;
 
 	/*
 	 * Start by tracing the RID alias down the PCI topology as
@@ -123,56 +146,56 @@ static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
 	 * bus into the system beyond, and which IOMMU it ends up at.
 	 */
 	iommu_spec.np = NULL;
-	if (of_pci_map_rid(bridge_np, iommu_spec.args[0], "iommu-map",
-			   "iommu-map-mask", &iommu_spec.np, iommu_spec.args))
-		return NULL;
+	err = of_pci_map_rid(bridge_np, iommu_spec.args[0], "iommu-map",
+			     "iommu-map-mask", &iommu_spec.np,
+			     iommu_spec.args);
+	if (err)
+		return err == -ENODEV ? NULL : ERR_PTR(err);
 
-	ops = iommu_ops_from_fwnode(&iommu_spec.np->fwnode);
-	if (!ops || !ops->of_xlate ||
-	    iommu_fwspec_init(&pdev->dev, &iommu_spec.np->fwnode, ops) ||
-	    ops->of_xlate(&pdev->dev, &iommu_spec))
-		ops = NULL;
+	ops = of_iommu_xlate(&pdev->dev, &iommu_spec);
 
 	of_node_put(iommu_spec.np);
 	return ops;
 }
 
-const struct iommu_ops *of_iommu_configure(struct device *dev,
-					   struct device_node *master_np)
+static const struct iommu_ops
+*of_platform_iommu_init(struct device *dev, struct device_node *np)
 {
 	struct of_phandle_args iommu_spec;
-	struct device_node *np;
 	const struct iommu_ops *ops = NULL;
 	int idx = 0;
 
-	if (dev_is_pci(dev))
-		return of_pci_iommu_configure(to_pci_dev(dev), master_np);
-
 	/*
 	 * We don't currently walk up the tree looking for a parent IOMMU.
 	 * See the `Notes:' section of
 	 * Documentation/devicetree/bindings/iommu/iommu.txt
 	 */
-	while (!of_parse_phandle_with_args(master_np, "iommus",
-					   "#iommu-cells", idx,
-					   &iommu_spec)) {
-		np = iommu_spec.np;
-		ops = iommu_ops_from_fwnode(&np->fwnode);
-
-		if (!ops || !ops->of_xlate ||
-		    iommu_fwspec_init(dev, &np->fwnode, ops) ||
-		    ops->of_xlate(dev, &iommu_spec))
-			goto err_put_node;
-
-		of_node_put(np);
+	while (!of_parse_phandle_with_args(np, "iommus", "#iommu-cells",
+					   idx, &iommu_spec)) {
+		ops = of_iommu_xlate(dev, &iommu_spec);
+		of_node_put(iommu_spec.np);
 		idx++;
+		if (IS_ERR_OR_NULL(ops))
+			break;
 	}
 
 	return ops;
+}
+
+const struct iommu_ops *of_iommu_configure(struct device *dev,
+					   struct device_node *master_np)
+{
+	const struct iommu_ops *ops;
+
+	if (!master_np)
+		return NULL;
+
+	if (dev_is_pci(dev))
+		ops = of_pci_iommu_init(to_pci_dev(dev), master_np);
+	else
+		ops = of_platform_iommu_init(dev, master_np);
 
-err_put_node:
-	of_node_put(np);
-	return NULL;
+	return IS_ERR(ops) ? NULL : ops;
 }
 
 static int __init of_iommu_init(void)
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V11 01/11] iommu/of: Refactor of_iommu_configure() for error handling
@ 2017-04-10 11:20     ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:20 UTC (permalink / raw)
  To: linux-arm-kernel

From: Robin Murphy <robin.murphy@arm.com>

In preparation for some upcoming cleverness, rework the control flow in
of_iommu_configure() to minimise duplication and improve the propogation
of errors. It's also as good a time as any to switch over from the
now-just-a-compatibility-wrapper of_iommu_get_ops() to using the generic
IOMMU instance interface directly.

Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 drivers/iommu/of_iommu.c | 83 +++++++++++++++++++++++++++++++-----------------
 1 file changed, 53 insertions(+), 30 deletions(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 2683e9f..8f4e599 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -96,6 +96,28 @@ int of_get_dma_window(struct device_node *dn, const char *prefix, int index,
 }
 EXPORT_SYMBOL_GPL(of_get_dma_window);
 
+static const struct iommu_ops
+*of_iommu_xlate(struct device *dev, struct of_phandle_args *iommu_spec)
+{
+	const struct iommu_ops *ops;
+	struct fwnode_handle *fwnode = &iommu_spec->np->fwnode;
+	int err;
+
+	ops = iommu_ops_from_fwnode(fwnode);
+	if (!ops || !ops->of_xlate)
+		return NULL;
+
+	err = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
+	if (err)
+		return ERR_PTR(err);
+
+	err = ops->of_xlate(dev, iommu_spec);
+	if (err)
+		return ERR_PTR(err);
+
+	return ops;
+}
+
 static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
 {
 	struct of_phandle_args *iommu_spec = data;
@@ -105,10 +127,11 @@ static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
 }
 
 static const struct iommu_ops
-*of_pci_iommu_configure(struct pci_dev *pdev, struct device_node *bridge_np)
+*of_pci_iommu_init(struct pci_dev *pdev, struct device_node *bridge_np)
 {
 	const struct iommu_ops *ops;
 	struct of_phandle_args iommu_spec;
+	int err;
 
 	/*
 	 * Start by tracing the RID alias down the PCI topology as
@@ -123,56 +146,56 @@ static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
 	 * bus into the system beyond, and which IOMMU it ends up at.
 	 */
 	iommu_spec.np = NULL;
-	if (of_pci_map_rid(bridge_np, iommu_spec.args[0], "iommu-map",
-			   "iommu-map-mask", &iommu_spec.np, iommu_spec.args))
-		return NULL;
+	err = of_pci_map_rid(bridge_np, iommu_spec.args[0], "iommu-map",
+			     "iommu-map-mask", &iommu_spec.np,
+			     iommu_spec.args);
+	if (err)
+		return err == -ENODEV ? NULL : ERR_PTR(err);
 
-	ops = iommu_ops_from_fwnode(&iommu_spec.np->fwnode);
-	if (!ops || !ops->of_xlate ||
-	    iommu_fwspec_init(&pdev->dev, &iommu_spec.np->fwnode, ops) ||
-	    ops->of_xlate(&pdev->dev, &iommu_spec))
-		ops = NULL;
+	ops = of_iommu_xlate(&pdev->dev, &iommu_spec);
 
 	of_node_put(iommu_spec.np);
 	return ops;
 }
 
-const struct iommu_ops *of_iommu_configure(struct device *dev,
-					   struct device_node *master_np)
+static const struct iommu_ops
+*of_platform_iommu_init(struct device *dev, struct device_node *np)
 {
 	struct of_phandle_args iommu_spec;
-	struct device_node *np;
 	const struct iommu_ops *ops = NULL;
 	int idx = 0;
 
-	if (dev_is_pci(dev))
-		return of_pci_iommu_configure(to_pci_dev(dev), master_np);
-
 	/*
 	 * We don't currently walk up the tree looking for a parent IOMMU.
 	 * See the `Notes:' section of
 	 * Documentation/devicetree/bindings/iommu/iommu.txt
 	 */
-	while (!of_parse_phandle_with_args(master_np, "iommus",
-					   "#iommu-cells", idx,
-					   &iommu_spec)) {
-		np = iommu_spec.np;
-		ops = iommu_ops_from_fwnode(&np->fwnode);
-
-		if (!ops || !ops->of_xlate ||
-		    iommu_fwspec_init(dev, &np->fwnode, ops) ||
-		    ops->of_xlate(dev, &iommu_spec))
-			goto err_put_node;
-
-		of_node_put(np);
+	while (!of_parse_phandle_with_args(np, "iommus", "#iommu-cells",
+					   idx, &iommu_spec)) {
+		ops = of_iommu_xlate(dev, &iommu_spec);
+		of_node_put(iommu_spec.np);
 		idx++;
+		if (IS_ERR_OR_NULL(ops))
+			break;
 	}
 
 	return ops;
+}
+
+const struct iommu_ops *of_iommu_configure(struct device *dev,
+					   struct device_node *master_np)
+{
+	const struct iommu_ops *ops;
+
+	if (!master_np)
+		return NULL;
+
+	if (dev_is_pci(dev))
+		ops = of_pci_iommu_init(to_pci_dev(dev), master_np);
+	else
+		ops = of_platform_iommu_init(dev, master_np);
 
-err_put_node:
-	of_node_put(np);
-	return NULL;
+	return IS_ERR(ops) ? NULL : ops;
 }
 
 static int __init of_iommu_init(void)
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 02/11] iommu/of: Prepare for deferred IOMMU configuration
  2017-04-10 11:20   ` Sricharan R
  (?)
@ 2017-04-10 11:20     ` Sricharan R
  -1 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:20 UTC (permalink / raw)
  To: robin.murphy, will.deacon, joro, lorenzo.pieralisi, iommu,
	linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh
  Cc: sricharan

From: Robin Murphy <robin.murphy@arm.com>

IOMMU configuration represents unchanging properties of the hardware,
and as such should only need happen once in a device's lifetime, but
the necessary interaction with the IOMMU device and driver complicates
exactly when that point should be.

Since the only reasonable tool available for handling the inter-device
dependency is probe deferral, we need to prepare of_iommu_configure()
to run later than it is currently called (i.e. at driver probe rather
than device creation), to handle being retried, and to tell whether a
not-yet present IOMMU should be waited for or skipped (by virtue of
having declared a built-in driver or not).

Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 drivers/iommu/of_iommu.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 8f4e599..c8be889 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -96,6 +96,19 @@ int of_get_dma_window(struct device_node *dn, const char *prefix, int index,
 }
 EXPORT_SYMBOL_GPL(of_get_dma_window);
 
+static bool of_iommu_driver_present(struct device_node *np)
+{
+	/*
+	 * If the IOMMU still isn't ready by the time we reach init, assume
+	 * it never will be. We don't want to defer indefinitely, nor attempt
+	 * to dereference __iommu_of_table after it's been freed.
+	 */
+	if (system_state > SYSTEM_BOOTING)
+		return false;
+
+	return of_match_node(&__iommu_of_table, np);
+}
+
 static const struct iommu_ops
 *of_iommu_xlate(struct device *dev, struct of_phandle_args *iommu_spec)
 {
@@ -104,12 +117,20 @@ int of_get_dma_window(struct device_node *dn, const char *prefix, int index,
 	int err;
 
 	ops = iommu_ops_from_fwnode(fwnode);
-	if (!ops || !ops->of_xlate)
+	if ((ops && !ops->of_xlate) ||
+	    (!ops && !of_iommu_driver_present(iommu_spec->np)))
 		return NULL;
 
 	err = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
 	if (err)
 		return ERR_PTR(err);
+	/*
+	 * The otherwise-empty fwspec handily serves to indicate the specific
+	 * IOMMU device we're waiting for, which will be useful if we ever get
+	 * a proper probe-ordering dependency mechanism in future.
+	 */
+	if (!ops)
+		return ERR_PTR(-EPROBE_DEFER);
 
 	err = ops->of_xlate(dev, iommu_spec);
 	if (err)
@@ -186,14 +207,34 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
 					   struct device_node *master_np)
 {
 	const struct iommu_ops *ops;
+	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
 
 	if (!master_np)
 		return NULL;
 
+	if (fwspec) {
+		if (fwspec->ops)
+			return fwspec->ops;
+
+		/* In the deferred case, start again from scratch */
+		iommu_fwspec_free(dev);
+	}
+
 	if (dev_is_pci(dev))
 		ops = of_pci_iommu_init(to_pci_dev(dev), master_np);
 	else
 		ops = of_platform_iommu_init(dev, master_np);
+	/*
+	 * If we have reason to believe the IOMMU driver missed the initial
+	 * add_device callback for dev, replay it to get things in order.
+	 */
+	if (!IS_ERR_OR_NULL(ops) && ops->add_device &&
+	    dev->bus && !dev->iommu_group) {
+		int err = ops->add_device(dev);
+
+		if (err)
+			ops = ERR_PTR(err);
+	}
 
 	return IS_ERR(ops) ? NULL : ops;
 }
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 02/11] iommu/of: Prepare for deferred IOMMU configuration
@ 2017-04-10 11:20     ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:20 UTC (permalink / raw)
  To: robin.murphy, will.deacon, joro, lorenzo.pieralisi, iommu,
	linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh
  Cc: sricharan

From: Robin Murphy <robin.murphy@arm.com>

IOMMU configuration represents unchanging properties of the hardware,
and as such should only need happen once in a device's lifetime, but
the necessary interaction with the IOMMU device and driver complicates
exactly when that point should be.

Since the only reasonable tool available for handling the inter-device
dependency is probe deferral, we need to prepare of_iommu_configure()
to run later than it is currently called (i.e. at driver probe rather
than device creation), to handle being retried, and to tell whether a
not-yet present IOMMU should be waited for or skipped (by virtue of
having declared a built-in driver or not).

Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 drivers/iommu/of_iommu.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 8f4e599..c8be889 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -96,6 +96,19 @@ int of_get_dma_window(struct device_node *dn, const char *prefix, int index,
 }
 EXPORT_SYMBOL_GPL(of_get_dma_window);
 
+static bool of_iommu_driver_present(struct device_node *np)
+{
+	/*
+	 * If the IOMMU still isn't ready by the time we reach init, assume
+	 * it never will be. We don't want to defer indefinitely, nor attempt
+	 * to dereference __iommu_of_table after it's been freed.
+	 */
+	if (system_state > SYSTEM_BOOTING)
+		return false;
+
+	return of_match_node(&__iommu_of_table, np);
+}
+
 static const struct iommu_ops
 *of_iommu_xlate(struct device *dev, struct of_phandle_args *iommu_spec)
 {
@@ -104,12 +117,20 @@ int of_get_dma_window(struct device_node *dn, const char *prefix, int index,
 	int err;
 
 	ops = iommu_ops_from_fwnode(fwnode);
-	if (!ops || !ops->of_xlate)
+	if ((ops && !ops->of_xlate) ||
+	    (!ops && !of_iommu_driver_present(iommu_spec->np)))
 		return NULL;
 
 	err = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
 	if (err)
 		return ERR_PTR(err);
+	/*
+	 * The otherwise-empty fwspec handily serves to indicate the specific
+	 * IOMMU device we're waiting for, which will be useful if we ever get
+	 * a proper probe-ordering dependency mechanism in future.
+	 */
+	if (!ops)
+		return ERR_PTR(-EPROBE_DEFER);
 
 	err = ops->of_xlate(dev, iommu_spec);
 	if (err)
@@ -186,14 +207,34 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
 					   struct device_node *master_np)
 {
 	const struct iommu_ops *ops;
+	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
 
 	if (!master_np)
 		return NULL;
 
+	if (fwspec) {
+		if (fwspec->ops)
+			return fwspec->ops;
+
+		/* In the deferred case, start again from scratch */
+		iommu_fwspec_free(dev);
+	}
+
 	if (dev_is_pci(dev))
 		ops = of_pci_iommu_init(to_pci_dev(dev), master_np);
 	else
 		ops = of_platform_iommu_init(dev, master_np);
+	/*
+	 * If we have reason to believe the IOMMU driver missed the initial
+	 * add_device callback for dev, replay it to get things in order.
+	 */
+	if (!IS_ERR_OR_NULL(ops) && ops->add_device &&
+	    dev->bus && !dev->iommu_group) {
+		int err = ops->add_device(dev);
+
+		if (err)
+			ops = ERR_PTR(err);
+	}
 
 	return IS_ERR(ops) ? NULL : ops;
 }
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V11 02/11] iommu/of: Prepare for deferred IOMMU configuration
@ 2017-04-10 11:20     ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:20 UTC (permalink / raw)
  To: linux-arm-kernel

From: Robin Murphy <robin.murphy@arm.com>

IOMMU configuration represents unchanging properties of the hardware,
and as such should only need happen once in a device's lifetime, but
the necessary interaction with the IOMMU device and driver complicates
exactly when that point should be.

Since the only reasonable tool available for handling the inter-device
dependency is probe deferral, we need to prepare of_iommu_configure()
to run later than it is currently called (i.e. at driver probe rather
than device creation), to handle being retried, and to tell whether a
not-yet present IOMMU should be waited for or skipped (by virtue of
having declared a built-in driver or not).

Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 drivers/iommu/of_iommu.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 8f4e599..c8be889 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -96,6 +96,19 @@ int of_get_dma_window(struct device_node *dn, const char *prefix, int index,
 }
 EXPORT_SYMBOL_GPL(of_get_dma_window);
 
+static bool of_iommu_driver_present(struct device_node *np)
+{
+	/*
+	 * If the IOMMU still isn't ready by the time we reach init, assume
+	 * it never will be. We don't want to defer indefinitely, nor attempt
+	 * to dereference __iommu_of_table after it's been freed.
+	 */
+	if (system_state > SYSTEM_BOOTING)
+		return false;
+
+	return of_match_node(&__iommu_of_table, np);
+}
+
 static const struct iommu_ops
 *of_iommu_xlate(struct device *dev, struct of_phandle_args *iommu_spec)
 {
@@ -104,12 +117,20 @@ int of_get_dma_window(struct device_node *dn, const char *prefix, int index,
 	int err;
 
 	ops = iommu_ops_from_fwnode(fwnode);
-	if (!ops || !ops->of_xlate)
+	if ((ops && !ops->of_xlate) ||
+	    (!ops && !of_iommu_driver_present(iommu_spec->np)))
 		return NULL;
 
 	err = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
 	if (err)
 		return ERR_PTR(err);
+	/*
+	 * The otherwise-empty fwspec handily serves to indicate the specific
+	 * IOMMU device we're waiting for, which will be useful if we ever get
+	 * a proper probe-ordering dependency mechanism in future.
+	 */
+	if (!ops)
+		return ERR_PTR(-EPROBE_DEFER);
 
 	err = ops->of_xlate(dev, iommu_spec);
 	if (err)
@@ -186,14 +207,34 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
 					   struct device_node *master_np)
 {
 	const struct iommu_ops *ops;
+	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
 
 	if (!master_np)
 		return NULL;
 
+	if (fwspec) {
+		if (fwspec->ops)
+			return fwspec->ops;
+
+		/* In the deferred case, start again from scratch */
+		iommu_fwspec_free(dev);
+	}
+
 	if (dev_is_pci(dev))
 		ops = of_pci_iommu_init(to_pci_dev(dev), master_np);
 	else
 		ops = of_platform_iommu_init(dev, master_np);
+	/*
+	 * If we have reason to believe the IOMMU driver missed the initial
+	 * add_device callback for dev, replay it to get things in order.
+	 */
+	if (!IS_ERR_OR_NULL(ops) && ops->add_device &&
+	    dev->bus && !dev->iommu_group) {
+		int err = ops->add_device(dev);
+
+		if (err)
+			ops = ERR_PTR(err);
+	}
 
 	return IS_ERR(ops) ? NULL : ops;
 }
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 03/11] of: dma: Make of_dma_deconfigure() public
  2017-04-10 11:20   ` Sricharan R
  (?)
@ 2017-04-10 11:20     ` Sricharan R
  -1 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:20 UTC (permalink / raw)
  To: robin.murphy, will.deacon, joro, lorenzo.pieralisi, iommu,
	linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh
  Cc: sricharan, Laurent Pinchart

From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

As part of moving DMA initializing to probe time the
of_dma_deconfigure() function will need to be called from different
source files. Make it public and move it to drivers/of/device.c where
the of_dma_configure() function is.

Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/of/device.c       | 12 ++++++++++++
 drivers/of/platform.c     |  5 -----
 include/linux/of_device.h |  3 +++
 3 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index b1e6beb..0d378c0 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -151,6 +151,18 @@ void of_dma_configure(struct device *dev, struct device_node *np)
 }
 EXPORT_SYMBOL_GPL(of_dma_configure);
 
+/**
+ * of_dma_deconfigure - Clean up DMA configuration
+ * @dev:	Device for which to clean up DMA configuration
+ *
+ * Clean up all configuration performed by of_dma_configure_ops() and free all
+ * resources that have been allocated.
+ */
+void of_dma_deconfigure(struct device *dev)
+{
+	arch_teardown_dma_ops(dev);
+}
+
 int of_device_register(struct platform_device *pdev)
 {
 	device_initialize(&pdev->dev);
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 5dfcc96..5344db5 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -158,11 +158,6 @@ struct platform_device *of_device_alloc(struct device_node *np,
 }
 EXPORT_SYMBOL(of_device_alloc);
 
-static void of_dma_deconfigure(struct device *dev)
-{
-	arch_teardown_dma_ops(dev);
-}
-
 /**
  * of_platform_device_create_pdata - Alloc, initialize and register an of_device
  * @np: pointer to node to create device for
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index c12dace..af98455 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -56,6 +56,7 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
 }
 
 void of_dma_configure(struct device *dev, struct device_node *np);
+void of_dma_deconfigure(struct device *dev);
 #else /* CONFIG_OF */
 
 static inline int of_driver_match_device(struct device *dev,
@@ -105,6 +106,8 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
 }
 static inline void of_dma_configure(struct device *dev, struct device_node *np)
 {}
+static inline void of_dma_deconfigure(struct device *dev)
+{}
 #endif /* CONFIG_OF */
 
 #endif /* _LINUX_OF_DEVICE_H */
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 03/11] of: dma: Make of_dma_deconfigure() public
@ 2017-04-10 11:20     ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:20 UTC (permalink / raw)
  To: robin.murphy, will.deacon, joro, lorenzo.pieralisi, iommu,
	linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh
  Cc: Laurent Pinchart, sricharan

From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

As part of moving DMA initializing to probe time the
of_dma_deconfigure() function will need to be called from different
source files. Make it public and move it to drivers/of/device.c where
the of_dma_configure() function is.

Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/of/device.c       | 12 ++++++++++++
 drivers/of/platform.c     |  5 -----
 include/linux/of_device.h |  3 +++
 3 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index b1e6beb..0d378c0 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -151,6 +151,18 @@ void of_dma_configure(struct device *dev, struct device_node *np)
 }
 EXPORT_SYMBOL_GPL(of_dma_configure);
 
+/**
+ * of_dma_deconfigure - Clean up DMA configuration
+ * @dev:	Device for which to clean up DMA configuration
+ *
+ * Clean up all configuration performed by of_dma_configure_ops() and free all
+ * resources that have been allocated.
+ */
+void of_dma_deconfigure(struct device *dev)
+{
+	arch_teardown_dma_ops(dev);
+}
+
 int of_device_register(struct platform_device *pdev)
 {
 	device_initialize(&pdev->dev);
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 5dfcc96..5344db5 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -158,11 +158,6 @@ struct platform_device *of_device_alloc(struct device_node *np,
 }
 EXPORT_SYMBOL(of_device_alloc);
 
-static void of_dma_deconfigure(struct device *dev)
-{
-	arch_teardown_dma_ops(dev);
-}
-
 /**
  * of_platform_device_create_pdata - Alloc, initialize and register an of_device
  * @np: pointer to node to create device for
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index c12dace..af98455 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -56,6 +56,7 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
 }
 
 void of_dma_configure(struct device *dev, struct device_node *np);
+void of_dma_deconfigure(struct device *dev);
 #else /* CONFIG_OF */
 
 static inline int of_driver_match_device(struct device *dev,
@@ -105,6 +106,8 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
 }
 static inline void of_dma_configure(struct device *dev, struct device_node *np)
 {}
+static inline void of_dma_deconfigure(struct device *dev)
+{}
 #endif /* CONFIG_OF */
 
 #endif /* _LINUX_OF_DEVICE_H */
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V11 03/11] of: dma: Make of_dma_deconfigure() public
@ 2017-04-10 11:20     ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:20 UTC (permalink / raw)
  To: linux-arm-kernel

From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

As part of moving DMA initializing to probe time the
of_dma_deconfigure() function will need to be called from different
source files. Make it public and move it to drivers/of/device.c where
the of_dma_configure() function is.

Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/of/device.c       | 12 ++++++++++++
 drivers/of/platform.c     |  5 -----
 include/linux/of_device.h |  3 +++
 3 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index b1e6beb..0d378c0 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -151,6 +151,18 @@ void of_dma_configure(struct device *dev, struct device_node *np)
 }
 EXPORT_SYMBOL_GPL(of_dma_configure);
 
+/**
+ * of_dma_deconfigure - Clean up DMA configuration
+ * @dev:	Device for which to clean up DMA configuration
+ *
+ * Clean up all configuration performed by of_dma_configure_ops() and free all
+ * resources that have been allocated.
+ */
+void of_dma_deconfigure(struct device *dev)
+{
+	arch_teardown_dma_ops(dev);
+}
+
 int of_device_register(struct platform_device *pdev)
 {
 	device_initialize(&pdev->dev);
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 5dfcc96..5344db5 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -158,11 +158,6 @@ struct platform_device *of_device_alloc(struct device_node *np,
 }
 EXPORT_SYMBOL(of_device_alloc);
 
-static void of_dma_deconfigure(struct device *dev)
-{
-	arch_teardown_dma_ops(dev);
-}
-
 /**
  * of_platform_device_create_pdata - Alloc, initialize and register an of_device
  * @np: pointer to node to create device for
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index c12dace..af98455 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -56,6 +56,7 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
 }
 
 void of_dma_configure(struct device *dev, struct device_node *np);
+void of_dma_deconfigure(struct device *dev);
 #else /* CONFIG_OF */
 
 static inline int of_driver_match_device(struct device *dev,
@@ -105,6 +106,8 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
 }
 static inline void of_dma_configure(struct device *dev, struct device_node *np)
 {}
+static inline void of_dma_deconfigure(struct device *dev)
+{}
 #endif /* CONFIG_OF */
 
 #endif /* _LINUX_OF_DEVICE_H */
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 04/11] ACPI/IORT: Add function to check SMMUs drivers presence
  2017-04-10 11:20   ` Sricharan R
  (?)
@ 2017-04-10 11:20     ` Sricharan R
  -1 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:20 UTC (permalink / raw)
  To: robin.murphy, will.deacon, joro, lorenzo.pieralisi, iommu,
	linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh
  Cc: sricharan

From: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

The IOMMU probe deferral implementation requires a mechanism to detect
if drivers for SMMU components are built-in in the kernel to detect
whether IOMMU configuration for a given device should be deferred (ie
SMMU drivers present but still not probed) or not (drivers not present).

Add a simple function to IORT to detect if SMMU drivers for SMMU
components managed by IORT are built-in in the kernel.

Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Cc: Sricharan R <sricharan@codeaurora.org>
---
 drivers/acpi/arm64/iort.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 4a5bb96..3dd9ec3 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -523,6 +523,19 @@ static int arm_smmu_iort_xlate(struct device *dev, u32 streamid,
 	return ret;
 }
 
+static inline bool iort_iommu_driver_enabled(u8 type)
+{
+	switch (type) {
+	case ACPI_IORT_NODE_SMMU_V3:
+		return IS_BUILTIN(CONFIG_ARM_SMMU_V3);
+	case ACPI_IORT_NODE_SMMU:
+		return IS_BUILTIN(CONFIG_ARM_SMMU);
+	default:
+		pr_warn("IORT node type %u does not describe an SMMU\n", type);
+		return false;
+	}
+}
+
 static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
 					struct acpi_iort_node *node,
 					u32 streamid)
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 04/11] ACPI/IORT: Add function to check SMMUs drivers presence
@ 2017-04-10 11:20     ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:20 UTC (permalink / raw)
  To: robin.murphy, will.deacon, joro, lorenzo.pieralisi, iommu,
	linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh
  Cc: sricharan

From: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

The IOMMU probe deferral implementation requires a mechanism to detect
if drivers for SMMU components are built-in in the kernel to detect
whether IOMMU configuration for a given device should be deferred (ie
SMMU drivers present but still not probed) or not (drivers not present).

Add a simple function to IORT to detect if SMMU drivers for SMMU
components managed by IORT are built-in in the kernel.

Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Cc: Sricharan R <sricharan@codeaurora.org>
---
 drivers/acpi/arm64/iort.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 4a5bb96..3dd9ec3 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -523,6 +523,19 @@ static int arm_smmu_iort_xlate(struct device *dev, u32 streamid,
 	return ret;
 }
 
+static inline bool iort_iommu_driver_enabled(u8 type)
+{
+	switch (type) {
+	case ACPI_IORT_NODE_SMMU_V3:
+		return IS_BUILTIN(CONFIG_ARM_SMMU_V3);
+	case ACPI_IORT_NODE_SMMU:
+		return IS_BUILTIN(CONFIG_ARM_SMMU);
+	default:
+		pr_warn("IORT node type %u does not describe an SMMU\n", type);
+		return false;
+	}
+}
+
 static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
 					struct acpi_iort_node *node,
 					u32 streamid)
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V11 04/11] ACPI/IORT: Add function to check SMMUs drivers presence
@ 2017-04-10 11:20     ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:20 UTC (permalink / raw)
  To: linux-arm-kernel

From: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

The IOMMU probe deferral implementation requires a mechanism to detect
if drivers for SMMU components are built-in in the kernel to detect
whether IOMMU configuration for a given device should be deferred (ie
SMMU drivers present but still not probed) or not (drivers not present).

Add a simple function to IORT to detect if SMMU drivers for SMMU
components managed by IORT are built-in in the kernel.

Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Cc: Sricharan R <sricharan@codeaurora.org>
---
 drivers/acpi/arm64/iort.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 4a5bb96..3dd9ec3 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -523,6 +523,19 @@ static int arm_smmu_iort_xlate(struct device *dev, u32 streamid,
 	return ret;
 }
 
+static inline bool iort_iommu_driver_enabled(u8 type)
+{
+	switch (type) {
+	case ACPI_IORT_NODE_SMMU_V3:
+		return IS_BUILTIN(CONFIG_ARM_SMMU_V3);
+	case ACPI_IORT_NODE_SMMU:
+		return IS_BUILTIN(CONFIG_ARM_SMMU);
+	default:
+		pr_warn("IORT node type %u does not describe an SMMU\n", type);
+		return false;
+	}
+}
+
 static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
 					struct acpi_iort_node *node,
 					u32 streamid)
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 05/11] of: device: Fix overflow of coherent_dma_mask
  2017-04-10 11:20   ` Sricharan R
@ 2017-04-10 11:21     ` Sricharan R
  -1 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
  To: robin.murphy, will.deacon, joro, lorenzo.pieralisi, iommu,
	linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh
  Cc: sricharan

Size of the dma-range is calculated as coherent_dma_mask + 1
and passed to arch_setup_dma_ops further. It overflows when
the coherent_dma_mask is set for full 64 bits 0xFFFFFFFFFFFFFFFF,
resulting in size getting passed as 0 wrongly. Fix this by
passsing in max(mask, mask + 1). Note that in this case
when the mask is set to full 64bits, we will be passing the mask
itself to arch_setup_dma_ops instead of the size. The real fix
for this should be to make arch_setup_dma_ops receive the
mask and handle it, to be done in the future.

Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
---
 drivers/of/device.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index 0d378c0..e1ae9e7 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -107,7 +107,7 @@ void of_dma_configure(struct device *dev, struct device_node *np)
 	ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
 	if (ret < 0) {
 		dma_addr = offset = 0;
-		size = dev->coherent_dma_mask + 1;
+		size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
 	} else {
 		offset = PFN_DOWN(paddr - dma_addr);
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation


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

* [PATCH V11 05/11] of: device: Fix overflow of coherent_dma_mask
@ 2017-04-10 11:21     ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
  To: linux-arm-kernel

Size of the dma-range is calculated as coherent_dma_mask + 1
and passed to arch_setup_dma_ops further. It overflows when
the coherent_dma_mask is set for full 64 bits 0xFFFFFFFFFFFFFFFF,
resulting in size getting passed as 0 wrongly. Fix this by
passsing in max(mask, mask + 1). Note that in this case
when the mask is set to full 64bits, we will be passing the mask
itself to arch_setup_dma_ops instead of the size. The real fix
for this should be to make arch_setup_dma_ops receive the
mask and handle it, to be done in the future.

Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
---
 drivers/of/device.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index 0d378c0..e1ae9e7 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -107,7 +107,7 @@ void of_dma_configure(struct device *dev, struct device_node *np)
 	ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
 	if (ret < 0) {
 		dma_addr = offset = 0;
-		size = dev->coherent_dma_mask + 1;
+		size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
 	} else {
 		offset = PFN_DOWN(paddr - dma_addr);
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 06/11] of/acpi: Configure dma operations at probe time for platform/amba/pci bus devices
  2017-04-10 11:20   ` Sricharan R
  (?)
  (?)
@ 2017-04-10 11:21       ` Sricharan R
  -1 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
  To: robin.murphy-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
	joro-zLv9SwRftAIdnm+yROfE0A, lorenzo.pieralisi-5wv7dgnIgG8,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ,
	bhelgaas-hpIqsD4AKlfQT0dZR+AlfA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
	hanjun.guo-QSEj5FYQhm4dnm+yROfE0A, okaya-sgV2jX0FEOL9JmXXK+q4OQ,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, sudeep.holla-5wv7dgnIgG8,
	rjw-LthD3rsA81gm4RdzfppkhA, lenb-DgEjT+Ai2ygdnm+yROfE0A,
	catalin.marinas-5wv7dgnIgG8, arnd-r2nGTMty4D4,
	linux-arch-u79uwXL29TY76Z2rM5mHXA,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r

Configuring DMA ops at probe time will allow deferring device probe when
the IOMMU isn't available yet. The dma_configure for the device is
now called from the generic device_attach callback just before the
bus/driver probe is called. This way, configuring the DMA ops for the
device would be called at the same place for all bus_types, hence the
deferred probing mechanism should work for all buses as well.

pci_bus_add_devices    (platform/amba)(_device_create/driver_register)
       |                         |
pci_bus_add_device     (device_add/driver_register)
       |                         |
device_attach           device_initial_probe
       |                         |
__device_attach_driver    __device_attach_driver
       |
driver_probe_device
       |
really_probe
       |
dma_configure

Similarly on the device/driver_unregister path __device_release_driver is
called which inturn calls dma_deconfigure.

This patch changes the dma ops configuration to probe time for
both OF and ACPI based platform/amba/pci bus devices.

Tested-by: Marek Szyprowski <m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Tested-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Reviewed-by: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Acked-by: Bjorn Helgaas <bhelgaas-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org> (drivers/pci part)
Acked-by: Rafael J. Wysocki <rafael.j.wysocki-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Signed-off-by: Sricharan R <sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
---
 drivers/acpi/glue.c         |  5 -----
 drivers/base/dd.c           |  9 +++++++++
 drivers/base/dma-mapping.c  | 40 ++++++++++++++++++++++++++++++++++++++++
 drivers/of/platform.c       |  5 +----
 drivers/pci/probe.c         | 28 ----------------------------
 include/linux/dma-mapping.h | 12 ++++++++++++
 6 files changed, 62 insertions(+), 37 deletions(-)

diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index fb19e1c..c05f241 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -176,7 +176,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
 	struct list_head *physnode_list;
 	unsigned int node_id;
 	int retval = -EINVAL;
-	enum dev_dma_attr attr;
 
 	if (has_acpi_companion(dev)) {
 		if (acpi_dev) {
@@ -233,10 +232,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
 	if (!has_acpi_companion(dev))
 		ACPI_COMPANION_SET(dev, acpi_dev);
 
-	attr = acpi_get_dma_attr(acpi_dev);
-	if (attr != DEV_DMA_NOT_SUPPORTED)
-		acpi_dma_configure(dev, attr);
-
 	acpi_physnode_link_name(physical_node_name, node_id);
 	retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
 				   physical_node_name);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index a1fbf55..4882f06 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -19,6 +19,7 @@
 
 #include <linux/device.h>
 #include <linux/delay.h>
+#include <linux/dma-mapping.h>
 #include <linux/module.h>
 #include <linux/kthread.h>
 #include <linux/wait.h>
@@ -356,6 +357,10 @@ static int really_probe(struct device *dev, struct device_driver *drv)
 	if (ret)
 		goto pinctrl_bind_failed;
 
+	ret = dma_configure(dev);
+	if (ret)
+		goto dma_failed;
+
 	if (driver_sysfs_add(dev)) {
 		printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
 			__func__, dev_name(dev));
@@ -417,6 +422,8 @@ static int really_probe(struct device *dev, struct device_driver *drv)
 	goto done;
 
 probe_failed:
+	dma_deconfigure(dev);
+dma_failed:
 	if (dev->bus)
 		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
 					     BUS_NOTIFY_DRIVER_NOT_BOUND, dev);
@@ -826,6 +833,8 @@ static void __device_release_driver(struct device *dev, struct device *parent)
 			drv->remove(dev);
 
 		device_links_driver_cleanup(dev);
+		dma_deconfigure(dev);
+
 		devres_release_all(dev);
 		dev->driver = NULL;
 		dev_set_drvdata(dev, NULL);
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index efd71cf..449b948 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -7,9 +7,11 @@
  * This file is released under the GPLv2.
  */
 
+#include <linux/acpi.h>
 #include <linux/dma-mapping.h>
 #include <linux/export.h>
 #include <linux/gfp.h>
+#include <linux/of_device.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 
@@ -341,3 +343,41 @@ void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags)
 	vunmap(cpu_addr);
 }
 #endif
+
+/*
+ * Common configuration to enable DMA API use for a device
+ */
+#include <linux/pci.h>
+
+int dma_configure(struct device *dev)
+{
+	struct device *bridge = NULL, *dma_dev = dev;
+	enum dev_dma_attr attr;
+
+	if (dev_is_pci(dev)) {
+		bridge = pci_get_host_bridge_device(to_pci_dev(dev));
+		dma_dev = bridge;
+		if (IS_ENABLED(CONFIG_OF) && dma_dev->parent &&
+		    dma_dev->parent->of_node)
+			dma_dev = dma_dev->parent;
+	}
+
+	if (dma_dev->of_node) {
+		of_dma_configure(dev, dma_dev->of_node);
+	} else if (has_acpi_companion(dma_dev)) {
+		attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
+		if (attr != DEV_DMA_NOT_SUPPORTED)
+			acpi_dma_configure(dev, attr);
+	}
+
+	if (bridge)
+		pci_put_host_bridge_device(bridge);
+
+	return 0;
+}
+
+void dma_deconfigure(struct device *dev)
+{
+	of_dma_deconfigure(dev);
+	acpi_dma_deconfigure(dev);
+}
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 5344db5..2aa4ebb 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
+#include <linux/of_iommu.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
@@ -186,11 +187,9 @@ static struct platform_device *of_platform_device_create_pdata(
 
 	dev->dev.bus = &platform_bus_type;
 	dev->dev.platform_data = platform_data;
-	of_dma_configure(&dev->dev, dev->dev.of_node);
 	of_msi_configure(&dev->dev, dev->dev.of_node);
 
 	if (of_device_add(dev) != 0) {
-		of_dma_deconfigure(&dev->dev);
 		platform_device_put(dev);
 		goto err_clear_flag;
 	}
@@ -248,7 +247,6 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
 		dev_set_name(&dev->dev, "%s", bus_id);
 	else
 		of_device_make_bus_id(&dev->dev);
-	of_dma_configure(&dev->dev, dev->dev.of_node);
 
 	/* Allow the HW Peripheral ID to be overridden */
 	prop = of_get_property(node, "arm,primecell-periphid", NULL);
@@ -542,7 +540,6 @@ static int of_platform_device_destroy(struct device *dev, void *data)
 		amba_device_unregister(to_amba_device(dev));
 #endif
 
-	of_dma_deconfigure(dev);
 	of_node_clear_flag(dev->of_node, OF_POPULATED);
 	of_node_clear_flag(dev->of_node, OF_POPULATED_BUS);
 	return 0;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index dfc9a27..5a8dd43 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1893,33 +1893,6 @@ static void pci_set_msi_domain(struct pci_dev *dev)
 	dev_set_msi_domain(&dev->dev, d);
 }
 
-/**
- * pci_dma_configure - Setup DMA configuration
- * @dev: ptr to pci_dev struct of the PCI device
- *
- * Function to update PCI devices's DMA configuration using the same
- * info from the OF node or ACPI node of host bridge's parent (if any).
- */
-static void pci_dma_configure(struct pci_dev *dev)
-{
-	struct device *bridge = pci_get_host_bridge_device(dev);
-
-	if (IS_ENABLED(CONFIG_OF) &&
-		bridge->parent && bridge->parent->of_node) {
-			of_dma_configure(&dev->dev, bridge->parent->of_node);
-	} else if (has_acpi_companion(bridge)) {
-		struct acpi_device *adev = to_acpi_device_node(bridge->fwnode);
-		enum dev_dma_attr attr = acpi_get_dma_attr(adev);
-
-		if (attr == DEV_DMA_NOT_SUPPORTED)
-			dev_warn(&dev->dev, "DMA not supported.\n");
-		else
-			acpi_dma_configure(&dev->dev, attr);
-	}
-
-	pci_put_host_bridge_device(bridge);
-}
-
 void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 {
 	int ret;
@@ -1933,7 +1906,6 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 	dev->dev.dma_mask = &dev->dma_mask;
 	dev->dev.dma_parms = &dev->dma_parms;
 	dev->dev.coherent_dma_mask = 0xffffffffull;
-	pci_dma_configure(dev);
 
 	pci_set_dma_max_seg_size(dev, 65536);
 	pci_set_dma_seg_boundary(dev, 0xffffffff);
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 0977317..4f3eece 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -728,6 +728,18 @@ void *dma_mark_declared_memory_occupied(struct device *dev,
 }
 #endif /* CONFIG_HAVE_GENERIC_DMA_COHERENT */
 
+#ifdef CONFIG_HAS_DMA
+int dma_configure(struct device *dev);
+void dma_deconfigure(struct device *dev);
+#else
+static inline int dma_configure(struct device *dev)
+{
+	return 0;
+}
+
+static inline void dma_deconfigure(struct device *dev) {}
+#endif
+
 /*
  * Managed DMA API
  */
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 06/11] of/acpi: Configure dma operations at probe time for platform/amba/pci bus devices
@ 2017-04-10 11:21       ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
  To: robin.murphy, will.deacon, joro, lorenzo.pieralisi, iommu,
	linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh
  Cc: sricharan

Configuring DMA ops at probe time will allow deferring device probe when
the IOMMU isn't available yet. The dma_configure for the device is
now called from the generic device_attach callback just before the
bus/driver probe is called. This way, configuring the DMA ops for the
device would be called at the same place for all bus_types, hence the
deferred probing mechanism should work for all buses as well.

pci_bus_add_devices    (platform/amba)(_device_create/driver_register)
       |                         |
pci_bus_add_device     (device_add/driver_register)
       |                         |
device_attach           device_initial_probe
       |                         |
__device_attach_driver    __device_attach_driver
       |
driver_probe_device
       |
really_probe
       |
dma_configure

Similarly on the device/driver_unregister path __device_release_driver is
called which inturn calls dma_deconfigure.

This patch changes the dma ops configuration to probe time for
both OF and ACPI based platform/amba/pci bus devices.

Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bjorn Helgaas <bhelgaas@google.com> (drivers/pci part)
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
---
 drivers/acpi/glue.c         |  5 -----
 drivers/base/dd.c           |  9 +++++++++
 drivers/base/dma-mapping.c  | 40 ++++++++++++++++++++++++++++++++++++++++
 drivers/of/platform.c       |  5 +----
 drivers/pci/probe.c         | 28 ----------------------------
 include/linux/dma-mapping.h | 12 ++++++++++++
 6 files changed, 62 insertions(+), 37 deletions(-)

diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index fb19e1c..c05f241 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -176,7 +176,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
 	struct list_head *physnode_list;
 	unsigned int node_id;
 	int retval = -EINVAL;
-	enum dev_dma_attr attr;
 
 	if (has_acpi_companion(dev)) {
 		if (acpi_dev) {
@@ -233,10 +232,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
 	if (!has_acpi_companion(dev))
 		ACPI_COMPANION_SET(dev, acpi_dev);
 
-	attr = acpi_get_dma_attr(acpi_dev);
-	if (attr != DEV_DMA_NOT_SUPPORTED)
-		acpi_dma_configure(dev, attr);
-
 	acpi_physnode_link_name(physical_node_name, node_id);
 	retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
 				   physical_node_name);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index a1fbf55..4882f06 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -19,6 +19,7 @@
 
 #include <linux/device.h>
 #include <linux/delay.h>
+#include <linux/dma-mapping.h>
 #include <linux/module.h>
 #include <linux/kthread.h>
 #include <linux/wait.h>
@@ -356,6 +357,10 @@ static int really_probe(struct device *dev, struct device_driver *drv)
 	if (ret)
 		goto pinctrl_bind_failed;
 
+	ret = dma_configure(dev);
+	if (ret)
+		goto dma_failed;
+
 	if (driver_sysfs_add(dev)) {
 		printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
 			__func__, dev_name(dev));
@@ -417,6 +422,8 @@ static int really_probe(struct device *dev, struct device_driver *drv)
 	goto done;
 
 probe_failed:
+	dma_deconfigure(dev);
+dma_failed:
 	if (dev->bus)
 		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
 					     BUS_NOTIFY_DRIVER_NOT_BOUND, dev);
@@ -826,6 +833,8 @@ static void __device_release_driver(struct device *dev, struct device *parent)
 			drv->remove(dev);
 
 		device_links_driver_cleanup(dev);
+		dma_deconfigure(dev);
+
 		devres_release_all(dev);
 		dev->driver = NULL;
 		dev_set_drvdata(dev, NULL);
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index efd71cf..449b948 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -7,9 +7,11 @@
  * This file is released under the GPLv2.
  */
 
+#include <linux/acpi.h>
 #include <linux/dma-mapping.h>
 #include <linux/export.h>
 #include <linux/gfp.h>
+#include <linux/of_device.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 
@@ -341,3 +343,41 @@ void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags)
 	vunmap(cpu_addr);
 }
 #endif
+
+/*
+ * Common configuration to enable DMA API use for a device
+ */
+#include <linux/pci.h>
+
+int dma_configure(struct device *dev)
+{
+	struct device *bridge = NULL, *dma_dev = dev;
+	enum dev_dma_attr attr;
+
+	if (dev_is_pci(dev)) {
+		bridge = pci_get_host_bridge_device(to_pci_dev(dev));
+		dma_dev = bridge;
+		if (IS_ENABLED(CONFIG_OF) && dma_dev->parent &&
+		    dma_dev->parent->of_node)
+			dma_dev = dma_dev->parent;
+	}
+
+	if (dma_dev->of_node) {
+		of_dma_configure(dev, dma_dev->of_node);
+	} else if (has_acpi_companion(dma_dev)) {
+		attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
+		if (attr != DEV_DMA_NOT_SUPPORTED)
+			acpi_dma_configure(dev, attr);
+	}
+
+	if (bridge)
+		pci_put_host_bridge_device(bridge);
+
+	return 0;
+}
+
+void dma_deconfigure(struct device *dev)
+{
+	of_dma_deconfigure(dev);
+	acpi_dma_deconfigure(dev);
+}
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 5344db5..2aa4ebb 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
+#include <linux/of_iommu.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
@@ -186,11 +187,9 @@ static struct platform_device *of_platform_device_create_pdata(
 
 	dev->dev.bus = &platform_bus_type;
 	dev->dev.platform_data = platform_data;
-	of_dma_configure(&dev->dev, dev->dev.of_node);
 	of_msi_configure(&dev->dev, dev->dev.of_node);
 
 	if (of_device_add(dev) != 0) {
-		of_dma_deconfigure(&dev->dev);
 		platform_device_put(dev);
 		goto err_clear_flag;
 	}
@@ -248,7 +247,6 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
 		dev_set_name(&dev->dev, "%s", bus_id);
 	else
 		of_device_make_bus_id(&dev->dev);
-	of_dma_configure(&dev->dev, dev->dev.of_node);
 
 	/* Allow the HW Peripheral ID to be overridden */
 	prop = of_get_property(node, "arm,primecell-periphid", NULL);
@@ -542,7 +540,6 @@ static int of_platform_device_destroy(struct device *dev, void *data)
 		amba_device_unregister(to_amba_device(dev));
 #endif
 
-	of_dma_deconfigure(dev);
 	of_node_clear_flag(dev->of_node, OF_POPULATED);
 	of_node_clear_flag(dev->of_node, OF_POPULATED_BUS);
 	return 0;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index dfc9a27..5a8dd43 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1893,33 +1893,6 @@ static void pci_set_msi_domain(struct pci_dev *dev)
 	dev_set_msi_domain(&dev->dev, d);
 }
 
-/**
- * pci_dma_configure - Setup DMA configuration
- * @dev: ptr to pci_dev struct of the PCI device
- *
- * Function to update PCI devices's DMA configuration using the same
- * info from the OF node or ACPI node of host bridge's parent (if any).
- */
-static void pci_dma_configure(struct pci_dev *dev)
-{
-	struct device *bridge = pci_get_host_bridge_device(dev);
-
-	if (IS_ENABLED(CONFIG_OF) &&
-		bridge->parent && bridge->parent->of_node) {
-			of_dma_configure(&dev->dev, bridge->parent->of_node);
-	} else if (has_acpi_companion(bridge)) {
-		struct acpi_device *adev = to_acpi_device_node(bridge->fwnode);
-		enum dev_dma_attr attr = acpi_get_dma_attr(adev);
-
-		if (attr == DEV_DMA_NOT_SUPPORTED)
-			dev_warn(&dev->dev, "DMA not supported.\n");
-		else
-			acpi_dma_configure(&dev->dev, attr);
-	}
-
-	pci_put_host_bridge_device(bridge);
-}
-
 void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 {
 	int ret;
@@ -1933,7 +1906,6 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 	dev->dev.dma_mask = &dev->dma_mask;
 	dev->dev.dma_parms = &dev->dma_parms;
 	dev->dev.coherent_dma_mask = 0xffffffffull;
-	pci_dma_configure(dev);
 
 	pci_set_dma_max_seg_size(dev, 65536);
 	pci_set_dma_seg_boundary(dev, 0xffffffff);
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 0977317..4f3eece 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -728,6 +728,18 @@ void *dma_mark_declared_memory_occupied(struct device *dev,
 }
 #endif /* CONFIG_HAVE_GENERIC_DMA_COHERENT */
 
+#ifdef CONFIG_HAS_DMA
+int dma_configure(struct device *dev);
+void dma_deconfigure(struct device *dev);
+#else
+static inline int dma_configure(struct device *dev)
+{
+	return 0;
+}
+
+static inline void dma_deconfigure(struct device *dev) {}
+#endif
+
 /*
  * Managed DMA API
  */
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 06/11] of/acpi: Configure dma operations at probe time for platform/amba/pci bus devices
@ 2017-04-10 11:21       ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
  To: robin.murphy, will.deacon, joro, lorenzo.pieralisi, iommu,
	linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh
  Cc: sricharan

Configuring DMA ops at probe time will allow deferring device probe when
the IOMMU isn't available yet. The dma_configure for the device is
now called from the generic device_attach callback just before the
bus/driver probe is called. This way, configuring the DMA ops for the
device would be called at the same place for all bus_types, hence the
deferred probing mechanism should work for all buses as well.

pci_bus_add_devices    (platform/amba)(_device_create/driver_register)
       |                         |
pci_bus_add_device     (device_add/driver_register)
       |                         |
device_attach           device_initial_probe
       |                         |
__device_attach_driver    __device_attach_driver
       |
driver_probe_device
       |
really_probe
       |
dma_configure

Similarly on the device/driver_unregister path __device_release_driver is
called which inturn calls dma_deconfigure.

This patch changes the dma ops configuration to probe time for
both OF and ACPI based platform/amba/pci bus devices.

Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bjorn Helgaas <bhelgaas@google.com> (drivers/pci part)
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
---
 drivers/acpi/glue.c         |  5 -----
 drivers/base/dd.c           |  9 +++++++++
 drivers/base/dma-mapping.c  | 40 ++++++++++++++++++++++++++++++++++++++++
 drivers/of/platform.c       |  5 +----
 drivers/pci/probe.c         | 28 ----------------------------
 include/linux/dma-mapping.h | 12 ++++++++++++
 6 files changed, 62 insertions(+), 37 deletions(-)

diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index fb19e1c..c05f241 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -176,7 +176,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
 	struct list_head *physnode_list;
 	unsigned int node_id;
 	int retval = -EINVAL;
-	enum dev_dma_attr attr;
 
 	if (has_acpi_companion(dev)) {
 		if (acpi_dev) {
@@ -233,10 +232,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
 	if (!has_acpi_companion(dev))
 		ACPI_COMPANION_SET(dev, acpi_dev);
 
-	attr = acpi_get_dma_attr(acpi_dev);
-	if (attr != DEV_DMA_NOT_SUPPORTED)
-		acpi_dma_configure(dev, attr);
-
 	acpi_physnode_link_name(physical_node_name, node_id);
 	retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
 				   physical_node_name);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index a1fbf55..4882f06 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -19,6 +19,7 @@
 
 #include <linux/device.h>
 #include <linux/delay.h>
+#include <linux/dma-mapping.h>
 #include <linux/module.h>
 #include <linux/kthread.h>
 #include <linux/wait.h>
@@ -356,6 +357,10 @@ static int really_probe(struct device *dev, struct device_driver *drv)
 	if (ret)
 		goto pinctrl_bind_failed;
 
+	ret = dma_configure(dev);
+	if (ret)
+		goto dma_failed;
+
 	if (driver_sysfs_add(dev)) {
 		printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
 			__func__, dev_name(dev));
@@ -417,6 +422,8 @@ static int really_probe(struct device *dev, struct device_driver *drv)
 	goto done;
 
 probe_failed:
+	dma_deconfigure(dev);
+dma_failed:
 	if (dev->bus)
 		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
 					     BUS_NOTIFY_DRIVER_NOT_BOUND, dev);
@@ -826,6 +833,8 @@ static void __device_release_driver(struct device *dev, struct device *parent)
 			drv->remove(dev);
 
 		device_links_driver_cleanup(dev);
+		dma_deconfigure(dev);
+
 		devres_release_all(dev);
 		dev->driver = NULL;
 		dev_set_drvdata(dev, NULL);
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index efd71cf..449b948 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -7,9 +7,11 @@
  * This file is released under the GPLv2.
  */
 
+#include <linux/acpi.h>
 #include <linux/dma-mapping.h>
 #include <linux/export.h>
 #include <linux/gfp.h>
+#include <linux/of_device.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 
@@ -341,3 +343,41 @@ void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags)
 	vunmap(cpu_addr);
 }
 #endif
+
+/*
+ * Common configuration to enable DMA API use for a device
+ */
+#include <linux/pci.h>
+
+int dma_configure(struct device *dev)
+{
+	struct device *bridge = NULL, *dma_dev = dev;
+	enum dev_dma_attr attr;
+
+	if (dev_is_pci(dev)) {
+		bridge = pci_get_host_bridge_device(to_pci_dev(dev));
+		dma_dev = bridge;
+		if (IS_ENABLED(CONFIG_OF) && dma_dev->parent &&
+		    dma_dev->parent->of_node)
+			dma_dev = dma_dev->parent;
+	}
+
+	if (dma_dev->of_node) {
+		of_dma_configure(dev, dma_dev->of_node);
+	} else if (has_acpi_companion(dma_dev)) {
+		attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
+		if (attr != DEV_DMA_NOT_SUPPORTED)
+			acpi_dma_configure(dev, attr);
+	}
+
+	if (bridge)
+		pci_put_host_bridge_device(bridge);
+
+	return 0;
+}
+
+void dma_deconfigure(struct device *dev)
+{
+	of_dma_deconfigure(dev);
+	acpi_dma_deconfigure(dev);
+}
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 5344db5..2aa4ebb 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
+#include <linux/of_iommu.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
@@ -186,11 +187,9 @@ static struct platform_device *of_platform_device_create_pdata(
 
 	dev->dev.bus = &platform_bus_type;
 	dev->dev.platform_data = platform_data;
-	of_dma_configure(&dev->dev, dev->dev.of_node);
 	of_msi_configure(&dev->dev, dev->dev.of_node);
 
 	if (of_device_add(dev) != 0) {
-		of_dma_deconfigure(&dev->dev);
 		platform_device_put(dev);
 		goto err_clear_flag;
 	}
@@ -248,7 +247,6 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
 		dev_set_name(&dev->dev, "%s", bus_id);
 	else
 		of_device_make_bus_id(&dev->dev);
-	of_dma_configure(&dev->dev, dev->dev.of_node);
 
 	/* Allow the HW Peripheral ID to be overridden */
 	prop = of_get_property(node, "arm,primecell-periphid", NULL);
@@ -542,7 +540,6 @@ static int of_platform_device_destroy(struct device *dev, void *data)
 		amba_device_unregister(to_amba_device(dev));
 #endif
 
-	of_dma_deconfigure(dev);
 	of_node_clear_flag(dev->of_node, OF_POPULATED);
 	of_node_clear_flag(dev->of_node, OF_POPULATED_BUS);
 	return 0;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index dfc9a27..5a8dd43 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1893,33 +1893,6 @@ static void pci_set_msi_domain(struct pci_dev *dev)
 	dev_set_msi_domain(&dev->dev, d);
 }
 
-/**
- * pci_dma_configure - Setup DMA configuration
- * @dev: ptr to pci_dev struct of the PCI device
- *
- * Function to update PCI devices's DMA configuration using the same
- * info from the OF node or ACPI node of host bridge's parent (if any).
- */
-static void pci_dma_configure(struct pci_dev *dev)
-{
-	struct device *bridge = pci_get_host_bridge_device(dev);
-
-	if (IS_ENABLED(CONFIG_OF) &&
-		bridge->parent && bridge->parent->of_node) {
-			of_dma_configure(&dev->dev, bridge->parent->of_node);
-	} else if (has_acpi_companion(bridge)) {
-		struct acpi_device *adev = to_acpi_device_node(bridge->fwnode);
-		enum dev_dma_attr attr = acpi_get_dma_attr(adev);
-
-		if (attr == DEV_DMA_NOT_SUPPORTED)
-			dev_warn(&dev->dev, "DMA not supported.\n");
-		else
-			acpi_dma_configure(&dev->dev, attr);
-	}
-
-	pci_put_host_bridge_device(bridge);
-}
-
 void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 {
 	int ret;
@@ -1933,7 +1906,6 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 	dev->dev.dma_mask = &dev->dma_mask;
 	dev->dev.dma_parms = &dev->dma_parms;
 	dev->dev.coherent_dma_mask = 0xffffffffull;
-	pci_dma_configure(dev);
 
 	pci_set_dma_max_seg_size(dev, 65536);
 	pci_set_dma_seg_boundary(dev, 0xffffffff);
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 0977317..4f3eece 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -728,6 +728,18 @@ void *dma_mark_declared_memory_occupied(struct device *dev,
 }
 #endif /* CONFIG_HAVE_GENERIC_DMA_COHERENT */
 
+#ifdef CONFIG_HAS_DMA
+int dma_configure(struct device *dev);
+void dma_deconfigure(struct device *dev);
+#else
+static inline int dma_configure(struct device *dev)
+{
+	return 0;
+}
+
+static inline void dma_deconfigure(struct device *dev) {}
+#endif
+
 /*
  * Managed DMA API
  */
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V11 06/11] of/acpi: Configure dma operations at probe time for platform/amba/pci bus devices
@ 2017-04-10 11:21       ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
  To: linux-arm-kernel

Configuring DMA ops at probe time will allow deferring device probe when
the IOMMU isn't available yet. The dma_configure for the device is
now called from the generic device_attach callback just before the
bus/driver probe is called. This way, configuring the DMA ops for the
device would be called at the same place for all bus_types, hence the
deferred probing mechanism should work for all buses as well.

pci_bus_add_devices    (platform/amba)(_device_create/driver_register)
       |                         |
pci_bus_add_device     (device_add/driver_register)
       |                         |
device_attach           device_initial_probe
       |                         |
__device_attach_driver    __device_attach_driver
       |
driver_probe_device
       |
really_probe
       |
dma_configure

Similarly on the device/driver_unregister path __device_release_driver is
called which inturn calls dma_deconfigure.

This patch changes the dma ops configuration to probe time for
both OF and ACPI based platform/amba/pci bus devices.

Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bjorn Helgaas <bhelgaas@google.com> (drivers/pci part)
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
---
 drivers/acpi/glue.c         |  5 -----
 drivers/base/dd.c           |  9 +++++++++
 drivers/base/dma-mapping.c  | 40 ++++++++++++++++++++++++++++++++++++++++
 drivers/of/platform.c       |  5 +----
 drivers/pci/probe.c         | 28 ----------------------------
 include/linux/dma-mapping.h | 12 ++++++++++++
 6 files changed, 62 insertions(+), 37 deletions(-)

diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index fb19e1c..c05f241 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -176,7 +176,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
 	struct list_head *physnode_list;
 	unsigned int node_id;
 	int retval = -EINVAL;
-	enum dev_dma_attr attr;
 
 	if (has_acpi_companion(dev)) {
 		if (acpi_dev) {
@@ -233,10 +232,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
 	if (!has_acpi_companion(dev))
 		ACPI_COMPANION_SET(dev, acpi_dev);
 
-	attr = acpi_get_dma_attr(acpi_dev);
-	if (attr != DEV_DMA_NOT_SUPPORTED)
-		acpi_dma_configure(dev, attr);
-
 	acpi_physnode_link_name(physical_node_name, node_id);
 	retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
 				   physical_node_name);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index a1fbf55..4882f06 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -19,6 +19,7 @@
 
 #include <linux/device.h>
 #include <linux/delay.h>
+#include <linux/dma-mapping.h>
 #include <linux/module.h>
 #include <linux/kthread.h>
 #include <linux/wait.h>
@@ -356,6 +357,10 @@ static int really_probe(struct device *dev, struct device_driver *drv)
 	if (ret)
 		goto pinctrl_bind_failed;
 
+	ret = dma_configure(dev);
+	if (ret)
+		goto dma_failed;
+
 	if (driver_sysfs_add(dev)) {
 		printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
 			__func__, dev_name(dev));
@@ -417,6 +422,8 @@ static int really_probe(struct device *dev, struct device_driver *drv)
 	goto done;
 
 probe_failed:
+	dma_deconfigure(dev);
+dma_failed:
 	if (dev->bus)
 		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
 					     BUS_NOTIFY_DRIVER_NOT_BOUND, dev);
@@ -826,6 +833,8 @@ static void __device_release_driver(struct device *dev, struct device *parent)
 			drv->remove(dev);
 
 		device_links_driver_cleanup(dev);
+		dma_deconfigure(dev);
+
 		devres_release_all(dev);
 		dev->driver = NULL;
 		dev_set_drvdata(dev, NULL);
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index efd71cf..449b948 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -7,9 +7,11 @@
  * This file is released under the GPLv2.
  */
 
+#include <linux/acpi.h>
 #include <linux/dma-mapping.h>
 #include <linux/export.h>
 #include <linux/gfp.h>
+#include <linux/of_device.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 
@@ -341,3 +343,41 @@ void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags)
 	vunmap(cpu_addr);
 }
 #endif
+
+/*
+ * Common configuration to enable DMA API use for a device
+ */
+#include <linux/pci.h>
+
+int dma_configure(struct device *dev)
+{
+	struct device *bridge = NULL, *dma_dev = dev;
+	enum dev_dma_attr attr;
+
+	if (dev_is_pci(dev)) {
+		bridge = pci_get_host_bridge_device(to_pci_dev(dev));
+		dma_dev = bridge;
+		if (IS_ENABLED(CONFIG_OF) && dma_dev->parent &&
+		    dma_dev->parent->of_node)
+			dma_dev = dma_dev->parent;
+	}
+
+	if (dma_dev->of_node) {
+		of_dma_configure(dev, dma_dev->of_node);
+	} else if (has_acpi_companion(dma_dev)) {
+		attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
+		if (attr != DEV_DMA_NOT_SUPPORTED)
+			acpi_dma_configure(dev, attr);
+	}
+
+	if (bridge)
+		pci_put_host_bridge_device(bridge);
+
+	return 0;
+}
+
+void dma_deconfigure(struct device *dev)
+{
+	of_dma_deconfigure(dev);
+	acpi_dma_deconfigure(dev);
+}
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 5344db5..2aa4ebb 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
+#include <linux/of_iommu.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
@@ -186,11 +187,9 @@ static struct platform_device *of_platform_device_create_pdata(
 
 	dev->dev.bus = &platform_bus_type;
 	dev->dev.platform_data = platform_data;
-	of_dma_configure(&dev->dev, dev->dev.of_node);
 	of_msi_configure(&dev->dev, dev->dev.of_node);
 
 	if (of_device_add(dev) != 0) {
-		of_dma_deconfigure(&dev->dev);
 		platform_device_put(dev);
 		goto err_clear_flag;
 	}
@@ -248,7 +247,6 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
 		dev_set_name(&dev->dev, "%s", bus_id);
 	else
 		of_device_make_bus_id(&dev->dev);
-	of_dma_configure(&dev->dev, dev->dev.of_node);
 
 	/* Allow the HW Peripheral ID to be overridden */
 	prop = of_get_property(node, "arm,primecell-periphid", NULL);
@@ -542,7 +540,6 @@ static int of_platform_device_destroy(struct device *dev, void *data)
 		amba_device_unregister(to_amba_device(dev));
 #endif
 
-	of_dma_deconfigure(dev);
 	of_node_clear_flag(dev->of_node, OF_POPULATED);
 	of_node_clear_flag(dev->of_node, OF_POPULATED_BUS);
 	return 0;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index dfc9a27..5a8dd43 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1893,33 +1893,6 @@ static void pci_set_msi_domain(struct pci_dev *dev)
 	dev_set_msi_domain(&dev->dev, d);
 }
 
-/**
- * pci_dma_configure - Setup DMA configuration
- * @dev: ptr to pci_dev struct of the PCI device
- *
- * Function to update PCI devices's DMA configuration using the same
- * info from the OF node or ACPI node of host bridge's parent (if any).
- */
-static void pci_dma_configure(struct pci_dev *dev)
-{
-	struct device *bridge = pci_get_host_bridge_device(dev);
-
-	if (IS_ENABLED(CONFIG_OF) &&
-		bridge->parent && bridge->parent->of_node) {
-			of_dma_configure(&dev->dev, bridge->parent->of_node);
-	} else if (has_acpi_companion(bridge)) {
-		struct acpi_device *adev = to_acpi_device_node(bridge->fwnode);
-		enum dev_dma_attr attr = acpi_get_dma_attr(adev);
-
-		if (attr == DEV_DMA_NOT_SUPPORTED)
-			dev_warn(&dev->dev, "DMA not supported.\n");
-		else
-			acpi_dma_configure(&dev->dev, attr);
-	}
-
-	pci_put_host_bridge_device(bridge);
-}
-
 void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 {
 	int ret;
@@ -1933,7 +1906,6 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 	dev->dev.dma_mask = &dev->dma_mask;
 	dev->dev.dma_parms = &dev->dma_parms;
 	dev->dev.coherent_dma_mask = 0xffffffffull;
-	pci_dma_configure(dev);
 
 	pci_set_dma_max_seg_size(dev, 65536);
 	pci_set_dma_seg_boundary(dev, 0xffffffff);
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 0977317..4f3eece 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -728,6 +728,18 @@ void *dma_mark_declared_memory_occupied(struct device *dev,
 }
 #endif /* CONFIG_HAVE_GENERIC_DMA_COHERENT */
 
+#ifdef CONFIG_HAS_DMA
+int dma_configure(struct device *dev);
+void dma_deconfigure(struct device *dev);
+#else
+static inline int dma_configure(struct device *dev)
+{
+	return 0;
+}
+
+static inline void dma_deconfigure(struct device *dev) {}
+#endif
+
 /*
  * Managed DMA API
  */
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 07/11] iommu: of: Handle IOMMU lookup failure with deferred probing or error
  2017-04-10 11:20   ` Sricharan R
  (?)
  (?)
@ 2017-04-10 11:21       ` Sricharan R
  -1 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
  To: robin.murphy-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
	joro-zLv9SwRftAIdnm+yROfE0A, lorenzo.pieralisi-5wv7dgnIgG8,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ,
	bhelgaas-hpIqsD4AKlfQT0dZR+AlfA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
	hanjun.guo-QSEj5FYQhm4dnm+yROfE0A, okaya-sgV2jX0FEOL9JmXXK+q4OQ,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, sudeep.holla-5wv7dgnIgG8,
	rjw-LthD3rsA81gm4RdzfppkhA, lenb-DgEjT+Ai2ygdnm+yROfE0A,
	catalin.marinas-5wv7dgnIgG8, arnd-r2nGTMty4D4,
	linux-arch-u79uwXL29TY76Z2rM5mHXA,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r
  Cc: Laurent Pinchart

From: Laurent Pinchart <laurent.pinchart+renesas-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org>

Failures to look up an IOMMU when parsing the DT iommus property need to
be handled separately from the .of_xlate() failures to support deferred
probing.

The lack of a registered IOMMU can be caused by the lack of a driver for
the IOMMU, the IOMMU device probe not having been performed yet, having
been deferred, or having failed.

The first case occurs when the device tree describes the bus master and
IOMMU topology correctly but no device driver exists for the IOMMU yet
or the device driver has not been compiled in. Return NULL, the caller
will configure the device without an IOMMU.

The second and third cases are handled by deferring the probe of the bus
master device which will eventually get reprobed after the IOMMU.

The last case is currently handled by deferring the probe of the bus
master device as well. A mechanism to either configure the bus master
device without an IOMMU or to fail the bus master device probe depending
on whether the IOMMU is optional or mandatory would be a good
enhancement.

Tested-by: Marek Szyprowski <m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Reviewed-by: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Laurent Pichart <laurent.pinchart+renesas-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org>
Signed-off-by: Sricharan R <sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
---

 [V11] Small change to return non-void value in one of returns
       in of_dma_configure, as a result of dropping patch #3 from
       previous V10. No functional impact.

 drivers/base/dma-mapping.c | 5 +++--
 drivers/iommu/of_iommu.c   | 4 ++--
 drivers/of/device.c        | 9 +++++++--
 include/linux/of_device.h  | 9 ++++++---
 4 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index 449b948..82bd45c 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -353,6 +353,7 @@ int dma_configure(struct device *dev)
 {
 	struct device *bridge = NULL, *dma_dev = dev;
 	enum dev_dma_attr attr;
+	int ret = 0;
 
 	if (dev_is_pci(dev)) {
 		bridge = pci_get_host_bridge_device(to_pci_dev(dev));
@@ -363,7 +364,7 @@ int dma_configure(struct device *dev)
 	}
 
 	if (dma_dev->of_node) {
-		of_dma_configure(dev, dma_dev->of_node);
+		ret = of_dma_configure(dev, dma_dev->of_node);
 	} else if (has_acpi_companion(dma_dev)) {
 		attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
 		if (attr != DEV_DMA_NOT_SUPPORTED)
@@ -373,7 +374,7 @@ int dma_configure(struct device *dev)
 	if (bridge)
 		pci_put_host_bridge_device(bridge);
 
-	return 0;
+	return ret;
 }
 
 void dma_deconfigure(struct device *dev)
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index c8be889..9f44ee8 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -236,7 +236,7 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
 			ops = ERR_PTR(err);
 	}
 
-	return IS_ERR(ops) ? NULL : ops;
+	return ops;
 }
 
 static int __init of_iommu_init(void)
@@ -247,7 +247,7 @@ static int __init of_iommu_init(void)
 	for_each_matching_node_and_match(np, matches, &match) {
 		const of_iommu_init_fn init_fn = match->data;
 
-		if (init_fn(np))
+		if (init_fn && init_fn(np))
 			pr_err("Failed to initialise IOMMU %s\n",
 				of_node_full_name(np));
 	}
diff --git a/drivers/of/device.c b/drivers/of/device.c
index e1ae9e7..8bd3d8c 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -82,7 +82,7 @@ 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.
  */
-void of_dma_configure(struct device *dev, struct device_node *np)
+int of_dma_configure(struct device *dev, struct device_node *np)
 {
 	u64 dma_addr, paddr, size;
 	int ret;
@@ -123,7 +123,7 @@ void of_dma_configure(struct device *dev, struct device_node *np)
 
 		if (!size) {
 			dev_err(dev, "Adjusted size 0x%llx invalid\n", size);
-			return;
+			return -EINVAL;
 		}
 		dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
 	}
@@ -144,10 +144,15 @@ void of_dma_configure(struct device *dev, struct device_node *np)
 		coherent ? " " : " not ");
 
 	iommu = of_iommu_configure(dev, np);
+	if (IS_ERR(iommu))
+		return PTR_ERR(iommu);
+
 	dev_dbg(dev, "device is%sbehind an iommu\n",
 		iommu ? " " : " not ");
 
 	arch_setup_dma_ops(dev, dma_addr, size, iommu, coherent);
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(of_dma_configure);
 
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index af98455..2cacdd8 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -55,7 +55,7 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
 	return of_node_get(cpu_dev->of_node);
 }
 
-void of_dma_configure(struct device *dev, struct device_node *np);
+int of_dma_configure(struct device *dev, struct device_node *np);
 void of_dma_deconfigure(struct device *dev);
 #else /* CONFIG_OF */
 
@@ -104,8 +104,11 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
 {
 	return NULL;
 }
-static inline void of_dma_configure(struct device *dev, struct device_node *np)
-{}
+
+static inline int of_dma_configure(struct device *dev, struct device_node *np)
+{
+	return 0;
+}
 static inline void of_dma_deconfigure(struct device *dev)
 {}
 #endif /* CONFIG_OF */
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 07/11] iommu: of: Handle IOMMU lookup failure with deferred probing or error
@ 2017-04-10 11:21       ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
  To: robin.murphy, will.deacon, joro, lorenzo.pieralisi, iommu,
	linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh
  Cc: sricharan, Laurent Pinchart

From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Failures to look up an IOMMU when parsing the DT iommus property need to
be handled separately from the .of_xlate() failures to support deferred
probing.

The lack of a registered IOMMU can be caused by the lack of a driver for
the IOMMU, the IOMMU device probe not having been performed yet, having
been deferred, or having failed.

The first case occurs when the device tree describes the bus master and
IOMMU topology correctly but no device driver exists for the IOMMU yet
or the device driver has not been compiled in. Return NULL, the caller
will configure the device without an IOMMU.

The second and third cases are handled by deferring the probe of the bus
master device which will eventually get reprobed after the IOMMU.

The last case is currently handled by deferring the probe of the bus
master device as well. A mechanism to either configure the bus master
device without an IOMMU or to fail the bus master device probe depending
on whether the IOMMU is optional or mandatory would be a good
enhancement.

Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Laurent Pichart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
---

 [V11] Small change to return non-void value in one of returns
       in of_dma_configure, as a result of dropping patch #3 from
       previous V10. No functional impact.

 drivers/base/dma-mapping.c | 5 +++--
 drivers/iommu/of_iommu.c   | 4 ++--
 drivers/of/device.c        | 9 +++++++--
 include/linux/of_device.h  | 9 ++++++---
 4 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index 449b948..82bd45c 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -353,6 +353,7 @@ int dma_configure(struct device *dev)
 {
 	struct device *bridge = NULL, *dma_dev = dev;
 	enum dev_dma_attr attr;
+	int ret = 0;
 
 	if (dev_is_pci(dev)) {
 		bridge = pci_get_host_bridge_device(to_pci_dev(dev));
@@ -363,7 +364,7 @@ int dma_configure(struct device *dev)
 	}
 
 	if (dma_dev->of_node) {
-		of_dma_configure(dev, dma_dev->of_node);
+		ret = of_dma_configure(dev, dma_dev->of_node);
 	} else if (has_acpi_companion(dma_dev)) {
 		attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
 		if (attr != DEV_DMA_NOT_SUPPORTED)
@@ -373,7 +374,7 @@ int dma_configure(struct device *dev)
 	if (bridge)
 		pci_put_host_bridge_device(bridge);
 
-	return 0;
+	return ret;
 }
 
 void dma_deconfigure(struct device *dev)
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index c8be889..9f44ee8 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -236,7 +236,7 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
 			ops = ERR_PTR(err);
 	}
 
-	return IS_ERR(ops) ? NULL : ops;
+	return ops;
 }
 
 static int __init of_iommu_init(void)
@@ -247,7 +247,7 @@ static int __init of_iommu_init(void)
 	for_each_matching_node_and_match(np, matches, &match) {
 		const of_iommu_init_fn init_fn = match->data;
 
-		if (init_fn(np))
+		if (init_fn && init_fn(np))
 			pr_err("Failed to initialise IOMMU %s\n",
 				of_node_full_name(np));
 	}
diff --git a/drivers/of/device.c b/drivers/of/device.c
index e1ae9e7..8bd3d8c 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -82,7 +82,7 @@ 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.
  */
-void of_dma_configure(struct device *dev, struct device_node *np)
+int of_dma_configure(struct device *dev, struct device_node *np)
 {
 	u64 dma_addr, paddr, size;
 	int ret;
@@ -123,7 +123,7 @@ void of_dma_configure(struct device *dev, struct device_node *np)
 
 		if (!size) {
 			dev_err(dev, "Adjusted size 0x%llx invalid\n", size);
-			return;
+			return -EINVAL;
 		}
 		dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
 	}
@@ -144,10 +144,15 @@ void of_dma_configure(struct device *dev, struct device_node *np)
 		coherent ? " " : " not ");
 
 	iommu = of_iommu_configure(dev, np);
+	if (IS_ERR(iommu))
+		return PTR_ERR(iommu);
+
 	dev_dbg(dev, "device is%sbehind an iommu\n",
 		iommu ? " " : " not ");
 
 	arch_setup_dma_ops(dev, dma_addr, size, iommu, coherent);
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(of_dma_configure);
 
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index af98455..2cacdd8 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -55,7 +55,7 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
 	return of_node_get(cpu_dev->of_node);
 }
 
-void of_dma_configure(struct device *dev, struct device_node *np);
+int of_dma_configure(struct device *dev, struct device_node *np);
 void of_dma_deconfigure(struct device *dev);
 #else /* CONFIG_OF */
 
@@ -104,8 +104,11 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
 {
 	return NULL;
 }
-static inline void of_dma_configure(struct device *dev, struct device_node *np)
-{}
+
+static inline int of_dma_configure(struct device *dev, struct device_node *np)
+{
+	return 0;
+}
 static inline void of_dma_deconfigure(struct device *dev)
 {}
 #endif /* CONFIG_OF */
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 07/11] iommu: of: Handle IOMMU lookup failure with deferred probing or error
@ 2017-04-10 11:21       ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
  To: robin.murphy, will.deacon, joro, lorenzo.pieralisi, iommu,
	linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh
  Cc: Laurent Pinchart, sricharan

From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Failures to look up an IOMMU when parsing the DT iommus property need to
be handled separately from the .of_xlate() failures to support deferred
probing.

The lack of a registered IOMMU can be caused by the lack of a driver for
the IOMMU, the IOMMU device probe not having been performed yet, having
been deferred, or having failed.

The first case occurs when the device tree describes the bus master and
IOMMU topology correctly but no device driver exists for the IOMMU yet
or the device driver has not been compiled in. Return NULL, the caller
will configure the device without an IOMMU.

The second and third cases are handled by deferring the probe of the bus
master device which will eventually get reprobed after the IOMMU.

The last case is currently handled by deferring the probe of the bus
master device as well. A mechanism to either configure the bus master
device without an IOMMU or to fail the bus master device probe depending
on whether the IOMMU is optional or mandatory would be a good
enhancement.

Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Laurent Pichart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
---

 [V11] Small change to return non-void value in one of returns
       in of_dma_configure, as a result of dropping patch #3 from
       previous V10. No functional impact.

 drivers/base/dma-mapping.c | 5 +++--
 drivers/iommu/of_iommu.c   | 4 ++--
 drivers/of/device.c        | 9 +++++++--
 include/linux/of_device.h  | 9 ++++++---
 4 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index 449b948..82bd45c 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -353,6 +353,7 @@ int dma_configure(struct device *dev)
 {
 	struct device *bridge = NULL, *dma_dev = dev;
 	enum dev_dma_attr attr;
+	int ret = 0;
 
 	if (dev_is_pci(dev)) {
 		bridge = pci_get_host_bridge_device(to_pci_dev(dev));
@@ -363,7 +364,7 @@ int dma_configure(struct device *dev)
 	}
 
 	if (dma_dev->of_node) {
-		of_dma_configure(dev, dma_dev->of_node);
+		ret = of_dma_configure(dev, dma_dev->of_node);
 	} else if (has_acpi_companion(dma_dev)) {
 		attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
 		if (attr != DEV_DMA_NOT_SUPPORTED)
@@ -373,7 +374,7 @@ int dma_configure(struct device *dev)
 	if (bridge)
 		pci_put_host_bridge_device(bridge);
 
-	return 0;
+	return ret;
 }
 
 void dma_deconfigure(struct device *dev)
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index c8be889..9f44ee8 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -236,7 +236,7 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
 			ops = ERR_PTR(err);
 	}
 
-	return IS_ERR(ops) ? NULL : ops;
+	return ops;
 }
 
 static int __init of_iommu_init(void)
@@ -247,7 +247,7 @@ static int __init of_iommu_init(void)
 	for_each_matching_node_and_match(np, matches, &match) {
 		const of_iommu_init_fn init_fn = match->data;
 
-		if (init_fn(np))
+		if (init_fn && init_fn(np))
 			pr_err("Failed to initialise IOMMU %s\n",
 				of_node_full_name(np));
 	}
diff --git a/drivers/of/device.c b/drivers/of/device.c
index e1ae9e7..8bd3d8c 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -82,7 +82,7 @@ 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.
  */
-void of_dma_configure(struct device *dev, struct device_node *np)
+int of_dma_configure(struct device *dev, struct device_node *np)
 {
 	u64 dma_addr, paddr, size;
 	int ret;
@@ -123,7 +123,7 @@ void of_dma_configure(struct device *dev, struct device_node *np)
 
 		if (!size) {
 			dev_err(dev, "Adjusted size 0x%llx invalid\n", size);
-			return;
+			return -EINVAL;
 		}
 		dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
 	}
@@ -144,10 +144,15 @@ void of_dma_configure(struct device *dev, struct device_node *np)
 		coherent ? " " : " not ");
 
 	iommu = of_iommu_configure(dev, np);
+	if (IS_ERR(iommu))
+		return PTR_ERR(iommu);
+
 	dev_dbg(dev, "device is%sbehind an iommu\n",
 		iommu ? " " : " not ");
 
 	arch_setup_dma_ops(dev, dma_addr, size, iommu, coherent);
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(of_dma_configure);
 
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index af98455..2cacdd8 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -55,7 +55,7 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
 	return of_node_get(cpu_dev->of_node);
 }
 
-void of_dma_configure(struct device *dev, struct device_node *np);
+int of_dma_configure(struct device *dev, struct device_node *np);
 void of_dma_deconfigure(struct device *dev);
 #else /* CONFIG_OF */
 
@@ -104,8 +104,11 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
 {
 	return NULL;
 }
-static inline void of_dma_configure(struct device *dev, struct device_node *np)
-{}
+
+static inline int of_dma_configure(struct device *dev, struct device_node *np)
+{
+	return 0;
+}
 static inline void of_dma_deconfigure(struct device *dev)
 {}
 #endif /* CONFIG_OF */
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V11 07/11] iommu: of: Handle IOMMU lookup failure with deferred probing or error
@ 2017-04-10 11:21       ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
  To: linux-arm-kernel

From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Failures to look up an IOMMU when parsing the DT iommus property need to
be handled separately from the .of_xlate() failures to support deferred
probing.

The lack of a registered IOMMU can be caused by the lack of a driver for
the IOMMU, the IOMMU device probe not having been performed yet, having
been deferred, or having failed.

The first case occurs when the device tree describes the bus master and
IOMMU topology correctly but no device driver exists for the IOMMU yet
or the device driver has not been compiled in. Return NULL, the caller
will configure the device without an IOMMU.

The second and third cases are handled by deferring the probe of the bus
master device which will eventually get reprobed after the IOMMU.

The last case is currently handled by deferring the probe of the bus
master device as well. A mechanism to either configure the bus master
device without an IOMMU or to fail the bus master device probe depending
on whether the IOMMU is optional or mandatory would be a good
enhancement.

Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Laurent Pichart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
---

 [V11] Small change to return non-void value in one of returns
       in of_dma_configure, as a result of dropping patch #3 from
       previous V10. No functional impact.

 drivers/base/dma-mapping.c | 5 +++--
 drivers/iommu/of_iommu.c   | 4 ++--
 drivers/of/device.c        | 9 +++++++--
 include/linux/of_device.h  | 9 ++++++---
 4 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index 449b948..82bd45c 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -353,6 +353,7 @@ int dma_configure(struct device *dev)
 {
 	struct device *bridge = NULL, *dma_dev = dev;
 	enum dev_dma_attr attr;
+	int ret = 0;
 
 	if (dev_is_pci(dev)) {
 		bridge = pci_get_host_bridge_device(to_pci_dev(dev));
@@ -363,7 +364,7 @@ int dma_configure(struct device *dev)
 	}
 
 	if (dma_dev->of_node) {
-		of_dma_configure(dev, dma_dev->of_node);
+		ret = of_dma_configure(dev, dma_dev->of_node);
 	} else if (has_acpi_companion(dma_dev)) {
 		attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
 		if (attr != DEV_DMA_NOT_SUPPORTED)
@@ -373,7 +374,7 @@ int dma_configure(struct device *dev)
 	if (bridge)
 		pci_put_host_bridge_device(bridge);
 
-	return 0;
+	return ret;
 }
 
 void dma_deconfigure(struct device *dev)
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index c8be889..9f44ee8 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -236,7 +236,7 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
 			ops = ERR_PTR(err);
 	}
 
-	return IS_ERR(ops) ? NULL : ops;
+	return ops;
 }
 
 static int __init of_iommu_init(void)
@@ -247,7 +247,7 @@ static int __init of_iommu_init(void)
 	for_each_matching_node_and_match(np, matches, &match) {
 		const of_iommu_init_fn init_fn = match->data;
 
-		if (init_fn(np))
+		if (init_fn && init_fn(np))
 			pr_err("Failed to initialise IOMMU %s\n",
 				of_node_full_name(np));
 	}
diff --git a/drivers/of/device.c b/drivers/of/device.c
index e1ae9e7..8bd3d8c 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -82,7 +82,7 @@ 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.
  */
-void of_dma_configure(struct device *dev, struct device_node *np)
+int of_dma_configure(struct device *dev, struct device_node *np)
 {
 	u64 dma_addr, paddr, size;
 	int ret;
@@ -123,7 +123,7 @@ void of_dma_configure(struct device *dev, struct device_node *np)
 
 		if (!size) {
 			dev_err(dev, "Adjusted size 0x%llx invalid\n", size);
-			return;
+			return -EINVAL;
 		}
 		dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
 	}
@@ -144,10 +144,15 @@ void of_dma_configure(struct device *dev, struct device_node *np)
 		coherent ? " " : " not ");
 
 	iommu = of_iommu_configure(dev, np);
+	if (IS_ERR(iommu))
+		return PTR_ERR(iommu);
+
 	dev_dbg(dev, "device is%sbehind an iommu\n",
 		iommu ? " " : " not ");
 
 	arch_setup_dma_ops(dev, dma_addr, size, iommu, coherent);
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(of_dma_configure);
 
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index af98455..2cacdd8 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -55,7 +55,7 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
 	return of_node_get(cpu_dev->of_node);
 }
 
-void of_dma_configure(struct device *dev, struct device_node *np);
+int of_dma_configure(struct device *dev, struct device_node *np);
 void of_dma_deconfigure(struct device *dev);
 #else /* CONFIG_OF */
 
@@ -104,8 +104,11 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
 {
 	return NULL;
 }
-static inline void of_dma_configure(struct device *dev, struct device_node *np)
-{}
+
+static inline int of_dma_configure(struct device *dev, struct device_node *np)
+{
+	return 0;
+}
 static inline void of_dma_deconfigure(struct device *dev)
 {}
 #endif /* CONFIG_OF */
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
  2017-04-10 11:20   ` Sricharan R
  (?)
@ 2017-04-10 11:21       ` Sricharan R
  -1 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
  To: robin.murphy-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
	joro-zLv9SwRftAIdnm+yROfE0A, lorenzo.pieralisi-5wv7dgnIgG8,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ,
	bhelgaas-hpIqsD4AKlfQT0dZR+AlfA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
	hanjun.guo-QSEj5FYQhm4dnm+yROfE0A, okaya-sgV2jX0FEOL9JmXXK+q4OQ,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, sudeep.holla-5wv7dgnIgG8,
	rjw-LthD3rsA81gm4RdzfppkhA, lenb-DgEjT+Ai2ygdnm+yROfE0A,
	catalin.marinas-5wv7dgnIgG8, arnd-r2nGTMty4D4,
	linux-arch-u79uwXL29TY76Z2rM5mHXA,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r

This is an equivalent to the DT's handling of the iommu master's probe
with deferred probing when the corrsponding iommu is not probed yet.
The lack of a registered IOMMU can be caused by the lack of a driver for
the IOMMU, the IOMMU device probe not having been performed yet, having
been deferred, or having failed.

The first case occurs when the firmware describes the bus master and
IOMMU topology correctly but no device driver exists for the IOMMU yet
or the device driver has not been compiled in. Return NULL, the caller
will configure the device without an IOMMU.

The second and third cases are handled by deferring the probe of the bus
master device which will eventually get reprobed after the IOMMU.

The last case is currently handled by deferring the probe of the bus
master device as well. A mechanism to either configure the bus master
device without an IOMMU or to fail the bus master device probe depending
on whether the IOMMU is optional or mandatory would be a good
enhancement.

Tested-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Reviewed-by: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
[Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
          called multiple times for same device]
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
Signed-off-by: Sricharan R <sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
---
 drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
 drivers/acpi/scan.c        | 11 ++++++++---
 drivers/base/dma-mapping.c |  2 +-
 include/acpi/acpi_bus.h    |  2 +-
 include/linux/acpi.h       |  7 +++++--
 5 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 3dd9ec3..e323ece 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
 	const struct iommu_ops *ops = NULL;
 	int ret = -ENODEV;
 	struct fwnode_handle *iort_fwnode;
+	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
+
+	/*
+	 * If we already translated the fwspec there
+	 * is nothing left to do, return the iommu_ops.
+	 */
+	if (fwspec && fwspec->ops)
+		return fwspec->ops;
 
 	if (node) {
 		iort_fwnode = iort_get_fwnode(node);
@@ -550,8 +558,17 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
 			return NULL;
 
 		ops = iommu_ops_from_fwnode(iort_fwnode);
+		/*
+		 * If the ops look-up fails, this means that either
+		 * the SMMU drivers have not been probed yet or that
+		 * the SMMU drivers are not built in the kernel;
+		 * Depending on whether the SMMU drivers are built-in
+		 * in the kernel or not, defer the IOMMU configuration
+		 * or just abort it.
+		 */
 		if (!ops)
-			return NULL;
+			return iort_iommu_driver_enabled(node->type) ?
+			       ERR_PTR(-EPROBE_DEFER) : NULL;
 
 		ret = arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops);
 	}
@@ -625,12 +642,26 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
 
 		while (parent) {
 			ops = iort_iommu_xlate(dev, parent, streamid);
+			if (IS_ERR_OR_NULL(ops))
+				return ops;
 
 			parent = iort_node_get_id(node, &streamid,
 						  IORT_IOMMU_TYPE, i++);
 		}
 	}
 
+	/*
+	 * If we have reason to believe the IOMMU driver missed the initial
+	 * add_device callback for dev, replay it to get things in order.
+	 */
+	if (!IS_ERR_OR_NULL(ops) && ops->add_device &&
+	    dev->bus && !dev->iommu_group) {
+		int err = ops->add_device(dev);
+
+		if (err)
+			ops = ERR_PTR(err);
+	}
+
 	return ops;
 }
 
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 1926918..2a513cc 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1373,20 +1373,25 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
  * @dev: The pointer to the device
  * @attr: device dma attributes
  */
-void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
+int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
 {
 	const struct iommu_ops *iommu;
+	u64 size;
 
 	iort_set_dma_mask(dev);
 
 	iommu = iort_iommu_configure(dev);
+	if (IS_ERR(iommu))
+		return PTR_ERR(iommu);
 
+	size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
 	/*
 	 * Assume dma valid range starts at 0 and covers the whole
 	 * coherent_dma_mask.
 	 */
-	arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, iommu,
-			   attr == DEV_DMA_COHERENT);
+	arch_setup_dma_ops(dev, 0, size, iommu, attr == DEV_DMA_COHERENT);
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(acpi_dma_configure);
 
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index 82bd45c..755a2b5 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -368,7 +368,7 @@ int dma_configure(struct device *dev)
 	} else if (has_acpi_companion(dma_dev)) {
 		attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
 		if (attr != DEV_DMA_NOT_SUPPORTED)
-			acpi_dma_configure(dev, attr);
+			ret = acpi_dma_configure(dev, attr);
 	}
 
 	if (bridge)
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index ef0ae8a..2a9a5de 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -575,7 +575,7 @@ struct acpi_pci_root {
 
 bool acpi_dma_supported(struct acpi_device *adev);
 enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
-void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
+int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
 void acpi_dma_deconfigure(struct device *dev);
 
 struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 9b05886..79d06ef6 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -762,8 +762,11 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
 	return DEV_DMA_NOT_SUPPORTED;
 }
 
-static inline void acpi_dma_configure(struct device *dev,
-				      enum dev_dma_attr attr) { }
+static inline int acpi_dma_configure(struct device *dev,
+				     enum dev_dma_attr attr)
+{
+	return 0;
+}
 
 static inline void acpi_dma_deconfigure(struct device *dev) { }
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
@ 2017-04-10 11:21       ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
  To: robin.murphy, will.deacon, joro, lorenzo.pieralisi, iommu,
	linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh
  Cc: sricharan

This is an equivalent to the DT's handling of the iommu master's probe
with deferred probing when the corrsponding iommu is not probed yet.
The lack of a registered IOMMU can be caused by the lack of a driver for
the IOMMU, the IOMMU device probe not having been performed yet, having
been deferred, or having failed.

The first case occurs when the firmware describes the bus master and
IOMMU topology correctly but no device driver exists for the IOMMU yet
or the device driver has not been compiled in. Return NULL, the caller
will configure the device without an IOMMU.

The second and third cases are handled by deferring the probe of the bus
master device which will eventually get reprobed after the IOMMU.

The last case is currently handled by deferring the probe of the bus
master device as well. A mechanism to either configure the bus master
device without an IOMMU or to fail the bus master device probe depending
on whether the IOMMU is optional or mandatory would be a good
enhancement.

Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
[Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
          called multiple times for same device]
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
---
 drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
 drivers/acpi/scan.c        | 11 ++++++++---
 drivers/base/dma-mapping.c |  2 +-
 include/acpi/acpi_bus.h    |  2 +-
 include/linux/acpi.h       |  7 +++++--
 5 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 3dd9ec3..e323ece 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
 	const struct iommu_ops *ops = NULL;
 	int ret = -ENODEV;
 	struct fwnode_handle *iort_fwnode;
+	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
+
+	/*
+	 * If we already translated the fwspec there
+	 * is nothing left to do, return the iommu_ops.
+	 */
+	if (fwspec && fwspec->ops)
+		return fwspec->ops;
 
 	if (node) {
 		iort_fwnode = iort_get_fwnode(node);
@@ -550,8 +558,17 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
 			return NULL;
 
 		ops = iommu_ops_from_fwnode(iort_fwnode);
+		/*
+		 * If the ops look-up fails, this means that either
+		 * the SMMU drivers have not been probed yet or that
+		 * the SMMU drivers are not built in the kernel;
+		 * Depending on whether the SMMU drivers are built-in
+		 * in the kernel or not, defer the IOMMU configuration
+		 * or just abort it.
+		 */
 		if (!ops)
-			return NULL;
+			return iort_iommu_driver_enabled(node->type) ?
+			       ERR_PTR(-EPROBE_DEFER) : NULL;
 
 		ret = arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops);
 	}
@@ -625,12 +642,26 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
 
 		while (parent) {
 			ops = iort_iommu_xlate(dev, parent, streamid);
+			if (IS_ERR_OR_NULL(ops))
+				return ops;
 
 			parent = iort_node_get_id(node, &streamid,
 						  IORT_IOMMU_TYPE, i++);
 		}
 	}
 
+	/*
+	 * If we have reason to believe the IOMMU driver missed the initial
+	 * add_device callback for dev, replay it to get things in order.
+	 */
+	if (!IS_ERR_OR_NULL(ops) && ops->add_device &&
+	    dev->bus && !dev->iommu_group) {
+		int err = ops->add_device(dev);
+
+		if (err)
+			ops = ERR_PTR(err);
+	}
+
 	return ops;
 }
 
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 1926918..2a513cc 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1373,20 +1373,25 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
  * @dev: The pointer to the device
  * @attr: device dma attributes
  */
-void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
+int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
 {
 	const struct iommu_ops *iommu;
+	u64 size;
 
 	iort_set_dma_mask(dev);
 
 	iommu = iort_iommu_configure(dev);
+	if (IS_ERR(iommu))
+		return PTR_ERR(iommu);
 
+	size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
 	/*
 	 * Assume dma valid range starts at 0 and covers the whole
 	 * coherent_dma_mask.
 	 */
-	arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, iommu,
-			   attr == DEV_DMA_COHERENT);
+	arch_setup_dma_ops(dev, 0, size, iommu, attr == DEV_DMA_COHERENT);
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(acpi_dma_configure);
 
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index 82bd45c..755a2b5 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -368,7 +368,7 @@ int dma_configure(struct device *dev)
 	} else if (has_acpi_companion(dma_dev)) {
 		attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
 		if (attr != DEV_DMA_NOT_SUPPORTED)
-			acpi_dma_configure(dev, attr);
+			ret = acpi_dma_configure(dev, attr);
 	}
 
 	if (bridge)
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index ef0ae8a..2a9a5de 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -575,7 +575,7 @@ struct acpi_pci_root {
 
 bool acpi_dma_supported(struct acpi_device *adev);
 enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
-void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
+int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
 void acpi_dma_deconfigure(struct device *dev);
 
 struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 9b05886..79d06ef6 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -762,8 +762,11 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
 	return DEV_DMA_NOT_SUPPORTED;
 }
 
-static inline void acpi_dma_configure(struct device *dev,
-				      enum dev_dma_attr attr) { }
+static inline int acpi_dma_configure(struct device *dev,
+				     enum dev_dma_attr attr)
+{
+	return 0;
+}
 
 static inline void acpi_dma_deconfigure(struct device *dev) { }
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
@ 2017-04-10 11:21       ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
  To: linux-arm-kernel

This is an equivalent to the DT's handling of the iommu master's probe
with deferred probing when the corrsponding iommu is not probed yet.
The lack of a registered IOMMU can be caused by the lack of a driver for
the IOMMU, the IOMMU device probe not having been performed yet, having
been deferred, or having failed.

The first case occurs when the firmware describes the bus master and
IOMMU topology correctly but no device driver exists for the IOMMU yet
or the device driver has not been compiled in. Return NULL, the caller
will configure the device without an IOMMU.

The second and third cases are handled by deferring the probe of the bus
master device which will eventually get reprobed after the IOMMU.

The last case is currently handled by deferring the probe of the bus
master device as well. A mechanism to either configure the bus master
device without an IOMMU or to fail the bus master device probe depending
on whether the IOMMU is optional or mandatory would be a good
enhancement.

Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
[Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
          called multiple times for same device]
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
---
 drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
 drivers/acpi/scan.c        | 11 ++++++++---
 drivers/base/dma-mapping.c |  2 +-
 include/acpi/acpi_bus.h    |  2 +-
 include/linux/acpi.h       |  7 +++++--
 5 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 3dd9ec3..e323ece 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
 	const struct iommu_ops *ops = NULL;
 	int ret = -ENODEV;
 	struct fwnode_handle *iort_fwnode;
+	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
+
+	/*
+	 * If we already translated the fwspec there
+	 * is nothing left to do, return the iommu_ops.
+	 */
+	if (fwspec && fwspec->ops)
+		return fwspec->ops;
 
 	if (node) {
 		iort_fwnode = iort_get_fwnode(node);
@@ -550,8 +558,17 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
 			return NULL;
 
 		ops = iommu_ops_from_fwnode(iort_fwnode);
+		/*
+		 * If the ops look-up fails, this means that either
+		 * the SMMU drivers have not been probed yet or that
+		 * the SMMU drivers are not built in the kernel;
+		 * Depending on whether the SMMU drivers are built-in
+		 * in the kernel or not, defer the IOMMU configuration
+		 * or just abort it.
+		 */
 		if (!ops)
-			return NULL;
+			return iort_iommu_driver_enabled(node->type) ?
+			       ERR_PTR(-EPROBE_DEFER) : NULL;
 
 		ret = arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops);
 	}
@@ -625,12 +642,26 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
 
 		while (parent) {
 			ops = iort_iommu_xlate(dev, parent, streamid);
+			if (IS_ERR_OR_NULL(ops))
+				return ops;
 
 			parent = iort_node_get_id(node, &streamid,
 						  IORT_IOMMU_TYPE, i++);
 		}
 	}
 
+	/*
+	 * If we have reason to believe the IOMMU driver missed the initial
+	 * add_device callback for dev, replay it to get things in order.
+	 */
+	if (!IS_ERR_OR_NULL(ops) && ops->add_device &&
+	    dev->bus && !dev->iommu_group) {
+		int err = ops->add_device(dev);
+
+		if (err)
+			ops = ERR_PTR(err);
+	}
+
 	return ops;
 }
 
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 1926918..2a513cc 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1373,20 +1373,25 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
  * @dev: The pointer to the device
  * @attr: device dma attributes
  */
-void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
+int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
 {
 	const struct iommu_ops *iommu;
+	u64 size;
 
 	iort_set_dma_mask(dev);
 
 	iommu = iort_iommu_configure(dev);
+	if (IS_ERR(iommu))
+		return PTR_ERR(iommu);
 
+	size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
 	/*
 	 * Assume dma valid range starts at 0 and covers the whole
 	 * coherent_dma_mask.
 	 */
-	arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, iommu,
-			   attr == DEV_DMA_COHERENT);
+	arch_setup_dma_ops(dev, 0, size, iommu, attr == DEV_DMA_COHERENT);
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(acpi_dma_configure);
 
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index 82bd45c..755a2b5 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -368,7 +368,7 @@ int dma_configure(struct device *dev)
 	} else if (has_acpi_companion(dma_dev)) {
 		attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
 		if (attr != DEV_DMA_NOT_SUPPORTED)
-			acpi_dma_configure(dev, attr);
+			ret = acpi_dma_configure(dev, attr);
 	}
 
 	if (bridge)
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index ef0ae8a..2a9a5de 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -575,7 +575,7 @@ struct acpi_pci_root {
 
 bool acpi_dma_supported(struct acpi_device *adev);
 enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
-void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
+int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
 void acpi_dma_deconfigure(struct device *dev);
 
 struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 9b05886..79d06ef6 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -762,8 +762,11 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
 	return DEV_DMA_NOT_SUPPORTED;
 }
 
-static inline void acpi_dma_configure(struct device *dev,
-				      enum dev_dma_attr attr) { }
+static inline int acpi_dma_configure(struct device *dev,
+				     enum dev_dma_attr attr)
+{
+	return 0;
+}
 
 static inline void acpi_dma_deconfigure(struct device *dev) { }
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 09/11] arm64: dma-mapping: Remove the notifier trick to handle early setting of dma_ops
  2017-04-10 11:20   ` Sricharan R
  (?)
@ 2017-04-10 11:21       ` Sricharan R
  -1 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
  To: robin.murphy-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
	joro-zLv9SwRftAIdnm+yROfE0A, lorenzo.pieralisi-5wv7dgnIgG8,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ,
	bhelgaas-hpIqsD4AKlfQT0dZR+AlfA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
	hanjun.guo-QSEj5FYQhm4dnm+yROfE0A, okaya-sgV2jX0FEOL9JmXXK+q4OQ,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, sudeep.holla-5wv7dgnIgG8,
	rjw-LthD3rsA81gm4RdzfppkhA, lenb-DgEjT+Ai2ygdnm+yROfE0A,
	catalin.marinas-5wv7dgnIgG8, arnd-r2nGTMty4D4,
	linux-arch-u79uwXL29TY76Z2rM5mHXA,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r

With arch_setup_dma_ops now being called late during device's probe after
the device's iommu is probed, the notifier trick required to handle the
early setup of dma_ops before the iommu group gets created is not
required. So removing the notifier's here.

Tested-by: Marek Szyprowski <m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Tested-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Acked-by: Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>
Signed-off-by: Sricharan R <sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
[rm: clean up even more]
Signed-off-by: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
---
 arch/arm64/mm/dma-mapping.c | 142 ++++++--------------------------------------
 1 file changed, 18 insertions(+), 124 deletions(-)

diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 81cdb2e..b465759 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -813,34 +813,26 @@ static void __iommu_unmap_sg_attrs(struct device *dev,
 	.mapping_error = iommu_dma_mapping_error,
 };
 
-/*
- * TODO: Right now __iommu_setup_dma_ops() gets called too early to do
- * everything it needs to - the device is only partially created and the
- * IOMMU driver hasn't seen it yet, so it can't have a group. Thus we
- * need this delayed attachment dance. Once IOMMU probe ordering is sorted
- * to move the arch_setup_dma_ops() call later, all the notifier bits below
- * become unnecessary, and will go away.
- */
-struct iommu_dma_notifier_data {
-	struct list_head list;
-	struct device *dev;
-	const struct iommu_ops *ops;
-	u64 dma_base;
-	u64 size;
-};
-static LIST_HEAD(iommu_dma_masters);
-static DEFINE_MUTEX(iommu_dma_notifier_lock);
+static int __init __iommu_dma_init(void)
+{
+	return iommu_dma_init();
+}
+arch_initcall(__iommu_dma_init);
 
-static bool do_iommu_attach(struct device *dev, const struct iommu_ops *ops,
-			   u64 dma_base, u64 size)
+static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+				  const struct iommu_ops *ops)
 {
-	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
+	struct iommu_domain *domain;
+
+	if (!ops)
+		return;
 
 	/*
-	 * If the IOMMU driver has the DMA domain support that we require,
-	 * then the IOMMU core will have already configured a group for this
-	 * device, and allocated the default domain for that group.
+	 * The IOMMU core code allocates the default DMA domain, which the
+	 * underlying IOMMU driver needs to support via the dma-iommu layer.
 	 */
+	domain = iommu_get_domain_for_dev(dev);
+
 	if (!domain)
 		goto out_err;
 
@@ -851,109 +843,11 @@ static bool do_iommu_attach(struct device *dev, const struct iommu_ops *ops,
 		dev->dma_ops = &iommu_dma_ops;
 	}
 
-	return true;
+	return;
+
 out_err:
-	pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA ops\n",
+	 pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA ops\n",
 		 dev_name(dev));
-	return false;
-}
-
-static void queue_iommu_attach(struct device *dev, const struct iommu_ops *ops,
-			      u64 dma_base, u64 size)
-{
-	struct iommu_dma_notifier_data *iommudata;
-
-	iommudata = kzalloc(sizeof(*iommudata), GFP_KERNEL);
-	if (!iommudata)
-		return;
-
-	iommudata->dev = dev;
-	iommudata->ops = ops;
-	iommudata->dma_base = dma_base;
-	iommudata->size = size;
-
-	mutex_lock(&iommu_dma_notifier_lock);
-	list_add(&iommudata->list, &iommu_dma_masters);
-	mutex_unlock(&iommu_dma_notifier_lock);
-}
-
-static int __iommu_attach_notifier(struct notifier_block *nb,
-				   unsigned long action, void *data)
-{
-	struct iommu_dma_notifier_data *master, *tmp;
-
-	if (action != BUS_NOTIFY_BIND_DRIVER)
-		return 0;
-
-	mutex_lock(&iommu_dma_notifier_lock);
-	list_for_each_entry_safe(master, tmp, &iommu_dma_masters, list) {
-		if (data == master->dev && do_iommu_attach(master->dev,
-				master->ops, master->dma_base, master->size)) {
-			list_del(&master->list);
-			kfree(master);
-			break;
-		}
-	}
-	mutex_unlock(&iommu_dma_notifier_lock);
-	return 0;
-}
-
-static int __init register_iommu_dma_ops_notifier(struct bus_type *bus)
-{
-	struct notifier_block *nb = kzalloc(sizeof(*nb), GFP_KERNEL);
-	int ret;
-
-	if (!nb)
-		return -ENOMEM;
-
-	nb->notifier_call = __iommu_attach_notifier;
-
-	ret = bus_register_notifier(bus, nb);
-	if (ret) {
-		pr_warn("Failed to register DMA domain notifier; IOMMU DMA ops unavailable on bus '%s'\n",
-			bus->name);
-		kfree(nb);
-	}
-	return ret;
-}
-
-static int __init __iommu_dma_init(void)
-{
-	int ret;
-
-	ret = iommu_dma_init();
-	if (!ret)
-		ret = register_iommu_dma_ops_notifier(&platform_bus_type);
-	if (!ret)
-		ret = register_iommu_dma_ops_notifier(&amba_bustype);
-#ifdef CONFIG_PCI
-	if (!ret)
-		ret = register_iommu_dma_ops_notifier(&pci_bus_type);
-#endif
-	return ret;
-}
-arch_initcall(__iommu_dma_init);
-
-static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-				  const struct iommu_ops *ops)
-{
-	struct iommu_group *group;
-
-	if (!ops)
-		return;
-	/*
-	 * TODO: As a concession to the future, we're ready to handle being
-	 * called both early and late (i.e. after bus_add_device). Once all
-	 * the platform bus code is reworked to call us late and the notifier
-	 * junk above goes away, move the body of do_iommu_attach here.
-	 */
-	group = iommu_group_get(dev);
-	if (group) {
-		do_iommu_attach(dev, ops, dma_base, size);
-		iommu_group_put(group);
-	} else {
-		queue_iommu_attach(dev, ops, dma_base, size);
-	}
 }
 
 void arch_teardown_dma_ops(struct device *dev)
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 09/11] arm64: dma-mapping: Remove the notifier trick to handle early setting of dma_ops
@ 2017-04-10 11:21       ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
  To: robin.murphy, will.deacon, joro, lorenzo.pieralisi, iommu,
	linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh
  Cc: sricharan

With arch_setup_dma_ops now being called late during device's probe after
the device's iommu is probed, the notifier trick required to handle the
early setup of dma_ops before the iommu group gets created is not
required. So removing the notifier's here.

Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
Acked-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
[rm: clean up even more]
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 arch/arm64/mm/dma-mapping.c | 142 ++++++--------------------------------------
 1 file changed, 18 insertions(+), 124 deletions(-)

diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 81cdb2e..b465759 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -813,34 +813,26 @@ static void __iommu_unmap_sg_attrs(struct device *dev,
 	.mapping_error = iommu_dma_mapping_error,
 };
 
-/*
- * TODO: Right now __iommu_setup_dma_ops() gets called too early to do
- * everything it needs to - the device is only partially created and the
- * IOMMU driver hasn't seen it yet, so it can't have a group. Thus we
- * need this delayed attachment dance. Once IOMMU probe ordering is sorted
- * to move the arch_setup_dma_ops() call later, all the notifier bits below
- * become unnecessary, and will go away.
- */
-struct iommu_dma_notifier_data {
-	struct list_head list;
-	struct device *dev;
-	const struct iommu_ops *ops;
-	u64 dma_base;
-	u64 size;
-};
-static LIST_HEAD(iommu_dma_masters);
-static DEFINE_MUTEX(iommu_dma_notifier_lock);
+static int __init __iommu_dma_init(void)
+{
+	return iommu_dma_init();
+}
+arch_initcall(__iommu_dma_init);
 
-static bool do_iommu_attach(struct device *dev, const struct iommu_ops *ops,
-			   u64 dma_base, u64 size)
+static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+				  const struct iommu_ops *ops)
 {
-	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
+	struct iommu_domain *domain;
+
+	if (!ops)
+		return;
 
 	/*
-	 * If the IOMMU driver has the DMA domain support that we require,
-	 * then the IOMMU core will have already configured a group for this
-	 * device, and allocated the default domain for that group.
+	 * The IOMMU core code allocates the default DMA domain, which the
+	 * underlying IOMMU driver needs to support via the dma-iommu layer.
 	 */
+	domain = iommu_get_domain_for_dev(dev);
+
 	if (!domain)
 		goto out_err;
 
@@ -851,109 +843,11 @@ static bool do_iommu_attach(struct device *dev, const struct iommu_ops *ops,
 		dev->dma_ops = &iommu_dma_ops;
 	}
 
-	return true;
+	return;
+
 out_err:
-	pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA ops\n",
+	 pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA ops\n",
 		 dev_name(dev));
-	return false;
-}
-
-static void queue_iommu_attach(struct device *dev, const struct iommu_ops *ops,
-			      u64 dma_base, u64 size)
-{
-	struct iommu_dma_notifier_data *iommudata;
-
-	iommudata = kzalloc(sizeof(*iommudata), GFP_KERNEL);
-	if (!iommudata)
-		return;
-
-	iommudata->dev = dev;
-	iommudata->ops = ops;
-	iommudata->dma_base = dma_base;
-	iommudata->size = size;
-
-	mutex_lock(&iommu_dma_notifier_lock);
-	list_add(&iommudata->list, &iommu_dma_masters);
-	mutex_unlock(&iommu_dma_notifier_lock);
-}
-
-static int __iommu_attach_notifier(struct notifier_block *nb,
-				   unsigned long action, void *data)
-{
-	struct iommu_dma_notifier_data *master, *tmp;
-
-	if (action != BUS_NOTIFY_BIND_DRIVER)
-		return 0;
-
-	mutex_lock(&iommu_dma_notifier_lock);
-	list_for_each_entry_safe(master, tmp, &iommu_dma_masters, list) {
-		if (data == master->dev && do_iommu_attach(master->dev,
-				master->ops, master->dma_base, master->size)) {
-			list_del(&master->list);
-			kfree(master);
-			break;
-		}
-	}
-	mutex_unlock(&iommu_dma_notifier_lock);
-	return 0;
-}
-
-static int __init register_iommu_dma_ops_notifier(struct bus_type *bus)
-{
-	struct notifier_block *nb = kzalloc(sizeof(*nb), GFP_KERNEL);
-	int ret;
-
-	if (!nb)
-		return -ENOMEM;
-
-	nb->notifier_call = __iommu_attach_notifier;
-
-	ret = bus_register_notifier(bus, nb);
-	if (ret) {
-		pr_warn("Failed to register DMA domain notifier; IOMMU DMA ops unavailable on bus '%s'\n",
-			bus->name);
-		kfree(nb);
-	}
-	return ret;
-}
-
-static int __init __iommu_dma_init(void)
-{
-	int ret;
-
-	ret = iommu_dma_init();
-	if (!ret)
-		ret = register_iommu_dma_ops_notifier(&platform_bus_type);
-	if (!ret)
-		ret = register_iommu_dma_ops_notifier(&amba_bustype);
-#ifdef CONFIG_PCI
-	if (!ret)
-		ret = register_iommu_dma_ops_notifier(&pci_bus_type);
-#endif
-	return ret;
-}
-arch_initcall(__iommu_dma_init);
-
-static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-				  const struct iommu_ops *ops)
-{
-	struct iommu_group *group;
-
-	if (!ops)
-		return;
-	/*
-	 * TODO: As a concession to the future, we're ready to handle being
-	 * called both early and late (i.e. after bus_add_device). Once all
-	 * the platform bus code is reworked to call us late and the notifier
-	 * junk above goes away, move the body of do_iommu_attach here.
-	 */
-	group = iommu_group_get(dev);
-	if (group) {
-		do_iommu_attach(dev, ops, dma_base, size);
-		iommu_group_put(group);
-	} else {
-		queue_iommu_attach(dev, ops, dma_base, size);
-	}
 }
 
 void arch_teardown_dma_ops(struct device *dev)
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 09/11] arm64: dma-mapping: Remove the notifier trick to handle early setting of dma_ops
@ 2017-04-10 11:21       ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
  To: linux-arm-kernel

With arch_setup_dma_ops now being called late during device's probe after
the device's iommu is probed, the notifier trick required to handle the
early setup of dma_ops before the iommu group gets created is not
required. So removing the notifier's here.

Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
Acked-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
[rm: clean up even more]
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 arch/arm64/mm/dma-mapping.c | 142 ++++++--------------------------------------
 1 file changed, 18 insertions(+), 124 deletions(-)

diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 81cdb2e..b465759 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -813,34 +813,26 @@ static void __iommu_unmap_sg_attrs(struct device *dev,
 	.mapping_error = iommu_dma_mapping_error,
 };
 
-/*
- * TODO: Right now __iommu_setup_dma_ops() gets called too early to do
- * everything it needs to - the device is only partially created and the
- * IOMMU driver hasn't seen it yet, so it can't have a group. Thus we
- * need this delayed attachment dance. Once IOMMU probe ordering is sorted
- * to move the arch_setup_dma_ops() call later, all the notifier bits below
- * become unnecessary, and will go away.
- */
-struct iommu_dma_notifier_data {
-	struct list_head list;
-	struct device *dev;
-	const struct iommu_ops *ops;
-	u64 dma_base;
-	u64 size;
-};
-static LIST_HEAD(iommu_dma_masters);
-static DEFINE_MUTEX(iommu_dma_notifier_lock);
+static int __init __iommu_dma_init(void)
+{
+	return iommu_dma_init();
+}
+arch_initcall(__iommu_dma_init);
 
-static bool do_iommu_attach(struct device *dev, const struct iommu_ops *ops,
-			   u64 dma_base, u64 size)
+static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+				  const struct iommu_ops *ops)
 {
-	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
+	struct iommu_domain *domain;
+
+	if (!ops)
+		return;
 
 	/*
-	 * If the IOMMU driver has the DMA domain support that we require,
-	 * then the IOMMU core will have already configured a group for this
-	 * device, and allocated the default domain for that group.
+	 * The IOMMU core code allocates the default DMA domain, which the
+	 * underlying IOMMU driver needs to support via the dma-iommu layer.
 	 */
+	domain = iommu_get_domain_for_dev(dev);
+
 	if (!domain)
 		goto out_err;
 
@@ -851,109 +843,11 @@ static bool do_iommu_attach(struct device *dev, const struct iommu_ops *ops,
 		dev->dma_ops = &iommu_dma_ops;
 	}
 
-	return true;
+	return;
+
 out_err:
-	pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA ops\n",
+	 pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA ops\n",
 		 dev_name(dev));
-	return false;
-}
-
-static void queue_iommu_attach(struct device *dev, const struct iommu_ops *ops,
-			      u64 dma_base, u64 size)
-{
-	struct iommu_dma_notifier_data *iommudata;
-
-	iommudata = kzalloc(sizeof(*iommudata), GFP_KERNEL);
-	if (!iommudata)
-		return;
-
-	iommudata->dev = dev;
-	iommudata->ops = ops;
-	iommudata->dma_base = dma_base;
-	iommudata->size = size;
-
-	mutex_lock(&iommu_dma_notifier_lock);
-	list_add(&iommudata->list, &iommu_dma_masters);
-	mutex_unlock(&iommu_dma_notifier_lock);
-}
-
-static int __iommu_attach_notifier(struct notifier_block *nb,
-				   unsigned long action, void *data)
-{
-	struct iommu_dma_notifier_data *master, *tmp;
-
-	if (action != BUS_NOTIFY_BIND_DRIVER)
-		return 0;
-
-	mutex_lock(&iommu_dma_notifier_lock);
-	list_for_each_entry_safe(master, tmp, &iommu_dma_masters, list) {
-		if (data == master->dev && do_iommu_attach(master->dev,
-				master->ops, master->dma_base, master->size)) {
-			list_del(&master->list);
-			kfree(master);
-			break;
-		}
-	}
-	mutex_unlock(&iommu_dma_notifier_lock);
-	return 0;
-}
-
-static int __init register_iommu_dma_ops_notifier(struct bus_type *bus)
-{
-	struct notifier_block *nb = kzalloc(sizeof(*nb), GFP_KERNEL);
-	int ret;
-
-	if (!nb)
-		return -ENOMEM;
-
-	nb->notifier_call = __iommu_attach_notifier;
-
-	ret = bus_register_notifier(bus, nb);
-	if (ret) {
-		pr_warn("Failed to register DMA domain notifier; IOMMU DMA ops unavailable on bus '%s'\n",
-			bus->name);
-		kfree(nb);
-	}
-	return ret;
-}
-
-static int __init __iommu_dma_init(void)
-{
-	int ret;
-
-	ret = iommu_dma_init();
-	if (!ret)
-		ret = register_iommu_dma_ops_notifier(&platform_bus_type);
-	if (!ret)
-		ret = register_iommu_dma_ops_notifier(&amba_bustype);
-#ifdef CONFIG_PCI
-	if (!ret)
-		ret = register_iommu_dma_ops_notifier(&pci_bus_type);
-#endif
-	return ret;
-}
-arch_initcall(__iommu_dma_init);
-
-static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
-				  const struct iommu_ops *ops)
-{
-	struct iommu_group *group;
-
-	if (!ops)
-		return;
-	/*
-	 * TODO: As a concession to the future, we're ready to handle being
-	 * called both early and late (i.e. after bus_add_device). Once all
-	 * the platform bus code is reworked to call us late and the notifier
-	 * junk above goes away, move the body of do_iommu_attach here.
-	 */
-	group = iommu_group_get(dev);
-	if (group) {
-		do_iommu_attach(dev, ops, dma_base, size);
-		iommu_group_put(group);
-	} else {
-		queue_iommu_attach(dev, ops, dma_base, size);
-	}
 }
 
 void arch_teardown_dma_ops(struct device *dev)
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 10/11] iommu/arm-smmu: Clean up early-probing workarounds
  2017-04-10 11:20   ` Sricharan R
  (?)
@ 2017-04-10 11:21       ` Sricharan R
  -1 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
  To: robin.murphy-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
	joro-zLv9SwRftAIdnm+yROfE0A, lorenzo.pieralisi-5wv7dgnIgG8,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ,
	bhelgaas-hpIqsD4AKlfQT0dZR+AlfA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
	hanjun.guo-QSEj5FYQhm4dnm+yROfE0A, okaya-sgV2jX0FEOL9JmXXK+q4OQ,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, sudeep.holla-5wv7dgnIgG8,
	rjw-LthD3rsA81gm4RdzfppkhA, lenb-DgEjT+Ai2ygdnm+yROfE0A,
	catalin.marinas-5wv7dgnIgG8, arnd-r2nGTMty4D4,
	linux-arch-u79uwXL29TY76Z2rM5mHXA,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r

From: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>

Now that the appropriate ordering is enforced via probe-deferral of
masters in core code, rip it all out and bask in the simplicity.

Tested-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Acked-by: Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>
Signed-off-by: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
[Sricharan: Rebased on top of ACPI IORT SMMU series]
Signed-off-by: Sricharan R <sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
---
 drivers/iommu/arm-smmu-v3.c |  46 +-----------------
 drivers/iommu/arm-smmu.c    | 110 +++++++++++++++++++-------------------------
 2 files changed, 49 insertions(+), 107 deletions(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 5806a6a..9497800 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2761,51 +2761,9 @@ static int arm_smmu_device_remove(struct platform_device *pdev)
 	.probe	= arm_smmu_device_probe,
 	.remove	= arm_smmu_device_remove,
 };
+module_platform_driver(arm_smmu_driver);
 
-static int __init arm_smmu_init(void)
-{
-	static bool registered;
-	int ret = 0;
-
-	if (!registered) {
-		ret = platform_driver_register(&arm_smmu_driver);
-		registered = !ret;
-	}
-	return ret;
-}
-
-static void __exit arm_smmu_exit(void)
-{
-	return platform_driver_unregister(&arm_smmu_driver);
-}
-
-subsys_initcall(arm_smmu_init);
-module_exit(arm_smmu_exit);
-
-static int __init arm_smmu_of_init(struct device_node *np)
-{
-	int ret = arm_smmu_init();
-
-	if (ret)
-		return ret;
-
-	if (!of_platform_device_create(np, NULL, platform_bus_type.dev_root))
-		return -ENODEV;
-
-	return 0;
-}
-IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3", arm_smmu_of_init);
-
-#ifdef CONFIG_ACPI
-static int __init acpi_smmu_v3_init(struct acpi_table_header *table)
-{
-	if (iort_node_match(ACPI_IORT_NODE_SMMU_V3))
-		return arm_smmu_init();
-
-	return 0;
-}
-IORT_ACPI_DECLARE(arm_smmu_v3, ACPI_SIG_IORT, acpi_smmu_v3_init);
-#endif
+IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3", NULL);
 
 MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
 MODULE_AUTHOR("Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>");
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index abf6496..be53b02 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -2075,6 +2075,23 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev,
 	return 0;
 }
 
+static void arm_smmu_bus_init(void)
+{
+	/* Oh, for a proper bus abstraction */
+	if (!iommu_present(&platform_bus_type))
+		bus_set_iommu(&platform_bus_type, &arm_smmu_ops);
+#ifdef CONFIG_ARM_AMBA
+	if (!iommu_present(&amba_bustype))
+		bus_set_iommu(&amba_bustype, &arm_smmu_ops);
+#endif
+#ifdef CONFIG_PCI
+	if (!iommu_present(&pci_bus_type)) {
+		pci_request_acs();
+		bus_set_iommu(&pci_bus_type, &arm_smmu_ops);
+	}
+#endif
+}
+
 static int arm_smmu_device_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -2180,21 +2197,30 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 	arm_smmu_device_reset(smmu);
 	arm_smmu_test_smr_masks(smmu);
 
-	/* Oh, for a proper bus abstraction */
-	if (!iommu_present(&platform_bus_type))
-		bus_set_iommu(&platform_bus_type, &arm_smmu_ops);
-#ifdef CONFIG_ARM_AMBA
-	if (!iommu_present(&amba_bustype))
-		bus_set_iommu(&amba_bustype, &arm_smmu_ops);
-#endif
-#ifdef CONFIG_PCI
-	if (!iommu_present(&pci_bus_type)) {
-		pci_request_acs();
-		bus_set_iommu(&pci_bus_type, &arm_smmu_ops);
-	}
-#endif
+	/*
+	 * For ACPI and generic DT bindings, an SMMU will be probed before
+	 * any device which might need it, so we want the bus ops in place
+	 * ready to handle default domain setup as soon as any SMMU exists.
+	 */
+	if (!using_legacy_binding)
+		arm_smmu_bus_init();
+
+	return 0;
+}
+
+/*
+ * With the legacy DT binding in play, though, we have no guarantees about
+ * probe order, but then we're also not doing default domains, so we can
+ * delay setting bus ops until we're sure every possible SMMU is ready,
+ * and that way ensure that no add_device() calls get missed.
+ */
+static int arm_smmu_legacy_bus_init(void)
+{
+	if (using_legacy_binding)
+		arm_smmu_bus_init();
 	return 0;
 }
+device_initcall_sync(arm_smmu_legacy_bus_init);
 
 static int arm_smmu_device_remove(struct platform_device *pdev)
 {
@@ -2219,56 +2245,14 @@ static int arm_smmu_device_remove(struct platform_device *pdev)
 	.probe	= arm_smmu_device_probe,
 	.remove	= arm_smmu_device_remove,
 };
-
-static int __init arm_smmu_init(void)
-{
-	static bool registered;
-	int ret = 0;
-
-	if (!registered) {
-		ret = platform_driver_register(&arm_smmu_driver);
-		registered = !ret;
-	}
-	return ret;
-}
-
-static void __exit arm_smmu_exit(void)
-{
-	return platform_driver_unregister(&arm_smmu_driver);
-}
-
-subsys_initcall(arm_smmu_init);
-module_exit(arm_smmu_exit);
-
-static int __init arm_smmu_of_init(struct device_node *np)
-{
-	int ret = arm_smmu_init();
-
-	if (ret)
-		return ret;
-
-	if (!of_platform_device_create(np, NULL, platform_bus_type.dev_root))
-		return -ENODEV;
-
-	return 0;
-}
-IOMMU_OF_DECLARE(arm_smmuv1, "arm,smmu-v1", arm_smmu_of_init);
-IOMMU_OF_DECLARE(arm_smmuv2, "arm,smmu-v2", arm_smmu_of_init);
-IOMMU_OF_DECLARE(arm_mmu400, "arm,mmu-400", arm_smmu_of_init);
-IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401", arm_smmu_of_init);
-IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500", arm_smmu_of_init);
-IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2", arm_smmu_of_init);
-
-#ifdef CONFIG_ACPI
-static int __init arm_smmu_acpi_init(struct acpi_table_header *table)
-{
-	if (iort_node_match(ACPI_IORT_NODE_SMMU))
-		return arm_smmu_init();
-
-	return 0;
-}
-IORT_ACPI_DECLARE(arm_smmu, ACPI_SIG_IORT, arm_smmu_acpi_init);
-#endif
+module_platform_driver(arm_smmu_driver);
+
+IOMMU_OF_DECLARE(arm_smmuv1, "arm,smmu-v1", NULL);
+IOMMU_OF_DECLARE(arm_smmuv2, "arm,smmu-v2", NULL);
+IOMMU_OF_DECLARE(arm_mmu400, "arm,mmu-400", NULL);
+IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401", NULL);
+IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500", NULL);
+IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2", NULL);
 
 MODULE_DESCRIPTION("IOMMU API for ARM architected SMMU implementations");
 MODULE_AUTHOR("Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>");
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 10/11] iommu/arm-smmu: Clean up early-probing workarounds
@ 2017-04-10 11:21       ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
  To: robin.murphy, will.deacon, joro, lorenzo.pieralisi, iommu,
	linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh
  Cc: sricharan

From: Robin Murphy <robin.murphy@arm.com>

Now that the appropriate ordering is enforced via probe-deferral of
masters in core code, rip it all out and bask in the simplicity.

Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
Acked-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
[Sricharan: Rebased on top of ACPI IORT SMMU series]
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
---
 drivers/iommu/arm-smmu-v3.c |  46 +-----------------
 drivers/iommu/arm-smmu.c    | 110 +++++++++++++++++++-------------------------
 2 files changed, 49 insertions(+), 107 deletions(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 5806a6a..9497800 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2761,51 +2761,9 @@ static int arm_smmu_device_remove(struct platform_device *pdev)
 	.probe	= arm_smmu_device_probe,
 	.remove	= arm_smmu_device_remove,
 };
+module_platform_driver(arm_smmu_driver);
 
-static int __init arm_smmu_init(void)
-{
-	static bool registered;
-	int ret = 0;
-
-	if (!registered) {
-		ret = platform_driver_register(&arm_smmu_driver);
-		registered = !ret;
-	}
-	return ret;
-}
-
-static void __exit arm_smmu_exit(void)
-{
-	return platform_driver_unregister(&arm_smmu_driver);
-}
-
-subsys_initcall(arm_smmu_init);
-module_exit(arm_smmu_exit);
-
-static int __init arm_smmu_of_init(struct device_node *np)
-{
-	int ret = arm_smmu_init();
-
-	if (ret)
-		return ret;
-
-	if (!of_platform_device_create(np, NULL, platform_bus_type.dev_root))
-		return -ENODEV;
-
-	return 0;
-}
-IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3", arm_smmu_of_init);
-
-#ifdef CONFIG_ACPI
-static int __init acpi_smmu_v3_init(struct acpi_table_header *table)
-{
-	if (iort_node_match(ACPI_IORT_NODE_SMMU_V3))
-		return arm_smmu_init();
-
-	return 0;
-}
-IORT_ACPI_DECLARE(arm_smmu_v3, ACPI_SIG_IORT, acpi_smmu_v3_init);
-#endif
+IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3", NULL);
 
 MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
 MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index abf6496..be53b02 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -2075,6 +2075,23 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev,
 	return 0;
 }
 
+static void arm_smmu_bus_init(void)
+{
+	/* Oh, for a proper bus abstraction */
+	if (!iommu_present(&platform_bus_type))
+		bus_set_iommu(&platform_bus_type, &arm_smmu_ops);
+#ifdef CONFIG_ARM_AMBA
+	if (!iommu_present(&amba_bustype))
+		bus_set_iommu(&amba_bustype, &arm_smmu_ops);
+#endif
+#ifdef CONFIG_PCI
+	if (!iommu_present(&pci_bus_type)) {
+		pci_request_acs();
+		bus_set_iommu(&pci_bus_type, &arm_smmu_ops);
+	}
+#endif
+}
+
 static int arm_smmu_device_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -2180,21 +2197,30 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 	arm_smmu_device_reset(smmu);
 	arm_smmu_test_smr_masks(smmu);
 
-	/* Oh, for a proper bus abstraction */
-	if (!iommu_present(&platform_bus_type))
-		bus_set_iommu(&platform_bus_type, &arm_smmu_ops);
-#ifdef CONFIG_ARM_AMBA
-	if (!iommu_present(&amba_bustype))
-		bus_set_iommu(&amba_bustype, &arm_smmu_ops);
-#endif
-#ifdef CONFIG_PCI
-	if (!iommu_present(&pci_bus_type)) {
-		pci_request_acs();
-		bus_set_iommu(&pci_bus_type, &arm_smmu_ops);
-	}
-#endif
+	/*
+	 * For ACPI and generic DT bindings, an SMMU will be probed before
+	 * any device which might need it, so we want the bus ops in place
+	 * ready to handle default domain setup as soon as any SMMU exists.
+	 */
+	if (!using_legacy_binding)
+		arm_smmu_bus_init();
+
+	return 0;
+}
+
+/*
+ * With the legacy DT binding in play, though, we have no guarantees about
+ * probe order, but then we're also not doing default domains, so we can
+ * delay setting bus ops until we're sure every possible SMMU is ready,
+ * and that way ensure that no add_device() calls get missed.
+ */
+static int arm_smmu_legacy_bus_init(void)
+{
+	if (using_legacy_binding)
+		arm_smmu_bus_init();
 	return 0;
 }
+device_initcall_sync(arm_smmu_legacy_bus_init);
 
 static int arm_smmu_device_remove(struct platform_device *pdev)
 {
@@ -2219,56 +2245,14 @@ static int arm_smmu_device_remove(struct platform_device *pdev)
 	.probe	= arm_smmu_device_probe,
 	.remove	= arm_smmu_device_remove,
 };
-
-static int __init arm_smmu_init(void)
-{
-	static bool registered;
-	int ret = 0;
-
-	if (!registered) {
-		ret = platform_driver_register(&arm_smmu_driver);
-		registered = !ret;
-	}
-	return ret;
-}
-
-static void __exit arm_smmu_exit(void)
-{
-	return platform_driver_unregister(&arm_smmu_driver);
-}
-
-subsys_initcall(arm_smmu_init);
-module_exit(arm_smmu_exit);
-
-static int __init arm_smmu_of_init(struct device_node *np)
-{
-	int ret = arm_smmu_init();
-
-	if (ret)
-		return ret;
-
-	if (!of_platform_device_create(np, NULL, platform_bus_type.dev_root))
-		return -ENODEV;
-
-	return 0;
-}
-IOMMU_OF_DECLARE(arm_smmuv1, "arm,smmu-v1", arm_smmu_of_init);
-IOMMU_OF_DECLARE(arm_smmuv2, "arm,smmu-v2", arm_smmu_of_init);
-IOMMU_OF_DECLARE(arm_mmu400, "arm,mmu-400", arm_smmu_of_init);
-IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401", arm_smmu_of_init);
-IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500", arm_smmu_of_init);
-IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2", arm_smmu_of_init);
-
-#ifdef CONFIG_ACPI
-static int __init arm_smmu_acpi_init(struct acpi_table_header *table)
-{
-	if (iort_node_match(ACPI_IORT_NODE_SMMU))
-		return arm_smmu_init();
-
-	return 0;
-}
-IORT_ACPI_DECLARE(arm_smmu, ACPI_SIG_IORT, arm_smmu_acpi_init);
-#endif
+module_platform_driver(arm_smmu_driver);
+
+IOMMU_OF_DECLARE(arm_smmuv1, "arm,smmu-v1", NULL);
+IOMMU_OF_DECLARE(arm_smmuv2, "arm,smmu-v2", NULL);
+IOMMU_OF_DECLARE(arm_mmu400, "arm,mmu-400", NULL);
+IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401", NULL);
+IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500", NULL);
+IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2", NULL);
 
 MODULE_DESCRIPTION("IOMMU API for ARM architected SMMU implementations");
 MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 10/11] iommu/arm-smmu: Clean up early-probing workarounds
@ 2017-04-10 11:21       ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
  To: linux-arm-kernel

From: Robin Murphy <robin.murphy@arm.com>

Now that the appropriate ordering is enforced via probe-deferral of
masters in core code, rip it all out and bask in the simplicity.

Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
Acked-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
[Sricharan: Rebased on top of ACPI IORT SMMU series]
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
---
 drivers/iommu/arm-smmu-v3.c |  46 +-----------------
 drivers/iommu/arm-smmu.c    | 110 +++++++++++++++++++-------------------------
 2 files changed, 49 insertions(+), 107 deletions(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 5806a6a..9497800 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2761,51 +2761,9 @@ static int arm_smmu_device_remove(struct platform_device *pdev)
 	.probe	= arm_smmu_device_probe,
 	.remove	= arm_smmu_device_remove,
 };
+module_platform_driver(arm_smmu_driver);
 
-static int __init arm_smmu_init(void)
-{
-	static bool registered;
-	int ret = 0;
-
-	if (!registered) {
-		ret = platform_driver_register(&arm_smmu_driver);
-		registered = !ret;
-	}
-	return ret;
-}
-
-static void __exit arm_smmu_exit(void)
-{
-	return platform_driver_unregister(&arm_smmu_driver);
-}
-
-subsys_initcall(arm_smmu_init);
-module_exit(arm_smmu_exit);
-
-static int __init arm_smmu_of_init(struct device_node *np)
-{
-	int ret = arm_smmu_init();
-
-	if (ret)
-		return ret;
-
-	if (!of_platform_device_create(np, NULL, platform_bus_type.dev_root))
-		return -ENODEV;
-
-	return 0;
-}
-IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3", arm_smmu_of_init);
-
-#ifdef CONFIG_ACPI
-static int __init acpi_smmu_v3_init(struct acpi_table_header *table)
-{
-	if (iort_node_match(ACPI_IORT_NODE_SMMU_V3))
-		return arm_smmu_init();
-
-	return 0;
-}
-IORT_ACPI_DECLARE(arm_smmu_v3, ACPI_SIG_IORT, acpi_smmu_v3_init);
-#endif
+IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3", NULL);
 
 MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
 MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index abf6496..be53b02 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -2075,6 +2075,23 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev,
 	return 0;
 }
 
+static void arm_smmu_bus_init(void)
+{
+	/* Oh, for a proper bus abstraction */
+	if (!iommu_present(&platform_bus_type))
+		bus_set_iommu(&platform_bus_type, &arm_smmu_ops);
+#ifdef CONFIG_ARM_AMBA
+	if (!iommu_present(&amba_bustype))
+		bus_set_iommu(&amba_bustype, &arm_smmu_ops);
+#endif
+#ifdef CONFIG_PCI
+	if (!iommu_present(&pci_bus_type)) {
+		pci_request_acs();
+		bus_set_iommu(&pci_bus_type, &arm_smmu_ops);
+	}
+#endif
+}
+
 static int arm_smmu_device_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -2180,21 +2197,30 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 	arm_smmu_device_reset(smmu);
 	arm_smmu_test_smr_masks(smmu);
 
-	/* Oh, for a proper bus abstraction */
-	if (!iommu_present(&platform_bus_type))
-		bus_set_iommu(&platform_bus_type, &arm_smmu_ops);
-#ifdef CONFIG_ARM_AMBA
-	if (!iommu_present(&amba_bustype))
-		bus_set_iommu(&amba_bustype, &arm_smmu_ops);
-#endif
-#ifdef CONFIG_PCI
-	if (!iommu_present(&pci_bus_type)) {
-		pci_request_acs();
-		bus_set_iommu(&pci_bus_type, &arm_smmu_ops);
-	}
-#endif
+	/*
+	 * For ACPI and generic DT bindings, an SMMU will be probed before
+	 * any device which might need it, so we want the bus ops in place
+	 * ready to handle default domain setup as soon as any SMMU exists.
+	 */
+	if (!using_legacy_binding)
+		arm_smmu_bus_init();
+
+	return 0;
+}
+
+/*
+ * With the legacy DT binding in play, though, we have no guarantees about
+ * probe order, but then we're also not doing default domains, so we can
+ * delay setting bus ops until we're sure every possible SMMU is ready,
+ * and that way ensure that no add_device() calls get missed.
+ */
+static int arm_smmu_legacy_bus_init(void)
+{
+	if (using_legacy_binding)
+		arm_smmu_bus_init();
 	return 0;
 }
+device_initcall_sync(arm_smmu_legacy_bus_init);
 
 static int arm_smmu_device_remove(struct platform_device *pdev)
 {
@@ -2219,56 +2245,14 @@ static int arm_smmu_device_remove(struct platform_device *pdev)
 	.probe	= arm_smmu_device_probe,
 	.remove	= arm_smmu_device_remove,
 };
-
-static int __init arm_smmu_init(void)
-{
-	static bool registered;
-	int ret = 0;
-
-	if (!registered) {
-		ret = platform_driver_register(&arm_smmu_driver);
-		registered = !ret;
-	}
-	return ret;
-}
-
-static void __exit arm_smmu_exit(void)
-{
-	return platform_driver_unregister(&arm_smmu_driver);
-}
-
-subsys_initcall(arm_smmu_init);
-module_exit(arm_smmu_exit);
-
-static int __init arm_smmu_of_init(struct device_node *np)
-{
-	int ret = arm_smmu_init();
-
-	if (ret)
-		return ret;
-
-	if (!of_platform_device_create(np, NULL, platform_bus_type.dev_root))
-		return -ENODEV;
-
-	return 0;
-}
-IOMMU_OF_DECLARE(arm_smmuv1, "arm,smmu-v1", arm_smmu_of_init);
-IOMMU_OF_DECLARE(arm_smmuv2, "arm,smmu-v2", arm_smmu_of_init);
-IOMMU_OF_DECLARE(arm_mmu400, "arm,mmu-400", arm_smmu_of_init);
-IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401", arm_smmu_of_init);
-IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500", arm_smmu_of_init);
-IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2", arm_smmu_of_init);
-
-#ifdef CONFIG_ACPI
-static int __init arm_smmu_acpi_init(struct acpi_table_header *table)
-{
-	if (iort_node_match(ACPI_IORT_NODE_SMMU))
-		return arm_smmu_init();
-
-	return 0;
-}
-IORT_ACPI_DECLARE(arm_smmu, ACPI_SIG_IORT, arm_smmu_acpi_init);
-#endif
+module_platform_driver(arm_smmu_driver);
+
+IOMMU_OF_DECLARE(arm_smmuv1, "arm,smmu-v1", NULL);
+IOMMU_OF_DECLARE(arm_smmuv2, "arm,smmu-v2", NULL);
+IOMMU_OF_DECLARE(arm_mmu400, "arm,mmu-400", NULL);
+IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401", NULL);
+IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500", NULL);
+IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2", NULL);
 
 MODULE_DESCRIPTION("IOMMU API for ARM architected SMMU implementations");
 MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 11/11] ACPI/IORT: Remove linker section for IORT entries probing
  2017-04-10 11:20   ` Sricharan R
  (?)
@ 2017-04-10 11:21       ` Sricharan R
  -1 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
  To: robin.murphy-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
	joro-zLv9SwRftAIdnm+yROfE0A, lorenzo.pieralisi-5wv7dgnIgG8,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ,
	bhelgaas-hpIqsD4AKlfQT0dZR+AlfA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
	hanjun.guo-QSEj5FYQhm4dnm+yROfE0A, okaya-sgV2jX0FEOL9JmXXK+q4OQ,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, sudeep.holla-5wv7dgnIgG8,
	rjw-LthD3rsA81gm4RdzfppkhA, lenb-DgEjT+Ai2ygdnm+yROfE0A,
	catalin.marinas-5wv7dgnIgG8, arnd-r2nGTMty4D4,
	linux-arch-u79uwXL29TY76Z2rM5mHXA,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r

From: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>

The IORT linker section introduced by commit 34ceea275f62
("ACPI/IORT: Introduce linker section for IORT entries probing")
was needed to make sure SMMU drivers are registered (and therefore
probed) in the kernel before devices using the SMMU have a chance
to probe in turn.

Through the introduction of deferred IOMMU configuration the linker
section based IORT probing infrastructure is not needed any longer, in
that device/SMMU probe dependencies are managed through the probe
deferral mechanism, making the IORT linker section infrastructure
unused, so that it can be removed.

Remove the unused IORT linker section probing infrastructure
from the kernel to complete the ACPI IORT IOMMU configure probe
deferral mechanism implementation.

Tested-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Reviewed-by: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
Cc: Sricharan R <sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
---
 drivers/acpi/arm64/iort.c         | 2 --
 include/asm-generic/vmlinux.lds.h | 1 -
 include/linux/acpi_iort.h         | 3 ---
 3 files changed, 6 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index e323ece..e7b1940 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -1000,6 +1000,4 @@ void __init acpi_iort_init(void)
 	}
 
 	iort_init_platform_devices();
-
-	acpi_probe_device_table(iort);
 }
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 0968d13..9faa26c 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -566,7 +566,6 @@
 	IRQCHIP_OF_MATCH_TABLE()					\
 	ACPI_PROBE_TABLE(irqchip)					\
 	ACPI_PROBE_TABLE(clksrc)					\
-	ACPI_PROBE_TABLE(iort)						\
 	EARLYCON_TABLE()
 
 #define INIT_TEXT							\
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 77e0809..f167e1d04 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -52,7 +52,4 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
 { return NULL; }
 #endif
 
-#define IORT_ACPI_DECLARE(name, table_id, fn)		\
-	ACPI_DECLARE_PROBE_ENTRY(iort, name, table_id, 0, NULL, 0, fn)
-
 #endif /* __ACPI_IORT_H__ */
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 11/11] ACPI/IORT: Remove linker section for IORT entries probing
@ 2017-04-10 11:21       ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
  To: robin.murphy, will.deacon, joro, lorenzo.pieralisi, iommu,
	linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh
  Cc: sricharan

From: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

The IORT linker section introduced by commit 34ceea275f62
("ACPI/IORT: Introduce linker section for IORT entries probing")
was needed to make sure SMMU drivers are registered (and therefore
probed) in the kernel before devices using the SMMU have a chance
to probe in turn.

Through the introduction of deferred IOMMU configuration the linker
section based IORT probing infrastructure is not needed any longer, in
that device/SMMU probe dependencies are managed through the probe
deferral mechanism, making the IORT linker section infrastructure
unused, so that it can be removed.

Remove the unused IORT linker section probing infrastructure
from the kernel to complete the ACPI IORT IOMMU configure probe
deferral mechanism implementation.

Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Sricharan R <sricharan@codeaurora.org>
---
 drivers/acpi/arm64/iort.c         | 2 --
 include/asm-generic/vmlinux.lds.h | 1 -
 include/linux/acpi_iort.h         | 3 ---
 3 files changed, 6 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index e323ece..e7b1940 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -1000,6 +1000,4 @@ void __init acpi_iort_init(void)
 	}
 
 	iort_init_platform_devices();
-
-	acpi_probe_device_table(iort);
 }
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 0968d13..9faa26c 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -566,7 +566,6 @@
 	IRQCHIP_OF_MATCH_TABLE()					\
 	ACPI_PROBE_TABLE(irqchip)					\
 	ACPI_PROBE_TABLE(clksrc)					\
-	ACPI_PROBE_TABLE(iort)						\
 	EARLYCON_TABLE()
 
 #define INIT_TEXT							\
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 77e0809..f167e1d04 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -52,7 +52,4 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
 { return NULL; }
 #endif
 
-#define IORT_ACPI_DECLARE(name, table_id, fn)		\
-	ACPI_DECLARE_PROBE_ENTRY(iort, name, table_id, 0, NULL, 0, fn)
-
 #endif /* __ACPI_IORT_H__ */
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 11/11] ACPI/IORT: Remove linker section for IORT entries probing
@ 2017-04-10 11:21       ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-04-10 11:21 UTC (permalink / raw)
  To: linux-arm-kernel

From: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

The IORT linker section introduced by commit 34ceea275f62
("ACPI/IORT: Introduce linker section for IORT entries probing")
was needed to make sure SMMU drivers are registered (and therefore
probed) in the kernel before devices using the SMMU have a chance
to probe in turn.

Through the introduction of deferred IOMMU configuration the linker
section based IORT probing infrastructure is not needed any longer, in
that device/SMMU probe dependencies are managed through the probe
deferral mechanism, making the IORT linker section infrastructure
unused, so that it can be removed.

Remove the unused IORT linker section probing infrastructure
from the kernel to complete the ACPI IORT IOMMU configure probe
deferral mechanism implementation.

Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Sricharan R <sricharan@codeaurora.org>
---
 drivers/acpi/arm64/iort.c         | 2 --
 include/asm-generic/vmlinux.lds.h | 1 -
 include/linux/acpi_iort.h         | 3 ---
 3 files changed, 6 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index e323ece..e7b1940 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -1000,6 +1000,4 @@ void __init acpi_iort_init(void)
 	}
 
 	iort_init_platform_devices();
-
-	acpi_probe_device_table(iort);
 }
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 0968d13..9faa26c 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -566,7 +566,6 @@
 	IRQCHIP_OF_MATCH_TABLE()					\
 	ACPI_PROBE_TABLE(irqchip)					\
 	ACPI_PROBE_TABLE(clksrc)					\
-	ACPI_PROBE_TABLE(iort)						\
 	EARLYCON_TABLE()
 
 #define INIT_TEXT							\
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 77e0809..f167e1d04 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -52,7 +52,4 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
 { return NULL; }
 #endif
 
-#define IORT_ACPI_DECLARE(name, table_id, fn)		\
-	ACPI_DECLARE_PROBE_ENTRY(iort, name, table_id, 0, NULL, 0, fn)
-
 #endif /* __ACPI_IORT_H__ */
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* Re: [PATCH V11 00/11] IOMMU probe deferral support
  2017-04-10 11:20   ` Sricharan R
@ 2017-04-10 11:56     ` Frank Rowand
  -1 siblings, 0 replies; 70+ messages in thread
From: Frank Rowand @ 2017-04-10 11:56 UTC (permalink / raw)
  To: Sricharan R, robin.murphy, will.deacon, joro, lorenzo.pieralisi,
	iommu, linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh

On 04/10/17 04:20, Sricharan R wrote:
> This series calls the dma ops configuration for the devices
> at a generic place so that it works for all busses.
> The dma_configure_ops for a device is now called during
> the device_attach callback just before the probe of the
> bus/driver is called. Similarly dma_deconfigure is called during
> device/driver_detach path.
> 
> pci_bus_add_devices    (platform/amba)(_device_create/driver_register)
>        |                         |
> pci_bus_add_device     (device_add/driver_register)
>        |                         |
> device_attach           device_initial_probe
>        |                         |
> __device_attach_driver    __device_attach_driver
>        |
> driver_probe_device
>        |
> really_probe
>        |
> dma_configure
> 
> Similarly on the device/driver_unregister path __device_release_driver is
> called which inturn calls dma_deconfigure.
> 
> Rebased the series against mainline 4.11-rc5. Applies and builds cleanly
> against iommu-next and with 3-way merge applies on top of linux-next
> as well (patch #8), because of "ACPI platform MSI support" from
> Hanjun being merged.
>   
> * Tested with platform and pci devices for probe deferral
>   and reprobe on arm64 based platform.
> 
> Previous post of this series [8]. 
> 
> Please note that, i have kept the tested/acked tags intact from V8
> because V9/10/11 were for more fixes that was added, so the original
> tags that was given for the functional testing remains the same.
> 
>  [V11]
>      * No functional changes.
> 
>      * Rebased on top of 4.11-rc6.
> 
>      * Dropped patch#3 from V10, as a result have to make
>        a change in patch#7 to return a 'non-void' to fix a
>        build warning.
> 
>      * Added Robin's and Rob's tags.

< snip >

The changes are good enough for me and you have Rob's acks, so the
series looks good from the device tree standpoint.

-Frank


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

* [PATCH V11 00/11] IOMMU probe deferral support
@ 2017-04-10 11:56     ` Frank Rowand
  0 siblings, 0 replies; 70+ messages in thread
From: Frank Rowand @ 2017-04-10 11:56 UTC (permalink / raw)
  To: linux-arm-kernel

On 04/10/17 04:20, Sricharan R wrote:
> This series calls the dma ops configuration for the devices
> at a generic place so that it works for all busses.
> The dma_configure_ops for a device is now called during
> the device_attach callback just before the probe of the
> bus/driver is called. Similarly dma_deconfigure is called during
> device/driver_detach path.
> 
> pci_bus_add_devices    (platform/amba)(_device_create/driver_register)
>        |                         |
> pci_bus_add_device     (device_add/driver_register)
>        |                         |
> device_attach           device_initial_probe
>        |                         |
> __device_attach_driver    __device_attach_driver
>        |
> driver_probe_device
>        |
> really_probe
>        |
> dma_configure
> 
> Similarly on the device/driver_unregister path __device_release_driver is
> called which inturn calls dma_deconfigure.
> 
> Rebased the series against mainline 4.11-rc5. Applies and builds cleanly
> against iommu-next and with 3-way merge applies on top of linux-next
> as well (patch #8), because of "ACPI platform MSI support" from
> Hanjun being merged.
>   
> * Tested with platform and pci devices for probe deferral
>   and reprobe on arm64 based platform.
> 
> Previous post of this series [8]. 
> 
> Please note that, i have kept the tested/acked tags intact from V8
> because V9/10/11 were for more fixes that was added, so the original
> tags that was given for the functional testing remains the same.
> 
>  [V11]
>      * No functional changes.
> 
>      * Rebased on top of 4.11-rc6.
> 
>      * Dropped patch#3 from V10, as a result have to make
>        a change in patch#7 to return a 'non-void' to fix a
>        build warning.
> 
>      * Added Robin's and Rob's tags.

< snip >

The changes are good enough for me and you have Rob's acks, so the
series looks good from the device tree standpoint.

-Frank

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

* Re: [PATCH V11 00/11] IOMMU probe deferral support
  2017-04-10 11:20   ` Sricharan R
  (?)
@ 2017-04-20 14:31       ` Joerg Roedel
  -1 siblings, 0 replies; 70+ messages in thread
From: Joerg Roedel @ 2017-04-20 14:31 UTC (permalink / raw)
  To: Sricharan R
  Cc: catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
	okaya-sgV2jX0FEOL9JmXXK+q4OQ,
	frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
	linux-arch-u79uwXL29TY76Z2rM5mHXA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, lenb-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, bhelgaas-hpIqsD4AKlfQT0dZR+AlfA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	rjw-LthD3rsA81gm4RdzfppkhA, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	sudeep.holla-5wv7dgnIgG8

On Mon, Apr 10, 2017 at 04:50:55PM +0530, Sricharan R wrote:
>  arch/arm64/mm/dma-mapping.c       | 142 +++++---------------------------------
>  drivers/acpi/arm64/iort.c         |  48 ++++++++++++-
>  drivers/acpi/glue.c               |   5 --
>  drivers/acpi/scan.c               |  11 ++-
>  drivers/base/dd.c                 |   9 +++
>  drivers/base/dma-mapping.c        |  41 +++++++++++
>  drivers/iommu/arm-smmu-v3.c       |  46 +-----------
>  drivers/iommu/arm-smmu.c          | 110 +++++++++++++----------------
>  drivers/iommu/of_iommu.c          | 126 ++++++++++++++++++++++++---------
>  drivers/of/device.c               |  23 +++++-
>  drivers/of/platform.c             |  10 +--
>  drivers/pci/probe.c               |  28 --------
>  include/acpi/acpi_bus.h           |   2 +-
>  include/asm-generic/vmlinux.lds.h |   1 -
>  include/linux/acpi.h              |   7 +-
>  include/linux/acpi_iort.h         |   3 -
>  include/linux/dma-mapping.h       |  12 ++++
>  include/linux/of_device.h         |  10 ++-
>  18 files changed, 312 insertions(+), 322 deletions(-)

Applied, thanks.

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

* Re: [PATCH V11 00/11] IOMMU probe deferral support
@ 2017-04-20 14:31       ` Joerg Roedel
  0 siblings, 0 replies; 70+ messages in thread
From: Joerg Roedel @ 2017-04-20 14:31 UTC (permalink / raw)
  To: Sricharan R
  Cc: robin.murphy, will.deacon, lorenzo.pieralisi, iommu,
	linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh

On Mon, Apr 10, 2017 at 04:50:55PM +0530, Sricharan R wrote:
>  arch/arm64/mm/dma-mapping.c       | 142 +++++---------------------------------
>  drivers/acpi/arm64/iort.c         |  48 ++++++++++++-
>  drivers/acpi/glue.c               |   5 --
>  drivers/acpi/scan.c               |  11 ++-
>  drivers/base/dd.c                 |   9 +++
>  drivers/base/dma-mapping.c        |  41 +++++++++++
>  drivers/iommu/arm-smmu-v3.c       |  46 +-----------
>  drivers/iommu/arm-smmu.c          | 110 +++++++++++++----------------
>  drivers/iommu/of_iommu.c          | 126 ++++++++++++++++++++++++---------
>  drivers/of/device.c               |  23 +++++-
>  drivers/of/platform.c             |  10 +--
>  drivers/pci/probe.c               |  28 --------
>  include/acpi/acpi_bus.h           |   2 +-
>  include/asm-generic/vmlinux.lds.h |   1 -
>  include/linux/acpi.h              |   7 +-
>  include/linux/acpi_iort.h         |   3 -
>  include/linux/dma-mapping.h       |  12 ++++
>  include/linux/of_device.h         |  10 ++-
>  18 files changed, 312 insertions(+), 322 deletions(-)

Applied, thanks.

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

* [PATCH V11 00/11] IOMMU probe deferral support
@ 2017-04-20 14:31       ` Joerg Roedel
  0 siblings, 0 replies; 70+ messages in thread
From: Joerg Roedel @ 2017-04-20 14:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Apr 10, 2017 at 04:50:55PM +0530, Sricharan R wrote:
>  arch/arm64/mm/dma-mapping.c       | 142 +++++---------------------------------
>  drivers/acpi/arm64/iort.c         |  48 ++++++++++++-
>  drivers/acpi/glue.c               |   5 --
>  drivers/acpi/scan.c               |  11 ++-
>  drivers/base/dd.c                 |   9 +++
>  drivers/base/dma-mapping.c        |  41 +++++++++++
>  drivers/iommu/arm-smmu-v3.c       |  46 +-----------
>  drivers/iommu/arm-smmu.c          | 110 +++++++++++++----------------
>  drivers/iommu/of_iommu.c          | 126 ++++++++++++++++++++++++---------
>  drivers/of/device.c               |  23 +++++-
>  drivers/of/platform.c             |  10 +--
>  drivers/pci/probe.c               |  28 --------
>  include/acpi/acpi_bus.h           |   2 +-
>  include/asm-generic/vmlinux.lds.h |   1 -
>  include/linux/acpi.h              |   7 +-
>  include/linux/acpi_iort.h         |   3 -
>  include/linux/dma-mapping.h       |  12 ++++
>  include/linux/of_device.h         |  10 ++-
>  18 files changed, 312 insertions(+), 322 deletions(-)

Applied, thanks.

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

* Re: [PATCH V11 00/11] IOMMU probe deferral support
  2017-04-10 11:20   ` Sricharan R
  (?)
@ 2017-05-08 11:23     ` Marek Szyprowski
  -1 siblings, 0 replies; 70+ messages in thread
From: Marek Szyprowski @ 2017-05-08 11:23 UTC (permalink / raw)
  To: Sricharan R, robin.murphy, will.deacon, joro, lorenzo.pieralisi,
	iommu, linux-arm-kernel, linux-arm-msm, bhelgaas, linux-pci,
	linux-acpi, tn, hanjun.guo, okaya, robh+dt, frowand.list,
	devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh

Hi Sricharan,

On 2017-04-10 13:20, Sricharan R wrote:
> This series calls the dma ops configuration for the devices
> at a generic place so that it works for all busses.
> The dma_configure_ops for a device is now called during
> the device_attach callback just before the probe of the
> bus/driver is called. Similarly dma_deconfigure is called during
> device/driver_detach path.
>
> pci_bus_add_devices    (platform/amba)(_device_create/driver_register)
>         |                         |
> pci_bus_add_device     (device_add/driver_register)
>         |                         |
> device_attach           device_initial_probe
>         |                         |
> __device_attach_driver    __device_attach_driver
>         |
> driver_probe_device
>         |
> really_probe
>         |
> dma_configure
>
> Similarly on the device/driver_unregister path __device_release_driver is
> called which inturn calls dma_deconfigure.
>
> Rebased the series against mainline 4.11-rc5. Applies and builds cleanly
> against iommu-next and with 3-way merge applies on top of linux-next
> as well (patch #8), because of "ACPI platform MSI support" from
> Hanjun being merged.
>    
> * Tested with platform and pci devices for probe deferral
>    and reprobe on arm64 based platform.

I just noticed that in the meantime the following patch: "arm: dma-mapping:
Reset the device's dma_ops" (https://patchwork.kernel.org/patch/9434105/ )
has been dropped from this series.

Lack of it causes serious issues with deferred probe of devices, which are
under IOMMU on ARM architecture. Please check where it got lost and push it
to Russell's patch tracking system ASAP to get it during v4.12-rcX cycle.

>
> Previous post of this series [8].
>
> Please note that, i have kept the tested/acked tags intact from V8
> because V9/10/11 were for more fixes that was added, so the original
> tags that was given for the functional testing remains the same.
>
>   [V11]
>       * No functional changes.
>
>       * Rebased on top of 4.11-rc6.
>
>       * Dropped patch#3 from V10, as a result have to make
>         a change in patch#7 to return a 'non-void' to fix a
>         build warning.
>
>       * Added Robin's and Rob's tags.
>
>   [V10]
>       * Rebased on top of 4.11-rc5.
>   
>       * Fixed coherent_dma_mask 64bit overflow issue [8]
>         for OF. The fix for OF was added as a separate
>         patch#6, since the issue is true even without probe deferral,
>         but gets reproduced with the probe deferral series.
>         Added Lorenzo's ACPI fix for coherent_dma_mask overflow
>         and the fix for dma_configure getting called more than
>         once for the same device.
>
>       * Also fixed an build issue caught by kbuild robot for
>         m68k arch. The issue was dma_(de)configure was not
>         getting defined for !CONFIG_HAS_DMA, so fixed that as well.
>
>   [V9]
>       * Rebased on top of 4.11-rc1.
>
>       * Merged Robin's fixes for legacy binding issue,
>         pci devices with no iommu-map property and deferencing
>         of_iommu_table after init.
>       
>   [V8]
>       * Picked up all the acks and tested tags from Marek and
>         Hanjun for DT and ACPI patches respectively, since
>         no functional changes was done.
>
>       * Addressed Minor comments Sinan and Bjorn.
>
>       * Added Robin's fix for fixing the deferencing NULL for
>         of_iommu_table after init in patch #2.
>
>       * Rebased it on top of linux-next
>
>   [V7]
>       * Updated the subject and commit log for patch #6 as per
>         comments from Lorenzo. No functional changes.
>
>   [V6]
>       * Fixed a bug in dma_configure function pointed out by
>         Robin.
>       * Reordered the patches as per comments from Robin and
>         Lorenzo.
>       * Added Tags.
>
>   [V5]
>       * Reworked the pci configuration code hanging outside and
>         pushed it to dma_configure as in PATCH#5,6,7.
>         Also added a couple of patches that Lorenzo provided for
>         correcting the Probe deferring mechanism in case of
>         ACPI devices from here [5].
>
>   [V4]
>       * Took the reworked patches [2] from Robin's branch and
>         rebased on top of Lorenzo's ACPI IORT ARM support series [3].
>
>       * Added the patches for moving the dma ops configuration of
>         acpi based devices to probe time as well.
>   [V3]
>       * Removed the patch to split dma_masks/dma_ops configuration
>         separately based on review comments that both masks and ops are
>         required only during the device probe time.
>
>       * Reworked the series based on Generic DT bindings series.
>
>       * Added call to iommu's remove_device in the cleanup path for arm and
>         arm64.
>
>       * Removed the notifier trick in arm64 to handle early device
>         registration.
>
>       * Added reset of dma_ops in cleanup path for arm based on comments.
>
>       * Fixed the pci_iommu_configure path and tested with PCI device as
>         well.
>   
>       * Fixed a bug to return the correct iommu_ops from patch 7 [4] in
>         last post.
>
>       * Fixed few other cosmetic comments.
>    
>   [V2]
>       * Updated the Initial post to call dma_configure/deconfigure from
>         generic code
>   
>       * Added iommu add_device callback from of_iommu_configure path
>
>   [V1]
>       * Initial post from Laurent Pinchart [1]
>
> [1] http://lists.linuxfoundation.org/pipermail/iommu/2015-May/013016.html
> [2] http://www.linux-arm.org/git?p=linux-rm.git;a=shortlog;h=refs/heads/iommu/defer
> [3] https://lkml.org/lkml/2016/11/21/141
> [4] https://www.mail-archive.com/iommu@xxxxxxxxxxxxxxxxxxxxxxxxxx/msg13940.html
> [5] git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git iommu/probe-deferral
> [6] http://www.spinics.net/lists/linux-pci/msg57992.html
> [7] https://www.spinics.net/lists/arm-kernel/msg556209.html
> [8] http://lkml.iu.edu/hypermail/linux/kernel/1704.0/01557.html
>
> Laurent Pinchart (2):
>    of: dma: Make of_dma_deconfigure() public
>    iommu: of: Handle IOMMU lookup failure with deferred probing or error
>
> Lorenzo Pieralisi (2):
>    ACPI/IORT: Add function to check SMMUs drivers presence
>    ACPI/IORT: Remove linker section for IORT entries probing
>
> Robin Murphy (3):
>    iommu/of: Refactor of_iommu_configure() for error handling
>    iommu/of: Prepare for deferred IOMMU configuration
>    iommu/arm-smmu: Clean up early-probing workarounds
>
> Sricharan R (4):
>    of: device: Fix overflow of coherent_dma_mask
>    of/acpi: Configure dma operations at probe time for platform/amba/pci
>      bus devices
>    drivers: acpi: Handle IOMMU lookup failure with deferred probing or
>      error
>    arm64: dma-mapping: Remove the notifier trick to handle early setting
>      of dma_ops
>
>   arch/arm64/mm/dma-mapping.c       | 142 +++++---------------------------------
>   drivers/acpi/arm64/iort.c         |  48 ++++++++++++-
>   drivers/acpi/glue.c               |   5 --
>   drivers/acpi/scan.c               |  11 ++-
>   drivers/base/dd.c                 |   9 +++
>   drivers/base/dma-mapping.c        |  41 +++++++++++
>   drivers/iommu/arm-smmu-v3.c       |  46 +-----------
>   drivers/iommu/arm-smmu.c          | 110 +++++++++++++----------------
>   drivers/iommu/of_iommu.c          | 126 ++++++++++++++++++++++++---------
>   drivers/of/device.c               |  23 +++++-
>   drivers/of/platform.c             |  10 +--
>   drivers/pci/probe.c               |  28 --------
>   include/acpi/acpi_bus.h           |   2 +-
>   include/asm-generic/vmlinux.lds.h |   1 -
>   include/linux/acpi.h              |   7 +-
>   include/linux/acpi_iort.h         |   3 -
>   include/linux/dma-mapping.h       |  12 ++++
>   include/linux/of_device.h         |  10 ++-
>   18 files changed, 312 insertions(+), 322 deletions(-)
>

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland


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

* Re: [PATCH V11 00/11] IOMMU probe deferral support
@ 2017-05-08 11:23     ` Marek Szyprowski
  0 siblings, 0 replies; 70+ messages in thread
From: Marek Szyprowski @ 2017-05-08 11:23 UTC (permalink / raw)
  To: Sricharan R, robin.murphy, will.deacon, joro, lorenzo.pieralisi,
	iommu, linux-arm-kernel, linux-arm-msm, bhelgaas, linux-pci,
	linux-acpi, tn, hanjun.guo, okaya, robh+dt, frowand.list,
	devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh

Hi Sricharan,

On 2017-04-10 13:20, Sricharan R wrote:
> This series calls the dma ops configuration for the devices
> at a generic place so that it works for all busses.
> The dma_configure_ops for a device is now called during
> the device_attach callback just before the probe of the
> bus/driver is called. Similarly dma_deconfigure is called during
> device/driver_detach path.
>
> pci_bus_add_devices    (platform/amba)(_device_create/driver_register)
>         |                         |
> pci_bus_add_device     (device_add/driver_register)
>         |                         |
> device_attach           device_initial_probe
>         |                         |
> __device_attach_driver    __device_attach_driver
>         |
> driver_probe_device
>         |
> really_probe
>         |
> dma_configure
>
> Similarly on the device/driver_unregister path __device_release_driver is
> called which inturn calls dma_deconfigure.
>
> Rebased the series against mainline 4.11-rc5. Applies and builds cleanly
> against iommu-next and with 3-way merge applies on top of linux-next
> as well (patch #8), because of "ACPI platform MSI support" from
> Hanjun being merged.
>    
> * Tested with platform and pci devices for probe deferral
>    and reprobe on arm64 based platform.

I just noticed that in the meantime the following patch: "arm: dma-mapping:
Reset the device's dma_ops" (https://patchwork.kernel.org/patch/9434105/ )
has been dropped from this series.

Lack of it causes serious issues with deferred probe of devices, which are
under IOMMU on ARM architecture. Please check where it got lost and push it
to Russell's patch tracking system ASAP to get it during v4.12-rcX cycle.

>
> Previous post of this series [8].
>
> Please note that, i have kept the tested/acked tags intact from V8
> because V9/10/11 were for more fixes that was added, so the original
> tags that was given for the functional testing remains the same.
>
>   [V11]
>       * No functional changes.
>
>       * Rebased on top of 4.11-rc6.
>
>       * Dropped patch#3 from V10, as a result have to make
>         a change in patch#7 to return a 'non-void' to fix a
>         build warning.
>
>       * Added Robin's and Rob's tags.
>
>   [V10]
>       * Rebased on top of 4.11-rc5.
>   
>       * Fixed coherent_dma_mask 64bit overflow issue [8]
>         for OF. The fix for OF was added as a separate
>         patch#6, since the issue is true even without probe deferral,
>         but gets reproduced with the probe deferral series.
>         Added Lorenzo's ACPI fix for coherent_dma_mask overflow
>         and the fix for dma_configure getting called more than
>         once for the same device.
>
>       * Also fixed an build issue caught by kbuild robot for
>         m68k arch. The issue was dma_(de)configure was not
>         getting defined for !CONFIG_HAS_DMA, so fixed that as well.
>
>   [V9]
>       * Rebased on top of 4.11-rc1.
>
>       * Merged Robin's fixes for legacy binding issue,
>         pci devices with no iommu-map property and deferencing
>         of_iommu_table after init.
>       
>   [V8]
>       * Picked up all the acks and tested tags from Marek and
>         Hanjun for DT and ACPI patches respectively, since
>         no functional changes was done.
>
>       * Addressed Minor comments Sinan and Bjorn.
>
>       * Added Robin's fix for fixing the deferencing NULL for
>         of_iommu_table after init in patch #2.
>
>       * Rebased it on top of linux-next
>
>   [V7]
>       * Updated the subject and commit log for patch #6 as per
>         comments from Lorenzo. No functional changes.
>
>   [V6]
>       * Fixed a bug in dma_configure function pointed out by
>         Robin.
>       * Reordered the patches as per comments from Robin and
>         Lorenzo.
>       * Added Tags.
>
>   [V5]
>       * Reworked the pci configuration code hanging outside and
>         pushed it to dma_configure as in PATCH#5,6,7.
>         Also added a couple of patches that Lorenzo provided for
>         correcting the Probe deferring mechanism in case of
>         ACPI devices from here [5].
>
>   [V4]
>       * Took the reworked patches [2] from Robin's branch and
>         rebased on top of Lorenzo's ACPI IORT ARM support series [3].
>
>       * Added the patches for moving the dma ops configuration of
>         acpi based devices to probe time as well.
>   [V3]
>       * Removed the patch to split dma_masks/dma_ops configuration
>         separately based on review comments that both masks and ops are
>         required only during the device probe time.
>
>       * Reworked the series based on Generic DT bindings series.
>
>       * Added call to iommu's remove_device in the cleanup path for arm and
>         arm64.
>
>       * Removed the notifier trick in arm64 to handle early device
>         registration.
>
>       * Added reset of dma_ops in cleanup path for arm based on comments.
>
>       * Fixed the pci_iommu_configure path and tested with PCI device as
>         well.
>   
>       * Fixed a bug to return the correct iommu_ops from patch 7 [4] in
>         last post.
>
>       * Fixed few other cosmetic comments.
>    
>   [V2]
>       * Updated the Initial post to call dma_configure/deconfigure from
>         generic code
>   
>       * Added iommu add_device callback from of_iommu_configure path
>
>   [V1]
>       * Initial post from Laurent Pinchart [1]
>
> [1] http://lists.linuxfoundation.org/pipermail/iommu/2015-May/013016.html
> [2] http://www.linux-arm.org/git?p=linux-rm.git;a=shortlog;h=refs/heads/iommu/defer
> [3] https://lkml.org/lkml/2016/11/21/141
> [4] https://www.mail-archive.com/iommu@xxxxxxxxxxxxxxxxxxxxxxxxxx/msg13940.html
> [5] git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git iommu/probe-deferral
> [6] http://www.spinics.net/lists/linux-pci/msg57992.html
> [7] https://www.spinics.net/lists/arm-kernel/msg556209.html
> [8] http://lkml.iu.edu/hypermail/linux/kernel/1704.0/01557.html
>
> Laurent Pinchart (2):
>    of: dma: Make of_dma_deconfigure() public
>    iommu: of: Handle IOMMU lookup failure with deferred probing or error
>
> Lorenzo Pieralisi (2):
>    ACPI/IORT: Add function to check SMMUs drivers presence
>    ACPI/IORT: Remove linker section for IORT entries probing
>
> Robin Murphy (3):
>    iommu/of: Refactor of_iommu_configure() for error handling
>    iommu/of: Prepare for deferred IOMMU configuration
>    iommu/arm-smmu: Clean up early-probing workarounds
>
> Sricharan R (4):
>    of: device: Fix overflow of coherent_dma_mask
>    of/acpi: Configure dma operations at probe time for platform/amba/pci
>      bus devices
>    drivers: acpi: Handle IOMMU lookup failure with deferred probing or
>      error
>    arm64: dma-mapping: Remove the notifier trick to handle early setting
>      of dma_ops
>
>   arch/arm64/mm/dma-mapping.c       | 142 +++++---------------------------------
>   drivers/acpi/arm64/iort.c         |  48 ++++++++++++-
>   drivers/acpi/glue.c               |   5 --
>   drivers/acpi/scan.c               |  11 ++-
>   drivers/base/dd.c                 |   9 +++
>   drivers/base/dma-mapping.c        |  41 +++++++++++
>   drivers/iommu/arm-smmu-v3.c       |  46 +-----------
>   drivers/iommu/arm-smmu.c          | 110 +++++++++++++----------------
>   drivers/iommu/of_iommu.c          | 126 ++++++++++++++++++++++++---------
>   drivers/of/device.c               |  23 +++++-
>   drivers/of/platform.c             |  10 +--
>   drivers/pci/probe.c               |  28 --------
>   include/acpi/acpi_bus.h           |   2 +-
>   include/asm-generic/vmlinux.lds.h |   1 -
>   include/linux/acpi.h              |   7 +-
>   include/linux/acpi_iort.h         |   3 -
>   include/linux/dma-mapping.h       |  12 ++++
>   include/linux/of_device.h         |  10 ++-
>   18 files changed, 312 insertions(+), 322 deletions(-)
>

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V11 00/11] IOMMU probe deferral support
@ 2017-05-08 11:23     ` Marek Szyprowski
  0 siblings, 0 replies; 70+ messages in thread
From: Marek Szyprowski @ 2017-05-08 11:23 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Sricharan,

On 2017-04-10 13:20, Sricharan R wrote:
> This series calls the dma ops configuration for the devices
> at a generic place so that it works for all busses.
> The dma_configure_ops for a device is now called during
> the device_attach callback just before the probe of the
> bus/driver is called. Similarly dma_deconfigure is called during
> device/driver_detach path.
>
> pci_bus_add_devices    (platform/amba)(_device_create/driver_register)
>         |                         |
> pci_bus_add_device     (device_add/driver_register)
>         |                         |
> device_attach           device_initial_probe
>         |                         |
> __device_attach_driver    __device_attach_driver
>         |
> driver_probe_device
>         |
> really_probe
>         |
> dma_configure
>
> Similarly on the device/driver_unregister path __device_release_driver is
> called which inturn calls dma_deconfigure.
>
> Rebased the series against mainline 4.11-rc5. Applies and builds cleanly
> against iommu-next and with 3-way merge applies on top of linux-next
> as well (patch #8), because of "ACPI platform MSI support" from
> Hanjun being merged.
>    
> * Tested with platform and pci devices for probe deferral
>    and reprobe on arm64 based platform.

I just noticed that in the meantime the following patch: "arm: dma-mapping:
Reset the device's dma_ops" (https://patchwork.kernel.org/patch/9434105/ )
has been dropped from this series.

Lack of it causes serious issues with deferred probe of devices, which are
under IOMMU on ARM architecture. Please check where it got lost and push it
to Russell's patch tracking system ASAP to get it during v4.12-rcX cycle.

>
> Previous post of this series [8].
>
> Please note that, i have kept the tested/acked tags intact from V8
> because V9/10/11 were for more fixes that was added, so the original
> tags that was given for the functional testing remains the same.
>
>   [V11]
>       * No functional changes.
>
>       * Rebased on top of 4.11-rc6.
>
>       * Dropped patch#3 from V10, as a result have to make
>         a change in patch#7 to return a 'non-void' to fix a
>         build warning.
>
>       * Added Robin's and Rob's tags.
>
>   [V10]
>       * Rebased on top of 4.11-rc5.
>   
>       * Fixed coherent_dma_mask 64bit overflow issue [8]
>         for OF. The fix for OF was added as a separate
>         patch#6, since the issue is true even without probe deferral,
>         but gets reproduced with the probe deferral series.
>         Added Lorenzo's ACPI fix for coherent_dma_mask overflow
>         and the fix for dma_configure getting called more than
>         once for the same device.
>
>       * Also fixed an build issue caught by kbuild robot for
>         m68k arch. The issue was dma_(de)configure was not
>         getting defined for !CONFIG_HAS_DMA, so fixed that as well.
>
>   [V9]
>       * Rebased on top of 4.11-rc1.
>
>       * Merged Robin's fixes for legacy binding issue,
>         pci devices with no iommu-map property and deferencing
>         of_iommu_table after init.
>       
>   [V8]
>       * Picked up all the acks and tested tags from Marek and
>         Hanjun for DT and ACPI patches respectively, since
>         no functional changes was done.
>
>       * Addressed Minor comments Sinan and Bjorn.
>
>       * Added Robin's fix for fixing the deferencing NULL for
>         of_iommu_table after init in patch #2.
>
>       * Rebased it on top of linux-next
>
>   [V7]
>       * Updated the subject and commit log for patch #6 as per
>         comments from Lorenzo. No functional changes.
>
>   [V6]
>       * Fixed a bug in dma_configure function pointed out by
>         Robin.
>       * Reordered the patches as per comments from Robin and
>         Lorenzo.
>       * Added Tags.
>
>   [V5]
>       * Reworked the pci configuration code hanging outside and
>         pushed it to dma_configure as in PATCH#5,6,7.
>         Also added a couple of patches that Lorenzo provided for
>         correcting the Probe deferring mechanism in case of
>         ACPI devices from here [5].
>
>   [V4]
>       * Took the reworked patches [2] from Robin's branch and
>         rebased on top of Lorenzo's ACPI IORT ARM support series [3].
>
>       * Added the patches for moving the dma ops configuration of
>         acpi based devices to probe time as well.
>   [V3]
>       * Removed the patch to split dma_masks/dma_ops configuration
>         separately based on review comments that both masks and ops are
>         required only during the device probe time.
>
>       * Reworked the series based on Generic DT bindings series.
>
>       * Added call to iommu's remove_device in the cleanup path for arm and
>         arm64.
>
>       * Removed the notifier trick in arm64 to handle early device
>         registration.
>
>       * Added reset of dma_ops in cleanup path for arm based on comments.
>
>       * Fixed the pci_iommu_configure path and tested with PCI device as
>         well.
>   
>       * Fixed a bug to return the correct iommu_ops from patch 7 [4] in
>         last post.
>
>       * Fixed few other cosmetic comments.
>    
>   [V2]
>       * Updated the Initial post to call dma_configure/deconfigure from
>         generic code
>   
>       * Added iommu add_device callback from of_iommu_configure path
>
>   [V1]
>       * Initial post from Laurent Pinchart [1]
>
> [1] http://lists.linuxfoundation.org/pipermail/iommu/2015-May/013016.html
> [2] http://www.linux-arm.org/git?p=linux-rm.git;a=shortlog;h=refs/heads/iommu/defer
> [3] https://lkml.org/lkml/2016/11/21/141
> [4] https://www.mail-archive.com/iommu at xxxxxxxxxxxxxxxxxxxxxxxxxx/msg13940.html
> [5] git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git iommu/probe-deferral
> [6] http://www.spinics.net/lists/linux-pci/msg57992.html
> [7] https://www.spinics.net/lists/arm-kernel/msg556209.html
> [8] http://lkml.iu.edu/hypermail/linux/kernel/1704.0/01557.html
>
> Laurent Pinchart (2):
>    of: dma: Make of_dma_deconfigure() public
>    iommu: of: Handle IOMMU lookup failure with deferred probing or error
>
> Lorenzo Pieralisi (2):
>    ACPI/IORT: Add function to check SMMUs drivers presence
>    ACPI/IORT: Remove linker section for IORT entries probing
>
> Robin Murphy (3):
>    iommu/of: Refactor of_iommu_configure() for error handling
>    iommu/of: Prepare for deferred IOMMU configuration
>    iommu/arm-smmu: Clean up early-probing workarounds
>
> Sricharan R (4):
>    of: device: Fix overflow of coherent_dma_mask
>    of/acpi: Configure dma operations at probe time for platform/amba/pci
>      bus devices
>    drivers: acpi: Handle IOMMU lookup failure with deferred probing or
>      error
>    arm64: dma-mapping: Remove the notifier trick to handle early setting
>      of dma_ops
>
>   arch/arm64/mm/dma-mapping.c       | 142 +++++---------------------------------
>   drivers/acpi/arm64/iort.c         |  48 ++++++++++++-
>   drivers/acpi/glue.c               |   5 --
>   drivers/acpi/scan.c               |  11 ++-
>   drivers/base/dd.c                 |   9 +++
>   drivers/base/dma-mapping.c        |  41 +++++++++++
>   drivers/iommu/arm-smmu-v3.c       |  46 +-----------
>   drivers/iommu/arm-smmu.c          | 110 +++++++++++++----------------
>   drivers/iommu/of_iommu.c          | 126 ++++++++++++++++++++++++---------
>   drivers/of/device.c               |  23 +++++-
>   drivers/of/platform.c             |  10 +--
>   drivers/pci/probe.c               |  28 --------
>   include/acpi/acpi_bus.h           |   2 +-
>   include/asm-generic/vmlinux.lds.h |   1 -
>   include/linux/acpi.h              |   7 +-
>   include/linux/acpi_iort.h         |   3 -
>   include/linux/dma-mapping.h       |  12 ++++
>   include/linux/of_device.h         |  10 ++-
>   18 files changed, 312 insertions(+), 322 deletions(-)
>

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

* Re: [PATCH V11 00/11] IOMMU probe deferral support
  2017-05-08 11:23     ` Marek Szyprowski
@ 2017-05-08 14:57       ` Sricharan R
  -1 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-05-08 14:57 UTC (permalink / raw)
  To: Marek Szyprowski, robin.murphy, will.deacon, joro,
	lorenzo.pieralisi, iommu, linux-arm-kernel, linux-arm-msm,
	bhelgaas, linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh

Hi,

On 5/8/2017 4:53 PM, Marek Szyprowski wrote:
> Hi Sricharan,
> 
> On 2017-04-10 13:20, Sricharan R wrote:
>> This series calls the dma ops configuration for the devices
>> at a generic place so that it works for all busses.
>> The dma_configure_ops for a device is now called during
>> the device_attach callback just before the probe of the
>> bus/driver is called. Similarly dma_deconfigure is called during
>> device/driver_detach path.
>>
>> pci_bus_add_devices    (platform/amba)(_device_create/driver_register)
>>         |                         |
>> pci_bus_add_device     (device_add/driver_register)
>>         |                         |
>> device_attach           device_initial_probe
>>         |                         |
>> __device_attach_driver    __device_attach_driver
>>         |
>> driver_probe_device
>>         |
>> really_probe
>>         |
>> dma_configure
>>
>> Similarly on the device/driver_unregister path __device_release_driver is
>> called which inturn calls dma_deconfigure.
>>
>> Rebased the series against mainline 4.11-rc5. Applies and builds cleanly
>> against iommu-next and with 3-way merge applies on top of linux-next
>> as well (patch #8), because of "ACPI platform MSI support" from
>> Hanjun being merged.
>>    * Tested with platform and pci devices for probe deferral
>>    and reprobe on arm64 based platform.
> 
> I just noticed that in the meantime the following patch: "arm: dma-mapping:
> Reset the device's dma_ops" (https://patchwork.kernel.org/patch/9434105/ )
> has been dropped from this series.
> 
> Lack of it causes serious issues with deferred probe of devices, which are
> under IOMMU on ARM architecture. Please check where it got lost and push it
> to Russell's patch tracking system ASAP to get it during v4.12-rcX cycle.

ha, bad on me. I posted this patch independently from the series, but was not
added to patch system. Will add it now.

Regards,
 Sricharan

> 
>>
>> Previous post of this series [8].
>>
>> Please note that, i have kept the tested/acked tags intact from V8
>> because V9/10/11 were for more fixes that was added, so the original
>> tags that was given for the functional testing remains the same.
>>
>>   [V11]
>>       * No functional changes.
>>
>>       * Rebased on top of 4.11-rc6.
>>
>>       * Dropped patch#3 from V10, as a result have to make
>>         a change in patch#7 to return a 'non-void' to fix a
>>         build warning.
>>
>>       * Added Robin's and Rob's tags.
>>
>>   [V10]
>>       * Rebased on top of 4.11-rc5.
>>         * Fixed coherent_dma_mask 64bit overflow issue [8]
>>         for OF. The fix for OF was added as a separate
>>         patch#6, since the issue is true even without probe deferral,
>>         but gets reproduced with the probe deferral series.
>>         Added Lorenzo's ACPI fix for coherent_dma_mask overflow
>>         and the fix for dma_configure getting called more than
>>         once for the same device.
>>
>>       * Also fixed an build issue caught by kbuild robot for
>>         m68k arch. The issue was dma_(de)configure was not
>>         getting defined for !CONFIG_HAS_DMA, so fixed that as well.
>>
>>   [V9]
>>       * Rebased on top of 4.11-rc1.
>>
>>       * Merged Robin's fixes for legacy binding issue,
>>         pci devices with no iommu-map property and deferencing
>>         of_iommu_table after init.
>>         [V8]
>>       * Picked up all the acks and tested tags from Marek and
>>         Hanjun for DT and ACPI patches respectively, since
>>         no functional changes was done.
>>
>>       * Addressed Minor comments Sinan and Bjorn.
>>
>>       * Added Robin's fix for fixing the deferencing NULL for
>>         of_iommu_table after init in patch #2.
>>
>>       * Rebased it on top of linux-next
>>
>>   [V7]
>>       * Updated the subject and commit log for patch #6 as per
>>         comments from Lorenzo. No functional changes.
>>
>>   [V6]
>>       * Fixed a bug in dma_configure function pointed out by
>>         Robin.
>>       * Reordered the patches as per comments from Robin and
>>         Lorenzo.
>>       * Added Tags.
>>
>>   [V5]
>>       * Reworked the pci configuration code hanging outside and
>>         pushed it to dma_configure as in PATCH#5,6,7.
>>         Also added a couple of patches that Lorenzo provided for
>>         correcting the Probe deferring mechanism in case of
>>         ACPI devices from here [5].
>>
>>   [V4]
>>       * Took the reworked patches [2] from Robin's branch and
>>         rebased on top of Lorenzo's ACPI IORT ARM support series [3].
>>
>>       * Added the patches for moving the dma ops configuration of
>>         acpi based devices to probe time as well.
>>   [V3]
>>       * Removed the patch to split dma_masks/dma_ops configuration
>>         separately based on review comments that both masks and ops are
>>         required only during the device probe time.
>>
>>       * Reworked the series based on Generic DT bindings series.
>>
>>       * Added call to iommu's remove_device in the cleanup path for arm and
>>         arm64.
>>
>>       * Removed the notifier trick in arm64 to handle early device
>>         registration.
>>
>>       * Added reset of dma_ops in cleanup path for arm based on comments.
>>
>>       * Fixed the pci_iommu_configure path and tested with PCI device as
>>         well.
>>         * Fixed a bug to return the correct iommu_ops from patch 7 [4] in
>>         last post.
>>
>>       * Fixed few other cosmetic comments.
>>      [V2]
>>       * Updated the Initial post to call dma_configure/deconfigure from
>>         generic code
>>         * Added iommu add_device callback from of_iommu_configure path
>>
>>   [V1]
>>       * Initial post from Laurent Pinchart [1]
>>
>> [1] http://lists.linuxfoundation.org/pipermail/iommu/2015-May/013016.html
>> [2] http://www.linux-arm.org/git?p=linux-rm.git;a=shortlog;h=refs/heads/iommu/defer
>> [3] https://lkml.org/lkml/2016/11/21/141
>> [4] https://www.mail-archive.com/iommu@xxxxxxxxxxxxxxxxxxxxxxxxxx/msg13940.html
>> [5] git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git iommu/probe-deferral
>> [6] http://www.spinics.net/lists/linux-pci/msg57992.html
>> [7] https://www.spinics.net/lists/arm-kernel/msg556209.html
>> [8] http://lkml.iu.edu/hypermail/linux/kernel/1704.0/01557.html
>>
>> Laurent Pinchart (2):
>>    of: dma: Make of_dma_deconfigure() public
>>    iommu: of: Handle IOMMU lookup failure with deferred probing or error
>>
>> Lorenzo Pieralisi (2):
>>    ACPI/IORT: Add function to check SMMUs drivers presence
>>    ACPI/IORT: Remove linker section for IORT entries probing
>>
>> Robin Murphy (3):
>>    iommu/of: Refactor of_iommu_configure() for error handling
>>    iommu/of: Prepare for deferred IOMMU configuration
>>    iommu/arm-smmu: Clean up early-probing workarounds
>>
>> Sricharan R (4):
>>    of: device: Fix overflow of coherent_dma_mask
>>    of/acpi: Configure dma operations at probe time for platform/amba/pci
>>      bus devices
>>    drivers: acpi: Handle IOMMU lookup failure with deferred probing or
>>      error
>>    arm64: dma-mapping: Remove the notifier trick to handle early setting
>>      of dma_ops
>>
>>   arch/arm64/mm/dma-mapping.c       | 142 +++++---------------------------------
>>   drivers/acpi/arm64/iort.c         |  48 ++++++++++++-
>>   drivers/acpi/glue.c               |   5 --
>>   drivers/acpi/scan.c               |  11 ++-
>>   drivers/base/dd.c                 |   9 +++
>>   drivers/base/dma-mapping.c        |  41 +++++++++++
>>   drivers/iommu/arm-smmu-v3.c       |  46 +-----------
>>   drivers/iommu/arm-smmu.c          | 110 +++++++++++++----------------
>>   drivers/iommu/of_iommu.c          | 126 ++++++++++++++++++++++++---------
>>   drivers/of/device.c               |  23 +++++-
>>   drivers/of/platform.c             |  10 +--
>>   drivers/pci/probe.c               |  28 --------
>>   include/acpi/acpi_bus.h           |   2 +-
>>   include/asm-generic/vmlinux.lds.h |   1 -
>>   include/linux/acpi.h              |   7 +-
>>   include/linux/acpi_iort.h         |   3 -
>>   include/linux/dma-mapping.h       |  12 ++++
>>   include/linux/of_device.h         |  10 ++-
>>   18 files changed, 312 insertions(+), 322 deletions(-)
>>
> 
> Best regards

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* [PATCH V11 00/11] IOMMU probe deferral support
@ 2017-05-08 14:57       ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-05-08 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 5/8/2017 4:53 PM, Marek Szyprowski wrote:
> Hi Sricharan,
> 
> On 2017-04-10 13:20, Sricharan R wrote:
>> This series calls the dma ops configuration for the devices
>> at a generic place so that it works for all busses.
>> The dma_configure_ops for a device is now called during
>> the device_attach callback just before the probe of the
>> bus/driver is called. Similarly dma_deconfigure is called during
>> device/driver_detach path.
>>
>> pci_bus_add_devices    (platform/amba)(_device_create/driver_register)
>>         |                         |
>> pci_bus_add_device     (device_add/driver_register)
>>         |                         |
>> device_attach           device_initial_probe
>>         |                         |
>> __device_attach_driver    __device_attach_driver
>>         |
>> driver_probe_device
>>         |
>> really_probe
>>         |
>> dma_configure
>>
>> Similarly on the device/driver_unregister path __device_release_driver is
>> called which inturn calls dma_deconfigure.
>>
>> Rebased the series against mainline 4.11-rc5. Applies and builds cleanly
>> against iommu-next and with 3-way merge applies on top of linux-next
>> as well (patch #8), because of "ACPI platform MSI support" from
>> Hanjun being merged.
>>    * Tested with platform and pci devices for probe deferral
>>    and reprobe on arm64 based platform.
> 
> I just noticed that in the meantime the following patch: "arm: dma-mapping:
> Reset the device's dma_ops" (https://patchwork.kernel.org/patch/9434105/ )
> has been dropped from this series.
> 
> Lack of it causes serious issues with deferred probe of devices, which are
> under IOMMU on ARM architecture. Please check where it got lost and push it
> to Russell's patch tracking system ASAP to get it during v4.12-rcX cycle.

ha, bad on me. I posted this patch independently from the series, but was not
added to patch system. Will add it now.

Regards,
 Sricharan

> 
>>
>> Previous post of this series [8].
>>
>> Please note that, i have kept the tested/acked tags intact from V8
>> because V9/10/11 were for more fixes that was added, so the original
>> tags that was given for the functional testing remains the same.
>>
>>   [V11]
>>       * No functional changes.
>>
>>       * Rebased on top of 4.11-rc6.
>>
>>       * Dropped patch#3 from V10, as a result have to make
>>         a change in patch#7 to return a 'non-void' to fix a
>>         build warning.
>>
>>       * Added Robin's and Rob's tags.
>>
>>   [V10]
>>       * Rebased on top of 4.11-rc5.
>>         * Fixed coherent_dma_mask 64bit overflow issue [8]
>>         for OF. The fix for OF was added as a separate
>>         patch#6, since the issue is true even without probe deferral,
>>         but gets reproduced with the probe deferral series.
>>         Added Lorenzo's ACPI fix for coherent_dma_mask overflow
>>         and the fix for dma_configure getting called more than
>>         once for the same device.
>>
>>       * Also fixed an build issue caught by kbuild robot for
>>         m68k arch. The issue was dma_(de)configure was not
>>         getting defined for !CONFIG_HAS_DMA, so fixed that as well.
>>
>>   [V9]
>>       * Rebased on top of 4.11-rc1.
>>
>>       * Merged Robin's fixes for legacy binding issue,
>>         pci devices with no iommu-map property and deferencing
>>         of_iommu_table after init.
>>         [V8]
>>       * Picked up all the acks and tested tags from Marek and
>>         Hanjun for DT and ACPI patches respectively, since
>>         no functional changes was done.
>>
>>       * Addressed Minor comments Sinan and Bjorn.
>>
>>       * Added Robin's fix for fixing the deferencing NULL for
>>         of_iommu_table after init in patch #2.
>>
>>       * Rebased it on top of linux-next
>>
>>   [V7]
>>       * Updated the subject and commit log for patch #6 as per
>>         comments from Lorenzo. No functional changes.
>>
>>   [V6]
>>       * Fixed a bug in dma_configure function pointed out by
>>         Robin.
>>       * Reordered the patches as per comments from Robin and
>>         Lorenzo.
>>       * Added Tags.
>>
>>   [V5]
>>       * Reworked the pci configuration code hanging outside and
>>         pushed it to dma_configure as in PATCH#5,6,7.
>>         Also added a couple of patches that Lorenzo provided for
>>         correcting the Probe deferring mechanism in case of
>>         ACPI devices from here [5].
>>
>>   [V4]
>>       * Took the reworked patches [2] from Robin's branch and
>>         rebased on top of Lorenzo's ACPI IORT ARM support series [3].
>>
>>       * Added the patches for moving the dma ops configuration of
>>         acpi based devices to probe time as well.
>>   [V3]
>>       * Removed the patch to split dma_masks/dma_ops configuration
>>         separately based on review comments that both masks and ops are
>>         required only during the device probe time.
>>
>>       * Reworked the series based on Generic DT bindings series.
>>
>>       * Added call to iommu's remove_device in the cleanup path for arm and
>>         arm64.
>>
>>       * Removed the notifier trick in arm64 to handle early device
>>         registration.
>>
>>       * Added reset of dma_ops in cleanup path for arm based on comments.
>>
>>       * Fixed the pci_iommu_configure path and tested with PCI device as
>>         well.
>>         * Fixed a bug to return the correct iommu_ops from patch 7 [4] in
>>         last post.
>>
>>       * Fixed few other cosmetic comments.
>>      [V2]
>>       * Updated the Initial post to call dma_configure/deconfigure from
>>         generic code
>>         * Added iommu add_device callback from of_iommu_configure path
>>
>>   [V1]
>>       * Initial post from Laurent Pinchart [1]
>>
>> [1] http://lists.linuxfoundation.org/pipermail/iommu/2015-May/013016.html
>> [2] http://www.linux-arm.org/git?p=linux-rm.git;a=shortlog;h=refs/heads/iommu/defer
>> [3] https://lkml.org/lkml/2016/11/21/141
>> [4] https://www.mail-archive.com/iommu at xxxxxxxxxxxxxxxxxxxxxxxxxx/msg13940.html
>> [5] git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git iommu/probe-deferral
>> [6] http://www.spinics.net/lists/linux-pci/msg57992.html
>> [7] https://www.spinics.net/lists/arm-kernel/msg556209.html
>> [8] http://lkml.iu.edu/hypermail/linux/kernel/1704.0/01557.html
>>
>> Laurent Pinchart (2):
>>    of: dma: Make of_dma_deconfigure() public
>>    iommu: of: Handle IOMMU lookup failure with deferred probing or error
>>
>> Lorenzo Pieralisi (2):
>>    ACPI/IORT: Add function to check SMMUs drivers presence
>>    ACPI/IORT: Remove linker section for IORT entries probing
>>
>> Robin Murphy (3):
>>    iommu/of: Refactor of_iommu_configure() for error handling
>>    iommu/of: Prepare for deferred IOMMU configuration
>>    iommu/arm-smmu: Clean up early-probing workarounds
>>
>> Sricharan R (4):
>>    of: device: Fix overflow of coherent_dma_mask
>>    of/acpi: Configure dma operations at probe time for platform/amba/pci
>>      bus devices
>>    drivers: acpi: Handle IOMMU lookup failure with deferred probing or
>>      error
>>    arm64: dma-mapping: Remove the notifier trick to handle early setting
>>      of dma_ops
>>
>>   arch/arm64/mm/dma-mapping.c       | 142 +++++---------------------------------
>>   drivers/acpi/arm64/iort.c         |  48 ++++++++++++-
>>   drivers/acpi/glue.c               |   5 --
>>   drivers/acpi/scan.c               |  11 ++-
>>   drivers/base/dd.c                 |   9 +++
>>   drivers/base/dma-mapping.c        |  41 +++++++++++
>>   drivers/iommu/arm-smmu-v3.c       |  46 +-----------
>>   drivers/iommu/arm-smmu.c          | 110 +++++++++++++----------------
>>   drivers/iommu/of_iommu.c          | 126 ++++++++++++++++++++++++---------
>>   drivers/of/device.c               |  23 +++++-
>>   drivers/of/platform.c             |  10 +--
>>   drivers/pci/probe.c               |  28 --------
>>   include/acpi/acpi_bus.h           |   2 +-
>>   include/asm-generic/vmlinux.lds.h |   1 -
>>   include/linux/acpi.h              |   7 +-
>>   include/linux/acpi_iort.h         |   3 -
>>   include/linux/dma-mapping.h       |  12 ++++
>>   include/linux/of_device.h         |  10 ++-
>>   18 files changed, 312 insertions(+), 322 deletions(-)
>>
> 
> Best regards

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* Re: [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
  2017-04-10 11:21       ` Sricharan R
  (?)
  (?)
@ 2017-05-23  6:26           ` Nate Watterson
  -1 siblings, 0 replies; 70+ messages in thread
From: Nate Watterson @ 2017-05-23  6:26 UTC (permalink / raw)
  To: Sricharan R, robin.murphy-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
	joro-zLv9SwRftAIdnm+yROfE0A, lorenzo.pieralisi-5wv7dgnIgG8,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ,
	bhelgaas-hpIqsD4AKlfQT0dZR+AlfA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
	hanjun.guo-QSEj5FYQhm4dnm+yROfE0A, okaya-sgV2jX0FEOL9JmXXK+q4OQ,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, sudeep.holla-5wv7dgnIgG8,
	rjw-LthD3rsA81gm4RdzfppkhA, lenb-DgEjT+Ai2ygdnm+yROfE0A,
	catalin.marinas-5wv7dgnIgG8, arnd-r2nGTMty4D4,
	linux-arch-u79uwXL29TY76Z2rM5mHXA,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r

Hi Sricharan,

On 4/10/2017 7:21 AM, Sricharan R wrote:
> This is an equivalent to the DT's handling of the iommu master's probe
> with deferred probing when the corrsponding iommu is not probed yet.
> The lack of a registered IOMMU can be caused by the lack of a driver for
> the IOMMU, the IOMMU device probe not having been performed yet, having
> been deferred, or having failed.
> 
> The first case occurs when the firmware describes the bus master and
> IOMMU topology correctly but no device driver exists for the IOMMU yet
> or the device driver has not been compiled in. Return NULL, the caller
> will configure the device without an IOMMU.
> 
> The second and third cases are handled by deferring the probe of the bus
> master device which will eventually get reprobed after the IOMMU.
> 
> The last case is currently handled by deferring the probe of the bus
> master device as well. A mechanism to either configure the bus master
> device without an IOMMU or to fail the bus master device probe depending
> on whether the IOMMU is optional or mandatory would be a good
> enhancement.
> 
> Tested-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Reviewed-by: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
> [Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
>            called multiple times for same device]
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
> Signed-off-by: Sricharan R <sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
> ---
>   drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
>   drivers/acpi/scan.c        | 11 ++++++++---
>   drivers/base/dma-mapping.c |  2 +-
>   include/acpi/acpi_bus.h    |  2 +-
>   include/linux/acpi.h       |  7 +++++--
>   5 files changed, 47 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index 3dd9ec3..e323ece 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>   	const struct iommu_ops *ops = NULL;
>   	int ret = -ENODEV;
>   	struct fwnode_handle *iort_fwnode;
> +	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
> +
> +	/*
> +	 * If we already translated the fwspec there
> +	 * is nothing left to do, return the iommu_ops.
> +	 */
> +	if (fwspec && fwspec->ops)
> +		return fwspec->ops;

Is this logic strictly required? It breaks masters with multiple SIDs
as only the first SID is actually added to the master's fwspec.

>   
>   	if (node) {
>   		iort_fwnode = iort_get_fwnode(node);
> @@ -550,8 +558,17 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>   			return NULL;
>   
>   		ops = iommu_ops_from_fwnode(iort_fwnode);
> +		/*
> +		 * If the ops look-up fails, this means that either
> +		 * the SMMU drivers have not been probed yet or that
> +		 * the SMMU drivers are not built in the kernel;
> +		 * Depending on whether the SMMU drivers are built-in
> +		 * in the kernel or not, defer the IOMMU configuration
> +		 * or just abort it.
> +		 */
>   		if (!ops)
> -			return NULL;
> +			return iort_iommu_driver_enabled(node->type) ?
> +			       ERR_PTR(-EPROBE_DEFER) : NULL;
>   
>   		ret = arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops);
>   	}
> @@ -625,12 +642,26 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
>   
>   		while (parent) {
>   			ops = iort_iommu_xlate(dev, parent, streamid);
> +			if (IS_ERR_OR_NULL(ops))
> +				return ops;
>   
>   			parent = iort_node_get_id(node, &streamid,
>   						  IORT_IOMMU_TYPE, i++);
>   		}
>   	}
>   
> +	/*
> +	 * If we have reason to believe the IOMMU driver missed the initial
> +	 * add_device callback for dev, replay it to get things in order.
> +	 */
> +	if (!IS_ERR_OR_NULL(ops) && ops->add_device &&
> +	    dev->bus && !dev->iommu_group) {
> +		int err = ops->add_device(dev);
> +
> +		if (err)
> +			ops = ERR_PTR(err);
> +	}
> +
>   	return ops;
>   }
>   
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index 1926918..2a513cc 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1373,20 +1373,25 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
>    * @dev: The pointer to the device
>    * @attr: device dma attributes
>    */
> -void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
> +int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
>   {
>   	const struct iommu_ops *iommu;
> +	u64 size;
>   
>   	iort_set_dma_mask(dev);
>   
>   	iommu = iort_iommu_configure(dev);
> +	if (IS_ERR(iommu))
> +		return PTR_ERR(iommu);
>   
> +	size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
>   	/*
>   	 * Assume dma valid range starts at 0 and covers the whole
>   	 * coherent_dma_mask.
>   	 */
> -	arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, iommu,
> -			   attr == DEV_DMA_COHERENT);
> +	arch_setup_dma_ops(dev, 0, size, iommu, attr == DEV_DMA_COHERENT);
> +
> +	return 0;
>   }
>   EXPORT_SYMBOL_GPL(acpi_dma_configure);
>   
> diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
> index 82bd45c..755a2b5 100644
> --- a/drivers/base/dma-mapping.c
> +++ b/drivers/base/dma-mapping.c
> @@ -368,7 +368,7 @@ int dma_configure(struct device *dev)
>   	} else if (has_acpi_companion(dma_dev)) {
>   		attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
>   		if (attr != DEV_DMA_NOT_SUPPORTED)
> -			acpi_dma_configure(dev, attr);
> +			ret = acpi_dma_configure(dev, attr);
>   	}
>   
>   	if (bridge)
> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> index ef0ae8a..2a9a5de 100644
> --- a/include/acpi/acpi_bus.h
> +++ b/include/acpi/acpi_bus.h
> @@ -575,7 +575,7 @@ struct acpi_pci_root {
>   
>   bool acpi_dma_supported(struct acpi_device *adev);
>   enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
> -void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
> +int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
>   void acpi_dma_deconfigure(struct device *dev);
>   
>   struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 9b05886..79d06ef6 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -762,8 +762,11 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
>   	return DEV_DMA_NOT_SUPPORTED;
>   }
>   
> -static inline void acpi_dma_configure(struct device *dev,
> -				      enum dev_dma_attr attr) { }
> +static inline int acpi_dma_configure(struct device *dev,
> +				     enum dev_dma_attr attr)
> +{
> +	return 0;
> +}
>   
>   static inline void acpi_dma_deconfigure(struct device *dev) { }
>   
> 

-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

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

* Re: [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
@ 2017-05-23  6:26           ` Nate Watterson
  0 siblings, 0 replies; 70+ messages in thread
From: Nate Watterson @ 2017-05-23  6:26 UTC (permalink / raw)
  To: Sricharan R, robin.murphy, will.deacon, joro, lorenzo.pieralisi,
	iommu, linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh

Hi Sricharan,

On 4/10/2017 7:21 AM, Sricharan R wrote:
> This is an equivalent to the DT's handling of the iommu master's probe
> with deferred probing when the corrsponding iommu is not probed yet.
> The lack of a registered IOMMU can be caused by the lack of a driver for
> the IOMMU, the IOMMU device probe not having been performed yet, having
> been deferred, or having failed.
> 
> The first case occurs when the firmware describes the bus master and
> IOMMU topology correctly but no device driver exists for the IOMMU yet
> or the device driver has not been compiled in. Return NULL, the caller
> will configure the device without an IOMMU.
> 
> The second and third cases are handled by deferring the probe of the bus
> master device which will eventually get reprobed after the IOMMU.
> 
> The last case is currently handled by deferring the probe of the bus
> master device as well. A mechanism to either configure the bus master
> device without an IOMMU or to fail the bus master device probe depending
> on whether the IOMMU is optional or mandatory would be a good
> enhancement.
> 
> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
> Reviewed-by: Robin Murphy <robin.murphy@arm.com>
> [Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
>            called multiple times for same device]
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> ---
>   drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
>   drivers/acpi/scan.c        | 11 ++++++++---
>   drivers/base/dma-mapping.c |  2 +-
>   include/acpi/acpi_bus.h    |  2 +-
>   include/linux/acpi.h       |  7 +++++--
>   5 files changed, 47 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index 3dd9ec3..e323ece 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>   	const struct iommu_ops *ops = NULL;
>   	int ret = -ENODEV;
>   	struct fwnode_handle *iort_fwnode;
> +	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
> +
> +	/*
> +	 * If we already translated the fwspec there
> +	 * is nothing left to do, return the iommu_ops.
> +	 */
> +	if (fwspec && fwspec->ops)
> +		return fwspec->ops;

Is this logic strictly required? It breaks masters with multiple SIDs
as only the first SID is actually added to the master's fwspec.

>   
>   	if (node) {
>   		iort_fwnode = iort_get_fwnode(node);
> @@ -550,8 +558,17 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>   			return NULL;
>   
>   		ops = iommu_ops_from_fwnode(iort_fwnode);
> +		/*
> +		 * If the ops look-up fails, this means that either
> +		 * the SMMU drivers have not been probed yet or that
> +		 * the SMMU drivers are not built in the kernel;
> +		 * Depending on whether the SMMU drivers are built-in
> +		 * in the kernel or not, defer the IOMMU configuration
> +		 * or just abort it.
> +		 */
>   		if (!ops)
> -			return NULL;
> +			return iort_iommu_driver_enabled(node->type) ?
> +			       ERR_PTR(-EPROBE_DEFER) : NULL;
>   
>   		ret = arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops);
>   	}
> @@ -625,12 +642,26 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
>   
>   		while (parent) {
>   			ops = iort_iommu_xlate(dev, parent, streamid);
> +			if (IS_ERR_OR_NULL(ops))
> +				return ops;
>   
>   			parent = iort_node_get_id(node, &streamid,
>   						  IORT_IOMMU_TYPE, i++);
>   		}
>   	}
>   
> +	/*
> +	 * If we have reason to believe the IOMMU driver missed the initial
> +	 * add_device callback for dev, replay it to get things in order.
> +	 */
> +	if (!IS_ERR_OR_NULL(ops) && ops->add_device &&
> +	    dev->bus && !dev->iommu_group) {
> +		int err = ops->add_device(dev);
> +
> +		if (err)
> +			ops = ERR_PTR(err);
> +	}
> +
>   	return ops;
>   }
>   
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index 1926918..2a513cc 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1373,20 +1373,25 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
>    * @dev: The pointer to the device
>    * @attr: device dma attributes
>    */
> -void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
> +int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
>   {
>   	const struct iommu_ops *iommu;
> +	u64 size;
>   
>   	iort_set_dma_mask(dev);
>   
>   	iommu = iort_iommu_configure(dev);
> +	if (IS_ERR(iommu))
> +		return PTR_ERR(iommu);
>   
> +	size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
>   	/*
>   	 * Assume dma valid range starts at 0 and covers the whole
>   	 * coherent_dma_mask.
>   	 */
> -	arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, iommu,
> -			   attr == DEV_DMA_COHERENT);
> +	arch_setup_dma_ops(dev, 0, size, iommu, attr == DEV_DMA_COHERENT);
> +
> +	return 0;
>   }
>   EXPORT_SYMBOL_GPL(acpi_dma_configure);
>   
> diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
> index 82bd45c..755a2b5 100644
> --- a/drivers/base/dma-mapping.c
> +++ b/drivers/base/dma-mapping.c
> @@ -368,7 +368,7 @@ int dma_configure(struct device *dev)
>   	} else if (has_acpi_companion(dma_dev)) {
>   		attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
>   		if (attr != DEV_DMA_NOT_SUPPORTED)
> -			acpi_dma_configure(dev, attr);
> +			ret = acpi_dma_configure(dev, attr);
>   	}
>   
>   	if (bridge)
> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> index ef0ae8a..2a9a5de 100644
> --- a/include/acpi/acpi_bus.h
> +++ b/include/acpi/acpi_bus.h
> @@ -575,7 +575,7 @@ struct acpi_pci_root {
>   
>   bool acpi_dma_supported(struct acpi_device *adev);
>   enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
> -void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
> +int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
>   void acpi_dma_deconfigure(struct device *dev);
>   
>   struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 9b05886..79d06ef6 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -762,8 +762,11 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
>   	return DEV_DMA_NOT_SUPPORTED;
>   }
>   
> -static inline void acpi_dma_configure(struct device *dev,
> -				      enum dev_dma_attr attr) { }
> +static inline int acpi_dma_configure(struct device *dev,
> +				     enum dev_dma_attr attr)
> +{
> +	return 0;
> +}
>   
>   static inline void acpi_dma_deconfigure(struct device *dev) { }
>   
> 

-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

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

* Re: [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
@ 2017-05-23  6:26           ` Nate Watterson
  0 siblings, 0 replies; 70+ messages in thread
From: Nate Watterson @ 2017-05-23  6:26 UTC (permalink / raw)
  To: Sricharan R, robin.murphy, will.deacon, joro, lorenzo.pieralisi,
	iommu, linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh

Hi Sricharan,

On 4/10/2017 7:21 AM, Sricharan R wrote:
> This is an equivalent to the DT's handling of the iommu master's probe
> with deferred probing when the corrsponding iommu is not probed yet.
> The lack of a registered IOMMU can be caused by the lack of a driver for
> the IOMMU, the IOMMU device probe not having been performed yet, having
> been deferred, or having failed.
> 
> The first case occurs when the firmware describes the bus master and
> IOMMU topology correctly but no device driver exists for the IOMMU yet
> or the device driver has not been compiled in. Return NULL, the caller
> will configure the device without an IOMMU.
> 
> The second and third cases are handled by deferring the probe of the bus
> master device which will eventually get reprobed after the IOMMU.
> 
> The last case is currently handled by deferring the probe of the bus
> master device as well. A mechanism to either configure the bus master
> device without an IOMMU or to fail the bus master device probe depending
> on whether the IOMMU is optional or mandatory would be a good
> enhancement.
> 
> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
> Reviewed-by: Robin Murphy <robin.murphy@arm.com>
> [Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
>            called multiple times for same device]
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> ---
>   drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
>   drivers/acpi/scan.c        | 11 ++++++++---
>   drivers/base/dma-mapping.c |  2 +-
>   include/acpi/acpi_bus.h    |  2 +-
>   include/linux/acpi.h       |  7 +++++--
>   5 files changed, 47 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index 3dd9ec3..e323ece 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>   	const struct iommu_ops *ops = NULL;
>   	int ret = -ENODEV;
>   	struct fwnode_handle *iort_fwnode;
> +	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
> +
> +	/*
> +	 * If we already translated the fwspec there
> +	 * is nothing left to do, return the iommu_ops.
> +	 */
> +	if (fwspec && fwspec->ops)
> +		return fwspec->ops;

Is this logic strictly required? It breaks masters with multiple SIDs
as only the first SID is actually added to the master's fwspec.

>   
>   	if (node) {
>   		iort_fwnode = iort_get_fwnode(node);
> @@ -550,8 +558,17 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>   			return NULL;
>   
>   		ops = iommu_ops_from_fwnode(iort_fwnode);
> +		/*
> +		 * If the ops look-up fails, this means that either
> +		 * the SMMU drivers have not been probed yet or that
> +		 * the SMMU drivers are not built in the kernel;
> +		 * Depending on whether the SMMU drivers are built-in
> +		 * in the kernel or not, defer the IOMMU configuration
> +		 * or just abort it.
> +		 */
>   		if (!ops)
> -			return NULL;
> +			return iort_iommu_driver_enabled(node->type) ?
> +			       ERR_PTR(-EPROBE_DEFER) : NULL;
>   
>   		ret = arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops);
>   	}
> @@ -625,12 +642,26 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
>   
>   		while (parent) {
>   			ops = iort_iommu_xlate(dev, parent, streamid);
> +			if (IS_ERR_OR_NULL(ops))
> +				return ops;
>   
>   			parent = iort_node_get_id(node, &streamid,
>   						  IORT_IOMMU_TYPE, i++);
>   		}
>   	}
>   
> +	/*
> +	 * If we have reason to believe the IOMMU driver missed the initial
> +	 * add_device callback for dev, replay it to get things in order.
> +	 */
> +	if (!IS_ERR_OR_NULL(ops) && ops->add_device &&
> +	    dev->bus && !dev->iommu_group) {
> +		int err = ops->add_device(dev);
> +
> +		if (err)
> +			ops = ERR_PTR(err);
> +	}
> +
>   	return ops;
>   }
>   
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index 1926918..2a513cc 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1373,20 +1373,25 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
>    * @dev: The pointer to the device
>    * @attr: device dma attributes
>    */
> -void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
> +int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
>   {
>   	const struct iommu_ops *iommu;
> +	u64 size;
>   
>   	iort_set_dma_mask(dev);
>   
>   	iommu = iort_iommu_configure(dev);
> +	if (IS_ERR(iommu))
> +		return PTR_ERR(iommu);
>   
> +	size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
>   	/*
>   	 * Assume dma valid range starts at 0 and covers the whole
>   	 * coherent_dma_mask.
>   	 */
> -	arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, iommu,
> -			   attr == DEV_DMA_COHERENT);
> +	arch_setup_dma_ops(dev, 0, size, iommu, attr == DEV_DMA_COHERENT);
> +
> +	return 0;
>   }
>   EXPORT_SYMBOL_GPL(acpi_dma_configure);
>   
> diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
> index 82bd45c..755a2b5 100644
> --- a/drivers/base/dma-mapping.c
> +++ b/drivers/base/dma-mapping.c
> @@ -368,7 +368,7 @@ int dma_configure(struct device *dev)
>   	} else if (has_acpi_companion(dma_dev)) {
>   		attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
>   		if (attr != DEV_DMA_NOT_SUPPORTED)
> -			acpi_dma_configure(dev, attr);
> +			ret = acpi_dma_configure(dev, attr);
>   	}
>   
>   	if (bridge)
> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> index ef0ae8a..2a9a5de 100644
> --- a/include/acpi/acpi_bus.h
> +++ b/include/acpi/acpi_bus.h
> @@ -575,7 +575,7 @@ struct acpi_pci_root {
>   
>   bool acpi_dma_supported(struct acpi_device *adev);
>   enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
> -void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
> +int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
>   void acpi_dma_deconfigure(struct device *dev);
>   
>   struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 9b05886..79d06ef6 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -762,8 +762,11 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
>   	return DEV_DMA_NOT_SUPPORTED;
>   }
>   
> -static inline void acpi_dma_configure(struct device *dev,
> -				      enum dev_dma_attr attr) { }
> +static inline int acpi_dma_configure(struct device *dev,
> +				     enum dev_dma_attr attr)
> +{
> +	return 0;
> +}
>   
>   static inline void acpi_dma_deconfigure(struct device *dev) { }
>   
> 

-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
@ 2017-05-23  6:26           ` Nate Watterson
  0 siblings, 0 replies; 70+ messages in thread
From: Nate Watterson @ 2017-05-23  6:26 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Sricharan,

On 4/10/2017 7:21 AM, Sricharan R wrote:
> This is an equivalent to the DT's handling of the iommu master's probe
> with deferred probing when the corrsponding iommu is not probed yet.
> The lack of a registered IOMMU can be caused by the lack of a driver for
> the IOMMU, the IOMMU device probe not having been performed yet, having
> been deferred, or having failed.
> 
> The first case occurs when the firmware describes the bus master and
> IOMMU topology correctly but no device driver exists for the IOMMU yet
> or the device driver has not been compiled in. Return NULL, the caller
> will configure the device without an IOMMU.
> 
> The second and third cases are handled by deferring the probe of the bus
> master device which will eventually get reprobed after the IOMMU.
> 
> The last case is currently handled by deferring the probe of the bus
> master device as well. A mechanism to either configure the bus master
> device without an IOMMU or to fail the bus master device probe depending
> on whether the IOMMU is optional or mandatory would be a good
> enhancement.
> 
> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
> Reviewed-by: Robin Murphy <robin.murphy@arm.com>
> [Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
>            called multiple times for same device]
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> ---
>   drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
>   drivers/acpi/scan.c        | 11 ++++++++---
>   drivers/base/dma-mapping.c |  2 +-
>   include/acpi/acpi_bus.h    |  2 +-
>   include/linux/acpi.h       |  7 +++++--
>   5 files changed, 47 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index 3dd9ec3..e323ece 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>   	const struct iommu_ops *ops = NULL;
>   	int ret = -ENODEV;
>   	struct fwnode_handle *iort_fwnode;
> +	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
> +
> +	/*
> +	 * If we already translated the fwspec there
> +	 * is nothing left to do, return the iommu_ops.
> +	 */
> +	if (fwspec && fwspec->ops)
> +		return fwspec->ops;

Is this logic strictly required? It breaks masters with multiple SIDs
as only the first SID is actually added to the master's fwspec.

>   
>   	if (node) {
>   		iort_fwnode = iort_get_fwnode(node);
> @@ -550,8 +558,17 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>   			return NULL;
>   
>   		ops = iommu_ops_from_fwnode(iort_fwnode);
> +		/*
> +		 * If the ops look-up fails, this means that either
> +		 * the SMMU drivers have not been probed yet or that
> +		 * the SMMU drivers are not built in the kernel;
> +		 * Depending on whether the SMMU drivers are built-in
> +		 * in the kernel or not, defer the IOMMU configuration
> +		 * or just abort it.
> +		 */
>   		if (!ops)
> -			return NULL;
> +			return iort_iommu_driver_enabled(node->type) ?
> +			       ERR_PTR(-EPROBE_DEFER) : NULL;
>   
>   		ret = arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops);
>   	}
> @@ -625,12 +642,26 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
>   
>   		while (parent) {
>   			ops = iort_iommu_xlate(dev, parent, streamid);
> +			if (IS_ERR_OR_NULL(ops))
> +				return ops;
>   
>   			parent = iort_node_get_id(node, &streamid,
>   						  IORT_IOMMU_TYPE, i++);
>   		}
>   	}
>   
> +	/*
> +	 * If we have reason to believe the IOMMU driver missed the initial
> +	 * add_device callback for dev, replay it to get things in order.
> +	 */
> +	if (!IS_ERR_OR_NULL(ops) && ops->add_device &&
> +	    dev->bus && !dev->iommu_group) {
> +		int err = ops->add_device(dev);
> +
> +		if (err)
> +			ops = ERR_PTR(err);
> +	}
> +
>   	return ops;
>   }
>   
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index 1926918..2a513cc 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1373,20 +1373,25 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
>    * @dev: The pointer to the device
>    * @attr: device dma attributes
>    */
> -void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
> +int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
>   {
>   	const struct iommu_ops *iommu;
> +	u64 size;
>   
>   	iort_set_dma_mask(dev);
>   
>   	iommu = iort_iommu_configure(dev);
> +	if (IS_ERR(iommu))
> +		return PTR_ERR(iommu);
>   
> +	size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
>   	/*
>   	 * Assume dma valid range starts at 0 and covers the whole
>   	 * coherent_dma_mask.
>   	 */
> -	arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, iommu,
> -			   attr == DEV_DMA_COHERENT);
> +	arch_setup_dma_ops(dev, 0, size, iommu, attr == DEV_DMA_COHERENT);
> +
> +	return 0;
>   }
>   EXPORT_SYMBOL_GPL(acpi_dma_configure);
>   
> diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
> index 82bd45c..755a2b5 100644
> --- a/drivers/base/dma-mapping.c
> +++ b/drivers/base/dma-mapping.c
> @@ -368,7 +368,7 @@ int dma_configure(struct device *dev)
>   	} else if (has_acpi_companion(dma_dev)) {
>   		attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
>   		if (attr != DEV_DMA_NOT_SUPPORTED)
> -			acpi_dma_configure(dev, attr);
> +			ret = acpi_dma_configure(dev, attr);
>   	}
>   
>   	if (bridge)
> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> index ef0ae8a..2a9a5de 100644
> --- a/include/acpi/acpi_bus.h
> +++ b/include/acpi/acpi_bus.h
> @@ -575,7 +575,7 @@ struct acpi_pci_root {
>   
>   bool acpi_dma_supported(struct acpi_device *adev);
>   enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
> -void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
> +int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
>   void acpi_dma_deconfigure(struct device *dev);
>   
>   struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 9b05886..79d06ef6 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -762,8 +762,11 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
>   	return DEV_DMA_NOT_SUPPORTED;
>   }
>   
> -static inline void acpi_dma_configure(struct device *dev,
> -				      enum dev_dma_attr attr) { }
> +static inline int acpi_dma_configure(struct device *dev,
> +				     enum dev_dma_attr attr)
> +{
> +	return 0;
> +}
>   
>   static inline void acpi_dma_deconfigure(struct device *dev) { }
>   
> 

-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

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

* Re: [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
  2017-05-23  6:26           ` Nate Watterson
  (?)
  (?)
@ 2017-05-23  8:52               ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 70+ messages in thread
From: Lorenzo Pieralisi @ 2017-05-23  8:52 UTC (permalink / raw)
  To: Nate Watterson
  Cc: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
	okaya-sgV2jX0FEOL9JmXXK+q4OQ,
	frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
	linux-arch-u79uwXL29TY76Z2rM5mHXA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, lenb-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, bhelgaas-hpIqsD4AKlfQT0dZR+AlfA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	rjw-LthD3rsA81gm4RdzfppkhA, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	sudeep.holla-5wv7dgnIgG8

On Tue, May 23, 2017 at 02:26:10AM -0400, Nate Watterson wrote:
> Hi Sricharan,
> 
> On 4/10/2017 7:21 AM, Sricharan R wrote:
> >This is an equivalent to the DT's handling of the iommu master's probe
> >with deferred probing when the corrsponding iommu is not probed yet.
> >The lack of a registered IOMMU can be caused by the lack of a driver for
> >the IOMMU, the IOMMU device probe not having been performed yet, having
> >been deferred, or having failed.
> >
> >The first case occurs when the firmware describes the bus master and
> >IOMMU topology correctly but no device driver exists for the IOMMU yet
> >or the device driver has not been compiled in. Return NULL, the caller
> >will configure the device without an IOMMU.
> >
> >The second and third cases are handled by deferring the probe of the bus
> >master device which will eventually get reprobed after the IOMMU.
> >
> >The last case is currently handled by deferring the probe of the bus
> >master device as well. A mechanism to either configure the bus master
> >device without an IOMMU or to fail the bus master device probe depending
> >on whether the IOMMU is optional or mandatory would be a good
> >enhancement.
> >
> >Tested-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> >Reviewed-by: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
> >[Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
> >           called multiple times for same device]
> >Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
> >Signed-off-by: Sricharan R <sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
> >---
> >  drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
> >  drivers/acpi/scan.c        | 11 ++++++++---
> >  drivers/base/dma-mapping.c |  2 +-
> >  include/acpi/acpi_bus.h    |  2 +-
> >  include/linux/acpi.h       |  7 +++++--
> >  5 files changed, 47 insertions(+), 8 deletions(-)
> >
> >diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> >index 3dd9ec3..e323ece 100644
> >--- a/drivers/acpi/arm64/iort.c
> >+++ b/drivers/acpi/arm64/iort.c
> >@@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
> >  	const struct iommu_ops *ops = NULL;
> >  	int ret = -ENODEV;
> >  	struct fwnode_handle *iort_fwnode;
> >+	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
> >+
> >+	/*
> >+	 * If we already translated the fwspec there
> >+	 * is nothing left to do, return the iommu_ops.
> >+	 */
> >+	if (fwspec && fwspec->ops)
> >+		return fwspec->ops;
> 
> Is this logic strictly required? It breaks masters with multiple SIDs
> as only the first SID is actually added to the master's fwspec.

My bad, that's indeed a silly bug I introduced. Please let me know if the
patch below fixes it, we will send it upstream shortly.

Lorenzo

-- >8 --
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index c5fecf9..e326f2a 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -666,14 +666,6 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
 	int ret = -ENODEV;
 	struct fwnode_handle *iort_fwnode;
 
-	/*
-	 * If we already translated the fwspec there
-	 * is nothing left to do, return the iommu_ops.
-	 */
-	ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
-	if (ops)
-		return ops;
-
 	if (node) {
 		iort_fwnode = iort_get_fwnode(node);
 		if (!iort_fwnode)
@@ -735,6 +727,14 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
 	u32 streamid = 0;
 	int err;
 
+	/*
+	 * If we already translated the fwspec there
+	 * is nothing left to do, return the iommu_ops.
+	 */
+	ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
+	if (ops)
+		return ops;
+
 	if (dev_is_pci(dev)) {
 		struct pci_bus *bus = to_pci_dev(dev)->bus;
 		u32 rid;

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

* Re: [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
@ 2017-05-23  8:52               ` Lorenzo Pieralisi
  0 siblings, 0 replies; 70+ messages in thread
From: Lorenzo Pieralisi @ 2017-05-23  8:52 UTC (permalink / raw)
  To: Nate Watterson
  Cc: Sricharan R, robin.murphy, will.deacon, joro, iommu,
	linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh

On Tue, May 23, 2017 at 02:26:10AM -0400, Nate Watterson wrote:
> Hi Sricharan,
> 
> On 4/10/2017 7:21 AM, Sricharan R wrote:
> >This is an equivalent to the DT's handling of the iommu master's probe
> >with deferred probing when the corrsponding iommu is not probed yet.
> >The lack of a registered IOMMU can be caused by the lack of a driver for
> >the IOMMU, the IOMMU device probe not having been performed yet, having
> >been deferred, or having failed.
> >
> >The first case occurs when the firmware describes the bus master and
> >IOMMU topology correctly but no device driver exists for the IOMMU yet
> >or the device driver has not been compiled in. Return NULL, the caller
> >will configure the device without an IOMMU.
> >
> >The second and third cases are handled by deferring the probe of the bus
> >master device which will eventually get reprobed after the IOMMU.
> >
> >The last case is currently handled by deferring the probe of the bus
> >master device as well. A mechanism to either configure the bus master
> >device without an IOMMU or to fail the bus master device probe depending
> >on whether the IOMMU is optional or mandatory would be a good
> >enhancement.
> >
> >Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
> >Reviewed-by: Robin Murphy <robin.murphy@arm.com>
> >[Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
> >           called multiple times for same device]
> >Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> >Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> >---
> >  drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
> >  drivers/acpi/scan.c        | 11 ++++++++---
> >  drivers/base/dma-mapping.c |  2 +-
> >  include/acpi/acpi_bus.h    |  2 +-
> >  include/linux/acpi.h       |  7 +++++--
> >  5 files changed, 47 insertions(+), 8 deletions(-)
> >
> >diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> >index 3dd9ec3..e323ece 100644
> >--- a/drivers/acpi/arm64/iort.c
> >+++ b/drivers/acpi/arm64/iort.c
> >@@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
> >  	const struct iommu_ops *ops = NULL;
> >  	int ret = -ENODEV;
> >  	struct fwnode_handle *iort_fwnode;
> >+	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
> >+
> >+	/*
> >+	 * If we already translated the fwspec there
> >+	 * is nothing left to do, return the iommu_ops.
> >+	 */
> >+	if (fwspec && fwspec->ops)
> >+		return fwspec->ops;
> 
> Is this logic strictly required? It breaks masters with multiple SIDs
> as only the first SID is actually added to the master's fwspec.

My bad, that's indeed a silly bug I introduced. Please let me know if the
patch below fixes it, we will send it upstream shortly.

Lorenzo

-- >8 --
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index c5fecf9..e326f2a 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -666,14 +666,6 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
 	int ret = -ENODEV;
 	struct fwnode_handle *iort_fwnode;
 
-	/*
-	 * If we already translated the fwspec there
-	 * is nothing left to do, return the iommu_ops.
-	 */
-	ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
-	if (ops)
-		return ops;
-
 	if (node) {
 		iort_fwnode = iort_get_fwnode(node);
 		if (!iort_fwnode)
@@ -735,6 +727,14 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
 	u32 streamid = 0;
 	int err;
 
+	/*
+	 * If we already translated the fwspec there
+	 * is nothing left to do, return the iommu_ops.
+	 */
+	ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
+	if (ops)
+		return ops;
+
 	if (dev_is_pci(dev)) {
 		struct pci_bus *bus = to_pci_dev(dev)->bus;
 		u32 rid;

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

* Re: [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
@ 2017-05-23  8:52               ` Lorenzo Pieralisi
  0 siblings, 0 replies; 70+ messages in thread
From: Lorenzo Pieralisi @ 2017-05-23  8:52 UTC (permalink / raw)
  To: Nate Watterson
  Cc: gregkh, catalin.marinas, will.deacon, okaya, frowand.list,
	m.szyprowski, linux-arch, tn, joro, linux-acpi, linux-pci, lenb,
	devicetree, arnd, linux-arm-msm, robh+dt, bhelgaas,
	linux-arm-kernel, robin.murphy, rjw, linux-kernel, iommu,
	hanjun.guo, sudeep.holla, Sricharan R

On Tue, May 23, 2017 at 02:26:10AM -0400, Nate Watterson wrote:
> Hi Sricharan,
> 
> On 4/10/2017 7:21 AM, Sricharan R wrote:
> >This is an equivalent to the DT's handling of the iommu master's probe
> >with deferred probing when the corrsponding iommu is not probed yet.
> >The lack of a registered IOMMU can be caused by the lack of a driver for
> >the IOMMU, the IOMMU device probe not having been performed yet, having
> >been deferred, or having failed.
> >
> >The first case occurs when the firmware describes the bus master and
> >IOMMU topology correctly but no device driver exists for the IOMMU yet
> >or the device driver has not been compiled in. Return NULL, the caller
> >will configure the device without an IOMMU.
> >
> >The second and third cases are handled by deferring the probe of the bus
> >master device which will eventually get reprobed after the IOMMU.
> >
> >The last case is currently handled by deferring the probe of the bus
> >master device as well. A mechanism to either configure the bus master
> >device without an IOMMU or to fail the bus master device probe depending
> >on whether the IOMMU is optional or mandatory would be a good
> >enhancement.
> >
> >Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
> >Reviewed-by: Robin Murphy <robin.murphy@arm.com>
> >[Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
> >           called multiple times for same device]
> >Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> >Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> >---
> >  drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
> >  drivers/acpi/scan.c        | 11 ++++++++---
> >  drivers/base/dma-mapping.c |  2 +-
> >  include/acpi/acpi_bus.h    |  2 +-
> >  include/linux/acpi.h       |  7 +++++--
> >  5 files changed, 47 insertions(+), 8 deletions(-)
> >
> >diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> >index 3dd9ec3..e323ece 100644
> >--- a/drivers/acpi/arm64/iort.c
> >+++ b/drivers/acpi/arm64/iort.c
> >@@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
> >  	const struct iommu_ops *ops = NULL;
> >  	int ret = -ENODEV;
> >  	struct fwnode_handle *iort_fwnode;
> >+	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
> >+
> >+	/*
> >+	 * If we already translated the fwspec there
> >+	 * is nothing left to do, return the iommu_ops.
> >+	 */
> >+	if (fwspec && fwspec->ops)
> >+		return fwspec->ops;
> 
> Is this logic strictly required? It breaks masters with multiple SIDs
> as only the first SID is actually added to the master's fwspec.

My bad, that's indeed a silly bug I introduced. Please let me know if the
patch below fixes it, we will send it upstream shortly.

Lorenzo

-- >8 --
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index c5fecf9..e326f2a 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -666,14 +666,6 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
 	int ret = -ENODEV;
 	struct fwnode_handle *iort_fwnode;
 
-	/*
-	 * If we already translated the fwspec there
-	 * is nothing left to do, return the iommu_ops.
-	 */
-	ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
-	if (ops)
-		return ops;
-
 	if (node) {
 		iort_fwnode = iort_get_fwnode(node);
 		if (!iort_fwnode)
@@ -735,6 +727,14 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
 	u32 streamid = 0;
 	int err;
 
+	/*
+	 * If we already translated the fwspec there
+	 * is nothing left to do, return the iommu_ops.
+	 */
+	ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
+	if (ops)
+		return ops;
+
 	if (dev_is_pci(dev)) {
 		struct pci_bus *bus = to_pci_dev(dev)->bus;
 		u32 rid;



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
@ 2017-05-23  8:52               ` Lorenzo Pieralisi
  0 siblings, 0 replies; 70+ messages in thread
From: Lorenzo Pieralisi @ 2017-05-23  8:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, May 23, 2017 at 02:26:10AM -0400, Nate Watterson wrote:
> Hi Sricharan,
> 
> On 4/10/2017 7:21 AM, Sricharan R wrote:
> >This is an equivalent to the DT's handling of the iommu master's probe
> >with deferred probing when the corrsponding iommu is not probed yet.
> >The lack of a registered IOMMU can be caused by the lack of a driver for
> >the IOMMU, the IOMMU device probe not having been performed yet, having
> >been deferred, or having failed.
> >
> >The first case occurs when the firmware describes the bus master and
> >IOMMU topology correctly but no device driver exists for the IOMMU yet
> >or the device driver has not been compiled in. Return NULL, the caller
> >will configure the device without an IOMMU.
> >
> >The second and third cases are handled by deferring the probe of the bus
> >master device which will eventually get reprobed after the IOMMU.
> >
> >The last case is currently handled by deferring the probe of the bus
> >master device as well. A mechanism to either configure the bus master
> >device without an IOMMU or to fail the bus master device probe depending
> >on whether the IOMMU is optional or mandatory would be a good
> >enhancement.
> >
> >Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
> >Reviewed-by: Robin Murphy <robin.murphy@arm.com>
> >[Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
> >           called multiple times for same device]
> >Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> >Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> >---
> >  drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
> >  drivers/acpi/scan.c        | 11 ++++++++---
> >  drivers/base/dma-mapping.c |  2 +-
> >  include/acpi/acpi_bus.h    |  2 +-
> >  include/linux/acpi.h       |  7 +++++--
> >  5 files changed, 47 insertions(+), 8 deletions(-)
> >
> >diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> >index 3dd9ec3..e323ece 100644
> >--- a/drivers/acpi/arm64/iort.c
> >+++ b/drivers/acpi/arm64/iort.c
> >@@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
> >  	const struct iommu_ops *ops = NULL;
> >  	int ret = -ENODEV;
> >  	struct fwnode_handle *iort_fwnode;
> >+	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
> >+
> >+	/*
> >+	 * If we already translated the fwspec there
> >+	 * is nothing left to do, return the iommu_ops.
> >+	 */
> >+	if (fwspec && fwspec->ops)
> >+		return fwspec->ops;
> 
> Is this logic strictly required? It breaks masters with multiple SIDs
> as only the first SID is actually added to the master's fwspec.

My bad, that's indeed a silly bug I introduced. Please let me know if the
patch below fixes it, we will send it upstream shortly.

Lorenzo

-- >8 --
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index c5fecf9..e326f2a 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -666,14 +666,6 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
 	int ret = -ENODEV;
 	struct fwnode_handle *iort_fwnode;
 
-	/*
-	 * If we already translated the fwspec there
-	 * is nothing left to do, return the iommu_ops.
-	 */
-	ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
-	if (ops)
-		return ops;
-
 	if (node) {
 		iort_fwnode = iort_get_fwnode(node);
 		if (!iort_fwnode)
@@ -735,6 +727,14 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
 	u32 streamid = 0;
 	int err;
 
+	/*
+	 * If we already translated the fwspec there
+	 * is nothing left to do, return the iommu_ops.
+	 */
+	ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
+	if (ops)
+		return ops;
+
 	if (dev_is_pci(dev)) {
 		struct pci_bus *bus = to_pci_dev(dev)->bus;
 		u32 rid;

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

* Re: [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
  2017-05-23  6:26           ` Nate Watterson
  (?)
  (?)
@ 2017-05-23  8:59               ` Sricharan R
  -1 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-05-23  8:59 UTC (permalink / raw)
  To: Nate Watterson, robin.murphy-5wv7dgnIgG8,
	will.deacon-5wv7dgnIgG8, joro-zLv9SwRftAIdnm+yROfE0A,
	lorenzo.pieralisi-5wv7dgnIgG8,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ,
	bhelgaas-hpIqsD4AKlfQT0dZR+AlfA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
	hanjun.guo-QSEj5FYQhm4dnm+yROfE0A, okaya-sgV2jX0FEOL9JmXXK+q4OQ,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, sudeep.holla-5wv7dgnIgG8,
	rjw-LthD3rsA81gm4RdzfppkhA, lenb-DgEjT+Ai2ygdnm+yROfE0A,
	catalin.marinas-5wv7dgnIgG8, arnd-r2nGTMty4D4,
	linux-arch-u79uwXL29TY76Z2rM5mHXA,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r

Hi,

On 5/23/2017 11:56 AM, Nate Watterson wrote:
> Hi Sricharan,
> 
> On 4/10/2017 7:21 AM, Sricharan R wrote:
>> This is an equivalent to the DT's handling of the iommu master's probe
>> with deferred probing when the corrsponding iommu is not probed yet.
>> The lack of a registered IOMMU can be caused by the lack of a driver for
>> the IOMMU, the IOMMU device probe not having been performed yet, having
>> been deferred, or having failed.
>>
>> The first case occurs when the firmware describes the bus master and
>> IOMMU topology correctly but no device driver exists for the IOMMU yet
>> or the device driver has not been compiled in. Return NULL, the caller
>> will configure the device without an IOMMU.
>>
>> The second and third cases are handled by deferring the probe of the bus
>> master device which will eventually get reprobed after the IOMMU.
>>
>> The last case is currently handled by deferring the probe of the bus
>> master device as well. A mechanism to either configure the bus master
>> device without an IOMMU or to fail the bus master device probe depending
>> on whether the IOMMU is optional or mandatory would be a good
>> enhancement.
>>
>> Tested-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>> Reviewed-by: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
>> [Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
>>            called multiple times for same device]
>> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
>> Signed-off-by: Sricharan R <sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
>> ---
>>   drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
>>   drivers/acpi/scan.c        | 11 ++++++++---
>>   drivers/base/dma-mapping.c |  2 +-
>>   include/acpi/acpi_bus.h    |  2 +-
>>   include/linux/acpi.h       |  7 +++++--
>>   5 files changed, 47 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
>> index 3dd9ec3..e323ece 100644
>> --- a/drivers/acpi/arm64/iort.c
>> +++ b/drivers/acpi/arm64/iort.c
>> @@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>>       const struct iommu_ops *ops = NULL;
>>       int ret = -ENODEV;
>>       struct fwnode_handle *iort_fwnode;
>> +    struct iommu_fwspec *fwspec = dev->iommu_fwspec;
>> +
>> +    /*
>> +     * If we already translated the fwspec there
>> +     * is nothing left to do, return the iommu_ops.
>> +     */
>> +    if (fwspec && fwspec->ops)
>> +        return fwspec->ops;
> 
> Is this logic strictly required? It breaks masters with multiple SIDs
> as only the first SID is actually added to the master's fwspec.
> 

The logic here is same as what is done in DT, in of_iommu_configure.
This is to pullback the iommu_ops that was set for the device from the
previous run. (when the device probe is deferred and called again).
Infact this piece of hunk was initially missing in ACPI, later added
since a bug was reported [1] on V9 and then this came in as a fix in V10.
But looks like this check should be in iort_iommu_configure.
Lorenzo, is that correct ?


[1] https://www.spinics.net/lists/arm-kernel/msg572069.html

If yes i will add this in the fixes that i have already posted.

Regards,
 Sricharan


>>         if (node) {
>>           iort_fwnode = iort_get_fwnode(node);
>> @@ -550,8 +558,17 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>>               return NULL;
>>             ops = iommu_ops_from_fwnode(iort_fwnode);
>> +        /*
>> +         * If the ops look-up fails, this means that either
>> +         * the SMMU drivers have not been probed yet or that
>> +         * the SMMU drivers are not built in the kernel;
>> +         * Depending on whether the SMMU drivers are built-in
>> +         * in the kernel or not, defer the IOMMU configuration
>> +         * or just abort it.
>> +         */
>>           if (!ops)
>> -            return NULL;
>> +            return iort_iommu_driver_enabled(node->type) ?
>> +                   ERR_PTR(-EPROBE_DEFER) : NULL;
>>             ret = arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops);
>>       }
>> @@ -625,12 +642,26 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
>>             while (parent) {
>>               ops = iort_iommu_xlate(dev, parent, streamid);
>> +            if (IS_ERR_OR_NULL(ops))
>> +                return ops;
>>                 parent = iort_node_get_id(node, &streamid,
>>                             IORT_IOMMU_TYPE, i++);
>>           }
>>       }
>>   +    /*
>> +     * If we have reason to believe the IOMMU driver missed the initial
>> +     * add_device callback for dev, replay it to get things in order.
>> +     */
>> +    if (!IS_ERR_OR_NULL(ops) && ops->add_device &&
>> +        dev->bus && !dev->iommu_group) {
>> +        int err = ops->add_device(dev);
>> +
>> +        if (err)
>> +            ops = ERR_PTR(err);
>> +    }
>> +
>>       return ops;
>>   }
>>   diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
>> index 1926918..2a513cc 100644
>> --- a/drivers/acpi/scan.c
>> +++ b/drivers/acpi/scan.c
>> @@ -1373,20 +1373,25 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
>>    * @dev: The pointer to the device
>>    * @attr: device dma attributes
>>    */
>> -void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
>> +int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
>>   {
>>       const struct iommu_ops *iommu;
>> +    u64 size;
>>         iort_set_dma_mask(dev);
>>         iommu = iort_iommu_configure(dev);
>> +    if (IS_ERR(iommu))
>> +        return PTR_ERR(iommu);
>>   +    size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
>>       /*
>>        * Assume dma valid range starts at 0 and covers the whole
>>        * coherent_dma_mask.
>>        */
>> -    arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, iommu,
>> -               attr == DEV_DMA_COHERENT);
>> +    arch_setup_dma_ops(dev, 0, size, iommu, attr == DEV_DMA_COHERENT);
>> +
>> +    return 0;
>>   }
>>   EXPORT_SYMBOL_GPL(acpi_dma_configure);
>>   diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
>> index 82bd45c..755a2b5 100644
>> --- a/drivers/base/dma-mapping.c
>> +++ b/drivers/base/dma-mapping.c
>> @@ -368,7 +368,7 @@ int dma_configure(struct device *dev)
>>       } else if (has_acpi_companion(dma_dev)) {
>>           attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
>>           if (attr != DEV_DMA_NOT_SUPPORTED)
>> -            acpi_dma_configure(dev, attr);
>> +            ret = acpi_dma_configure(dev, attr);
>>       }
>>         if (bridge)
>> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
>> index ef0ae8a..2a9a5de 100644
>> --- a/include/acpi/acpi_bus.h
>> +++ b/include/acpi/acpi_bus.h
>> @@ -575,7 +575,7 @@ struct acpi_pci_root {
>>     bool acpi_dma_supported(struct acpi_device *adev);
>>   enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
>> -void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
>> +int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
>>   void acpi_dma_deconfigure(struct device *dev);
>>     struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
>> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
>> index 9b05886..79d06ef6 100644
>> --- a/include/linux/acpi.h
>> +++ b/include/linux/acpi.h
>> @@ -762,8 +762,11 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
>>       return DEV_DMA_NOT_SUPPORTED;
>>   }
>>   -static inline void acpi_dma_configure(struct device *dev,
>> -                      enum dev_dma_attr attr) { }
>> +static inline int acpi_dma_configure(struct device *dev,
>> +                     enum dev_dma_attr attr)
>> +{
>> +    return 0;
>> +}
>>     static inline void acpi_dma_deconfigure(struct device *dev) { }
>>  
> 

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* Re: [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
@ 2017-05-23  8:59               ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-05-23  8:59 UTC (permalink / raw)
  To: Nate Watterson, robin.murphy, will.deacon, joro,
	lorenzo.pieralisi, iommu, linux-arm-kernel, linux-arm-msm,
	m.szyprowski, bhelgaas, linux-pci, linux-acpi, tn, hanjun.guo,
	okaya, robh+dt, frowand.list, devicetree, linux-kernel,
	sudeep.holla, rjw, lenb, catalin.marinas, arnd, linux-arch,
	gregkh

Hi,

On 5/23/2017 11:56 AM, Nate Watterson wrote:
> Hi Sricharan,
> 
> On 4/10/2017 7:21 AM, Sricharan R wrote:
>> This is an equivalent to the DT's handling of the iommu master's probe
>> with deferred probing when the corrsponding iommu is not probed yet.
>> The lack of a registered IOMMU can be caused by the lack of a driver for
>> the IOMMU, the IOMMU device probe not having been performed yet, having
>> been deferred, or having failed.
>>
>> The first case occurs when the firmware describes the bus master and
>> IOMMU topology correctly but no device driver exists for the IOMMU yet
>> or the device driver has not been compiled in. Return NULL, the caller
>> will configure the device without an IOMMU.
>>
>> The second and third cases are handled by deferring the probe of the bus
>> master device which will eventually get reprobed after the IOMMU.
>>
>> The last case is currently handled by deferring the probe of the bus
>> master device as well. A mechanism to either configure the bus master
>> device without an IOMMU or to fail the bus master device probe depending
>> on whether the IOMMU is optional or mandatory would be a good
>> enhancement.
>>
>> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Reviewed-by: Robin Murphy <robin.murphy@arm.com>
>> [Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
>>            called multiple times for same device]
>> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
>> ---
>>   drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
>>   drivers/acpi/scan.c        | 11 ++++++++---
>>   drivers/base/dma-mapping.c |  2 +-
>>   include/acpi/acpi_bus.h    |  2 +-
>>   include/linux/acpi.h       |  7 +++++--
>>   5 files changed, 47 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
>> index 3dd9ec3..e323ece 100644
>> --- a/drivers/acpi/arm64/iort.c
>> +++ b/drivers/acpi/arm64/iort.c
>> @@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>>       const struct iommu_ops *ops = NULL;
>>       int ret = -ENODEV;
>>       struct fwnode_handle *iort_fwnode;
>> +    struct iommu_fwspec *fwspec = dev->iommu_fwspec;
>> +
>> +    /*
>> +     * If we already translated the fwspec there
>> +     * is nothing left to do, return the iommu_ops.
>> +     */
>> +    if (fwspec && fwspec->ops)
>> +        return fwspec->ops;
> 
> Is this logic strictly required? It breaks masters with multiple SIDs
> as only the first SID is actually added to the master's fwspec.
> 

The logic here is same as what is done in DT, in of_iommu_configure.
This is to pullback the iommu_ops that was set for the device from the
previous run. (when the device probe is deferred and called again).
Infact this piece of hunk was initially missing in ACPI, later added
since a bug was reported [1] on V9 and then this came in as a fix in V10.
But looks like this check should be in iort_iommu_configure.
Lorenzo, is that correct ?


[1] https://www.spinics.net/lists/arm-kernel/msg572069.html

If yes i will add this in the fixes that i have already posted.

Regards,
 Sricharan


>>         if (node) {
>>           iort_fwnode = iort_get_fwnode(node);
>> @@ -550,8 +558,17 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>>               return NULL;
>>             ops = iommu_ops_from_fwnode(iort_fwnode);
>> +        /*
>> +         * If the ops look-up fails, this means that either
>> +         * the SMMU drivers have not been probed yet or that
>> +         * the SMMU drivers are not built in the kernel;
>> +         * Depending on whether the SMMU drivers are built-in
>> +         * in the kernel or not, defer the IOMMU configuration
>> +         * or just abort it.
>> +         */
>>           if (!ops)
>> -            return NULL;
>> +            return iort_iommu_driver_enabled(node->type) ?
>> +                   ERR_PTR(-EPROBE_DEFER) : NULL;
>>             ret = arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops);
>>       }
>> @@ -625,12 +642,26 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
>>             while (parent) {
>>               ops = iort_iommu_xlate(dev, parent, streamid);
>> +            if (IS_ERR_OR_NULL(ops))
>> +                return ops;
>>                 parent = iort_node_get_id(node, &streamid,
>>                             IORT_IOMMU_TYPE, i++);
>>           }
>>       }
>>   +    /*
>> +     * If we have reason to believe the IOMMU driver missed the initial
>> +     * add_device callback for dev, replay it to get things in order.
>> +     */
>> +    if (!IS_ERR_OR_NULL(ops) && ops->add_device &&
>> +        dev->bus && !dev->iommu_group) {
>> +        int err = ops->add_device(dev);
>> +
>> +        if (err)
>> +            ops = ERR_PTR(err);
>> +    }
>> +
>>       return ops;
>>   }
>>   diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
>> index 1926918..2a513cc 100644
>> --- a/drivers/acpi/scan.c
>> +++ b/drivers/acpi/scan.c
>> @@ -1373,20 +1373,25 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
>>    * @dev: The pointer to the device
>>    * @attr: device dma attributes
>>    */
>> -void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
>> +int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
>>   {
>>       const struct iommu_ops *iommu;
>> +    u64 size;
>>         iort_set_dma_mask(dev);
>>         iommu = iort_iommu_configure(dev);
>> +    if (IS_ERR(iommu))
>> +        return PTR_ERR(iommu);
>>   +    size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
>>       /*
>>        * Assume dma valid range starts at 0 and covers the whole
>>        * coherent_dma_mask.
>>        */
>> -    arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, iommu,
>> -               attr == DEV_DMA_COHERENT);
>> +    arch_setup_dma_ops(dev, 0, size, iommu, attr == DEV_DMA_COHERENT);
>> +
>> +    return 0;
>>   }
>>   EXPORT_SYMBOL_GPL(acpi_dma_configure);
>>   diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
>> index 82bd45c..755a2b5 100644
>> --- a/drivers/base/dma-mapping.c
>> +++ b/drivers/base/dma-mapping.c
>> @@ -368,7 +368,7 @@ int dma_configure(struct device *dev)
>>       } else if (has_acpi_companion(dma_dev)) {
>>           attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
>>           if (attr != DEV_DMA_NOT_SUPPORTED)
>> -            acpi_dma_configure(dev, attr);
>> +            ret = acpi_dma_configure(dev, attr);
>>       }
>>         if (bridge)
>> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
>> index ef0ae8a..2a9a5de 100644
>> --- a/include/acpi/acpi_bus.h
>> +++ b/include/acpi/acpi_bus.h
>> @@ -575,7 +575,7 @@ struct acpi_pci_root {
>>     bool acpi_dma_supported(struct acpi_device *adev);
>>   enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
>> -void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
>> +int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
>>   void acpi_dma_deconfigure(struct device *dev);
>>     struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
>> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
>> index 9b05886..79d06ef6 100644
>> --- a/include/linux/acpi.h
>> +++ b/include/linux/acpi.h
>> @@ -762,8 +762,11 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
>>       return DEV_DMA_NOT_SUPPORTED;
>>   }
>>   -static inline void acpi_dma_configure(struct device *dev,
>> -                      enum dev_dma_attr attr) { }
>> +static inline int acpi_dma_configure(struct device *dev,
>> +                     enum dev_dma_attr attr)
>> +{
>> +    return 0;
>> +}
>>     static inline void acpi_dma_deconfigure(struct device *dev) { }
>>  
> 

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* Re: [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
@ 2017-05-23  8:59               ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-05-23  8:59 UTC (permalink / raw)
  To: Nate Watterson, robin.murphy, will.deacon, joro,
	lorenzo.pieralisi, iommu, linux-arm-kernel, linux-arm-msm,
	m.szyprowski, bhelgaas, linux-pci, linux-acpi, tn, hanjun.guo,
	okaya, robh+dt, frowand.list, devicetree, linux-kernel,
	sudeep.holla, rjw, lenb, catalin.marinas, arnd, linux-arch,
	gregkh

Hi,

On 5/23/2017 11:56 AM, Nate Watterson wrote:
> Hi Sricharan,
> 
> On 4/10/2017 7:21 AM, Sricharan R wrote:
>> This is an equivalent to the DT's handling of the iommu master's probe
>> with deferred probing when the corrsponding iommu is not probed yet.
>> The lack of a registered IOMMU can be caused by the lack of a driver for
>> the IOMMU, the IOMMU device probe not having been performed yet, having
>> been deferred, or having failed.
>>
>> The first case occurs when the firmware describes the bus master and
>> IOMMU topology correctly but no device driver exists for the IOMMU yet
>> or the device driver has not been compiled in. Return NULL, the caller
>> will configure the device without an IOMMU.
>>
>> The second and third cases are handled by deferring the probe of the bus
>> master device which will eventually get reprobed after the IOMMU.
>>
>> The last case is currently handled by deferring the probe of the bus
>> master device as well. A mechanism to either configure the bus master
>> device without an IOMMU or to fail the bus master device probe depending
>> on whether the IOMMU is optional or mandatory would be a good
>> enhancement.
>>
>> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Reviewed-by: Robin Murphy <robin.murphy@arm.com>
>> [Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
>>            called multiple times for same device]
>> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
>> ---
>>   drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
>>   drivers/acpi/scan.c        | 11 ++++++++---
>>   drivers/base/dma-mapping.c |  2 +-
>>   include/acpi/acpi_bus.h    |  2 +-
>>   include/linux/acpi.h       |  7 +++++--
>>   5 files changed, 47 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
>> index 3dd9ec3..e323ece 100644
>> --- a/drivers/acpi/arm64/iort.c
>> +++ b/drivers/acpi/arm64/iort.c
>> @@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>>       const struct iommu_ops *ops = NULL;
>>       int ret = -ENODEV;
>>       struct fwnode_handle *iort_fwnode;
>> +    struct iommu_fwspec *fwspec = dev->iommu_fwspec;
>> +
>> +    /*
>> +     * If we already translated the fwspec there
>> +     * is nothing left to do, return the iommu_ops.
>> +     */
>> +    if (fwspec && fwspec->ops)
>> +        return fwspec->ops;
> 
> Is this logic strictly required? It breaks masters with multiple SIDs
> as only the first SID is actually added to the master's fwspec.
> 

The logic here is same as what is done in DT, in of_iommu_configure.
This is to pullback the iommu_ops that was set for the device from the
previous run. (when the device probe is deferred and called again).
Infact this piece of hunk was initially missing in ACPI, later added
since a bug was reported [1] on V9 and then this came in as a fix in V10.
But looks like this check should be in iort_iommu_configure.
Lorenzo, is that correct ?


[1] https://www.spinics.net/lists/arm-kernel/msg572069.html

If yes i will add this in the fixes that i have already posted.

Regards,
 Sricharan


>>         if (node) {
>>           iort_fwnode = iort_get_fwnode(node);
>> @@ -550,8 +558,17 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>>               return NULL;
>>             ops = iommu_ops_from_fwnode(iort_fwnode);
>> +        /*
>> +         * If the ops look-up fails, this means that either
>> +         * the SMMU drivers have not been probed yet or that
>> +         * the SMMU drivers are not built in the kernel;
>> +         * Depending on whether the SMMU drivers are built-in
>> +         * in the kernel or not, defer the IOMMU configuration
>> +         * or just abort it.
>> +         */
>>           if (!ops)
>> -            return NULL;
>> +            return iort_iommu_driver_enabled(node->type) ?
>> +                   ERR_PTR(-EPROBE_DEFER) : NULL;
>>             ret = arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops);
>>       }
>> @@ -625,12 +642,26 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
>>             while (parent) {
>>               ops = iort_iommu_xlate(dev, parent, streamid);
>> +            if (IS_ERR_OR_NULL(ops))
>> +                return ops;
>>                 parent = iort_node_get_id(node, &streamid,
>>                             IORT_IOMMU_TYPE, i++);
>>           }
>>       }
>>   +    /*
>> +     * If we have reason to believe the IOMMU driver missed the initial
>> +     * add_device callback for dev, replay it to get things in order.
>> +     */
>> +    if (!IS_ERR_OR_NULL(ops) && ops->add_device &&
>> +        dev->bus && !dev->iommu_group) {
>> +        int err = ops->add_device(dev);
>> +
>> +        if (err)
>> +            ops = ERR_PTR(err);
>> +    }
>> +
>>       return ops;
>>   }
>>   diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
>> index 1926918..2a513cc 100644
>> --- a/drivers/acpi/scan.c
>> +++ b/drivers/acpi/scan.c
>> @@ -1373,20 +1373,25 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
>>    * @dev: The pointer to the device
>>    * @attr: device dma attributes
>>    */
>> -void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
>> +int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
>>   {
>>       const struct iommu_ops *iommu;
>> +    u64 size;
>>         iort_set_dma_mask(dev);
>>         iommu = iort_iommu_configure(dev);
>> +    if (IS_ERR(iommu))
>> +        return PTR_ERR(iommu);
>>   +    size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
>>       /*
>>        * Assume dma valid range starts at 0 and covers the whole
>>        * coherent_dma_mask.
>>        */
>> -    arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, iommu,
>> -               attr == DEV_DMA_COHERENT);
>> +    arch_setup_dma_ops(dev, 0, size, iommu, attr == DEV_DMA_COHERENT);
>> +
>> +    return 0;
>>   }
>>   EXPORT_SYMBOL_GPL(acpi_dma_configure);
>>   diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
>> index 82bd45c..755a2b5 100644
>> --- a/drivers/base/dma-mapping.c
>> +++ b/drivers/base/dma-mapping.c
>> @@ -368,7 +368,7 @@ int dma_configure(struct device *dev)
>>       } else if (has_acpi_companion(dma_dev)) {
>>           attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
>>           if (attr != DEV_DMA_NOT_SUPPORTED)
>> -            acpi_dma_configure(dev, attr);
>> +            ret = acpi_dma_configure(dev, attr);
>>       }
>>         if (bridge)
>> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
>> index ef0ae8a..2a9a5de 100644
>> --- a/include/acpi/acpi_bus.h
>> +++ b/include/acpi/acpi_bus.h
>> @@ -575,7 +575,7 @@ struct acpi_pci_root {
>>     bool acpi_dma_supported(struct acpi_device *adev);
>>   enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
>> -void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
>> +int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
>>   void acpi_dma_deconfigure(struct device *dev);
>>     struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
>> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
>> index 9b05886..79d06ef6 100644
>> --- a/include/linux/acpi.h
>> +++ b/include/linux/acpi.h
>> @@ -762,8 +762,11 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
>>       return DEV_DMA_NOT_SUPPORTED;
>>   }
>>   -static inline void acpi_dma_configure(struct device *dev,
>> -                      enum dev_dma_attr attr) { }
>> +static inline int acpi_dma_configure(struct device *dev,
>> +                     enum dev_dma_attr attr)
>> +{
>> +    return 0;
>> +}
>>     static inline void acpi_dma_deconfigure(struct device *dev) { }
>>  
> 

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
@ 2017-05-23  8:59               ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-05-23  8:59 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 5/23/2017 11:56 AM, Nate Watterson wrote:
> Hi Sricharan,
> 
> On 4/10/2017 7:21 AM, Sricharan R wrote:
>> This is an equivalent to the DT's handling of the iommu master's probe
>> with deferred probing when the corrsponding iommu is not probed yet.
>> The lack of a registered IOMMU can be caused by the lack of a driver for
>> the IOMMU, the IOMMU device probe not having been performed yet, having
>> been deferred, or having failed.
>>
>> The first case occurs when the firmware describes the bus master and
>> IOMMU topology correctly but no device driver exists for the IOMMU yet
>> or the device driver has not been compiled in. Return NULL, the caller
>> will configure the device without an IOMMU.
>>
>> The second and third cases are handled by deferring the probe of the bus
>> master device which will eventually get reprobed after the IOMMU.
>>
>> The last case is currently handled by deferring the probe of the bus
>> master device as well. A mechanism to either configure the bus master
>> device without an IOMMU or to fail the bus master device probe depending
>> on whether the IOMMU is optional or mandatory would be a good
>> enhancement.
>>
>> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
>> Reviewed-by: Robin Murphy <robin.murphy@arm.com>
>> [Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
>>            called multiple times for same device]
>> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
>> ---
>>   drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
>>   drivers/acpi/scan.c        | 11 ++++++++---
>>   drivers/base/dma-mapping.c |  2 +-
>>   include/acpi/acpi_bus.h    |  2 +-
>>   include/linux/acpi.h       |  7 +++++--
>>   5 files changed, 47 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
>> index 3dd9ec3..e323ece 100644
>> --- a/drivers/acpi/arm64/iort.c
>> +++ b/drivers/acpi/arm64/iort.c
>> @@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>>       const struct iommu_ops *ops = NULL;
>>       int ret = -ENODEV;
>>       struct fwnode_handle *iort_fwnode;
>> +    struct iommu_fwspec *fwspec = dev->iommu_fwspec;
>> +
>> +    /*
>> +     * If we already translated the fwspec there
>> +     * is nothing left to do, return the iommu_ops.
>> +     */
>> +    if (fwspec && fwspec->ops)
>> +        return fwspec->ops;
> 
> Is this logic strictly required? It breaks masters with multiple SIDs
> as only the first SID is actually added to the master's fwspec.
> 

The logic here is same as what is done in DT, in of_iommu_configure.
This is to pullback the iommu_ops that was set for the device from the
previous run. (when the device probe is deferred and called again).
Infact this piece of hunk was initially missing in ACPI, later added
since a bug was reported [1] on V9 and then this came in as a fix in V10.
But looks like this check should be in iort_iommu_configure.
Lorenzo, is that correct ?


[1] https://www.spinics.net/lists/arm-kernel/msg572069.html

If yes i will add this in the fixes that i have already posted.

Regards,
 Sricharan


>>         if (node) {
>>           iort_fwnode = iort_get_fwnode(node);
>> @@ -550,8 +558,17 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>>               return NULL;
>>             ops = iommu_ops_from_fwnode(iort_fwnode);
>> +        /*
>> +         * If the ops look-up fails, this means that either
>> +         * the SMMU drivers have not been probed yet or that
>> +         * the SMMU drivers are not built in the kernel;
>> +         * Depending on whether the SMMU drivers are built-in
>> +         * in the kernel or not, defer the IOMMU configuration
>> +         * or just abort it.
>> +         */
>>           if (!ops)
>> -            return NULL;
>> +            return iort_iommu_driver_enabled(node->type) ?
>> +                   ERR_PTR(-EPROBE_DEFER) : NULL;
>>             ret = arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops);
>>       }
>> @@ -625,12 +642,26 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
>>             while (parent) {
>>               ops = iort_iommu_xlate(dev, parent, streamid);
>> +            if (IS_ERR_OR_NULL(ops))
>> +                return ops;
>>                 parent = iort_node_get_id(node, &streamid,
>>                             IORT_IOMMU_TYPE, i++);
>>           }
>>       }
>>   +    /*
>> +     * If we have reason to believe the IOMMU driver missed the initial
>> +     * add_device callback for dev, replay it to get things in order.
>> +     */
>> +    if (!IS_ERR_OR_NULL(ops) && ops->add_device &&
>> +        dev->bus && !dev->iommu_group) {
>> +        int err = ops->add_device(dev);
>> +
>> +        if (err)
>> +            ops = ERR_PTR(err);
>> +    }
>> +
>>       return ops;
>>   }
>>   diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
>> index 1926918..2a513cc 100644
>> --- a/drivers/acpi/scan.c
>> +++ b/drivers/acpi/scan.c
>> @@ -1373,20 +1373,25 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
>>    * @dev: The pointer to the device
>>    * @attr: device dma attributes
>>    */
>> -void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
>> +int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
>>   {
>>       const struct iommu_ops *iommu;
>> +    u64 size;
>>         iort_set_dma_mask(dev);
>>         iommu = iort_iommu_configure(dev);
>> +    if (IS_ERR(iommu))
>> +        return PTR_ERR(iommu);
>>   +    size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
>>       /*
>>        * Assume dma valid range starts at 0 and covers the whole
>>        * coherent_dma_mask.
>>        */
>> -    arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, iommu,
>> -               attr == DEV_DMA_COHERENT);
>> +    arch_setup_dma_ops(dev, 0, size, iommu, attr == DEV_DMA_COHERENT);
>> +
>> +    return 0;
>>   }
>>   EXPORT_SYMBOL_GPL(acpi_dma_configure);
>>   diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
>> index 82bd45c..755a2b5 100644
>> --- a/drivers/base/dma-mapping.c
>> +++ b/drivers/base/dma-mapping.c
>> @@ -368,7 +368,7 @@ int dma_configure(struct device *dev)
>>       } else if (has_acpi_companion(dma_dev)) {
>>           attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
>>           if (attr != DEV_DMA_NOT_SUPPORTED)
>> -            acpi_dma_configure(dev, attr);
>> +            ret = acpi_dma_configure(dev, attr);
>>       }
>>         if (bridge)
>> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
>> index ef0ae8a..2a9a5de 100644
>> --- a/include/acpi/acpi_bus.h
>> +++ b/include/acpi/acpi_bus.h
>> @@ -575,7 +575,7 @@ struct acpi_pci_root {
>>     bool acpi_dma_supported(struct acpi_device *adev);
>>   enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
>> -void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
>> +int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr);
>>   void acpi_dma_deconfigure(struct device *dev);
>>     struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
>> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
>> index 9b05886..79d06ef6 100644
>> --- a/include/linux/acpi.h
>> +++ b/include/linux/acpi.h
>> @@ -762,8 +762,11 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
>>       return DEV_DMA_NOT_SUPPORTED;
>>   }
>>   -static inline void acpi_dma_configure(struct device *dev,
>> -                      enum dev_dma_attr attr) { }
>> +static inline int acpi_dma_configure(struct device *dev,
>> +                     enum dev_dma_attr attr)
>> +{
>> +    return 0;
>> +}
>>     static inline void acpi_dma_deconfigure(struct device *dev) { }
>>  
> 

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* Re: [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
  2017-05-23  8:52               ` Lorenzo Pieralisi
  (?)
  (?)
@ 2017-05-23  9:01                 ` Sricharan R
  -1 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-05-23  9:01 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Nate Watterson
  Cc: catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
	okaya-sgV2jX0FEOL9JmXXK+q4OQ,
	frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
	linux-arch-u79uwXL29TY76Z2rM5mHXA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, lenb-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, bhelgaas-hpIqsD4AKlfQT0dZR+AlfA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	rjw-LthD3rsA81gm4RdzfppkhA, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	sudeep.holla-5wv7dgnIgG8

Hi Lorenzo,

On 5/23/2017 2:22 PM, Lorenzo Pieralisi wrote:
> On Tue, May 23, 2017 at 02:26:10AM -0400, Nate Watterson wrote:
>> Hi Sricharan,
>>
>> On 4/10/2017 7:21 AM, Sricharan R wrote:
>>> This is an equivalent to the DT's handling of the iommu master's probe
>>> with deferred probing when the corrsponding iommu is not probed yet.
>>> The lack of a registered IOMMU can be caused by the lack of a driver for
>>> the IOMMU, the IOMMU device probe not having been performed yet, having
>>> been deferred, or having failed.
>>>
>>> The first case occurs when the firmware describes the bus master and
>>> IOMMU topology correctly but no device driver exists for the IOMMU yet
>>> or the device driver has not been compiled in. Return NULL, the caller
>>> will configure the device without an IOMMU.
>>>
>>> The second and third cases are handled by deferring the probe of the bus
>>> master device which will eventually get reprobed after the IOMMU.
>>>
>>> The last case is currently handled by deferring the probe of the bus
>>> master device as well. A mechanism to either configure the bus master
>>> device without an IOMMU or to fail the bus master device probe depending
>>> on whether the IOMMU is optional or mandatory would be a good
>>> enhancement.
>>>
>>> Tested-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>>> Reviewed-by: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
>>> [Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
>>>           called multiple times for same device]
>>> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
>>> Signed-off-by: Sricharan R <sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
>>> ---
>>>  drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
>>>  drivers/acpi/scan.c        | 11 ++++++++---
>>>  drivers/base/dma-mapping.c |  2 +-
>>>  include/acpi/acpi_bus.h    |  2 +-
>>>  include/linux/acpi.h       |  7 +++++--
>>>  5 files changed, 47 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
>>> index 3dd9ec3..e323ece 100644
>>> --- a/drivers/acpi/arm64/iort.c
>>> +++ b/drivers/acpi/arm64/iort.c
>>> @@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>>>  	const struct iommu_ops *ops = NULL;
>>>  	int ret = -ENODEV;
>>>  	struct fwnode_handle *iort_fwnode;
>>> +	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
>>> +
>>> +	/*
>>> +	 * If we already translated the fwspec there
>>> +	 * is nothing left to do, return the iommu_ops.
>>> +	 */
>>> +	if (fwspec && fwspec->ops)
>>> +		return fwspec->ops;
>>
>> Is this logic strictly required? It breaks masters with multiple SIDs
>> as only the first SID is actually added to the master's fwspec.
> 
> My bad, that's indeed a silly bug I introduced. Please let me know if the
> patch below fixes it, we will send it upstream shortly.
> 

oops, i think emails crossed. Please let me know if you are ok to add this
to the other fixes.

Regards,
 Sricharan

> Lorenzo
> 
> -- >8 --
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index c5fecf9..e326f2a 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -666,14 +666,6 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>  	int ret = -ENODEV;
>  	struct fwnode_handle *iort_fwnode;
>  
> -	/*
> -	 * If we already translated the fwspec there
> -	 * is nothing left to do, return the iommu_ops.
> -	 */
> -	ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
> -	if (ops)
> -		return ops;
> -
>  	if (node) {
>  		iort_fwnode = iort_get_fwnode(node);
>  		if (!iort_fwnode)
> @@ -735,6 +727,14 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
>  	u32 streamid = 0;
>  	int err;
>  
> +	/*
> +	 * If we already translated the fwspec there
> +	 * is nothing left to do, return the iommu_ops.
> +	 */
> +	ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
> +	if (ops)
> +		return ops;
> +
>  	if (dev_is_pci(dev)) {
>  		struct pci_bus *bus = to_pci_dev(dev)->bus;
>  		u32 rid;
> 
> 

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* Re: [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
@ 2017-05-23  9:01                 ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-05-23  9:01 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Nate Watterson
  Cc: robin.murphy, will.deacon, joro, iommu, linux-arm-kernel,
	linux-arm-msm, m.szyprowski, bhelgaas, linux-pci, linux-acpi, tn,
	hanjun.guo, okaya, robh+dt, frowand.list, devicetree,
	linux-kernel, sudeep.holla, rjw, lenb, catalin.marinas, arnd,
	linux-arch, gregkh

Hi Lorenzo,

On 5/23/2017 2:22 PM, Lorenzo Pieralisi wrote:
> On Tue, May 23, 2017 at 02:26:10AM -0400, Nate Watterson wrote:
>> Hi Sricharan,
>>
>> On 4/10/2017 7:21 AM, Sricharan R wrote:
>>> This is an equivalent to the DT's handling of the iommu master's probe
>>> with deferred probing when the corrsponding iommu is not probed yet.
>>> The lack of a registered IOMMU can be caused by the lack of a driver for
>>> the IOMMU, the IOMMU device probe not having been performed yet, having
>>> been deferred, or having failed.
>>>
>>> The first case occurs when the firmware describes the bus master and
>>> IOMMU topology correctly but no device driver exists for the IOMMU yet
>>> or the device driver has not been compiled in. Return NULL, the caller
>>> will configure the device without an IOMMU.
>>>
>>> The second and third cases are handled by deferring the probe of the bus
>>> master device which will eventually get reprobed after the IOMMU.
>>>
>>> The last case is currently handled by deferring the probe of the bus
>>> master device as well. A mechanism to either configure the bus master
>>> device without an IOMMU or to fail the bus master device probe depending
>>> on whether the IOMMU is optional or mandatory would be a good
>>> enhancement.
>>>
>>> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> Reviewed-by: Robin Murphy <robin.murphy@arm.com>
>>> [Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
>>>           called multiple times for same device]
>>> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>>> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
>>> ---
>>>  drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
>>>  drivers/acpi/scan.c        | 11 ++++++++---
>>>  drivers/base/dma-mapping.c |  2 +-
>>>  include/acpi/acpi_bus.h    |  2 +-
>>>  include/linux/acpi.h       |  7 +++++--
>>>  5 files changed, 47 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
>>> index 3dd9ec3..e323ece 100644
>>> --- a/drivers/acpi/arm64/iort.c
>>> +++ b/drivers/acpi/arm64/iort.c
>>> @@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>>>  	const struct iommu_ops *ops = NULL;
>>>  	int ret = -ENODEV;
>>>  	struct fwnode_handle *iort_fwnode;
>>> +	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
>>> +
>>> +	/*
>>> +	 * If we already translated the fwspec there
>>> +	 * is nothing left to do, return the iommu_ops.
>>> +	 */
>>> +	if (fwspec && fwspec->ops)
>>> +		return fwspec->ops;
>>
>> Is this logic strictly required? It breaks masters with multiple SIDs
>> as only the first SID is actually added to the master's fwspec.
> 
> My bad, that's indeed a silly bug I introduced. Please let me know if the
> patch below fixes it, we will send it upstream shortly.
> 

oops, i think emails crossed. Please let me know if you are ok to add this
to the other fixes.

Regards,
 Sricharan

> Lorenzo
> 
> -- >8 --
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index c5fecf9..e326f2a 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -666,14 +666,6 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>  	int ret = -ENODEV;
>  	struct fwnode_handle *iort_fwnode;
>  
> -	/*
> -	 * If we already translated the fwspec there
> -	 * is nothing left to do, return the iommu_ops.
> -	 */
> -	ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
> -	if (ops)
> -		return ops;
> -
>  	if (node) {
>  		iort_fwnode = iort_get_fwnode(node);
>  		if (!iort_fwnode)
> @@ -735,6 +727,14 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
>  	u32 streamid = 0;
>  	int err;
>  
> +	/*
> +	 * If we already translated the fwspec there
> +	 * is nothing left to do, return the iommu_ops.
> +	 */
> +	ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
> +	if (ops)
> +		return ops;
> +
>  	if (dev_is_pci(dev)) {
>  		struct pci_bus *bus = to_pci_dev(dev)->bus;
>  		u32 rid;
> 
> 

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* Re: [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
@ 2017-05-23  9:01                 ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-05-23  9:01 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Nate Watterson
  Cc: catalin.marinas, will.deacon, okaya, frowand.list, m.szyprowski,
	linux-arch, tn, joro, linux-acpi, linux-pci, lenb, devicetree,
	arnd, linux-arm-msm, robh+dt, bhelgaas, linux-arm-kernel, gregkh,
	rjw, linux-kernel, iommu, hanjun.guo, sudeep.holla, robin.murphy

Hi Lorenzo,

On 5/23/2017 2:22 PM, Lorenzo Pieralisi wrote:
> On Tue, May 23, 2017 at 02:26:10AM -0400, Nate Watterson wrote:
>> Hi Sricharan,
>>
>> On 4/10/2017 7:21 AM, Sricharan R wrote:
>>> This is an equivalent to the DT's handling of the iommu master's probe
>>> with deferred probing when the corrsponding iommu is not probed yet.
>>> The lack of a registered IOMMU can be caused by the lack of a driver for
>>> the IOMMU, the IOMMU device probe not having been performed yet, having
>>> been deferred, or having failed.
>>>
>>> The first case occurs when the firmware describes the bus master and
>>> IOMMU topology correctly but no device driver exists for the IOMMU yet
>>> or the device driver has not been compiled in. Return NULL, the caller
>>> will configure the device without an IOMMU.
>>>
>>> The second and third cases are handled by deferring the probe of the bus
>>> master device which will eventually get reprobed after the IOMMU.
>>>
>>> The last case is currently handled by deferring the probe of the bus
>>> master device as well. A mechanism to either configure the bus master
>>> device without an IOMMU or to fail the bus master device probe depending
>>> on whether the IOMMU is optional or mandatory would be a good
>>> enhancement.
>>>
>>> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> Reviewed-by: Robin Murphy <robin.murphy@arm.com>
>>> [Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
>>>           called multiple times for same device]
>>> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>>> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
>>> ---
>>>  drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
>>>  drivers/acpi/scan.c        | 11 ++++++++---
>>>  drivers/base/dma-mapping.c |  2 +-
>>>  include/acpi/acpi_bus.h    |  2 +-
>>>  include/linux/acpi.h       |  7 +++++--
>>>  5 files changed, 47 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
>>> index 3dd9ec3..e323ece 100644
>>> --- a/drivers/acpi/arm64/iort.c
>>> +++ b/drivers/acpi/arm64/iort.c
>>> @@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>>>  	const struct iommu_ops *ops = NULL;
>>>  	int ret = -ENODEV;
>>>  	struct fwnode_handle *iort_fwnode;
>>> +	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
>>> +
>>> +	/*
>>> +	 * If we already translated the fwspec there
>>> +	 * is nothing left to do, return the iommu_ops.
>>> +	 */
>>> +	if (fwspec && fwspec->ops)
>>> +		return fwspec->ops;
>>
>> Is this logic strictly required? It breaks masters with multiple SIDs
>> as only the first SID is actually added to the master's fwspec.
> 
> My bad, that's indeed a silly bug I introduced. Please let me know if the
> patch below fixes it, we will send it upstream shortly.
> 

oops, i think emails crossed. Please let me know if you are ok to add this
to the other fixes.

Regards,
 Sricharan

> Lorenzo
> 
> -- >8 --
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index c5fecf9..e326f2a 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -666,14 +666,6 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>  	int ret = -ENODEV;
>  	struct fwnode_handle *iort_fwnode;
>  
> -	/*
> -	 * If we already translated the fwspec there
> -	 * is nothing left to do, return the iommu_ops.
> -	 */
> -	ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
> -	if (ops)
> -		return ops;
> -
>  	if (node) {
>  		iort_fwnode = iort_get_fwnode(node);
>  		if (!iort_fwnode)
> @@ -735,6 +727,14 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
>  	u32 streamid = 0;
>  	int err;
>  
> +	/*
> +	 * If we already translated the fwspec there
> +	 * is nothing left to do, return the iommu_ops.
> +	 */
> +	ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
> +	if (ops)
> +		return ops;
> +
>  	if (dev_is_pci(dev)) {
>  		struct pci_bus *bus = to_pci_dev(dev)->bus;
>  		u32 rid;
> 
> 

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
@ 2017-05-23  9:01                 ` Sricharan R
  0 siblings, 0 replies; 70+ messages in thread
From: Sricharan R @ 2017-05-23  9:01 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Lorenzo,

On 5/23/2017 2:22 PM, Lorenzo Pieralisi wrote:
> On Tue, May 23, 2017 at 02:26:10AM -0400, Nate Watterson wrote:
>> Hi Sricharan,
>>
>> On 4/10/2017 7:21 AM, Sricharan R wrote:
>>> This is an equivalent to the DT's handling of the iommu master's probe
>>> with deferred probing when the corrsponding iommu is not probed yet.
>>> The lack of a registered IOMMU can be caused by the lack of a driver for
>>> the IOMMU, the IOMMU device probe not having been performed yet, having
>>> been deferred, or having failed.
>>>
>>> The first case occurs when the firmware describes the bus master and
>>> IOMMU topology correctly but no device driver exists for the IOMMU yet
>>> or the device driver has not been compiled in. Return NULL, the caller
>>> will configure the device without an IOMMU.
>>>
>>> The second and third cases are handled by deferring the probe of the bus
>>> master device which will eventually get reprobed after the IOMMU.
>>>
>>> The last case is currently handled by deferring the probe of the bus
>>> master device as well. A mechanism to either configure the bus master
>>> device without an IOMMU or to fail the bus master device probe depending
>>> on whether the IOMMU is optional or mandatory would be a good
>>> enhancement.
>>>
>>> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> Reviewed-by: Robin Murphy <robin.murphy@arm.com>
>>> [Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
>>>           called multiple times for same device]
>>> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>>> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
>>> ---
>>>  drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
>>>  drivers/acpi/scan.c        | 11 ++++++++---
>>>  drivers/base/dma-mapping.c |  2 +-
>>>  include/acpi/acpi_bus.h    |  2 +-
>>>  include/linux/acpi.h       |  7 +++++--
>>>  5 files changed, 47 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
>>> index 3dd9ec3..e323ece 100644
>>> --- a/drivers/acpi/arm64/iort.c
>>> +++ b/drivers/acpi/arm64/iort.c
>>> @@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>>>  	const struct iommu_ops *ops = NULL;
>>>  	int ret = -ENODEV;
>>>  	struct fwnode_handle *iort_fwnode;
>>> +	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
>>> +
>>> +	/*
>>> +	 * If we already translated the fwspec there
>>> +	 * is nothing left to do, return the iommu_ops.
>>> +	 */
>>> +	if (fwspec && fwspec->ops)
>>> +		return fwspec->ops;
>>
>> Is this logic strictly required? It breaks masters with multiple SIDs
>> as only the first SID is actually added to the master's fwspec.
> 
> My bad, that's indeed a silly bug I introduced. Please let me know if the
> patch below fixes it, we will send it upstream shortly.
> 

oops, i think emails crossed. Please let me know if you are ok to add this
to the other fixes.

Regards,
 Sricharan

> Lorenzo
> 
> -- >8 --
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index c5fecf9..e326f2a 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -666,14 +666,6 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>  	int ret = -ENODEV;
>  	struct fwnode_handle *iort_fwnode;
>  
> -	/*
> -	 * If we already translated the fwspec there
> -	 * is nothing left to do, return the iommu_ops.
> -	 */
> -	ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
> -	if (ops)
> -		return ops;
> -
>  	if (node) {
>  		iort_fwnode = iort_get_fwnode(node);
>  		if (!iort_fwnode)
> @@ -735,6 +727,14 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
>  	u32 streamid = 0;
>  	int err;
>  
> +	/*
> +	 * If we already translated the fwspec there
> +	 * is nothing left to do, return the iommu_ops.
> +	 */
> +	ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
> +	if (ops)
> +		return ops;
> +
>  	if (dev_is_pci(dev)) {
>  		struct pci_bus *bus = to_pci_dev(dev)->bus;
>  		u32 rid;
> 
> 

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

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

* Re: [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
  2017-05-23  9:01                 ` Sricharan R
  (?)
  (?)
@ 2017-05-23  9:26                     ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 70+ messages in thread
From: Lorenzo Pieralisi @ 2017-05-23  9:26 UTC (permalink / raw)
  To: Sricharan R
  Cc: catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
	okaya-sgV2jX0FEOL9JmXXK+q4OQ,
	frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
	linux-arch-u79uwXL29TY76Z2rM5mHXA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, lenb-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, bhelgaas-hpIqsD4AKlfQT0dZR+AlfA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	rjw-LthD3rsA81gm4RdzfppkhA, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	sudeep.holla-5wv7dgnIgG8

On Tue, May 23, 2017 at 02:31:17PM +0530, Sricharan R wrote:
> Hi Lorenzo,
> 
> On 5/23/2017 2:22 PM, Lorenzo Pieralisi wrote:
> > On Tue, May 23, 2017 at 02:26:10AM -0400, Nate Watterson wrote:
> >> Hi Sricharan,
> >>
> >> On 4/10/2017 7:21 AM, Sricharan R wrote:
> >>> This is an equivalent to the DT's handling of the iommu master's probe
> >>> with deferred probing when the corrsponding iommu is not probed yet.
> >>> The lack of a registered IOMMU can be caused by the lack of a driver for
> >>> the IOMMU, the IOMMU device probe not having been performed yet, having
> >>> been deferred, or having failed.
> >>>
> >>> The first case occurs when the firmware describes the bus master and
> >>> IOMMU topology correctly but no device driver exists for the IOMMU yet
> >>> or the device driver has not been compiled in. Return NULL, the caller
> >>> will configure the device without an IOMMU.
> >>>
> >>> The second and third cases are handled by deferring the probe of the bus
> >>> master device which will eventually get reprobed after the IOMMU.
> >>>
> >>> The last case is currently handled by deferring the probe of the bus
> >>> master device as well. A mechanism to either configure the bus master
> >>> device without an IOMMU or to fail the bus master device probe depending
> >>> on whether the IOMMU is optional or mandatory would be a good
> >>> enhancement.
> >>>
> >>> Tested-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> >>> Reviewed-by: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
> >>> [Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
> >>>           called multiple times for same device]
> >>> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
> >>> Signed-off-by: Sricharan R <sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
> >>> ---
> >>>  drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
> >>>  drivers/acpi/scan.c        | 11 ++++++++---
> >>>  drivers/base/dma-mapping.c |  2 +-
> >>>  include/acpi/acpi_bus.h    |  2 +-
> >>>  include/linux/acpi.h       |  7 +++++--
> >>>  5 files changed, 47 insertions(+), 8 deletions(-)
> >>>
> >>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> >>> index 3dd9ec3..e323ece 100644
> >>> --- a/drivers/acpi/arm64/iort.c
> >>> +++ b/drivers/acpi/arm64/iort.c
> >>> @@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
> >>>  	const struct iommu_ops *ops = NULL;
> >>>  	int ret = -ENODEV;
> >>>  	struct fwnode_handle *iort_fwnode;
> >>> +	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
> >>> +
> >>> +	/*
> >>> +	 * If we already translated the fwspec there
> >>> +	 * is nothing left to do, return the iommu_ops.
> >>> +	 */
> >>> +	if (fwspec && fwspec->ops)
> >>> +		return fwspec->ops;
> >>
> >> Is this logic strictly required? It breaks masters with multiple SIDs
> >> as only the first SID is actually added to the master's fwspec.
> > 
> > My bad, that's indeed a silly bug I introduced. Please let me know if the
> > patch below fixes it, we will send it upstream shortly.
> > 
> 
> oops, i think emails crossed. Please let me know if you are ok to add
> this to the other fixes.

No worries, yes I am ok thanks but please give Nate some time to report
back to make sure the diff I sent actually fixes the problem.

Apologies for the breakage.

Lorenzo

> 
> Regards,
>  Sricharan
> 

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

* Re: [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
@ 2017-05-23  9:26                     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 70+ messages in thread
From: Lorenzo Pieralisi @ 2017-05-23  9:26 UTC (permalink / raw)
  To: Sricharan R
  Cc: Nate Watterson, robin.murphy, will.deacon, joro, iommu,
	linux-arm-kernel, linux-arm-msm, m.szyprowski, bhelgaas,
	linux-pci, linux-acpi, tn, hanjun.guo, okaya, robh+dt,
	frowand.list, devicetree, linux-kernel, sudeep.holla, rjw, lenb,
	catalin.marinas, arnd, linux-arch, gregkh

On Tue, May 23, 2017 at 02:31:17PM +0530, Sricharan R wrote:
> Hi Lorenzo,
> 
> On 5/23/2017 2:22 PM, Lorenzo Pieralisi wrote:
> > On Tue, May 23, 2017 at 02:26:10AM -0400, Nate Watterson wrote:
> >> Hi Sricharan,
> >>
> >> On 4/10/2017 7:21 AM, Sricharan R wrote:
> >>> This is an equivalent to the DT's handling of the iommu master's probe
> >>> with deferred probing when the corrsponding iommu is not probed yet.
> >>> The lack of a registered IOMMU can be caused by the lack of a driver for
> >>> the IOMMU, the IOMMU device probe not having been performed yet, having
> >>> been deferred, or having failed.
> >>>
> >>> The first case occurs when the firmware describes the bus master and
> >>> IOMMU topology correctly but no device driver exists for the IOMMU yet
> >>> or the device driver has not been compiled in. Return NULL, the caller
> >>> will configure the device without an IOMMU.
> >>>
> >>> The second and third cases are handled by deferring the probe of the bus
> >>> master device which will eventually get reprobed after the IOMMU.
> >>>
> >>> The last case is currently handled by deferring the probe of the bus
> >>> master device as well. A mechanism to either configure the bus master
> >>> device without an IOMMU or to fail the bus master device probe depending
> >>> on whether the IOMMU is optional or mandatory would be a good
> >>> enhancement.
> >>>
> >>> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
> >>> Reviewed-by: Robin Murphy <robin.murphy@arm.com>
> >>> [Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
> >>>           called multiple times for same device]
> >>> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> >>> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> >>> ---
> >>>  drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
> >>>  drivers/acpi/scan.c        | 11 ++++++++---
> >>>  drivers/base/dma-mapping.c |  2 +-
> >>>  include/acpi/acpi_bus.h    |  2 +-
> >>>  include/linux/acpi.h       |  7 +++++--
> >>>  5 files changed, 47 insertions(+), 8 deletions(-)
> >>>
> >>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> >>> index 3dd9ec3..e323ece 100644
> >>> --- a/drivers/acpi/arm64/iort.c
> >>> +++ b/drivers/acpi/arm64/iort.c
> >>> @@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
> >>>  	const struct iommu_ops *ops = NULL;
> >>>  	int ret = -ENODEV;
> >>>  	struct fwnode_handle *iort_fwnode;
> >>> +	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
> >>> +
> >>> +	/*
> >>> +	 * If we already translated the fwspec there
> >>> +	 * is nothing left to do, return the iommu_ops.
> >>> +	 */
> >>> +	if (fwspec && fwspec->ops)
> >>> +		return fwspec->ops;
> >>
> >> Is this logic strictly required? It breaks masters with multiple SIDs
> >> as only the first SID is actually added to the master's fwspec.
> > 
> > My bad, that's indeed a silly bug I introduced. Please let me know if the
> > patch below fixes it, we will send it upstream shortly.
> > 
> 
> oops, i think emails crossed. Please let me know if you are ok to add
> this to the other fixes.

No worries, yes I am ok thanks but please give Nate some time to report
back to make sure the diff I sent actually fixes the problem.

Apologies for the breakage.

Lorenzo

> 
> Regards,
>  Sricharan
> 

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

* Re: [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
@ 2017-05-23  9:26                     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 70+ messages in thread
From: Lorenzo Pieralisi @ 2017-05-23  9:26 UTC (permalink / raw)
  To: Sricharan R
  Cc: catalin.marinas, will.deacon, okaya, frowand.list, m.szyprowski,
	linux-arch, tn, joro, linux-acpi, linux-pci, lenb, devicetree,
	arnd, linux-arm-msm, robh+dt, bhelgaas, linux-arm-kernel, gregkh,
	rjw, linux-kernel, iommu, hanjun.guo, sudeep.holla, robin.murphy,
	Nate Watterson

On Tue, May 23, 2017 at 02:31:17PM +0530, Sricharan R wrote:
> Hi Lorenzo,
> 
> On 5/23/2017 2:22 PM, Lorenzo Pieralisi wrote:
> > On Tue, May 23, 2017 at 02:26:10AM -0400, Nate Watterson wrote:
> >> Hi Sricharan,
> >>
> >> On 4/10/2017 7:21 AM, Sricharan R wrote:
> >>> This is an equivalent to the DT's handling of the iommu master's probe
> >>> with deferred probing when the corrsponding iommu is not probed yet.
> >>> The lack of a registered IOMMU can be caused by the lack of a driver for
> >>> the IOMMU, the IOMMU device probe not having been performed yet, having
> >>> been deferred, or having failed.
> >>>
> >>> The first case occurs when the firmware describes the bus master and
> >>> IOMMU topology correctly but no device driver exists for the IOMMU yet
> >>> or the device driver has not been compiled in. Return NULL, the caller
> >>> will configure the device without an IOMMU.
> >>>
> >>> The second and third cases are handled by deferring the probe of the bus
> >>> master device which will eventually get reprobed after the IOMMU.
> >>>
> >>> The last case is currently handled by deferring the probe of the bus
> >>> master device as well. A mechanism to either configure the bus master
> >>> device without an IOMMU or to fail the bus master device probe depending
> >>> on whether the IOMMU is optional or mandatory would be a good
> >>> enhancement.
> >>>
> >>> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
> >>> Reviewed-by: Robin Murphy <robin.murphy@arm.com>
> >>> [Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
> >>>           called multiple times for same device]
> >>> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> >>> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> >>> ---
> >>>  drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
> >>>  drivers/acpi/scan.c        | 11 ++++++++---
> >>>  drivers/base/dma-mapping.c |  2 +-
> >>>  include/acpi/acpi_bus.h    |  2 +-
> >>>  include/linux/acpi.h       |  7 +++++--
> >>>  5 files changed, 47 insertions(+), 8 deletions(-)
> >>>
> >>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> >>> index 3dd9ec3..e323ece 100644
> >>> --- a/drivers/acpi/arm64/iort.c
> >>> +++ b/drivers/acpi/arm64/iort.c
> >>> @@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
> >>>  	const struct iommu_ops *ops = NULL;
> >>>  	int ret = -ENODEV;
> >>>  	struct fwnode_handle *iort_fwnode;
> >>> +	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
> >>> +
> >>> +	/*
> >>> +	 * If we already translated the fwspec there
> >>> +	 * is nothing left to do, return the iommu_ops.
> >>> +	 */
> >>> +	if (fwspec && fwspec->ops)
> >>> +		return fwspec->ops;
> >>
> >> Is this logic strictly required? It breaks masters with multiple SIDs
> >> as only the first SID is actually added to the master's fwspec.
> > 
> > My bad, that's indeed a silly bug I introduced. Please let me know if the
> > patch below fixes it, we will send it upstream shortly.
> > 
> 
> oops, i think emails crossed. Please let me know if you are ok to add
> this to the other fixes.

No worries, yes I am ok thanks but please give Nate some time to report
back to make sure the diff I sent actually fixes the problem.

Apologies for the breakage.

Lorenzo

> 
> Regards,
>  Sricharan
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
@ 2017-05-23  9:26                     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 70+ messages in thread
From: Lorenzo Pieralisi @ 2017-05-23  9:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, May 23, 2017 at 02:31:17PM +0530, Sricharan R wrote:
> Hi Lorenzo,
> 
> On 5/23/2017 2:22 PM, Lorenzo Pieralisi wrote:
> > On Tue, May 23, 2017 at 02:26:10AM -0400, Nate Watterson wrote:
> >> Hi Sricharan,
> >>
> >> On 4/10/2017 7:21 AM, Sricharan R wrote:
> >>> This is an equivalent to the DT's handling of the iommu master's probe
> >>> with deferred probing when the corrsponding iommu is not probed yet.
> >>> The lack of a registered IOMMU can be caused by the lack of a driver for
> >>> the IOMMU, the IOMMU device probe not having been performed yet, having
> >>> been deferred, or having failed.
> >>>
> >>> The first case occurs when the firmware describes the bus master and
> >>> IOMMU topology correctly but no device driver exists for the IOMMU yet
> >>> or the device driver has not been compiled in. Return NULL, the caller
> >>> will configure the device without an IOMMU.
> >>>
> >>> The second and third cases are handled by deferring the probe of the bus
> >>> master device which will eventually get reprobed after the IOMMU.
> >>>
> >>> The last case is currently handled by deferring the probe of the bus
> >>> master device as well. A mechanism to either configure the bus master
> >>> device without an IOMMU or to fail the bus master device probe depending
> >>> on whether the IOMMU is optional or mandatory would be a good
> >>> enhancement.
> >>>
> >>> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
> >>> Reviewed-by: Robin Murphy <robin.murphy@arm.com>
> >>> [Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
> >>>           called multiple times for same device]
> >>> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> >>> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
> >>> ---
> >>>  drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
> >>>  drivers/acpi/scan.c        | 11 ++++++++---
> >>>  drivers/base/dma-mapping.c |  2 +-
> >>>  include/acpi/acpi_bus.h    |  2 +-
> >>>  include/linux/acpi.h       |  7 +++++--
> >>>  5 files changed, 47 insertions(+), 8 deletions(-)
> >>>
> >>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> >>> index 3dd9ec3..e323ece 100644
> >>> --- a/drivers/acpi/arm64/iort.c
> >>> +++ b/drivers/acpi/arm64/iort.c
> >>> @@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
> >>>  	const struct iommu_ops *ops = NULL;
> >>>  	int ret = -ENODEV;
> >>>  	struct fwnode_handle *iort_fwnode;
> >>> +	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
> >>> +
> >>> +	/*
> >>> +	 * If we already translated the fwspec there
> >>> +	 * is nothing left to do, return the iommu_ops.
> >>> +	 */
> >>> +	if (fwspec && fwspec->ops)
> >>> +		return fwspec->ops;
> >>
> >> Is this logic strictly required? It breaks masters with multiple SIDs
> >> as only the first SID is actually added to the master's fwspec.
> > 
> > My bad, that's indeed a silly bug I introduced. Please let me know if the
> > patch below fixes it, we will send it upstream shortly.
> > 
> 
> oops, i think emails crossed. Please let me know if you are ok to add
> this to the other fixes.

No worries, yes I am ok thanks but please give Nate some time to report
back to make sure the diff I sent actually fixes the problem.

Apologies for the breakage.

Lorenzo

> 
> Regards,
>  Sricharan
> 

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

* Re: [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
  2017-05-23  9:26                     ` Lorenzo Pieralisi
  (?)
  (?)
@ 2017-05-23 11:27                       ` Nate Watterson
  -1 siblings, 0 replies; 70+ messages in thread
From: Nate Watterson @ 2017-05-23 11:27 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Sricharan R
  Cc: catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
	okaya-sgV2jX0FEOL9JmXXK+q4OQ,
	frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
	linux-arch-u79uwXL29TY76Z2rM5mHXA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, lenb-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, bhelgaas-hpIqsD4AKlfQT0dZR+AlfA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	rjw-LthD3rsA81gm4RdzfppkhA, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	sudeep.holla-5wv7dgnIgG8

Hi Lorenzo,

On 5/23/2017 5:26 AM, Lorenzo Pieralisi wrote:
> On Tue, May 23, 2017 at 02:31:17PM +0530, Sricharan R wrote:
>> Hi Lorenzo,
>>
>> On 5/23/2017 2:22 PM, Lorenzo Pieralisi wrote:
>>> On Tue, May 23, 2017 at 02:26:10AM -0400, Nate Watterson wrote:
>>>> Hi Sricharan,
>>>>
>>>> On 4/10/2017 7:21 AM, Sricharan R wrote:
>>>>> This is an equivalent to the DT's handling of the iommu master's probe
>>>>> with deferred probing when the corrsponding iommu is not probed yet.
>>>>> The lack of a registered IOMMU can be caused by the lack of a driver for
>>>>> the IOMMU, the IOMMU device probe not having been performed yet, having
>>>>> been deferred, or having failed.
>>>>>
>>>>> The first case occurs when the firmware describes the bus master and
>>>>> IOMMU topology correctly but no device driver exists for the IOMMU yet
>>>>> or the device driver has not been compiled in. Return NULL, the caller
>>>>> will configure the device without an IOMMU.
>>>>>
>>>>> The second and third cases are handled by deferring the probe of the bus
>>>>> master device which will eventually get reprobed after the IOMMU.
>>>>>
>>>>> The last case is currently handled by deferring the probe of the bus
>>>>> master device as well. A mechanism to either configure the bus master
>>>>> device without an IOMMU or to fail the bus master device probe depending
>>>>> on whether the IOMMU is optional or mandatory would be a good
>>>>> enhancement.
>>>>>
>>>>> Tested-by: Hanjun Guo <hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>>>>> Reviewed-by: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
>>>>> [Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
>>>>>            called multiple times for same device]
>>>>> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
>>>>> Signed-off-by: Sricharan R <sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
>>>>> ---
>>>>>   drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
>>>>>   drivers/acpi/scan.c        | 11 ++++++++---
>>>>>   drivers/base/dma-mapping.c |  2 +-
>>>>>   include/acpi/acpi_bus.h    |  2 +-
>>>>>   include/linux/acpi.h       |  7 +++++--
>>>>>   5 files changed, 47 insertions(+), 8 deletions(-)
>>>>>
>>>>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
>>>>> index 3dd9ec3..e323ece 100644
>>>>> --- a/drivers/acpi/arm64/iort.c
>>>>> +++ b/drivers/acpi/arm64/iort.c
>>>>> @@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>>>>>   	const struct iommu_ops *ops = NULL;
>>>>>   	int ret = -ENODEV;
>>>>>   	struct fwnode_handle *iort_fwnode;
>>>>> +	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
>>>>> +
>>>>> +	/*
>>>>> +	 * If we already translated the fwspec there
>>>>> +	 * is nothing left to do, return the iommu_ops.
>>>>> +	 */
>>>>> +	if (fwspec && fwspec->ops)
>>>>> +		return fwspec->ops;
>>>>
>>>> Is this logic strictly required? It breaks masters with multiple SIDs
>>>> as only the first SID is actually added to the master's fwspec.
>>>
>>> My bad, that's indeed a silly bug I introduced. Please let me know if the
>>> patch below fixes it, we will send it upstream shortly.
>>>
>>
>> oops, i think emails crossed. Please let me know if you are ok to add
>> this to the other fixes.
> 
> No worries, yes I am ok thanks but please give Nate some time to report
> back to make sure the diff I sent actually fixes the problem.

The patch you sent fixes the problem. Thanks for the quick turnaround.

> 
> Apologies for the breakage.
> 
> Lorenzo
> 
>>
>> Regards,
>>   Sricharan
>>

-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

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

* Re: [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
@ 2017-05-23 11:27                       ` Nate Watterson
  0 siblings, 0 replies; 70+ messages in thread
From: Nate Watterson @ 2017-05-23 11:27 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Sricharan R
  Cc: robin.murphy, will.deacon, joro, iommu, linux-arm-kernel,
	linux-arm-msm, m.szyprowski, bhelgaas, linux-pci, linux-acpi, tn,
	hanjun.guo, okaya, robh+dt, frowand.list, devicetree,
	linux-kernel, sudeep.holla, rjw, lenb, catalin.marinas, arnd,
	linux-arch, gregkh

Hi Lorenzo,

On 5/23/2017 5:26 AM, Lorenzo Pieralisi wrote:
> On Tue, May 23, 2017 at 02:31:17PM +0530, Sricharan R wrote:
>> Hi Lorenzo,
>>
>> On 5/23/2017 2:22 PM, Lorenzo Pieralisi wrote:
>>> On Tue, May 23, 2017 at 02:26:10AM -0400, Nate Watterson wrote:
>>>> Hi Sricharan,
>>>>
>>>> On 4/10/2017 7:21 AM, Sricharan R wrote:
>>>>> This is an equivalent to the DT's handling of the iommu master's probe
>>>>> with deferred probing when the corrsponding iommu is not probed yet.
>>>>> The lack of a registered IOMMU can be caused by the lack of a driver for
>>>>> the IOMMU, the IOMMU device probe not having been performed yet, having
>>>>> been deferred, or having failed.
>>>>>
>>>>> The first case occurs when the firmware describes the bus master and
>>>>> IOMMU topology correctly but no device driver exists for the IOMMU yet
>>>>> or the device driver has not been compiled in. Return NULL, the caller
>>>>> will configure the device without an IOMMU.
>>>>>
>>>>> The second and third cases are handled by deferring the probe of the bus
>>>>> master device which will eventually get reprobed after the IOMMU.
>>>>>
>>>>> The last case is currently handled by deferring the probe of the bus
>>>>> master device as well. A mechanism to either configure the bus master
>>>>> device without an IOMMU or to fail the bus master device probe depending
>>>>> on whether the IOMMU is optional or mandatory would be a good
>>>>> enhancement.
>>>>>
>>>>> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
>>>>> Reviewed-by: Robin Murphy <robin.murphy@arm.com>
>>>>> [Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
>>>>>            called multiple times for same device]
>>>>> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>>>>> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
>>>>> ---
>>>>>   drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
>>>>>   drivers/acpi/scan.c        | 11 ++++++++---
>>>>>   drivers/base/dma-mapping.c |  2 +-
>>>>>   include/acpi/acpi_bus.h    |  2 +-
>>>>>   include/linux/acpi.h       |  7 +++++--
>>>>>   5 files changed, 47 insertions(+), 8 deletions(-)
>>>>>
>>>>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
>>>>> index 3dd9ec3..e323ece 100644
>>>>> --- a/drivers/acpi/arm64/iort.c
>>>>> +++ b/drivers/acpi/arm64/iort.c
>>>>> @@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>>>>>   	const struct iommu_ops *ops = NULL;
>>>>>   	int ret = -ENODEV;
>>>>>   	struct fwnode_handle *iort_fwnode;
>>>>> +	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
>>>>> +
>>>>> +	/*
>>>>> +	 * If we already translated the fwspec there
>>>>> +	 * is nothing left to do, return the iommu_ops.
>>>>> +	 */
>>>>> +	if (fwspec && fwspec->ops)
>>>>> +		return fwspec->ops;
>>>>
>>>> Is this logic strictly required? It breaks masters with multiple SIDs
>>>> as only the first SID is actually added to the master's fwspec.
>>>
>>> My bad, that's indeed a silly bug I introduced. Please let me know if the
>>> patch below fixes it, we will send it upstream shortly.
>>>
>>
>> oops, i think emails crossed. Please let me know if you are ok to add
>> this to the other fixes.
> 
> No worries, yes I am ok thanks but please give Nate some time to report
> back to make sure the diff I sent actually fixes the problem.

The patch you sent fixes the problem. Thanks for the quick turnaround.

> 
> Apologies for the breakage.
> 
> Lorenzo
> 
>>
>> Regards,
>>   Sricharan
>>

-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

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

* Re: [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
@ 2017-05-23 11:27                       ` Nate Watterson
  0 siblings, 0 replies; 70+ messages in thread
From: Nate Watterson @ 2017-05-23 11:27 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Sricharan R
  Cc: catalin.marinas, will.deacon, okaya, frowand.list, m.szyprowski,
	linux-arch, tn, joro, linux-acpi, linux-pci, lenb, devicetree,
	arnd, linux-arm-msm, robh+dt, bhelgaas, linux-arm-kernel, gregkh,
	rjw, linux-kernel, iommu, hanjun.guo, sudeep.holla, robin.murphy

Hi Lorenzo,

On 5/23/2017 5:26 AM, Lorenzo Pieralisi wrote:
> On Tue, May 23, 2017 at 02:31:17PM +0530, Sricharan R wrote:
>> Hi Lorenzo,
>>
>> On 5/23/2017 2:22 PM, Lorenzo Pieralisi wrote:
>>> On Tue, May 23, 2017 at 02:26:10AM -0400, Nate Watterson wrote:
>>>> Hi Sricharan,
>>>>
>>>> On 4/10/2017 7:21 AM, Sricharan R wrote:
>>>>> This is an equivalent to the DT's handling of the iommu master's probe
>>>>> with deferred probing when the corrsponding iommu is not probed yet.
>>>>> The lack of a registered IOMMU can be caused by the lack of a driver for
>>>>> the IOMMU, the IOMMU device probe not having been performed yet, having
>>>>> been deferred, or having failed.
>>>>>
>>>>> The first case occurs when the firmware describes the bus master and
>>>>> IOMMU topology correctly but no device driver exists for the IOMMU yet
>>>>> or the device driver has not been compiled in. Return NULL, the caller
>>>>> will configure the device without an IOMMU.
>>>>>
>>>>> The second and third cases are handled by deferring the probe of the bus
>>>>> master device which will eventually get reprobed after the IOMMU.
>>>>>
>>>>> The last case is currently handled by deferring the probe of the bus
>>>>> master device as well. A mechanism to either configure the bus master
>>>>> device without an IOMMU or to fail the bus master device probe depending
>>>>> on whether the IOMMU is optional or mandatory would be a good
>>>>> enhancement.
>>>>>
>>>>> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
>>>>> Reviewed-by: Robin Murphy <robin.murphy@arm.com>
>>>>> [Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
>>>>>            called multiple times for same device]
>>>>> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>>>>> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
>>>>> ---
>>>>>   drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
>>>>>   drivers/acpi/scan.c        | 11 ++++++++---
>>>>>   drivers/base/dma-mapping.c |  2 +-
>>>>>   include/acpi/acpi_bus.h    |  2 +-
>>>>>   include/linux/acpi.h       |  7 +++++--
>>>>>   5 files changed, 47 insertions(+), 8 deletions(-)
>>>>>
>>>>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
>>>>> index 3dd9ec3..e323ece 100644
>>>>> --- a/drivers/acpi/arm64/iort.c
>>>>> +++ b/drivers/acpi/arm64/iort.c
>>>>> @@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>>>>>   	const struct iommu_ops *ops = NULL;
>>>>>   	int ret = -ENODEV;
>>>>>   	struct fwnode_handle *iort_fwnode;
>>>>> +	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
>>>>> +
>>>>> +	/*
>>>>> +	 * If we already translated the fwspec there
>>>>> +	 * is nothing left to do, return the iommu_ops.
>>>>> +	 */
>>>>> +	if (fwspec && fwspec->ops)
>>>>> +		return fwspec->ops;
>>>>
>>>> Is this logic strictly required? It breaks masters with multiple SIDs
>>>> as only the first SID is actually added to the master's fwspec.
>>>
>>> My bad, that's indeed a silly bug I introduced. Please let me know if the
>>> patch below fixes it, we will send it upstream shortly.
>>>
>>
>> oops, i think emails crossed. Please let me know if you are ok to add
>> this to the other fixes.
> 
> No worries, yes I am ok thanks but please give Nate some time to report
> back to make sure the diff I sent actually fixes the problem.

The patch you sent fixes the problem. Thanks for the quick turnaround.

> 
> Apologies for the breakage.
> 
> Lorenzo
> 
>>
>> Regards,
>>   Sricharan
>>

-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH V11 08/11] drivers: acpi: Handle IOMMU lookup failure with deferred probing or error
@ 2017-05-23 11:27                       ` Nate Watterson
  0 siblings, 0 replies; 70+ messages in thread
From: Nate Watterson @ 2017-05-23 11:27 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Lorenzo,

On 5/23/2017 5:26 AM, Lorenzo Pieralisi wrote:
> On Tue, May 23, 2017 at 02:31:17PM +0530, Sricharan R wrote:
>> Hi Lorenzo,
>>
>> On 5/23/2017 2:22 PM, Lorenzo Pieralisi wrote:
>>> On Tue, May 23, 2017 at 02:26:10AM -0400, Nate Watterson wrote:
>>>> Hi Sricharan,
>>>>
>>>> On 4/10/2017 7:21 AM, Sricharan R wrote:
>>>>> This is an equivalent to the DT's handling of the iommu master's probe
>>>>> with deferred probing when the corrsponding iommu is not probed yet.
>>>>> The lack of a registered IOMMU can be caused by the lack of a driver for
>>>>> the IOMMU, the IOMMU device probe not having been performed yet, having
>>>>> been deferred, or having failed.
>>>>>
>>>>> The first case occurs when the firmware describes the bus master and
>>>>> IOMMU topology correctly but no device driver exists for the IOMMU yet
>>>>> or the device driver has not been compiled in. Return NULL, the caller
>>>>> will configure the device without an IOMMU.
>>>>>
>>>>> The second and third cases are handled by deferring the probe of the bus
>>>>> master device which will eventually get reprobed after the IOMMU.
>>>>>
>>>>> The last case is currently handled by deferring the probe of the bus
>>>>> master device as well. A mechanism to either configure the bus master
>>>>> device without an IOMMU or to fail the bus master device probe depending
>>>>> on whether the IOMMU is optional or mandatory would be a good
>>>>> enhancement.
>>>>>
>>>>> Tested-by: Hanjun Guo <hanjun.guo@linaro.org>
>>>>> Reviewed-by: Robin Murphy <robin.murphy@arm.com>
>>>>> [Lorenzo: Added fixes for dma_coherent_mask overflow, acpi_dma_configure
>>>>>            called multiple times for same device]
>>>>> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>>>>> Signed-off-by: Sricharan R <sricharan@codeaurora.org>
>>>>> ---
>>>>>   drivers/acpi/arm64/iort.c  | 33 ++++++++++++++++++++++++++++++++-
>>>>>   drivers/acpi/scan.c        | 11 ++++++++---
>>>>>   drivers/base/dma-mapping.c |  2 +-
>>>>>   include/acpi/acpi_bus.h    |  2 +-
>>>>>   include/linux/acpi.h       |  7 +++++--
>>>>>   5 files changed, 47 insertions(+), 8 deletions(-)
>>>>>
>>>>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
>>>>> index 3dd9ec3..e323ece 100644
>>>>> --- a/drivers/acpi/arm64/iort.c
>>>>> +++ b/drivers/acpi/arm64/iort.c
>>>>> @@ -543,6 +543,14 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
>>>>>   	const struct iommu_ops *ops = NULL;
>>>>>   	int ret = -ENODEV;
>>>>>   	struct fwnode_handle *iort_fwnode;
>>>>> +	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
>>>>> +
>>>>> +	/*
>>>>> +	 * If we already translated the fwspec there
>>>>> +	 * is nothing left to do, return the iommu_ops.
>>>>> +	 */
>>>>> +	if (fwspec && fwspec->ops)
>>>>> +		return fwspec->ops;
>>>>
>>>> Is this logic strictly required? It breaks masters with multiple SIDs
>>>> as only the first SID is actually added to the master's fwspec.
>>>
>>> My bad, that's indeed a silly bug I introduced. Please let me know if the
>>> patch below fixes it, we will send it upstream shortly.
>>>
>>
>> oops, i think emails crossed. Please let me know if you are ok to add
>> this to the other fixes.
> 
> No worries, yes I am ok thanks but please give Nate some time to report
> back to make sure the diff I sent actually fixes the problem.

The patch you sent fixes the problem. Thanks for the quick turnaround.

> 
> Apologies for the breakage.
> 
> Lorenzo
> 
>>
>> Regards,
>>   Sricharan
>>

-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

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

end of thread, other threads:[~2017-05-23 11:27 UTC | newest]

Thread overview: 70+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CGME20170410112136epcas2p2cdd7dc21a8dc0ffcfab7f8290c4b7467@epcas2p2.samsung.com>
2017-04-10 11:20 ` [PATCH V11 00/11] IOMMU probe deferral support Sricharan R
2017-04-10 11:20   ` Sricharan R
2017-04-10 11:20   ` [PATCH V11 01/11] iommu/of: Refactor of_iommu_configure() for error handling Sricharan R
2017-04-10 11:20     ` Sricharan R
2017-04-10 11:20     ` Sricharan R
2017-04-10 11:20   ` [PATCH V11 02/11] iommu/of: Prepare for deferred IOMMU configuration Sricharan R
2017-04-10 11:20     ` Sricharan R
2017-04-10 11:20     ` Sricharan R
2017-04-10 11:20   ` [PATCH V11 03/11] of: dma: Make of_dma_deconfigure() public Sricharan R
2017-04-10 11:20     ` Sricharan R
2017-04-10 11:20     ` Sricharan R
2017-04-10 11:20   ` [PATCH V11 04/11] ACPI/IORT: Add function to check SMMUs drivers presence Sricharan R
2017-04-10 11:20     ` Sricharan R
2017-04-10 11:20     ` Sricharan R
2017-04-10 11:21   ` [PATCH V11 05/11] of: device: Fix overflow of coherent_dma_mask Sricharan R
2017-04-10 11:21     ` Sricharan R
     [not found]   ` <1491823266-1209-1-git-send-email-sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2017-04-10 11:21     ` [PATCH V11 06/11] of/acpi: Configure dma operations at probe time for platform/amba/pci bus devices Sricharan R
2017-04-10 11:21       ` Sricharan R
2017-04-10 11:21       ` Sricharan R
2017-04-10 11:21       ` Sricharan R
2017-04-10 11:21     ` [PATCH V11 07/11] iommu: of: Handle IOMMU lookup failure with deferred probing or error Sricharan R
2017-04-10 11:21       ` Sricharan R
2017-04-10 11:21       ` Sricharan R
2017-04-10 11:21       ` Sricharan R
2017-04-10 11:21     ` [PATCH V11 08/11] drivers: acpi: " Sricharan R
2017-04-10 11:21       ` Sricharan R
2017-04-10 11:21       ` Sricharan R
     [not found]       ` <1491823266-1209-9-git-send-email-sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2017-05-23  6:26         ` Nate Watterson
2017-05-23  6:26           ` Nate Watterson
2017-05-23  6:26           ` Nate Watterson
2017-05-23  6:26           ` Nate Watterson
     [not found]           ` <41668eff-271c-1c4c-7665-3bf0faa74669-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2017-05-23  8:52             ` Lorenzo Pieralisi
2017-05-23  8:52               ` Lorenzo Pieralisi
2017-05-23  8:52               ` Lorenzo Pieralisi
2017-05-23  8:52               ` Lorenzo Pieralisi
2017-05-23  9:01               ` Sricharan R
2017-05-23  9:01                 ` Sricharan R
2017-05-23  9:01                 ` Sricharan R
2017-05-23  9:01                 ` Sricharan R
     [not found]                 ` <c6d5c033-a8f9-03e3-9963-cd291ae2d7e1-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2017-05-23  9:26                   ` Lorenzo Pieralisi
2017-05-23  9:26                     ` Lorenzo Pieralisi
2017-05-23  9:26                     ` Lorenzo Pieralisi
2017-05-23  9:26                     ` Lorenzo Pieralisi
2017-05-23 11:27                     ` Nate Watterson
2017-05-23 11:27                       ` Nate Watterson
2017-05-23 11:27                       ` Nate Watterson
2017-05-23 11:27                       ` Nate Watterson
2017-05-23  8:59             ` Sricharan R
2017-05-23  8:59               ` Sricharan R
2017-05-23  8:59               ` Sricharan R
2017-05-23  8:59               ` Sricharan R
2017-04-10 11:21     ` [PATCH V11 09/11] arm64: dma-mapping: Remove the notifier trick to handle early setting of dma_ops Sricharan R
2017-04-10 11:21       ` Sricharan R
2017-04-10 11:21       ` Sricharan R
2017-04-10 11:21     ` [PATCH V11 10/11] iommu/arm-smmu: Clean up early-probing workarounds Sricharan R
2017-04-10 11:21       ` Sricharan R
2017-04-10 11:21       ` Sricharan R
2017-04-10 11:21     ` [PATCH V11 11/11] ACPI/IORT: Remove linker section for IORT entries probing Sricharan R
2017-04-10 11:21       ` Sricharan R
2017-04-10 11:21       ` Sricharan R
2017-04-20 14:31     ` [PATCH V11 00/11] IOMMU probe deferral support Joerg Roedel
2017-04-20 14:31       ` Joerg Roedel
2017-04-20 14:31       ` Joerg Roedel
2017-04-10 11:56   ` Frank Rowand
2017-04-10 11:56     ` Frank Rowand
2017-05-08 11:23   ` Marek Szyprowski
2017-05-08 11:23     ` Marek Szyprowski
2017-05-08 11:23     ` Marek Szyprowski
2017-05-08 14:57     ` Sricharan R
2017-05-08 14:57       ` Sricharan R

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.