diff options
author | Paul Mundt <lethal@linux-sh.org> | 2007-11-11 17:07:06 +0900 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2008-01-28 13:18:44 +0900 |
commit | 8a7bcf0dd0d49fe8b0071adef0dfe8610abdffaa (patch) | |
tree | e8f0875c391fa2c2d96746112d841c8ca48d1307 /arch | |
parent | b613881ead41c8fc2e1413aeb6ef8f021f00c1e7 (diff) |
sh: Add SH-5 support to the consistent DMA impl.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/sh/mm/consistent.c | 46 |
1 files changed, 28 insertions, 18 deletions
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c index e220c29a3c00..65ad30031ad7 100644 --- a/arch/sh/mm/consistent.c +++ b/arch/sh/mm/consistent.c @@ -1,7 +1,7 @@ /* * arch/sh/mm/consistent.c * - * Copyright (C) 2004 Paul Mundt + * Copyright (C) 2004 - 2007 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -16,7 +16,7 @@ void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle) { struct page *page, *end, *free; - void *ret; + void *ret, *vp; int order; size = PAGE_ALIGN(size); @@ -28,13 +28,20 @@ void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle) split_page(page, order); ret = page_address(page); - memset(ret, 0, size); *handle = virt_to_phys(ret); + vp = ioremap_nocache(*handle, size); + if (!vp) { + free_pages((unsigned long)ret, order); + return NULL; + } + + memset(vp, 0, size); + /* * We must flush the cache before we pass it on to the device */ - __flush_purge_region(ret, size); + dma_cache_sync(NULL, ret, size, DMA_BIDIRECTIONAL); page = virt_to_page(ret); free = page + (size >> PAGE_SHIFT); @@ -47,24 +54,31 @@ void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle) } } - return P2SEGADDR(ret); + return vp; } +EXPORT_SYMBOL(consistent_alloc); -void consistent_free(void *vaddr, size_t size) +void consistent_free(void *vaddr, size_t size, dma_addr_t dma_handle) { - unsigned long addr = P1SEGADDR((unsigned long)vaddr); - struct page *page=virt_to_page(addr); - int num_pages=(size+PAGE_SIZE-1) >> PAGE_SHIFT; - int i; + struct page *page; + unsigned long addr; - for(i=0;i<num_pages;i++) { - __free_page((page+i)); - } + addr = (unsigned long)phys_to_virt((unsigned long)dma_handle); + page = virt_to_page(addr); + + free_pages(addr, get_order(size)); + + iounmap(vaddr); } +EXPORT_SYMBOL(consistent_free); void consistent_sync(void *vaddr, size_t size, int direction) { - void * p1addr = (void*) P1SEGADDR((unsigned long)vaddr); +#ifdef CONFIG_CPU_SH5 + void *p1addr = vaddr; +#else + void *p1addr = (void*) P1SEGADDR((unsigned long)vaddr); +#endif switch (direction) { case DMA_FROM_DEVICE: /* invalidate only */ @@ -80,8 +94,4 @@ void consistent_sync(void *vaddr, size_t size, int direction) BUG(); } } - -EXPORT_SYMBOL(consistent_alloc); -EXPORT_SYMBOL(consistent_free); EXPORT_SYMBOL(consistent_sync); - |