[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>
This commit is contained in:

committed by
Russell King

parent
d3f4c571b6
commit
23759dc643
@@ -18,6 +18,7 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
#include <asm/memory.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/sizes.h>
|
||||
@@ -272,6 +273,17 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
|
||||
void *
|
||||
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
|
||||
{
|
||||
if (arch_is_coherent()) {
|
||||
void *virt;
|
||||
|
||||
virt = kmalloc(size, gfp);
|
||||
if (!virt)
|
||||
return NULL;
|
||||
*handle = virt_to_dma(dev, virt);
|
||||
|
||||
return virt;
|
||||
}
|
||||
|
||||
return __dma_alloc(dev, size, handle, gfp,
|
||||
pgprot_noncached(pgprot_kernel));
|
||||
}
|
||||
@@ -350,6 +362,11 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr
|
||||
|
||||
WARN_ON(irqs_disabled());
|
||||
|
||||
if (arch_is_coherent()) {
|
||||
kfree(cpu_addr);
|
||||
return;
|
||||
}
|
||||
|
||||
size = PAGE_ALIGN(size);
|
||||
|
||||
spin_lock_irqsave(&consistent_lock, flags);
|
||||
|
Reference in New Issue
Block a user