aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/dma-mapping.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2013-11-25 16:52:25 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2013-11-30 09:45:29 -0500
commit11a5aa32562e1e90ab2d0278748fe0fbecda1cbe (patch)
treee95ebca5e90b3afb5dd1d75bab11c5230542ffc4 /arch/arm/mm/dma-mapping.c
parent6ce4eac1f600b34f2f7f58f9cd8f0503d79e42ae (diff)
ARM: dma-mapping: check DMA mask against available memory
Some buses have negative offsets, which causes the DMA mask checks to falsely fail. Fix this by using the actual amount of memory fitted in the system. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mm/dma-mapping.c')
-rw-r--r--arch/arm/mm/dma-mapping.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 79f8b39801a8..f6b6bfa88ecf 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>
@@ -162,6 +163,8 @@ static u64 get_coherent_dma_mask(struct device *dev)
162 u64 mask = (u64)DMA_BIT_MASK(32); 163 u64 mask = (u64)DMA_BIT_MASK(32);
163 164
164 if (dev) { 165 if (dev) {
166 unsigned long max_dma_pfn;
167
165 mask = dev->coherent_dma_mask; 168 mask = dev->coherent_dma_mask;
166 169
167 /* 170 /*
@@ -173,6 +176,8 @@ static u64 get_coherent_dma_mask(struct device *dev)
173 return 0; 176 return 0;
174 } 177 }
175 178
179 max_dma_pfn = min(max_pfn, arm_dma_pfn_limit);
180
176 /* 181 /*
177 * If the mask allows for more memory than we can address, 182 * If the mask allows for more memory than we can address,
178 * and we actually have that much memory, then fail the 183 * and we actually have that much memory, then fail the
@@ -180,7 +185,7 @@ static u64 get_coherent_dma_mask(struct device *dev)
180 */ 185 */
181 if (sizeof(mask) != sizeof(dma_addr_t) && 186 if (sizeof(mask) != sizeof(dma_addr_t) &&
182 mask > (dma_addr_t)~0 && 187 mask > (dma_addr_t)~0 &&
183 dma_to_pfn(dev, ~0) > arm_dma_pfn_limit) { 188 dma_to_pfn(dev, ~0) > max_dma_pfn) {
184 dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n", 189 dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n",
185 mask); 190 mask);
186 dev_warn(dev, "Driver did not use or check the return value from dma_set_coherent_mask()?\n"); 191 dev_warn(dev, "Driver did not use or check the return value from dma_set_coherent_mask()?\n");
@@ -192,7 +197,7 @@ static u64 get_coherent_dma_mask(struct device *dev)
192 * fits within the allowable addresses which we can 197 * fits within the allowable addresses which we can
193 * allocate. 198 * allocate.
194 */ 199 */
195 if (dma_to_pfn(dev, mask) < arm_dma_pfn_limit) { 200 if (dma_to_pfn(dev, mask) < max_dma_pfn) {
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", 201 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, 202 mask,
198 dma_to_pfn(dev, 0), dma_to_pfn(dev, mask) + 1, 203 dma_to_pfn(dev, 0), dma_to_pfn(dev, mask) + 1,