aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Szyprowski <m.szyprowski@samsung.com>2014-02-25 07:01:09 -0500
committerMarek Szyprowski <m.szyprowski@samsung.com>2014-02-28 05:55:18 -0500
commit68efd7d2fb32c2606f1da318b6a851d933813f27 (patch)
tree2b86d6df14c10b8d288ad61624e485b429a1de18
parent4d852ef8c2544ce21ae41414099a7504c61164a0 (diff)
arm: dma-mapping: remove order parameter from arm_iommu_create_mapping()
The 'order' parameter for IOMMU-aware dma-mapping implementation was introduced mainly as a hack to reduce size of the bitmap used for tracking IO virtual address space. Since now it is possible to dynamically resize the bitmap, this hack is not needed and can be removed without any impact on the client devices. This way the parameters for arm_iommu_create_mapping() becomes much easier to understand. 'size' parameter now means the maximum supported IO address space size. The code will allocate (resize) bitmap in chunks, ensuring that a single chunk is not larger than a single memory page to avoid unreliable allocations of size larger than PAGE_SIZE in atomic context. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
-rw-r--r--arch/arm/include/asm/dma-iommu.h4
-rw-r--r--arch/arm/mm/dma-mapping.c43
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.h2
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_iommu.c6
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_iommu.h1
-rw-r--r--drivers/iommu/shmobile-iommu.c2
6 files changed, 25 insertions, 33 deletions
diff --git a/arch/arm/include/asm/dma-iommu.h b/arch/arm/include/asm/dma-iommu.h
index 686797cf5618..eec0a12c5c1d 100644
--- a/arch/arm/include/asm/dma-iommu.h
+++ b/arch/arm/include/asm/dma-iommu.h
@@ -19,7 +19,6 @@ struct dma_iommu_mapping {
19 size_t bitmap_size; /* size of a single bitmap */ 19 size_t bitmap_size; /* size of a single bitmap */
20 size_t bits; /* per bitmap */ 20 size_t bits; /* per bitmap */
21 unsigned int size; /* per bitmap */ 21 unsigned int size; /* per bitmap */
22 unsigned int order;
23 dma_addr_t base; 22 dma_addr_t base;
24 23
25 spinlock_t lock; 24 spinlock_t lock;
@@ -27,8 +26,7 @@ struct dma_iommu_mapping {
27}; 26};
28 27
29struct dma_iommu_mapping * 28struct dma_iommu_mapping *
30arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size, 29arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size);
31 int order);
32 30
33void arm_iommu_release_mapping(struct dma_iommu_mapping *mapping); 31void arm_iommu_release_mapping(struct dma_iommu_mapping *mapping);
34 32
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 4d06295b8e3e..4fe42ce720d2 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1084,11 +1084,8 @@ static inline dma_addr_t __alloc_iova(struct dma_iommu_mapping *mapping,
1084 if (order > CONFIG_ARM_DMA_IOMMU_ALIGNMENT) 1084 if (order > CONFIG_ARM_DMA_IOMMU_ALIGNMENT)
1085 order = CONFIG_ARM_DMA_IOMMU_ALIGNMENT; 1085 order = CONFIG_ARM_DMA_IOMMU_ALIGNMENT;
1086 1086
1087 count = ((PAGE_ALIGN(size) >> PAGE_SHIFT) + 1087 count = PAGE_ALIGN(size) >> PAGE_SHIFT;
1088 (1 << mapping->order) - 1) >> mapping->order; 1088 align = (1 << order) - 1;
1089
1090 if (order > mapping->order)
1091 align = (1 << (order - mapping->order)) - 1;
1092 1089
1093 spin_lock_irqsave(&mapping->lock, flags); 1090 spin_lock_irqsave(&mapping->lock, flags);
1094 for (i = 0; i < mapping->nr_bitmaps; i++) { 1091 for (i = 0; i < mapping->nr_bitmaps; i++) {
@@ -1126,7 +1123,7 @@ static inline dma_addr_t __alloc_iova(struct dma_iommu_mapping *mapping,
1126 spin_unlock_irqrestore(&mapping->lock, flags); 1123 spin_unlock_irqrestore(&mapping->lock, flags);
1127 1124
1128 iova = mapping->base + (mapping->size * i); 1125 iova = mapping->base + (mapping->size * i);
1129 iova += start << (mapping->order + PAGE_SHIFT); 1126 iova += start << PAGE_SHIFT;
1130 1127
1131 return iova; 1128 return iova;
1132} 1129}
@@ -1147,7 +1144,7 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping,
1147 1144
1148 bitmap_base = mapping->base + mapping->size * bitmap_index; 1145 bitmap_base = mapping->base + mapping->size * bitmap_index;
1149 1146
1150 start = (addr - bitmap_base) >> (mapping->order + PAGE_SHIFT); 1147 start = (addr - bitmap_base) >> PAGE_SHIFT;
1151 1148
1152 if (addr + size > bitmap_base + mapping->size) { 1149 if (addr + size > bitmap_base + mapping->size) {
1153 /* 1150 /*
@@ -1158,8 +1155,7 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping,
1158 */ 1155 */
1159 BUG(); 1156 BUG();
1160 } else 1157 } else
1161 count = ((size >> PAGE_SHIFT) + 1158 count = size >> PAGE_SHIFT;
1162 (1 << mapping->order) - 1) >> mapping->order;
1163 1159
1164 spin_lock_irqsave(&mapping->lock, flags); 1160 spin_lock_irqsave(&mapping->lock, flags);
1165 bitmap_clear(mapping->bitmaps[bitmap_index], start, count); 1161 bitmap_clear(mapping->bitmaps[bitmap_index], start, count);
@@ -1927,8 +1923,7 @@ struct dma_map_ops iommu_coherent_ops = {
1927 * arm_iommu_create_mapping 1923 * arm_iommu_create_mapping
1928 * @bus: pointer to the bus holding the client device (for IOMMU calls) 1924 * @bus: pointer to the bus holding the client device (for IOMMU calls)
1929 * @base: start address of the valid IO address space 1925 * @base: start address of the valid IO address space
1930 * @size: size of the valid IO address space 1926 * @size: maximum size of the valid IO address space
1931 * @order: accuracy of the IO addresses allocations
1932 * 1927 *
1933 * Creates a mapping structure which holds information about used/unused 1928 * Creates a mapping structure which holds information about used/unused
1934 * IO address ranges, which is required to perform memory allocation and 1929 * IO address ranges, which is required to perform memory allocation and
@@ -1938,37 +1933,41 @@ struct dma_map_ops iommu_coherent_ops = {
1938 * arm_iommu_attach_device function. 1933 * arm_iommu_attach_device function.
1939 */ 1934 */
1940struct dma_iommu_mapping * 1935struct dma_iommu_mapping *
1941arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size, 1936arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size)
1942 int order)
1943{ 1937{
1944 unsigned int count = size >> (PAGE_SHIFT + order); 1938 unsigned int bits = size >> PAGE_SHIFT;
1939 unsigned int bitmap_size = BITS_TO_LONGS(bits) * sizeof(long);
1945 struct dma_iommu_mapping *mapping; 1940 struct dma_iommu_mapping *mapping;
1946 int extensions = 0; 1941 int extensions = 1;
1947 int err = -ENOMEM; 1942 int err = -ENOMEM;
1948 1943
1949 if (!count) 1944 if (!bitmap_size)
1950 return ERR_PTR(-EINVAL); 1945 return ERR_PTR(-EINVAL);
1951 1946
1947 if (bitmap_size > PAGE_SIZE) {
1948 extensions = bitmap_size / PAGE_SIZE;
1949 bitmap_size = PAGE_SIZE;
1950 }
1951
1952 mapping = kzalloc(sizeof(struct dma_iommu_mapping), GFP_KERNEL); 1952 mapping = kzalloc(sizeof(struct dma_iommu_mapping), GFP_KERNEL);
1953 if (!mapping) 1953 if (!mapping)
1954 goto err; 1954 goto err;
1955 1955
1956 mapping->bitmap_size = BITS_TO_LONGS(count) * sizeof(long); 1956 mapping->bitmap_size = bitmap_size;
1957 mapping->bitmaps = kzalloc((extensions + 1) * sizeof(unsigned long *), 1957 mapping->bitmaps = kzalloc(extensions * sizeof(unsigned long *),
1958 GFP_KERNEL); 1958 GFP_KERNEL);
1959 if (!mapping->bitmaps) 1959 if (!mapping->bitmaps)
1960 goto err2; 1960 goto err2;
1961 1961
1962 mapping->bitmaps[0] = kzalloc(mapping->bitmap_size, GFP_KERNEL); 1962 mapping->bitmaps[0] = kzalloc(bitmap_size, GFP_KERNEL);
1963 if (!mapping->bitmaps[0]) 1963 if (!mapping->bitmaps[0])
1964 goto err3; 1964 goto err3;
1965 1965
1966 mapping->nr_bitmaps = 1; 1966 mapping->nr_bitmaps = 1;
1967 mapping->extensions = extensions; 1967 mapping->extensions = extensions;
1968 mapping->base = base; 1968 mapping->base = base;
1969 mapping->size = size; 1969 mapping->size = bitmap_size << PAGE_SHIFT;
1970 mapping->order = order; 1970 mapping->bits = BITS_PER_BYTE * bitmap_size;
1971 mapping->bits = BITS_PER_BYTE * mapping->bitmap_size;
1972 1971
1973 spin_lock_init(&mapping->lock); 1972 spin_lock_init(&mapping->lock);
1974 1973
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 0eaf5a27e120..a8f9dba2a816 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -237,7 +237,6 @@ struct drm_exynos_file_private {
237 * otherwise default one. 237 * otherwise default one.
238 * @da_space_size: size of device address space. 238 * @da_space_size: size of device address space.
239 * if 0 then default value is used for it. 239 * if 0 then default value is used for it.
240 * @da_space_order: order to device address space.
241 */ 240 */
242struct exynos_drm_private { 241struct exynos_drm_private {
243 struct drm_fb_helper *fb_helper; 242 struct drm_fb_helper *fb_helper;
@@ -255,7 +254,6 @@ struct exynos_drm_private {
255 254
256 unsigned long da_start; 255 unsigned long da_start;
257 unsigned long da_space_size; 256 unsigned long da_space_size;
258 unsigned long da_space_order;
259}; 257};
260 258
261/* 259/*
diff --git a/drivers/gpu/drm/exynos/exynos_drm_iommu.c b/drivers/gpu/drm/exynos/exynos_drm_iommu.c
index fb8db0378274..b32b291f88ff 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_iommu.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_iommu.c
@@ -36,12 +36,10 @@ int drm_create_iommu_mapping(struct drm_device *drm_dev)
36 priv->da_start = EXYNOS_DEV_ADDR_START; 36 priv->da_start = EXYNOS_DEV_ADDR_START;
37 if (!priv->da_space_size) 37 if (!priv->da_space_size)
38 priv->da_space_size = EXYNOS_DEV_ADDR_SIZE; 38 priv->da_space_size = EXYNOS_DEV_ADDR_SIZE;
39 if (!priv->da_space_order)
40 priv->da_space_order = EXYNOS_DEV_ADDR_ORDER;
41 39
42 mapping = arm_iommu_create_mapping(&platform_bus_type, priv->da_start, 40 mapping = arm_iommu_create_mapping(&platform_bus_type, priv->da_start,
43 priv->da_space_size, 41 priv->da_space_size);
44 priv->da_space_order); 42
45 if (IS_ERR(mapping)) 43 if (IS_ERR(mapping))
46 return PTR_ERR(mapping); 44 return PTR_ERR(mapping);
47 45
diff --git a/drivers/gpu/drm/exynos/exynos_drm_iommu.h b/drivers/gpu/drm/exynos/exynos_drm_iommu.h
index 598e60f57d4b..72376d41c512 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_iommu.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_iommu.h
@@ -14,7 +14,6 @@
14 14
15#define EXYNOS_DEV_ADDR_START 0x20000000 15#define EXYNOS_DEV_ADDR_START 0x20000000
16#define EXYNOS_DEV_ADDR_SIZE 0x40000000 16#define EXYNOS_DEV_ADDR_SIZE 0x40000000
17#define EXYNOS_DEV_ADDR_ORDER 0x0
18 17
19#ifdef CONFIG_DRM_EXYNOS_IOMMU 18#ifdef CONFIG_DRM_EXYNOS_IOMMU
20 19
diff --git a/drivers/iommu/shmobile-iommu.c b/drivers/iommu/shmobile-iommu.c
index 7a3b928fad1c..464acda0bbc4 100644
--- a/drivers/iommu/shmobile-iommu.c
+++ b/drivers/iommu/shmobile-iommu.c
@@ -343,7 +343,7 @@ static int shmobile_iommu_add_device(struct device *dev)
343 mapping = archdata->iommu_mapping; 343 mapping = archdata->iommu_mapping;
344 if (!mapping) { 344 if (!mapping) {
345 mapping = arm_iommu_create_mapping(&platform_bus_type, 0, 345 mapping = arm_iommu_create_mapping(&platform_bus_type, 0,
346 L1_LEN << 20, 0); 346 L1_LEN << 20);
347 if (IS_ERR(mapping)) 347 if (IS_ERR(mapping))
348 return PTR_ERR(mapping); 348 return PTR_ERR(mapping);
349 archdata->iommu_mapping = mapping; 349 archdata->iommu_mapping = mapping;