diff options
author | Robin Murphy <robin.murphy@arm.com> | 2016-01-26 13:06:36 -0500 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2016-02-18 10:02:43 -0500 |
commit | 9adb95949a343dac53b1cd81dc973b5f815c88d4 (patch) | |
tree | 88854134d48d0056bcb7a054fb060d616fd6196a /drivers/iommu/arm-smmu.c | |
parent | d346180e70b91b3d5a1ae7e5603e65593d4622bc (diff) |
iommu/arm-smmu: Support DMA-API domains
With DMA mapping ops provided by the iommu-dma code, only a minimal
contribution from the IOMMU driver is needed to create a suitable
DMA-API domain for them to use. Implement this for the ARM SMMUs.
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'drivers/iommu/arm-smmu.c')
-rw-r--r-- | drivers/iommu/arm-smmu.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 1f9093d76d93..e8e7bcc4540c 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #define pr_fmt(fmt) "arm-smmu: " fmt | 29 | #define pr_fmt(fmt) "arm-smmu: " fmt |
30 | 30 | ||
31 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
32 | #include <linux/dma-iommu.h> | ||
32 | #include <linux/dma-mapping.h> | 33 | #include <linux/dma-mapping.h> |
33 | #include <linux/err.h> | 34 | #include <linux/err.h> |
34 | #include <linux/interrupt.h> | 35 | #include <linux/interrupt.h> |
@@ -966,7 +967,7 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type) | |||
966 | { | 967 | { |
967 | struct arm_smmu_domain *smmu_domain; | 968 | struct arm_smmu_domain *smmu_domain; |
968 | 969 | ||
969 | if (type != IOMMU_DOMAIN_UNMANAGED) | 970 | if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA) |
970 | return NULL; | 971 | return NULL; |
971 | /* | 972 | /* |
972 | * Allocate the domain and initialise some of its data structures. | 973 | * Allocate the domain and initialise some of its data structures. |
@@ -977,6 +978,12 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type) | |||
977 | if (!smmu_domain) | 978 | if (!smmu_domain) |
978 | return NULL; | 979 | return NULL; |
979 | 980 | ||
981 | if (type == IOMMU_DOMAIN_DMA && | ||
982 | iommu_get_dma_cookie(&smmu_domain->domain)) { | ||
983 | kfree(smmu_domain); | ||
984 | return NULL; | ||
985 | } | ||
986 | |||
980 | mutex_init(&smmu_domain->init_mutex); | 987 | mutex_init(&smmu_domain->init_mutex); |
981 | spin_lock_init(&smmu_domain->pgtbl_lock); | 988 | spin_lock_init(&smmu_domain->pgtbl_lock); |
982 | 989 | ||
@@ -991,6 +998,7 @@ static void arm_smmu_domain_free(struct iommu_domain *domain) | |||
991 | * Free the domain resources. We assume that all devices have | 998 | * Free the domain resources. We assume that all devices have |
992 | * already been detached. | 999 | * already been detached. |
993 | */ | 1000 | */ |
1001 | iommu_put_dma_cookie(domain); | ||
994 | arm_smmu_destroy_domain_context(domain); | 1002 | arm_smmu_destroy_domain_context(domain); |
995 | kfree(smmu_domain); | 1003 | kfree(smmu_domain); |
996 | } | 1004 | } |