ARM: dma-mapping: fix coherent arch dma_alloc_coherent()
The coherent architecture dma_alloc_coherent was using kmalloc/kfree to
manage the memory. dma_alloc_coherent() is expected to work with a
granularity of a page, so this is wrong. Fix it by using the helper
functions now provided.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Greg Ungerer <gerg@uclinux.org>
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index dab2d7f..a671308 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -246,14 +246,16 @@
return memory;
if (arch_is_coherent()) {
- void *virt;
+ struct page *page;
- virt = kmalloc(size, gfp);
- if (!virt)
+ page = __dma_alloc_buffer(dev, PAGE_ALIGN(size), gfp);
+ if (!page) {
+ *handle = ~0;
return NULL;
- *handle = virt_to_dma(dev, virt);
+ }
- return virt;
+ *handle = page_to_dma(dev, page);
+ return page_address(page);
}
return __dma_alloc(dev, size, handle, gfp,
@@ -336,13 +338,13 @@
if (dma_release_from_coherent(dev, get_order(size), cpu_addr))
return;
+ size = PAGE_ALIGN(size);
+
if (arch_is_coherent()) {
- kfree(cpu_addr);
+ __dma_free_buffer(dma_to_page(dev, handle), size);
return;
}
- size = PAGE_ALIGN(size);
-
c = arm_vmregion_find_remove(&consistent_head, (unsigned long)cpu_addr);
if (!c)
goto no_area;