aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2011-07-18 18:00:42 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-07-18 18:00:42 -0400
commit07f1c295de593ec0b0dca3092299c048c03374da (patch)
treead8f291e550b3315f84c07e9f543e25adcf95dc3 /arch/arm/mm
parent4aa96ccf9ee35cdbd0d423e87a4d551019570218 (diff)
parentfb89fcfb151698776be6c900aec8161b01990e92 (diff)
Merge branch 'dma' of http://git.linaro.org/git/people/nico/linux into devel-stable
Diffstat (limited to 'arch/arm/mm')
-rw-r--r--arch/arm/mm/dma-mapping.c35
-rw-r--r--arch/arm/mm/init.c26
-rw-r--r--arch/arm/mm/mm.h6
3 files changed, 57 insertions, 10 deletions
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 82a093cee09a..0a0a1e7c20d2 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -25,9 +25,11 @@
25#include <asm/tlbflush.h> 25#include <asm/tlbflush.h>
26#include <asm/sizes.h> 26#include <asm/sizes.h>
27 27
28#include "mm.h"
29
28static u64 get_coherent_dma_mask(struct device *dev) 30static u64 get_coherent_dma_mask(struct device *dev)
29{ 31{
30 u64 mask = ISA_DMA_THRESHOLD; 32 u64 mask = (u64)arm_dma_limit;
31 33
32 if (dev) { 34 if (dev) {
33 mask = dev->coherent_dma_mask; 35 mask = dev->coherent_dma_mask;
@@ -41,10 +43,10 @@ static u64 get_coherent_dma_mask(struct device *dev)
41 return 0; 43 return 0;
42 } 44 }
43 45
44 if ((~mask) & ISA_DMA_THRESHOLD) { 46 if ((~mask) & (u64)arm_dma_limit) {
45 dev_warn(dev, "coherent DMA mask %#llx is smaller " 47 dev_warn(dev, "coherent DMA mask %#llx is smaller "
46 "than system GFP_DMA mask %#llx\n", 48 "than system GFP_DMA mask %#llx\n",
47 mask, (unsigned long long)ISA_DMA_THRESHOLD); 49 mask, (u64)arm_dma_limit);
48 return 0; 50 return 0;
49 } 51 }
50 } 52 }
@@ -657,6 +659,33 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
657} 659}
658EXPORT_SYMBOL(dma_sync_sg_for_device); 660EXPORT_SYMBOL(dma_sync_sg_for_device);
659 661
662/*
663 * Return whether the given device DMA address mask can be supported
664 * properly. For example, if your device can only drive the low 24-bits
665 * during bus mastering, then you would pass 0x00ffffff as the mask
666 * to this function.
667 */
668int dma_supported(struct device *dev, u64 mask)
669{
670 if (mask < (u64)arm_dma_limit)
671 return 0;
672 return 1;
673}
674EXPORT_SYMBOL(dma_supported);
675
676int dma_set_mask(struct device *dev, u64 dma_mask)
677{
678 if (!dev->dma_mask || !dma_supported(dev, dma_mask))
679 return -EIO;
680
681#ifndef CONFIG_DMABOUNCE
682 *dev->dma_mask = dma_mask;
683#endif
684
685 return 0;
686}
687EXPORT_SYMBOL(dma_set_mask);
688
660#define PREALLOC_DMA_DEBUG_ENTRIES 4096 689#define PREALLOC_DMA_DEBUG_ENTRIES 4096
661 690
662static int __init dma_debug_do_init(void) 691static int __init dma_debug_do_init(void)
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index c19571c40a21..90a38c6baca4 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -212,6 +212,18 @@ static void __init arm_bootmem_init(unsigned long start_pfn,
212} 212}
213 213
214#ifdef CONFIG_ZONE_DMA 214#ifdef CONFIG_ZONE_DMA
215
216unsigned long arm_dma_zone_size __read_mostly;
217EXPORT_SYMBOL(arm_dma_zone_size);
218
219/*
220 * The DMA mask corresponding to the maximum bus address allocatable
221 * using GFP_DMA. The default here places no restriction on DMA
222 * allocations. This must be the smallest DMA mask in the system,
223 * so a successful GFP_DMA allocation will always satisfy this.
224 */
225u32 arm_dma_limit;
226
215static void __init arm_adjust_dma_zone(unsigned long *size, unsigned long *hole, 227static void __init arm_adjust_dma_zone(unsigned long *size, unsigned long *hole,
216 unsigned long dma_size) 228 unsigned long dma_size)
217{ 229{
@@ -267,17 +279,17 @@ static void __init arm_bootmem_free(unsigned long min, unsigned long max_low,
267#endif 279#endif
268 } 280 }
269 281
270#ifdef ARM_DMA_ZONE_SIZE 282#ifdef CONFIG_ZONE_DMA
271#ifndef CONFIG_ZONE_DMA
272#error ARM_DMA_ZONE_SIZE set but no DMA zone to limit allocations
273#endif
274
275 /* 283 /*
276 * Adjust the sizes according to any special requirements for 284 * Adjust the sizes according to any special requirements for
277 * this machine type. 285 * this machine type.
278 */ 286 */
279 arm_adjust_dma_zone(zone_size, zhole_size, 287 if (arm_dma_zone_size) {
280 ARM_DMA_ZONE_SIZE >> PAGE_SHIFT); 288 arm_adjust_dma_zone(zone_size, zhole_size,
289 arm_dma_zone_size >> PAGE_SHIFT);
290 arm_dma_limit = PHYS_OFFSET + arm_dma_zone_size - 1;
291 } else
292 arm_dma_limit = 0xffffffff;
281#endif 293#endif
282 294
283 free_area_init_node(0, zone_size, min, zhole_size); 295 free_area_init_node(0, zone_size, min, zhole_size);
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index 5b3d7d543659..010566799c80 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -23,5 +23,11 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page
23 23
24#endif 24#endif
25 25
26#ifdef CONFIG_ZONE_DMA
27extern u32 arm_dma_limit;
28#else
29#define arm_dma_limit ((u32)~0)
30#endif
31
26void __init bootmem_init(void); 32void __init bootmem_init(void);
27void arm_mm_memblock_reserve(void); 33void arm_mm_memblock_reserve(void);