aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/of_iommu.c
diff options
context:
space:
mode:
authorRobin Murphy <robin.murphy@arm.com>2016-09-13 05:54:14 -0400
committerWill Deacon <will.deacon@arm.com>2016-09-16 04:34:15 -0400
commit57f98d2f61e191ef9d06863c9ce3f8621f3671ef (patch)
treefd6d52282bcada86b0893b9972eaa5b8a5f219e1 /drivers/iommu/of_iommu.c
parentb996444cf35e736621855e73f9d0762bd49f41f2 (diff)
iommu: Introduce iommu_fwspec
Introduce a common structure to hold the per-device firmware data that most IOMMU drivers need to keep track of. This enables us to configure much of that data from common firmware code, and consolidate a lot of the equivalent implementations, device look-up tables, etc. which are currently strewn across IOMMU drivers. This will also be enable us to address the outstanding "multiple IOMMUs on the platform bus" problem by tweaking IOMMU API calls to prefer dev->fwspec->ops before falling back to dev->bus->iommu_ops, and thus gracefully handle those troublesome systems which we currently cannot. As the first user, hook up the OF IOMMU configuration mechanism. The driver-defined nature of DT cells means that we still need the drivers to translate and add the IDs themselves, but future users such as the much less free-form ACPI IORT will be much simpler and self-contained. CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Suggested-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'drivers/iommu/of_iommu.c')
-rw-r--r--drivers/iommu/of_iommu.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 19e1e8f2f871..5b82862f571f 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -167,7 +167,9 @@ static const struct iommu_ops
167 return NULL; 167 return NULL;
168 168
169 ops = of_iommu_get_ops(iommu_spec.np); 169 ops = of_iommu_get_ops(iommu_spec.np);
170 if (!ops || !ops->of_xlate || ops->of_xlate(&pdev->dev, &iommu_spec)) 170 if (!ops || !ops->of_xlate ||
171 iommu_fwspec_init(&pdev->dev, &iommu_spec.np->fwnode, ops) ||
172 ops->of_xlate(&pdev->dev, &iommu_spec))
171 ops = NULL; 173 ops = NULL;
172 174
173 of_node_put(iommu_spec.np); 175 of_node_put(iommu_spec.np);
@@ -196,7 +198,9 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
196 np = iommu_spec.np; 198 np = iommu_spec.np;
197 ops = of_iommu_get_ops(np); 199 ops = of_iommu_get_ops(np);
198 200
199 if (!ops || !ops->of_xlate || ops->of_xlate(dev, &iommu_spec)) 201 if (!ops || !ops->of_xlate ||
202 iommu_fwspec_init(dev, &np->fwnode, ops) ||
203 ops->of_xlate(dev, &iommu_spec))
200 goto err_put_node; 204 goto err_put_node;
201 205
202 of_node_put(np); 206 of_node_put(np);