|
@@ -49,6 +49,61 @@ static inline void __exynos_iommu_detach(struct exynos_drm_private *priv,
|
|
arm_iommu_detach_device(dev);
|
|
arm_iommu_detach_device(dev);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#elif defined(CONFIG_IOMMU_DMA)
|
|
|
|
+#include <linux/dma-iommu.h>
|
|
|
|
+
|
|
|
|
+static inline int __exynos_iommu_create_mapping(struct exynos_drm_private *priv,
|
|
|
|
+ unsigned long start, unsigned long size)
|
|
|
|
+{
|
|
|
|
+ struct iommu_domain *domain;
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ domain = iommu_domain_alloc(priv->dma_dev->bus);
|
|
|
|
+ if (!domain)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+
|
|
|
|
+ ret = iommu_get_dma_cookie(domain);
|
|
|
|
+ if (ret)
|
|
|
|
+ goto free_domain;
|
|
|
|
+
|
|
|
|
+ ret = iommu_dma_init_domain(domain, start, size);
|
|
|
|
+ if (ret)
|
|
|
|
+ goto put_cookie;
|
|
|
|
+
|
|
|
|
+ priv->mapping = domain;
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+put_cookie:
|
|
|
|
+ iommu_put_dma_cookie(domain);
|
|
|
|
+free_domain:
|
|
|
|
+ iommu_domain_free(domain);
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void __exynos_iommu_release_mapping(struct exynos_drm_private *priv)
|
|
|
|
+{
|
|
|
|
+ struct iommu_domain *domain = priv->mapping;
|
|
|
|
+
|
|
|
|
+ iommu_put_dma_cookie(domain);
|
|
|
|
+ iommu_domain_free(domain);
|
|
|
|
+ priv->mapping = NULL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline int __exynos_iommu_attach(struct exynos_drm_private *priv,
|
|
|
|
+ struct device *dev)
|
|
|
|
+{
|
|
|
|
+ struct iommu_domain *domain = priv->mapping;
|
|
|
|
+
|
|
|
|
+ return iommu_attach_device(domain, dev);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void __exynos_iommu_detach(struct exynos_drm_private *priv,
|
|
|
|
+ struct device *dev)
|
|
|
|
+{
|
|
|
|
+ struct iommu_domain *domain = priv->mapping;
|
|
|
|
+
|
|
|
|
+ iommu_detach_device(domain, dev);
|
|
|
|
+}
|
|
#else
|
|
#else
|
|
#error Unsupported architecture and IOMMU/DMA-mapping glue code
|
|
#error Unsupported architecture and IOMMU/DMA-mapping glue code
|
|
#endif
|
|
#endif
|