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>
This commit is contained in:
Russell King 2013-11-25 21:52:25 +00:00
parent 6ce4eac1f6
commit 11a5aa3256
1 changed files with 7 additions and 2 deletions

View File

@ -9,6 +9,7 @@
*
* DMA uncached mapping support.
*/
#include <linux/bootmem.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/gfp.h>
@ -162,6 +163,8 @@ static u64 get_coherent_dma_mask(struct device *dev)
u64 mask = (u64)DMA_BIT_MASK(32);
if (dev) {
unsigned long max_dma_pfn;
mask = dev->coherent_dma_mask;
/*
@ -173,6 +176,8 @@ static u64 get_coherent_dma_mask(struct device *dev)
return 0;
}
max_dma_pfn = min(max_pfn, arm_dma_pfn_limit);
/*
* If the mask allows for more memory than we can address,
* and we actually have that much memory, then fail the
@ -180,7 +185,7 @@ static u64 get_coherent_dma_mask(struct device *dev)
*/
if (sizeof(mask) != sizeof(dma_addr_t) &&
mask > (dma_addr_t)~0 &&
dma_to_pfn(dev, ~0) > arm_dma_pfn_limit) {
dma_to_pfn(dev, ~0) > max_dma_pfn) {
dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n",
mask);
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)
* fits within the allowable addresses which we can
* allocate.
*/
if (dma_to_pfn(dev, mask) < arm_dma_pfn_limit) {
if (dma_to_pfn(dev, mask) < max_dma_pfn) {
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",
mask,
dma_to_pfn(dev, 0), dma_to_pfn(dev, mask) + 1,