diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-07-18 18:00:42 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-07-18 18:00:42 -0400 |
commit | 07f1c295de593ec0b0dca3092299c048c03374da (patch) | |
tree | ad8f291e550b3315f84c07e9f543e25adcf95dc3 /arch/arm/mm | |
parent | 4aa96ccf9ee35cdbd0d423e87a4d551019570218 (diff) | |
parent | fb89fcfb151698776be6c900aec8161b01990e92 (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.c | 35 | ||||
-rw-r--r-- | arch/arm/mm/init.c | 26 | ||||
-rw-r--r-- | arch/arm/mm/mm.h | 6 |
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 | |||
28 | static u64 get_coherent_dma_mask(struct device *dev) | 30 | static 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 | } |
658 | EXPORT_SYMBOL(dma_sync_sg_for_device); | 660 | EXPORT_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 | */ | ||
668 | int dma_supported(struct device *dev, u64 mask) | ||
669 | { | ||
670 | if (mask < (u64)arm_dma_limit) | ||
671 | return 0; | ||
672 | return 1; | ||
673 | } | ||
674 | EXPORT_SYMBOL(dma_supported); | ||
675 | |||
676 | int 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 | } | ||
687 | EXPORT_SYMBOL(dma_set_mask); | ||
688 | |||
660 | #define PREALLOC_DMA_DEBUG_ENTRIES 4096 | 689 | #define PREALLOC_DMA_DEBUG_ENTRIES 4096 |
661 | 690 | ||
662 | static int __init dma_debug_do_init(void) | 691 | static 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 | |||
216 | unsigned long arm_dma_zone_size __read_mostly; | ||
217 | EXPORT_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 | */ | ||
225 | u32 arm_dma_limit; | ||
226 | |||
215 | static void __init arm_adjust_dma_zone(unsigned long *size, unsigned long *hole, | 227 | static 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 | ||
27 | extern u32 arm_dma_limit; | ||
28 | #else | ||
29 | #define arm_dma_limit ((u32)~0) | ||
30 | #endif | ||
31 | |||
26 | void __init bootmem_init(void); | 32 | void __init bootmem_init(void); |
27 | void arm_mm_memblock_reserve(void); | 33 | void arm_mm_memblock_reserve(void); |