diff options
-rw-r--r-- | arch/sh/mm/consistent.c | 46 | ||||
-rw-r--r-- | include/asm-sh/dma-mapping.h | 4 |
2 files changed, 30 insertions, 20 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 @@ | |||
1 | /* | 1 | /* |
2 | * arch/sh/mm/consistent.c | 2 | * arch/sh/mm/consistent.c |
3 | * | 3 | * |
4 | * Copyright (C) 2004 Paul Mundt | 4 | * Copyright (C) 2004 - 2007 Paul Mundt |
5 | * | 5 | * |
6 | * This file is subject to the terms and conditions of the GNU General Public | 6 | * This file is subject to the terms and conditions of the GNU General Public |
7 | * License. See the file "COPYING" in the main directory of this archive | 7 | * License. See the file "COPYING" in the main directory of this archive |
@@ -16,7 +16,7 @@ | |||
16 | void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle) | 16 | void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle) |
17 | { | 17 | { |
18 | struct page *page, *end, *free; | 18 | struct page *page, *end, *free; |
19 | void *ret; | 19 | void *ret, *vp; |
20 | int order; | 20 | int order; |
21 | 21 | ||
22 | size = PAGE_ALIGN(size); | 22 | size = PAGE_ALIGN(size); |
@@ -28,13 +28,20 @@ void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle) | |||
28 | split_page(page, order); | 28 | split_page(page, order); |
29 | 29 | ||
30 | ret = page_address(page); | 30 | ret = page_address(page); |
31 | memset(ret, 0, size); | ||
32 | *handle = virt_to_phys(ret); | 31 | *handle = virt_to_phys(ret); |
33 | 32 | ||
33 | vp = ioremap_nocache(*handle, size); | ||
34 | if (!vp) { | ||
35 | free_pages((unsigned long)ret, order); | ||
36 | return NULL; | ||
37 | } | ||
38 | |||
39 | memset(vp, 0, size); | ||
40 | |||
34 | /* | 41 | /* |
35 | * We must flush the cache before we pass it on to the device | 42 | * We must flush the cache before we pass it on to the device |
36 | */ | 43 | */ |
37 | __flush_purge_region(ret, size); | 44 | dma_cache_sync(NULL, ret, size, DMA_BIDIRECTIONAL); |
38 | 45 | ||
39 | page = virt_to_page(ret); | 46 | page = virt_to_page(ret); |
40 | free = page + (size >> PAGE_SHIFT); | 47 | free = page + (size >> PAGE_SHIFT); |
@@ -47,24 +54,31 @@ void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle) | |||
47 | } | 54 | } |
48 | } | 55 | } |
49 | 56 | ||
50 | return P2SEGADDR(ret); | 57 | return vp; |
51 | } | 58 | } |
59 | EXPORT_SYMBOL(consistent_alloc); | ||
52 | 60 | ||
53 | void consistent_free(void *vaddr, size_t size) | 61 | void consistent_free(void *vaddr, size_t size, dma_addr_t dma_handle) |
54 | { | 62 | { |
55 | unsigned long addr = P1SEGADDR((unsigned long)vaddr); | 63 | struct page *page; |
56 | struct page *page=virt_to_page(addr); | 64 | unsigned long addr; |
57 | int num_pages=(size+PAGE_SIZE-1) >> PAGE_SHIFT; | ||
58 | int i; | ||
59 | 65 | ||
60 | for(i=0;i<num_pages;i++) { | 66 | addr = (unsigned long)phys_to_virt((unsigned long)dma_handle); |
61 | __free_page((page+i)); | 67 | page = virt_to_page(addr); |
62 | } | 68 | |
69 | free_pages(addr, get_order(size)); | ||
70 | |||
71 | iounmap(vaddr); | ||
63 | } | 72 | } |
73 | EXPORT_SYMBOL(consistent_free); | ||
64 | 74 | ||
65 | void consistent_sync(void *vaddr, size_t size, int direction) | 75 | void consistent_sync(void *vaddr, size_t size, int direction) |
66 | { | 76 | { |
67 | void * p1addr = (void*) P1SEGADDR((unsigned long)vaddr); | 77 | #ifdef CONFIG_CPU_SH5 |
78 | void *p1addr = vaddr; | ||
79 | #else | ||
80 | void *p1addr = (void*) P1SEGADDR((unsigned long)vaddr); | ||
81 | #endif | ||
68 | 82 | ||
69 | switch (direction) { | 83 | switch (direction) { |
70 | case DMA_FROM_DEVICE: /* invalidate only */ | 84 | case DMA_FROM_DEVICE: /* invalidate only */ |
@@ -80,8 +94,4 @@ void consistent_sync(void *vaddr, size_t size, int direction) | |||
80 | BUG(); | 94 | BUG(); |
81 | } | 95 | } |
82 | } | 96 | } |
83 | |||
84 | EXPORT_SYMBOL(consistent_alloc); | ||
85 | EXPORT_SYMBOL(consistent_free); | ||
86 | EXPORT_SYMBOL(consistent_sync); | 97 | EXPORT_SYMBOL(consistent_sync); |
87 | |||
diff --git a/include/asm-sh/dma-mapping.h b/include/asm-sh/dma-mapping.h index fcea067f7a9c..20ae762e5258 100644 --- a/include/asm-sh/dma-mapping.h +++ b/include/asm-sh/dma-mapping.h | |||
@@ -10,7 +10,7 @@ extern struct bus_type pci_bus_type; | |||
10 | 10 | ||
11 | /* arch/sh/mm/consistent.c */ | 11 | /* arch/sh/mm/consistent.c */ |
12 | extern void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle); | 12 | extern void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle); |
13 | extern void consistent_free(void *vaddr, size_t size); | 13 | extern void consistent_free(void *vaddr, size_t size, dma_addr_t handle); |
14 | extern void consistent_sync(void *vaddr, size_t size, int direction); | 14 | extern void consistent_sync(void *vaddr, size_t size, int direction); |
15 | 15 | ||
16 | #define dma_supported(dev, mask) (1) | 16 | #define dma_supported(dev, mask) (1) |
@@ -50,7 +50,7 @@ static inline void dma_free_coherent(struct device *dev, size_t size, | |||
50 | return; | 50 | return; |
51 | } | 51 | } |
52 | 52 | ||
53 | consistent_free(vaddr, size); | 53 | consistent_free(vaddr, size, dma_handle); |
54 | } | 54 | } |
55 | 55 | ||
56 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) | 56 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) |