2 * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch>
3 * Copyright (C) 2009 Wind River Systems Inc
4 * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
6 * Based on DMA code from MIPS.
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
13 #include <linux/types.h>
15 #include <linux/export.h>
16 #include <linux/string.h>
17 #include <linux/scatterlist.h>
18 #include <linux/dma-mapping.h>
20 #include <linux/cache.h>
21 #include <asm/cacheflush.h>
24 void *dma_alloc_coherent(struct device
*dev
, size_t size
,
25 dma_addr_t
*dma_handle
, gfp_t gfp
)
29 /* ignore region specifiers */
30 gfp
&= ~(__GFP_DMA
| __GFP_HIGHMEM
);
32 /* optimized page clearing */
35 if (dev
== NULL
|| (dev
->coherent_dma_mask
< 0xffffffff))
38 ret
= (void *) __get_free_pages(gfp
, get_order(size
));
40 *dma_handle
= virt_to_phys(ret
);
41 flush_dcache_range((unsigned long) ret
,
42 (unsigned long) ret
+ size
);
43 ret
= UNCAC_ADDR(ret
);
48 EXPORT_SYMBOL(dma_alloc_coherent
);
50 void dma_free_coherent(struct device
*dev
, size_t size
, void *vaddr
,
51 dma_addr_t dma_handle
)
53 unsigned long addr
= (unsigned long) CAC_ADDR((unsigned long) vaddr
);
55 free_pages(addr
, get_order(size
));
57 EXPORT_SYMBOL(dma_free_coherent
);
59 int dma_map_sg(struct device
*dev
, struct scatterlist
*sg
, int nents
,
60 enum dma_data_direction direction
)
64 BUG_ON(!valid_dma_direction(direction
));
66 for_each_sg(sg
, sg
, nents
, i
) {
71 __dma_sync_for_device(addr
, sg
->length
, direction
);
72 sg
->dma_address
= sg_phys(sg
);
78 EXPORT_SYMBOL(dma_map_sg
);
80 dma_addr_t
dma_map_page(struct device
*dev
, struct page
*page
,
81 unsigned long offset
, size_t size
,
82 enum dma_data_direction direction
)
86 BUG_ON(!valid_dma_direction(direction
));
88 addr
= page_address(page
) + offset
;
89 __dma_sync_for_device(addr
, size
, direction
);
91 return page_to_phys(page
) + offset
;
93 EXPORT_SYMBOL(dma_map_page
);
95 void dma_unmap_page(struct device
*dev
, dma_addr_t dma_address
, size_t size
,
96 enum dma_data_direction direction
)
98 BUG_ON(!valid_dma_direction(direction
));
100 __dma_sync_for_cpu(phys_to_virt(dma_address
), size
, direction
);
102 EXPORT_SYMBOL(dma_unmap_page
);
104 void dma_unmap_sg(struct device
*dev
, struct scatterlist
*sg
, int nhwentries
,
105 enum dma_data_direction direction
)
110 BUG_ON(!valid_dma_direction(direction
));
112 if (direction
== DMA_TO_DEVICE
)
115 for_each_sg(sg
, sg
, nhwentries
, i
) {
118 __dma_sync_for_cpu(addr
, sg
->length
, direction
);
121 EXPORT_SYMBOL(dma_unmap_sg
);
123 void dma_sync_single_for_cpu(struct device
*dev
, dma_addr_t dma_handle
,
124 size_t size
, enum dma_data_direction direction
)
126 BUG_ON(!valid_dma_direction(direction
));
128 __dma_sync_for_cpu(phys_to_virt(dma_handle
), size
, direction
);
130 EXPORT_SYMBOL(dma_sync_single_for_cpu
);
132 void dma_sync_single_for_device(struct device
*dev
, dma_addr_t dma_handle
,
133 size_t size
, enum dma_data_direction direction
)
135 BUG_ON(!valid_dma_direction(direction
));
137 __dma_sync_for_device(phys_to_virt(dma_handle
), size
, direction
);
139 EXPORT_SYMBOL(dma_sync_single_for_device
);
141 void dma_sync_single_range_for_cpu(struct device
*dev
, dma_addr_t dma_handle
,
142 unsigned long offset
, size_t size
,
143 enum dma_data_direction direction
)
145 BUG_ON(!valid_dma_direction(direction
));
147 __dma_sync_for_cpu(phys_to_virt(dma_handle
), size
, direction
);
149 EXPORT_SYMBOL(dma_sync_single_range_for_cpu
);
151 void dma_sync_single_range_for_device(struct device
*dev
, dma_addr_t dma_handle
,
152 unsigned long offset
, size_t size
,
153 enum dma_data_direction direction
)
155 BUG_ON(!valid_dma_direction(direction
));
157 __dma_sync_for_device(phys_to_virt(dma_handle
), size
, direction
);
159 EXPORT_SYMBOL(dma_sync_single_range_for_device
);
161 void dma_sync_sg_for_cpu(struct device
*dev
, struct scatterlist
*sg
, int nelems
,
162 enum dma_data_direction direction
)
166 BUG_ON(!valid_dma_direction(direction
));
168 /* Make sure that gcc doesn't leave the empty loop body. */
169 for_each_sg(sg
, sg
, nelems
, i
)
170 __dma_sync_for_cpu(sg_virt(sg
), sg
->length
, direction
);
172 EXPORT_SYMBOL(dma_sync_sg_for_cpu
);
174 void dma_sync_sg_for_device(struct device
*dev
, struct scatterlist
*sg
,
175 int nelems
, enum dma_data_direction direction
)
179 BUG_ON(!valid_dma_direction(direction
));
181 /* Make sure that gcc doesn't leave the empty loop body. */
182 for_each_sg(sg
, sg
, nelems
, i
)
183 __dma_sync_for_device(sg_virt(sg
), sg
->length
, direction
);
186 EXPORT_SYMBOL(dma_sync_sg_for_device
);