]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/gpu/drm/msm/msm_iommu.c
drm: msm: Add ASoC generic hdmi audio codec support.
[karo-tx-linux.git] / drivers / gpu / drm / msm / msm_iommu.c
index 7ac2f1997e4a4cbe4e57003f001928bba8a2c490..f033d48cd1f31c01cd6659a4ae293618f62cf6bf 100644 (file)
@@ -18,6 +18,8 @@
 #include "msm_drv.h"
 #include "msm_mmu.h"
 
+#define DUMMY_CONTEXT 0x1
+
 struct msm_iommu {
        struct msm_mmu base;
        struct iommu_domain *domain;
@@ -33,14 +35,51 @@ static int msm_fault_handler(struct iommu_domain *iommu, struct device *dev,
 
 static int msm_iommu_attach(struct msm_mmu *mmu, const char **names, int cnt)
 {
+       struct device *dev = mmu->dev;
        struct msm_iommu *iommu = to_msm_iommu(mmu);
-       return iommu_attach_device(iommu->domain, mmu->dev);
+       int i, ret;
+
+       for (i = 0; i < cnt; i++) {
+               struct device *msm_iommu_get_ctx(const char *ctx_name);
+               struct device *ctx = msm_iommu_get_ctx(names[i]);
+               if (IS_ERR_OR_NULL(ctx)) {
+                       dev_warn(dev, "couldn't get %s context", names[i]);
+                       continue;
+               }
+
+               if (ctx == (struct device *)DUMMY_CONTEXT) {
+                       return iommu_attach_device(iommu->domain, mmu->dev);
+               } else {
+                       ret = iommu_attach_device(iommu->domain, ctx);
+               }
+
+               if (ret) {
+                       dev_warn(dev, "could not attach iommu to %s", names[i]);
+                       return ret;
+               }
+       }
+
+       return 0;
 }
 
 static void msm_iommu_detach(struct msm_mmu *mmu, const char **names, int cnt)
 {
        struct msm_iommu *iommu = to_msm_iommu(mmu);
-       iommu_detach_device(iommu->domain, mmu->dev);
+       int i;
+
+       for (i = 0; i < cnt; i++) {
+               struct device *msm_iommu_get_ctx(const char *ctx_name);
+               struct device *ctx = msm_iommu_get_ctx(names[i]);
+               if (IS_ERR_OR_NULL(ctx))
+                       continue;
+
+               if (ctx == (struct device *)DUMMY_CONTEXT) {
+                       iommu_detach_device(iommu->domain, mmu->dev);
+                       break;
+               } else {
+                       iommu_detach_device(iommu->domain, ctx);
+               }
+       }
 }
 
 static int msm_iommu_map(struct msm_mmu *mmu, uint32_t iova,