aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-02 17:34:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-02 17:34:25 -0400
commit7474043eff6f7c20141b2f49f774d0aab6542220 (patch)
treef143f787c7ff3ee6c8fede1bd2fd60c36b328243
parentb9f2b21a32906a47c220b5167b88869f2c90f1c4 (diff)
parent68efd7d2fb32c2606f1da318b6a851d933813f27 (diff)
Merge branch 'for-3.15' of git://git.linaro.org/people/mszyprowski/linux-dma-mapping
Pull DMA-mapping updates from Marek Szyprowski: "This contains extension for more efficient handling of io address space for dma-mapping subsystem for ARM architecture" * 'for-3.15' of git://git.linaro.org/people/mszyprowski/linux-dma-mapping: arm: dma-mapping: remove order parameter from arm_iommu_create_mapping() arm: dma-mapping: Add support to extend DMA IOMMU mappings
-rw-r--r--arch/arm/include/asm/dma-iommu.h12
-rw-r--r--arch/arm/mm/dma-mapping.c144
-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, 124 insertions, 43 deletions
diff --git a/arch/arm/include/asm/dma-iommu.h b/arch/arm/include/asm/dma-iommu.h
index a8c56acc8c98..eec0a12c5c1d 100644
--- a/arch/arm/include/asm/dma-iommu.h
+++ b/arch/arm/include/asm/dma-iommu.h
@@ -13,9 +13,12 @@ struct dma_iommu_mapping {
13 /* iommu specific data */ 13 /* iommu specific data */
14 struct iommu_domain *domain; 14 struct iommu_domain *domain;
15 15
16 void *bitmap; 16 unsigned long **bitmaps; /* array of bitmaps */
17 size_t bits; 17 unsigned int nr_bitmaps; /* nr of elements in array */
18 unsigned int order; 18 unsigned int extensions;
19 size_t bitmap_size; /* size of a single bitmap */
20 size_t bits; /* per bitmap */
21 unsigned int size; /* per bitmap */
19 dma_addr_t base; 22 dma_addr_t base;
20 23
21 spinlock_t lock; 24 spinlock_t lock;
@@ -23,8 +26,7 @@ struct dma_iommu_mapping {
23}; 26};
24 27
25struct dma_iommu_mapping * 28struct dma_iommu_mapping *
26arm_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);
27 int order);
28 30
29void arm_iommu_release_mapping(struct dma_iommu_mapping *mapping); 31void arm_iommu_release_mapping(struct dma_iommu_mapping *mapping);
30 32
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 11b3914660d2..4fe42ce720d2 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1069,6 +1069,8 @@ fs_initcall(dma_debug_do_init);
1069 1069
1070/* IOMMU */ 1070/* IOMMU */
1071 1071
1072static int extend_iommu_mapping(struct dma_iommu_mapping *mapping);
1073
1072static inline dma_addr_t __alloc_iova(struct dma_iommu_mapping *mapping, 1074static inline dma_addr_t __alloc_iova(struct dma_iommu_mapping *mapping,
1073 size_t size) 1075 size_t size)
1074{ 1076{
@@ -1076,41 +1078,87 @@ static inline dma_addr_t __alloc_iova(struct dma_iommu_mapping *mapping,
1076 unsigned int align = 0; 1078 unsigned int align = 0;
1077 unsigned int count, start; 1079 unsigned int count, start;
1078 unsigned long flags; 1080 unsigned long flags;
1081 dma_addr_t iova;
1082 int i;
1079 1083
1080 if (order > CONFIG_ARM_DMA_IOMMU_ALIGNMENT) 1084 if (order > CONFIG_ARM_DMA_IOMMU_ALIGNMENT)
1081 order = CONFIG_ARM_DMA_IOMMU_ALIGNMENT; 1085 order = CONFIG_ARM_DMA_IOMMU_ALIGNMENT;
1082 1086
1083 count = ((PAGE_ALIGN(size) >> PAGE_SHIFT) + 1087 count = PAGE_ALIGN(size) >> PAGE_SHIFT;
1084 (1 << mapping->order) - 1) >> mapping->order; 1088 align = (1 << order) - 1;
1085
1086 if (order > mapping->order)
1087 align = (1 << (order - mapping->order)) - 1;
1088 1089
1089 spin_lock_irqsave(&mapping->lock, flags); 1090 spin_lock_irqsave(&mapping->lock, flags);
1090 start = bitmap_find_next_zero_area(mapping->bitmap, mapping->bits, 0, 1091 for (i = 0; i < mapping->nr_bitmaps; i++) {
1091 count, align); 1092 start = bitmap_find_next_zero_area(mapping->bitmaps[i],
1092 if (start > mapping->bits) { 1093 mapping->bits, 0, count, align);
1093 spin_unlock_irqrestore(&mapping->lock, flags); 1094
1094 return DMA_ERROR_CODE; 1095 if (start > mapping->bits)
1096 continue;
1097
1098 bitmap_set(mapping->bitmaps[i], start, count);
1099 break;
1095 } 1100 }
1096 1101
1097 bitmap_set(mapping->bitmap, start, count); 1102 /*
1103 * No unused range found. Try to extend the existing mapping
1104 * and perform a second attempt to reserve an IO virtual
1105 * address range of size bytes.
1106 */
1107 if (i == mapping->nr_bitmaps) {
1108 if (extend_iommu_mapping(mapping)) {
1109 spin_unlock_irqrestore(&mapping->lock, flags);
1110 return DMA_ERROR_CODE;
1111 }
1112
1113 start = bitmap_find_next_zero_area(mapping->bitmaps[i],
1114 mapping->bits, 0, count, align);
1115
1116 if (start > mapping->bits) {
1117 spin_unlock_irqrestore(&mapping->lock, flags);
1118 return DMA_ERROR_CODE;
1119 }
1120
1121 bitmap_set(mapping->bitmaps[i], start, count);
1122 }
1098 spin_unlock_irqrestore(&mapping->lock, flags); 1123 spin_unlock_irqrestore(&mapping->lock, flags);
1099 1124
1100 return mapping->base + (start << (mapping->order + PAGE_SHIFT)); 1125 iova = mapping->base + (mapping->size * i);
1126 iova += start << PAGE_SHIFT;
1127
1128 return iova;
1101} 1129}
1102 1130
1103static inline void __free_iova(struct dma_iommu_mapping *mapping, 1131static inline void __free_iova(struct dma_iommu_mapping *mapping,
1104 dma_addr_t addr, size_t size) 1132 dma_addr_t addr, size_t size)
1105{ 1133{
1106 unsigned int start = (addr - mapping->base) >> 1134 unsigned int start, count;
1107 (mapping->order + PAGE_SHIFT);
1108 unsigned int count = ((size >> PAGE_SHIFT) +
1109 (1 << mapping->order) - 1) >> mapping->order;
1110 unsigned long flags; 1135 unsigned long flags;
1136 dma_addr_t bitmap_base;
1137 u32 bitmap_index;
1138
1139 if (!size)
1140 return;
1141
1142 bitmap_index = (u32) (addr - mapping->base) / (u32) mapping->size;
1143 BUG_ON(addr < mapping->base || bitmap_index > mapping->extensions);
1144
1145 bitmap_base = mapping->base + mapping->size * bitmap_index;
1146
1147 start = (addr - bitmap_base) >> PAGE_SHIFT;
1148
1149 if (addr + size > bitmap_base + mapping->size) {
1150 /*
1151 * The address range to be freed reaches into the iova
1152 * range of the next bitmap. This should not happen as
1153 * we don't allow this in __alloc_iova (at the
1154 * moment).
1155 */
1156 BUG();
1157 } else
1158 count = size >> PAGE_SHIFT;
1111 1159
1112 spin_lock_irqsave(&mapping->lock, flags); 1160 spin_lock_irqsave(&mapping->lock, flags);
1113 bitmap_clear(mapping->bitmap, start, count); 1161 bitmap_clear(mapping->bitmaps[bitmap_index], start, count);
1114 spin_unlock_irqrestore(&mapping->lock, flags); 1162 spin_unlock_irqrestore(&mapping->lock, flags);
1115} 1163}
1116 1164
@@ -1875,8 +1923,7 @@ struct dma_map_ops iommu_coherent_ops = {
1875 * arm_iommu_create_mapping 1923 * arm_iommu_create_mapping
1876 * @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)
1877 * @base: start address of the valid IO address space 1925 * @base: start address of the valid IO address space
1878 * @size: size of the valid IO address space 1926 * @size: maximum size of the valid IO address space
1879 * @order: accuracy of the IO addresses allocations
1880 * 1927 *
1881 * Creates a mapping structure which holds information about used/unused 1928 * Creates a mapping structure which holds information about used/unused
1882 * IO address ranges, which is required to perform memory allocation and 1929 * IO address ranges, which is required to perform memory allocation and
@@ -1886,38 +1933,54 @@ struct dma_map_ops iommu_coherent_ops = {
1886 * arm_iommu_attach_device function. 1933 * arm_iommu_attach_device function.
1887 */ 1934 */
1888struct dma_iommu_mapping * 1935struct dma_iommu_mapping *
1889arm_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)
1890 int order)
1891{ 1937{
1892 unsigned int count = size >> (PAGE_SHIFT + order); 1938 unsigned int bits = size >> PAGE_SHIFT;
1893 unsigned int bitmap_size = BITS_TO_LONGS(count) * sizeof(long); 1939 unsigned int bitmap_size = BITS_TO_LONGS(bits) * sizeof(long);
1894 struct dma_iommu_mapping *mapping; 1940 struct dma_iommu_mapping *mapping;
1941 int extensions = 1;
1895 int err = -ENOMEM; 1942 int err = -ENOMEM;
1896 1943
1897 if (!count) 1944 if (!bitmap_size)
1898 return ERR_PTR(-EINVAL); 1945 return ERR_PTR(-EINVAL);
1899 1946
1947 if (bitmap_size > PAGE_SIZE) {
1948 extensions = bitmap_size / PAGE_SIZE;
1949 bitmap_size = PAGE_SIZE;
1950 }
1951
1900 mapping = kzalloc(sizeof(struct dma_iommu_mapping), GFP_KERNEL); 1952 mapping = kzalloc(sizeof(struct dma_iommu_mapping), GFP_KERNEL);
1901 if (!mapping) 1953 if (!mapping)
1902 goto err; 1954 goto err;
1903 1955
1904 mapping->bitmap = kzalloc(bitmap_size, GFP_KERNEL); 1956 mapping->bitmap_size = bitmap_size;
1905 if (!mapping->bitmap) 1957 mapping->bitmaps = kzalloc(extensions * sizeof(unsigned long *),
1958 GFP_KERNEL);
1959 if (!mapping->bitmaps)
1906 goto err2; 1960 goto err2;
1907 1961
1962 mapping->bitmaps[0] = kzalloc(bitmap_size, GFP_KERNEL);
1963 if (!mapping->bitmaps[0])
1964 goto err3;
1965
1966 mapping->nr_bitmaps = 1;
1967 mapping->extensions = extensions;
1908 mapping->base = base; 1968 mapping->base = base;
1969 mapping->size = bitmap_size << PAGE_SHIFT;
1909 mapping->bits = BITS_PER_BYTE * bitmap_size; 1970 mapping->bits = BITS_PER_BYTE * bitmap_size;
1910 mapping->order = order; 1971
1911 spin_lock_init(&mapping->lock); 1972 spin_lock_init(&mapping->lock);
1912 1973
1913 mapping->domain = iommu_domain_alloc(bus); 1974 mapping->domain = iommu_domain_alloc(bus);
1914 if (!mapping->domain) 1975 if (!mapping->domain)
1915 goto err3; 1976 goto err4;
1916 1977
1917 kref_init(&mapping->kref); 1978 kref_init(&mapping->kref);
1918 return mapping; 1979 return mapping;
1980err4:
1981 kfree(mapping->bitmaps[0]);
1919err3: 1982err3:
1920 kfree(mapping->bitmap); 1983 kfree(mapping->bitmaps);
1921err2: 1984err2:
1922 kfree(mapping); 1985 kfree(mapping);
1923err: 1986err:
@@ -1927,14 +1990,35 @@ EXPORT_SYMBOL_GPL(arm_iommu_create_mapping);
1927 1990
1928static void release_iommu_mapping(struct kref *kref) 1991static void release_iommu_mapping(struct kref *kref)
1929{ 1992{
1993 int i;
1930 struct dma_iommu_mapping *mapping = 1994 struct dma_iommu_mapping *mapping =
1931 container_of(kref, struct dma_iommu_mapping, kref); 1995 container_of(kref, struct dma_iommu_mapping, kref);
1932 1996
1933 iommu_domain_free(mapping->domain); 1997 iommu_domain_free(mapping->domain);
1934 kfree(mapping->bitmap); 1998 for (i = 0; i < mapping->nr_bitmaps; i++)
1999 kfree(mapping->bitmaps[i]);
2000 kfree(mapping->bitmaps);
1935 kfree(mapping); 2001 kfree(mapping);
1936} 2002}
1937 2003
2004static int extend_iommu_mapping(struct dma_iommu_mapping *mapping)
2005{
2006 int next_bitmap;
2007
2008 if (mapping->nr_bitmaps > mapping->extensions)
2009 return -EINVAL;
2010
2011 next_bitmap = mapping->nr_bitmaps;
2012 mapping->bitmaps[next_bitmap] = kzalloc(mapping->bitmap_size,
2013 GFP_ATOMIC);
2014 if (!mapping->bitmaps[next_bitmap])
2015 return -ENOMEM;
2016
2017 mapping->nr_bitmaps++;
2018
2019 return 0;
2020}
2021
1938void arm_iommu_release_mapping(struct dma_iommu_mapping *mapping) 2022void arm_iommu_release_mapping(struct dma_iommu_mapping *mapping)
1939{ 2023{
1940 if (mapping) 2024 if (mapping)
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;