gpu: host1x: Use IOMMU groups
authorThierry Reding <treding@nvidia.com>
Tue, 14 Nov 2017 15:11:28 +0000 (16:11 +0100)
committerThierry Reding <treding@nvidia.com>
Thu, 21 Dec 2017 13:52:36 +0000 (14:52 +0100)
Use IOMMU groups to attach the host1x device to its IOMMU domain. This
is not strictly necessary because the domain isn't shared with any other
device, but it makes the code consistent with how IOMMU is handled in
other drivers and provides an easy way to detect when no IOMMU has been
attached via device tree.

Signed-off-by: Thierry Reding <treding@nvidia.com>
drivers/gpu/host1x/dev.c
drivers/gpu/host1x/dev.h

index 1f916b579e9555b938ac981c3163fe8d1ca5a085..03db71173f5ded9cd0448bd441cf8c0378b18b16 100644 (file)
@@ -218,19 +218,24 @@ static int host1x_probe(struct platform_device *pdev)
                return err;
        }
 
-       if (iommu_present(&platform_bus_type)) {
+       host->group = iommu_group_get(&pdev->dev);
+       if (host->group) {
                struct iommu_domain_geometry *geometry;
                unsigned long order;
 
                host->domain = iommu_domain_alloc(&platform_bus_type);
-               if (!host->domain)
-                       return -ENOMEM;
+               if (!host->domain) {
+                       err = -ENOMEM;
+                       goto put_group;
+               }
 
-               err = iommu_attach_device(host->domain, &pdev->dev);
+               err = iommu_attach_group(host->domain, host->group);
                if (err) {
                        if (err == -ENODEV) {
                                iommu_domain_free(host->domain);
                                host->domain = NULL;
+                               iommu_group_put(host->group);
+                               host->group = NULL;
                                goto skip_iommu;
                        }
 
@@ -296,13 +301,15 @@ fail_unprepare_disable:
 fail_free_channels:
        host1x_channel_list_free(&host->channel_list);
 fail_detach_device:
-       if (host->domain) {
+       if (host->group && host->domain) {
                put_iova_domain(&host->iova);
-               iommu_detach_device(host->domain, &pdev->dev);
+               iommu_detach_group(host->domain, host->group);
        }
 fail_free_domain:
        if (host->domain)
                iommu_domain_free(host->domain);
+put_group:
+       iommu_group_put(host->group);
 
        return err;
 }
@@ -319,8 +326,9 @@ static int host1x_remove(struct platform_device *pdev)
 
        if (host->domain) {
                put_iova_domain(&host->iova);
-               iommu_detach_device(host->domain, &pdev->dev);
+               iommu_detach_group(host->domain, host->group);
                iommu_domain_free(host->domain);
+               iommu_group_put(host->group);
        }
 
        return 0;
index 50276972648060cc81d6ba0a12c42998904c019d..43e9fabb43a1f5bdf2f3e7e5ca37451934aba70d 100644 (file)
@@ -117,6 +117,7 @@ struct host1x {
        struct clk *clk;
        struct reset_control *rst;
 
+       struct iommu_group *group;
        struct iommu_domain *domain;
        struct iova_domain iova;
        dma_addr_t iova_end;