diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2006-11-11 01:25:14 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-12-04 04:38:57 -0500 |
commit | 92b20c40dcca2d441f367da57e7665cce15c492a (patch) | |
tree | 937e98acbbc3db12c8ed99c4499794d39287f98f /arch/powerpc/kernel/dma_64.c | |
parent | 3bc0f40c287a435805b0545ffc44ea41f11cd43e (diff) |
[POWERPC] Add an optional offset to direct DMA on 64 bits
This patch adds an optional global offset that can be added to DMA addresses
when using the direct DMA operations.
That brings it a step closer to the 32 bits direct DMA operations, and makes
it useable on Cell when the MMU is disabled and we are using a spider
southbridge.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/dma_64.c')
-rw-r--r-- | arch/powerpc/kernel/dma_64.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c index 4e6551199782..1d1dc76606ac 100644 --- a/arch/powerpc/kernel/dma_64.c +++ b/arch/powerpc/kernel/dma_64.c | |||
@@ -111,7 +111,11 @@ EXPORT_SYMBOL(dma_iommu_ops); | |||
111 | 111 | ||
112 | /* | 112 | /* |
113 | * Generic direct DMA implementation | 113 | * Generic direct DMA implementation |
114 | * | ||
115 | * This implementation supports a global offset that can be applied if | ||
116 | * the address at which memory is visible to devices is not 0. | ||
114 | */ | 117 | */ |
118 | unsigned long dma_direct_offset; | ||
115 | 119 | ||
116 | static void *dma_direct_alloc_coherent(struct device *dev, size_t size, | 120 | static void *dma_direct_alloc_coherent(struct device *dev, size_t size, |
117 | dma_addr_t *dma_handle, gfp_t flag) | 121 | dma_addr_t *dma_handle, gfp_t flag) |
@@ -122,7 +126,7 @@ static void *dma_direct_alloc_coherent(struct device *dev, size_t size, | |||
122 | ret = (void *)__get_free_pages(flag, get_order(size)); | 126 | ret = (void *)__get_free_pages(flag, get_order(size)); |
123 | if (ret != NULL) { | 127 | if (ret != NULL) { |
124 | memset(ret, 0, size); | 128 | memset(ret, 0, size); |
125 | *dma_handle = virt_to_abs(ret); | 129 | *dma_handle = virt_to_abs(ret) | dma_direct_offset; |
126 | } | 130 | } |
127 | return ret; | 131 | return ret; |
128 | } | 132 | } |
@@ -137,7 +141,7 @@ static dma_addr_t dma_direct_map_single(struct device *dev, void *ptr, | |||
137 | size_t size, | 141 | size_t size, |
138 | enum dma_data_direction direction) | 142 | enum dma_data_direction direction) |
139 | { | 143 | { |
140 | return virt_to_abs(ptr); | 144 | return virt_to_abs(ptr) | dma_direct_offset; |
141 | } | 145 | } |
142 | 146 | ||
143 | static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr, | 147 | static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr, |
@@ -152,7 +156,8 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sg, | |||
152 | int i; | 156 | int i; |
153 | 157 | ||
154 | for (i = 0; i < nents; i++, sg++) { | 158 | for (i = 0; i < nents; i++, sg++) { |
155 | sg->dma_address = page_to_phys(sg->page) + sg->offset; | 159 | sg->dma_address = (page_to_phys(sg->page) + sg->offset) | |
160 | dma_direct_offset; | ||
156 | sg->dma_length = sg->length; | 161 | sg->dma_length = sg->length; |
157 | } | 162 | } |
158 | 163 | ||