diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-11-19 10:38:12 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-11-24 12:41:34 -0500 |
commit | 3e82d012e9281a0b6388ff2356e8396b9d781e1c (patch) | |
tree | c76320422bd3988e499680662b3bebbf9796589b /arch/arm/mm/dma-mapping.c | |
parent | 7a9a32a9533fa01de911e1d056142ddd27360782 (diff) |
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>
Diffstat (limited to 'arch/arm/mm/dma-mapping.c')
-rw-r--r-- | arch/arm/mm/dma-mapping.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index dab2d7f04adf..a67130873431 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c | |||
@@ -246,14 +246,16 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gf | |||
246 | return memory; | 246 | return memory; |
247 | 247 | ||
248 | if (arch_is_coherent()) { | 248 | if (arch_is_coherent()) { |
249 | void *virt; | 249 | struct page *page; |
250 | 250 | ||
251 | virt = kmalloc(size, gfp); | 251 | page = __dma_alloc_buffer(dev, PAGE_ALIGN(size), gfp); |
252 | if (!virt) | 252 | if (!page) { |
253 | *handle = ~0; | ||
253 | return NULL; | 254 | return NULL; |
254 | *handle = virt_to_dma(dev, virt); | 255 | } |
255 | 256 | ||
256 | return virt; | 257 | *handle = page_to_dma(dev, page); |
258 | return page_address(page); | ||
257 | } | 259 | } |
258 | 260 | ||
259 | return __dma_alloc(dev, size, handle, gfp, | 261 | return __dma_alloc(dev, size, handle, gfp, |
@@ -336,13 +338,13 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr | |||
336 | if (dma_release_from_coherent(dev, get_order(size), cpu_addr)) | 338 | if (dma_release_from_coherent(dev, get_order(size), cpu_addr)) |
337 | return; | 339 | return; |
338 | 340 | ||
341 | size = PAGE_ALIGN(size); | ||
342 | |||
339 | if (arch_is_coherent()) { | 343 | if (arch_is_coherent()) { |
340 | kfree(cpu_addr); | 344 | __dma_free_buffer(dma_to_page(dev, handle), size); |
341 | return; | 345 | return; |
342 | } | 346 | } |
343 | 347 | ||
344 | size = PAGE_ALIGN(size); | ||
345 | |||
346 | c = arm_vmregion_find_remove(&consistent_head, (unsigned long)cpu_addr); | 348 | c = arm_vmregion_find_remove(&consistent_head, (unsigned long)cpu_addr); |
347 | if (!c) | 349 | if (!c) |
348 | goto no_area; | 350 | goto no_area; |