diff options
author | Lennert Buytenhek <buytenh@wantstofly.org> | 2006-04-01 18:07:39 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2006-04-01 18:07:39 -0500 |
commit | 23759dc6430428897a36c4d493f611eca55c9481 (patch) | |
tree | c62050927599b36ed223753c35fd737e3c0c6762 /arch/arm/mm/consistent.c | |
parent | d3f4c571b6e596f9d39c596426269006a309d3b8 (diff) |
[ARM] 3439/2: xsc3: add I/O coherency support
Patch from Lennert Buytenhek
This patch adds support for the I/O coherent cache available on the
xsc3. The approach is to provide a simple API to determine whether the
chipset supports coherency by calling arch_is_coherent() and then
setting the appropriate system memory PTE and PMD bits. In addition,
we call this API on dma_alloc_coherent() and dma_map_single() calls.
A generic version exists that will compile out all the coherency-related
code that is not needed on the majority of ARM systems.
Note that we do not check for coherency in the dma_alloc_writecombine()
function as that still requires a special PTE setting. We also don't
touch dma_mmap_coherent() as that is a special ARM-only API that is by
definition only used on non-coherent system.
Signed-off-by: Deepak Saxena <dsaxena@plexity.net>
Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mm/consistent.c')
-rw-r--r-- | arch/arm/mm/consistent.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c index 8a1bfcd50087..50e6b6bfb2e2 100644 --- a/arch/arm/mm/consistent.c +++ b/arch/arm/mm/consistent.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/device.h> | 18 | #include <linux/device.h> |
19 | #include <linux/dma-mapping.h> | 19 | #include <linux/dma-mapping.h> |
20 | 20 | ||
21 | #include <asm/memory.h> | ||
21 | #include <asm/cacheflush.h> | 22 | #include <asm/cacheflush.h> |
22 | #include <asm/tlbflush.h> | 23 | #include <asm/tlbflush.h> |
23 | #include <asm/sizes.h> | 24 | #include <asm/sizes.h> |
@@ -272,6 +273,17 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, | |||
272 | void * | 273 | void * |
273 | dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) | 274 | dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) |
274 | { | 275 | { |
276 | if (arch_is_coherent()) { | ||
277 | void *virt; | ||
278 | |||
279 | virt = kmalloc(size, gfp); | ||
280 | if (!virt) | ||
281 | return NULL; | ||
282 | *handle = virt_to_dma(dev, virt); | ||
283 | |||
284 | return virt; | ||
285 | } | ||
286 | |||
275 | return __dma_alloc(dev, size, handle, gfp, | 287 | return __dma_alloc(dev, size, handle, gfp, |
276 | pgprot_noncached(pgprot_kernel)); | 288 | pgprot_noncached(pgprot_kernel)); |
277 | } | 289 | } |
@@ -350,6 +362,11 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr | |||
350 | 362 | ||
351 | WARN_ON(irqs_disabled()); | 363 | WARN_ON(irqs_disabled()); |
352 | 364 | ||
365 | if (arch_is_coherent()) { | ||
366 | kfree(cpu_addr); | ||
367 | return; | ||
368 | } | ||
369 | |||
353 | size = PAGE_ALIGN(size); | 370 | size = PAGE_ALIGN(size); |
354 | 371 | ||
355 | spin_lock_irqsave(&consistent_lock, flags); | 372 | spin_lock_irqsave(&consistent_lock, flags); |