ARM: dma-mapping: fix nommu dma_alloc_coherent()
The nommu version of 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 a671308..62b4240 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -212,24 +212,17 @@
__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
pgprot_t prot)
{
- void *virt;
- u64 mask = get_coherent_dma_mask(dev);
+ struct page *page;
- if (!mask)
- goto error;
-
- if (mask < 0xffffffffULL)
- gfp |= GFP_DMA;
- virt = kmalloc(size, gfp);
- if (!virt)
- goto error;
-
- *handle = virt_to_dma(dev, virt);
- return virt;
-
-error:
*handle = ~0;
- return NULL;
+ size = PAGE_ALIGN(size);
+
+ page = __dma_alloc_buffer(dev, size, gfp);
+ if (!page)
+ return NULL;
+
+ *handle = page_to_dma(dev, page);
+ return page_address(page);
}
#endif /* CONFIG_MMU */
@@ -406,7 +399,7 @@
{
if (dma_release_from_coherent(dev, get_order(size), cpu_addr))
return;
- kfree(cpu_addr);
+ __dma_free_buffer(dma_to_page(dev, handle), PAGE_ALIGN(size));
}
#endif /* CONFIG_MMU */
EXPORT_SYMBOL(dma_free_coherent);