diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2006-11-15 21:56:12 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2007-02-13 17:40:50 -0500 |
commit | 9a88cbb5227970757881b1a65be01dea61fe2584 (patch) | |
tree | 2a1e6934ae253e75141efd383ae9df7042452d7c /arch/mips/mm/dma-noncoherent.c | |
parent | f65e4fa8e0c6022ad58dc88d1b11b12589ed7f9f (diff) |
[MIPS] Unify dma-{coherent,noncoherent.ip27,ip32}
Platforms will now have to supply a function dma_device_is_coherent which
returns if a particular device participates in the coherence domain. For
most platforms this function will always return 0 or 1.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/mm/dma-noncoherent.c')
-rw-r--r-- | arch/mips/mm/dma-noncoherent.c | 370 |
1 files changed, 0 insertions, 370 deletions
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c deleted file mode 100644 index 8cecef0957c3..000000000000 --- a/arch/mips/mm/dma-noncoherent.c +++ /dev/null | |||
@@ -1,370 +0,0 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2000 Ani Joshi <ajoshi@unixbox.com> | ||
7 | * Copyright (C) 2000, 2001 Ralf Baechle <ralf@gnu.org> | ||
8 | * swiped from i386, and cloned for MIPS by Geert, polished by Ralf. | ||
9 | */ | ||
10 | #include <linux/types.h> | ||
11 | #include <linux/mm.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/string.h> | ||
14 | #include <linux/dma-mapping.h> | ||
15 | |||
16 | #include <asm/cache.h> | ||
17 | #include <asm/io.h> | ||
18 | |||
19 | /* | ||
20 | * Warning on the terminology - Linux calls an uncached area coherent; | ||
21 | * MIPS terminology calls memory areas with hardware maintained coherency | ||
22 | * coherent. | ||
23 | */ | ||
24 | |||
25 | void *dma_alloc_noncoherent(struct device *dev, size_t size, | ||
26 | dma_addr_t * dma_handle, gfp_t gfp) | ||
27 | { | ||
28 | void *ret; | ||
29 | /* ignore region specifiers */ | ||
30 | gfp &= ~(__GFP_DMA | __GFP_HIGHMEM); | ||
31 | |||
32 | if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff)) | ||
33 | gfp |= GFP_DMA; | ||
34 | ret = (void *) __get_free_pages(gfp, get_order(size)); | ||
35 | |||
36 | if (ret != NULL) { | ||
37 | memset(ret, 0, size); | ||
38 | *dma_handle = virt_to_phys(ret); | ||
39 | } | ||
40 | |||
41 | return ret; | ||
42 | } | ||
43 | |||
44 | EXPORT_SYMBOL(dma_alloc_noncoherent); | ||
45 | |||
46 | void *dma_alloc_coherent(struct device *dev, size_t size, | ||
47 | dma_addr_t * dma_handle, gfp_t gfp) | ||
48 | { | ||
49 | void *ret; | ||
50 | |||
51 | ret = dma_alloc_noncoherent(dev, size, dma_handle, gfp); | ||
52 | if (ret) { | ||
53 | dma_cache_wback_inv((unsigned long) ret, size); | ||
54 | ret = UNCAC_ADDR(ret); | ||
55 | } | ||
56 | |||
57 | return ret; | ||
58 | } | ||
59 | |||
60 | EXPORT_SYMBOL(dma_alloc_coherent); | ||
61 | |||
62 | void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr, | ||
63 | dma_addr_t dma_handle) | ||
64 | { | ||
65 | free_pages((unsigned long) vaddr, get_order(size)); | ||
66 | } | ||
67 | |||
68 | EXPORT_SYMBOL(dma_free_noncoherent); | ||
69 | |||
70 | void dma_free_coherent(struct device *dev, size_t size, void *vaddr, | ||
71 | dma_addr_t dma_handle) | ||
72 | { | ||
73 | unsigned long addr = (unsigned long) vaddr; | ||
74 | |||
75 | addr = CAC_ADDR(addr); | ||
76 | free_pages(addr, get_order(size)); | ||
77 | } | ||
78 | |||
79 | EXPORT_SYMBOL(dma_free_coherent); | ||
80 | |||
81 | static inline void __dma_sync(unsigned long addr, size_t size, | ||
82 | enum dma_data_direction direction) | ||
83 | { | ||
84 | switch (direction) { | ||
85 | case DMA_TO_DEVICE: | ||
86 | dma_cache_wback(addr, size); | ||
87 | break; | ||
88 | |||
89 | case DMA_FROM_DEVICE: | ||
90 | dma_cache_inv(addr, size); | ||
91 | break; | ||
92 | |||
93 | case DMA_BIDIRECTIONAL: | ||
94 | dma_cache_wback_inv(addr, size); | ||
95 | break; | ||
96 | |||
97 | default: | ||
98 | BUG(); | ||
99 | } | ||
100 | } | ||
101 | |||
102 | dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, | ||
103 | enum dma_data_direction direction) | ||
104 | { | ||
105 | unsigned long addr = (unsigned long) ptr; | ||
106 | |||
107 | __dma_sync(addr, size, direction); | ||
108 | |||
109 | return virt_to_phys(ptr); | ||
110 | } | ||
111 | |||
112 | EXPORT_SYMBOL(dma_map_single); | ||
113 | |||
114 | void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, | ||
115 | enum dma_data_direction direction) | ||
116 | { | ||
117 | unsigned long addr; | ||
118 | addr = dma_addr + PAGE_OFFSET; | ||
119 | |||
120 | //__dma_sync(addr, size, direction); | ||
121 | } | ||
122 | |||
123 | EXPORT_SYMBOL(dma_unmap_single); | ||
124 | |||
125 | int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, | ||
126 | enum dma_data_direction direction) | ||
127 | { | ||
128 | int i; | ||
129 | |||
130 | BUG_ON(direction == DMA_NONE); | ||
131 | |||
132 | for (i = 0; i < nents; i++, sg++) { | ||
133 | unsigned long addr; | ||
134 | |||
135 | addr = (unsigned long) page_address(sg->page); | ||
136 | if (addr) { | ||
137 | __dma_sync(addr + sg->offset, sg->length, direction); | ||
138 | sg->dma_address = (dma_addr_t)page_to_phys(sg->page) | ||
139 | + sg->offset; | ||
140 | } | ||
141 | } | ||
142 | |||
143 | return nents; | ||
144 | } | ||
145 | |||
146 | EXPORT_SYMBOL(dma_map_sg); | ||
147 | |||
148 | dma_addr_t dma_map_page(struct device *dev, struct page *page, | ||
149 | unsigned long offset, size_t size, enum dma_data_direction direction) | ||
150 | { | ||
151 | unsigned long addr; | ||
152 | |||
153 | BUG_ON(direction == DMA_NONE); | ||
154 | |||
155 | addr = (unsigned long) page_address(page) + offset; | ||
156 | dma_cache_wback_inv(addr, size); | ||
157 | |||
158 | return page_to_phys(page) + offset; | ||
159 | } | ||
160 | |||
161 | EXPORT_SYMBOL(dma_map_page); | ||
162 | |||
163 | void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, | ||
164 | enum dma_data_direction direction) | ||
165 | { | ||
166 | BUG_ON(direction == DMA_NONE); | ||
167 | |||
168 | if (direction != DMA_TO_DEVICE) { | ||
169 | unsigned long addr; | ||
170 | |||
171 | addr = dma_address + PAGE_OFFSET; | ||
172 | dma_cache_wback_inv(addr, size); | ||
173 | } | ||
174 | } | ||
175 | |||
176 | EXPORT_SYMBOL(dma_unmap_page); | ||
177 | |||
178 | void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, | ||
179 | enum dma_data_direction direction) | ||
180 | { | ||
181 | unsigned long addr; | ||
182 | int i; | ||
183 | |||
184 | BUG_ON(direction == DMA_NONE); | ||
185 | |||
186 | if (direction == DMA_TO_DEVICE) | ||
187 | return; | ||
188 | |||
189 | for (i = 0; i < nhwentries; i++, sg++) { | ||
190 | addr = (unsigned long) page_address(sg->page); | ||
191 | if (addr) | ||
192 | __dma_sync(addr + sg->offset, sg->length, direction); | ||
193 | } | ||
194 | } | ||
195 | |||
196 | EXPORT_SYMBOL(dma_unmap_sg); | ||
197 | |||
198 | void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, | ||
199 | size_t size, enum dma_data_direction direction) | ||
200 | { | ||
201 | unsigned long addr; | ||
202 | |||
203 | BUG_ON(direction == DMA_NONE); | ||
204 | |||
205 | addr = dma_handle + PAGE_OFFSET; | ||
206 | __dma_sync(addr, size, direction); | ||
207 | } | ||
208 | |||
209 | EXPORT_SYMBOL(dma_sync_single_for_cpu); | ||
210 | |||
211 | void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, | ||
212 | size_t size, enum dma_data_direction direction) | ||
213 | { | ||
214 | unsigned long addr; | ||
215 | |||
216 | BUG_ON(direction == DMA_NONE); | ||
217 | |||
218 | addr = dma_handle + PAGE_OFFSET; | ||
219 | __dma_sync(addr, size, direction); | ||
220 | } | ||
221 | |||
222 | EXPORT_SYMBOL(dma_sync_single_for_device); | ||
223 | |||
224 | void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle, | ||
225 | unsigned long offset, size_t size, enum dma_data_direction direction) | ||
226 | { | ||
227 | unsigned long addr; | ||
228 | |||
229 | BUG_ON(direction == DMA_NONE); | ||
230 | |||
231 | addr = dma_handle + offset + PAGE_OFFSET; | ||
232 | __dma_sync(addr, size, direction); | ||
233 | } | ||
234 | |||
235 | EXPORT_SYMBOL(dma_sync_single_range_for_cpu); | ||
236 | |||
237 | void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle, | ||
238 | unsigned long offset, size_t size, enum dma_data_direction direction) | ||
239 | { | ||
240 | unsigned long addr; | ||
241 | |||
242 | BUG_ON(direction == DMA_NONE); | ||
243 | |||
244 | addr = dma_handle + offset + PAGE_OFFSET; | ||
245 | __dma_sync(addr, size, direction); | ||
246 | } | ||
247 | |||
248 | EXPORT_SYMBOL(dma_sync_single_range_for_device); | ||
249 | |||
250 | void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, | ||
251 | enum dma_data_direction direction) | ||
252 | { | ||
253 | int i; | ||
254 | |||
255 | BUG_ON(direction == DMA_NONE); | ||
256 | |||
257 | /* Make sure that gcc doesn't leave the empty loop body. */ | ||
258 | for (i = 0; i < nelems; i++, sg++) | ||
259 | __dma_sync((unsigned long)page_address(sg->page), | ||
260 | sg->length, direction); | ||
261 | } | ||
262 | |||
263 | EXPORT_SYMBOL(dma_sync_sg_for_cpu); | ||
264 | |||
265 | void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, | ||
266 | enum dma_data_direction direction) | ||
267 | { | ||
268 | int i; | ||
269 | |||
270 | BUG_ON(direction == DMA_NONE); | ||
271 | |||
272 | /* Make sure that gcc doesn't leave the empty loop body. */ | ||
273 | for (i = 0; i < nelems; i++, sg++) | ||
274 | __dma_sync((unsigned long)page_address(sg->page), | ||
275 | sg->length, direction); | ||
276 | } | ||
277 | |||
278 | EXPORT_SYMBOL(dma_sync_sg_for_device); | ||
279 | |||
280 | int dma_mapping_error(dma_addr_t dma_addr) | ||
281 | { | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | EXPORT_SYMBOL(dma_mapping_error); | ||
286 | |||
287 | int dma_supported(struct device *dev, u64 mask) | ||
288 | { | ||
289 | /* | ||
290 | * we fall back to GFP_DMA when the mask isn't all 1s, | ||
291 | * so we can't guarantee allocations that must be | ||
292 | * within a tighter range than GFP_DMA.. | ||
293 | */ | ||
294 | if (mask < 0x00ffffff) | ||
295 | return 0; | ||
296 | |||
297 | return 1; | ||
298 | } | ||
299 | |||
300 | EXPORT_SYMBOL(dma_supported); | ||
301 | |||
302 | int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) | ||
303 | { | ||
304 | return 1; | ||
305 | } | ||
306 | |||
307 | EXPORT_SYMBOL(dma_is_consistent); | ||
308 | |||
309 | void dma_cache_sync(struct device *dev, void *vaddr, size_t size, | ||
310 | enum dma_data_direction direction) | ||
311 | { | ||
312 | if (direction == DMA_NONE) | ||
313 | return; | ||
314 | |||
315 | dma_cache_wback_inv((unsigned long)vaddr, size); | ||
316 | } | ||
317 | |||
318 | EXPORT_SYMBOL(dma_cache_sync); | ||
319 | |||
320 | /* The DAC routines are a PCIism.. */ | ||
321 | |||
322 | #ifdef CONFIG_PCI | ||
323 | |||
324 | #include <linux/pci.h> | ||
325 | |||
326 | dma64_addr_t pci_dac_page_to_dma(struct pci_dev *pdev, | ||
327 | struct page *page, unsigned long offset, int direction) | ||
328 | { | ||
329 | return (dma64_addr_t)page_to_phys(page) + offset; | ||
330 | } | ||
331 | |||
332 | EXPORT_SYMBOL(pci_dac_page_to_dma); | ||
333 | |||
334 | struct page *pci_dac_dma_to_page(struct pci_dev *pdev, | ||
335 | dma64_addr_t dma_addr) | ||
336 | { | ||
337 | return mem_map + (dma_addr >> PAGE_SHIFT); | ||
338 | } | ||
339 | |||
340 | EXPORT_SYMBOL(pci_dac_dma_to_page); | ||
341 | |||
342 | unsigned long pci_dac_dma_to_offset(struct pci_dev *pdev, | ||
343 | dma64_addr_t dma_addr) | ||
344 | { | ||
345 | return dma_addr & ~PAGE_MASK; | ||
346 | } | ||
347 | |||
348 | EXPORT_SYMBOL(pci_dac_dma_to_offset); | ||
349 | |||
350 | void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev, | ||
351 | dma64_addr_t dma_addr, size_t len, int direction) | ||
352 | { | ||
353 | BUG_ON(direction == PCI_DMA_NONE); | ||
354 | |||
355 | dma_cache_wback_inv(dma_addr + PAGE_OFFSET, len); | ||
356 | } | ||
357 | |||
358 | EXPORT_SYMBOL(pci_dac_dma_sync_single_for_cpu); | ||
359 | |||
360 | void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, | ||
361 | dma64_addr_t dma_addr, size_t len, int direction) | ||
362 | { | ||
363 | BUG_ON(direction == PCI_DMA_NONE); | ||
364 | |||
365 | dma_cache_wback_inv(dma_addr + PAGE_OFFSET, len); | ||
366 | } | ||
367 | |||
368 | EXPORT_SYMBOL(pci_dac_dma_sync_single_for_device); | ||
369 | |||
370 | #endif /* CONFIG_PCI */ | ||