diff options
author | Marek Szyprowski <m.szyprowski@samsung.com> | 2016-02-18 17:12:49 +0300 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2016-02-25 17:32:09 +0300 |
commit | 58c6f6a3dc97ed1a5a5262279a2e9db41bd6d035 (patch) | |
tree | 0836e571a8a49a8248779f35d3fe75a03a8bf572 /drivers/iommu | |
parent | 6c2ae7e2916b028bd4c0fff04589bd176487a122 (diff) | |
download | linux-58c6f6a3dc97ed1a5a5262279a2e9db41bd6d035.tar.xz |
iommu/exynos: Add support for IOMMU_DOMAIN_DMA domain type
This patch adds support for DMA domain type. Such domain have DMA cookie
prepared and can be used by generic DMA-IOMMU glue layer.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu')
-rw-r--r-- | drivers/iommu/exynos-iommu.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 4fc079073c86..595e0da55db4 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -25,9 +25,9 @@ #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/slab.h> +#include <linux/dma-iommu.h> #include <asm/cacheflush.h> -#include <asm/dma-iommu.h> #include <asm/pgtable.h> typedef u32 sysmmu_iova_t; @@ -662,16 +662,21 @@ static struct iommu_domain *exynos_iommu_domain_alloc(unsigned type) struct exynos_iommu_domain *domain; int i; - if (type != IOMMU_DOMAIN_UNMANAGED) - return NULL; domain = kzalloc(sizeof(*domain), GFP_KERNEL); if (!domain) return NULL; + if (type == IOMMU_DOMAIN_DMA) { + if (iommu_get_dma_cookie(&domain->domain) != 0) + goto err_pgtable; + } else if (type != IOMMU_DOMAIN_UNMANAGED) { + goto err_pgtable; + } + domain->pgtable = (sysmmu_pte_t *)__get_free_pages(GFP_KERNEL, 2); if (!domain->pgtable) - goto err_pgtable; + goto err_dma_cookie; domain->lv2entcnt = (short *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1); if (!domain->lv2entcnt) @@ -703,6 +708,9 @@ static struct iommu_domain *exynos_iommu_domain_alloc(unsigned type) err_counter: free_pages((unsigned long)domain->pgtable, 2); +err_dma_cookie: + if (type == IOMMU_DOMAIN_DMA) + iommu_put_dma_cookie(&domain->domain); err_pgtable: kfree(domain); return NULL; @@ -727,6 +735,9 @@ static void exynos_iommu_domain_free(struct iommu_domain *iommu_domain) spin_unlock_irqrestore(&domain->lock, flags); + if (iommu_domain->type == IOMMU_DOMAIN_DMA) + iommu_put_dma_cookie(iommu_domain); + for (i = 0; i < NUM_LV1ENTRIES; i++) if (lv1ent_page(domain->pgtable + i)) kmem_cache_free(lv2table_kmem_cache, |