aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/host1x/dev.c
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2018-05-14 05:14:00 -0400
committerThierry Reding <treding@nvidia.com>2018-05-17 11:44:48 -0400
commitf40e1590c5270e5559fb95a5a0a7c1f5266a522d (patch)
tree15ca7fa9e087653bb225d3667cecf37b2dac9071 /drivers/gpu/host1x/dev.c
parent24cfdc1ac7d4260aa8416505b9cb6316c9e89021 (diff)
gpu: host1x: Acquire a reference to the IOVA cache
The IOVA API uses a memory cache to allocate IOVA nodes from. To make sure that this cache is available, obtain a reference to it and release the reference when the cache is no longer needed. On 64-bit ARM this is hidden by the fact that the DMA mapping API gets that reference and never releases it. On 32-bit ARM, this is papered over by the Tegra DRM driver (the sole user of the host1x API requiring the cache) acquiring a reference to the IOVA cache for its own purposes. However, there may be additional users of this API in the future, so fix this upfront to avoid surprises. Fixes: 404bfb78daf3 ("gpu: host1x: Add IOMMU support") Reviewed-by: Dmitry Osipenko <digetx@gmail.com> Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/gpu/host1x/dev.c')
-rw-r--r--drivers/gpu/host1x/dev.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 03db71173f5d..f1d5f76e9c33 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -223,10 +223,14 @@ static int host1x_probe(struct platform_device *pdev)
223 struct iommu_domain_geometry *geometry; 223 struct iommu_domain_geometry *geometry;
224 unsigned long order; 224 unsigned long order;
225 225
226 err = iova_cache_get();
227 if (err < 0)
228 goto put_group;
229
226 host->domain = iommu_domain_alloc(&platform_bus_type); 230 host->domain = iommu_domain_alloc(&platform_bus_type);
227 if (!host->domain) { 231 if (!host->domain) {
228 err = -ENOMEM; 232 err = -ENOMEM;
229 goto put_group; 233 goto put_cache;
230 } 234 }
231 235
232 err = iommu_attach_group(host->domain, host->group); 236 err = iommu_attach_group(host->domain, host->group);
@@ -234,6 +238,7 @@ static int host1x_probe(struct platform_device *pdev)
234 if (err == -ENODEV) { 238 if (err == -ENODEV) {
235 iommu_domain_free(host->domain); 239 iommu_domain_free(host->domain);
236 host->domain = NULL; 240 host->domain = NULL;
241 iova_cache_put();
237 iommu_group_put(host->group); 242 iommu_group_put(host->group);
238 host->group = NULL; 243 host->group = NULL;
239 goto skip_iommu; 244 goto skip_iommu;
@@ -308,6 +313,9 @@ fail_detach_device:
308fail_free_domain: 313fail_free_domain:
309 if (host->domain) 314 if (host->domain)
310 iommu_domain_free(host->domain); 315 iommu_domain_free(host->domain);
316put_cache:
317 if (host->group)
318 iova_cache_put();
311put_group: 319put_group:
312 iommu_group_put(host->group); 320 iommu_group_put(host->group);
313 321
@@ -328,6 +336,7 @@ static int host1x_remove(struct platform_device *pdev)
328 put_iova_domain(&host->iova); 336 put_iova_domain(&host->iova);
329 iommu_detach_group(host->domain, host->group); 337 iommu_detach_group(host->domain, host->group);
330 iommu_domain_free(host->domain); 338 iommu_domain_free(host->domain);
339 iova_cache_put();
331 iommu_group_put(host->group); 340 iommu_group_put(host->group);
332 } 341 }
333 342