diff options
Diffstat (limited to 'arch/arm/mm/dma-mapping.c')
-rw-r--r-- | arch/arm/mm/dma-mapping.c | 88 |
1 files changed, 41 insertions, 47 deletions
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 79f8b39801a8..f61a5707823a 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * | 9 | * |
10 | * DMA uncached mapping support. | 10 | * DMA uncached mapping support. |
11 | */ | 11 | */ |
12 | #include <linux/bootmem.h> | ||
12 | #include <linux/module.h> | 13 | #include <linux/module.h> |
13 | #include <linux/mm.h> | 14 | #include <linux/mm.h> |
14 | #include <linux/gfp.h> | 15 | #include <linux/gfp.h> |
@@ -157,6 +158,44 @@ struct dma_map_ops arm_coherent_dma_ops = { | |||
157 | }; | 158 | }; |
158 | EXPORT_SYMBOL(arm_coherent_dma_ops); | 159 | EXPORT_SYMBOL(arm_coherent_dma_ops); |
159 | 160 | ||
161 | static int __dma_supported(struct device *dev, u64 mask, bool warn) | ||
162 | { | ||
163 | unsigned long max_dma_pfn; | ||
164 | |||
165 | /* | ||
166 | * If the mask allows for more memory than we can address, | ||
167 | * and we actually have that much memory, then we must | ||
168 | * indicate that DMA to this device is not supported. | ||
169 | */ | ||
170 | if (sizeof(mask) != sizeof(dma_addr_t) && | ||
171 | mask > (dma_addr_t)~0 && | ||
172 | dma_to_pfn(dev, ~0) < max_pfn) { | ||
173 | if (warn) { | ||
174 | dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n", | ||
175 | mask); | ||
176 | dev_warn(dev, "Driver did not use or check the return value from dma_set_coherent_mask()?\n"); | ||
177 | } | ||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | max_dma_pfn = min(max_pfn, arm_dma_pfn_limit); | ||
182 | |||
183 | /* | ||
184 | * Translate the device's DMA mask to a PFN limit. This | ||
185 | * PFN number includes the page which we can DMA to. | ||
186 | */ | ||
187 | if (dma_to_pfn(dev, mask) < max_dma_pfn) { | ||
188 | if (warn) | ||
189 | dev_warn(dev, "Coherent DMA mask %#llx (pfn %#lx-%#lx) covers a smaller range of system memory than the DMA zone pfn 0x0-%#lx\n", | ||
190 | mask, | ||
191 | dma_to_pfn(dev, 0), dma_to_pfn(dev, mask) + 1, | ||
192 | max_dma_pfn + 1); | ||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | return 1; | ||
197 | } | ||
198 | |||
160 | static u64 get_coherent_dma_mask(struct device *dev) | 199 | static u64 get_coherent_dma_mask(struct device *dev) |
161 | { | 200 | { |
162 | u64 mask = (u64)DMA_BIT_MASK(32); | 201 | u64 mask = (u64)DMA_BIT_MASK(32); |
@@ -173,32 +212,8 @@ static u64 get_coherent_dma_mask(struct device *dev) | |||
173 | return 0; | 212 | return 0; |
174 | } | 213 | } |
175 | 214 | ||
176 | /* | 215 | if (!__dma_supported(dev, mask, true)) |
177 | * If the mask allows for more memory than we can address, | ||
178 | * and we actually have that much memory, then fail the | ||
179 | * allocation. | ||
180 | */ | ||
181 | if (sizeof(mask) != sizeof(dma_addr_t) && | ||
182 | mask > (dma_addr_t)~0 && | ||
183 | dma_to_pfn(dev, ~0) > arm_dma_pfn_limit) { | ||
184 | dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n", | ||
185 | mask); | ||
186 | dev_warn(dev, "Driver did not use or check the return value from dma_set_coherent_mask()?\n"); | ||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | /* | ||
191 | * Now check that the mask, when translated to a PFN, | ||
192 | * fits within the allowable addresses which we can | ||
193 | * allocate. | ||
194 | */ | ||
195 | if (dma_to_pfn(dev, mask) < arm_dma_pfn_limit) { | ||
196 | dev_warn(dev, "Coherent DMA mask %#llx (pfn %#lx-%#lx) covers a smaller range of system memory than the DMA zone pfn 0x0-%#lx\n", | ||
197 | mask, | ||
198 | dma_to_pfn(dev, 0), dma_to_pfn(dev, mask) + 1, | ||
199 | arm_dma_pfn_limit + 1); | ||
200 | return 0; | 216 | return 0; |
201 | } | ||
202 | } | 217 | } |
203 | 218 | ||
204 | return mask; | 219 | return mask; |
@@ -1027,28 +1042,7 @@ void arm_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, | |||
1027 | */ | 1042 | */ |
1028 | int dma_supported(struct device *dev, u64 mask) | 1043 | int dma_supported(struct device *dev, u64 mask) |
1029 | { | 1044 | { |
1030 | unsigned long limit; | 1045 | return __dma_supported(dev, mask, false); |
1031 | |||
1032 | /* | ||
1033 | * If the mask allows for more memory than we can address, | ||
1034 | * and we actually have that much memory, then we must | ||
1035 | * indicate that DMA to this device is not supported. | ||
1036 | */ | ||
1037 | if (sizeof(mask) != sizeof(dma_addr_t) && | ||
1038 | mask > (dma_addr_t)~0 && | ||
1039 | dma_to_pfn(dev, ~0) > arm_dma_pfn_limit) | ||
1040 | return 0; | ||
1041 | |||
1042 | /* | ||
1043 | * Translate the device's DMA mask to a PFN limit. This | ||
1044 | * PFN number includes the page which we can DMA to. | ||
1045 | */ | ||
1046 | limit = dma_to_pfn(dev, mask); | ||
1047 | |||
1048 | if (limit < arm_dma_pfn_limit) | ||
1049 | return 0; | ||
1050 | |||
1051 | return 1; | ||
1052 | } | 1046 | } |
1053 | EXPORT_SYMBOL(dma_supported); | 1047 | EXPORT_SYMBOL(dma_supported); |
1054 | 1048 | ||