aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-powerpc/dma-mapping.h
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-11-11 01:25:02 -0500
committerPaul Mackerras <paulus@samba.org>2006-12-04 04:38:40 -0500
commit12d04eef927bf61328af2c7cbe756c96f98ac3bf (patch)
tree18865369100e9059c7e883dec93ea67f7b52a287 /include/asm-powerpc/dma-mapping.h
parent7c719871ff4d5f15b71f0138d08b758281b58631 (diff)
[POWERPC] Refactor 64 bits DMA operations
This patch completely refactors DMA operations for 64 bits powerpc. 32 bits is untouched for now. We use the new dev_archdata structure to add the dma operations pointer and associated data to struct device. While at it, we also add the OF node pointer and numa node. In the future, we might want to look into merging that with pci_dn as well. The old vio, pci-iommu and pci-direct DMA ops are gone. They are now replaced by a set of generic iommu and direct DMA ops (non PCI specific) that can be used by bus types. The toplevel implementation is now inline. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'include/asm-powerpc/dma-mapping.h')
-rw-r--r--include/asm-powerpc/dma-mapping.h180
1 files changed, 141 insertions, 39 deletions
diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h
index 2ab9baf78bb4..8367810c994c 100644
--- a/include/asm-powerpc/dma-mapping.h
+++ b/include/asm-powerpc/dma-mapping.h
@@ -44,26 +44,148 @@ extern void __dma_sync_page(struct page *page, unsigned long offset,
44#endif /* ! CONFIG_NOT_COHERENT_CACHE */ 44#endif /* ! CONFIG_NOT_COHERENT_CACHE */
45 45
46#ifdef CONFIG_PPC64 46#ifdef CONFIG_PPC64
47/*
48 * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO
49 */
50struct dma_mapping_ops {
51 void * (*alloc_coherent)(struct device *dev, size_t size,
52 dma_addr_t *dma_handle, gfp_t flag);
53 void (*free_coherent)(struct device *dev, size_t size,
54 void *vaddr, dma_addr_t dma_handle);
55 dma_addr_t (*map_single)(struct device *dev, void *ptr,
56 size_t size, enum dma_data_direction direction);
57 void (*unmap_single)(struct device *dev, dma_addr_t dma_addr,
58 size_t size, enum dma_data_direction direction);
59 int (*map_sg)(struct device *dev, struct scatterlist *sg,
60 int nents, enum dma_data_direction direction);
61 void (*unmap_sg)(struct device *dev, struct scatterlist *sg,
62 int nents, enum dma_data_direction direction);
63 int (*dma_supported)(struct device *dev, u64 mask);
64 int (*dac_dma_supported)(struct device *dev, u64 mask);
65 int (*set_dma_mask)(struct device *dev, u64 dma_mask);
66};
67
68static inline struct dma_mapping_ops *get_dma_ops(struct device *dev)
69{
70 /* We don't handle the NULL dev case for ISA for now. We could
71 * do it via an out of line call but it is not needed for now. The
72 * only ISA DMA device we support is the floppy and we have a hack
73 * in the floppy driver directly to get a device for us.
74 */
75 if (unlikely(dev == NULL || dev->archdata.dma_ops == NULL))
76 return NULL;
77 return dev->archdata.dma_ops;
78}
79
80static inline int dma_supported(struct device *dev, u64 mask)
81{
82 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
83
84 if (unlikely(dma_ops == NULL))
85 return 0;
86 if (dma_ops->dma_supported == NULL)
87 return 1;
88 return dma_ops->dma_supported(dev, mask);
89}
90
91static inline int dma_set_mask(struct device *dev, u64 dma_mask)
92{
93 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
94
95 if (unlikely(dma_ops == NULL))
96 return -EIO;
97 if (dma_ops->set_dma_mask != NULL)
98 return dma_ops->set_dma_mask(dev, dma_mask);
99 if (!dev->dma_mask || !dma_supported(dev, *dev->dma_mask))
100 return -EIO;
101 *dev->dma_mask = dma_mask;
102 return 0;
103}
104
105static inline void *dma_alloc_coherent(struct device *dev, size_t size,
106 dma_addr_t *dma_handle, gfp_t flag)
107{
108 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
109
110 BUG_ON(!dma_ops);
111 return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
112}
113
114static inline void dma_free_coherent(struct device *dev, size_t size,
115 void *cpu_addr, dma_addr_t dma_handle)
116{
117 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
118
119 BUG_ON(!dma_ops);
120 dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
121}
122
123static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
124 size_t size,
125 enum dma_data_direction direction)
126{
127 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
128
129 BUG_ON(!dma_ops);
130 return dma_ops->map_single(dev, cpu_addr, size, direction);
131}
132
133static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
134 size_t size,
135 enum dma_data_direction direction)
136{
137 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
138
139 BUG_ON(!dma_ops);
140 dma_ops->unmap_single(dev, dma_addr, size, direction);
141}
142
143static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
144 unsigned long offset, size_t size,
145 enum dma_data_direction direction)
146{
147 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
148
149 BUG_ON(!dma_ops);
150 return dma_ops->map_single(dev, page_address(page) + offset, size,
151 direction);
152}
153
154static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
155 size_t size,
156 enum dma_data_direction direction)
157{
158 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
159
160 BUG_ON(!dma_ops);
161 dma_ops->unmap_single(dev, dma_address, size, direction);
162}
163
164static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
165 int nents, enum dma_data_direction direction)
166{
167 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
168
169 BUG_ON(!dma_ops);
170 return dma_ops->map_sg(dev, sg, nents, direction);
171}
172
173static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
174 int nhwentries,
175 enum dma_data_direction direction)
176{
177 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
178
179 BUG_ON(!dma_ops);
180 dma_ops->unmap_sg(dev, sg, nhwentries, direction);
181}
47 182
48extern int dma_supported(struct device *dev, u64 mask); 183
49extern int dma_set_mask(struct device *dev, u64 dma_mask); 184/*
50extern void *dma_alloc_coherent(struct device *dev, size_t size, 185 * Available generic sets of operations
51 dma_addr_t *dma_handle, gfp_t flag); 186 */
52extern void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, 187extern struct dma_mapping_ops dma_iommu_ops;
53 dma_addr_t dma_handle); 188extern struct dma_mapping_ops dma_direct_ops;
54extern dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
55 size_t size, enum dma_data_direction direction);
56extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
57 size_t size, enum dma_data_direction direction);
58extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
59 unsigned long offset, size_t size,
60 enum dma_data_direction direction);
61extern void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
62 size_t size, enum dma_data_direction direction);
63extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
64 enum dma_data_direction direction);
65extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
66 int nhwentries, enum dma_data_direction direction);
67 189
68#else /* CONFIG_PPC64 */ 190#else /* CONFIG_PPC64 */
69 191
@@ -261,25 +383,5 @@ static inline void dma_cache_sync(void *vaddr, size_t size,
261 __dma_sync(vaddr, size, (int)direction); 383 __dma_sync(vaddr, size, (int)direction);
262} 384}
263 385
264/*
265 * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO
266 */
267struct dma_mapping_ops {
268 void * (*alloc_coherent)(struct device *dev, size_t size,
269 dma_addr_t *dma_handle, gfp_t flag);
270 void (*free_coherent)(struct device *dev, size_t size,
271 void *vaddr, dma_addr_t dma_handle);
272 dma_addr_t (*map_single)(struct device *dev, void *ptr,
273 size_t size, enum dma_data_direction direction);
274 void (*unmap_single)(struct device *dev, dma_addr_t dma_addr,
275 size_t size, enum dma_data_direction direction);
276 int (*map_sg)(struct device *dev, struct scatterlist *sg,
277 int nents, enum dma_data_direction direction);
278 void (*unmap_sg)(struct device *dev, struct scatterlist *sg,
279 int nents, enum dma_data_direction direction);
280 int (*dma_supported)(struct device *dev, u64 mask);
281 int (*dac_dma_supported)(struct device *dev, u64 mask);
282};
283
284#endif /* __KERNEL__ */ 386#endif /* __KERNEL__ */
285#endif /* _ASM_DMA_MAPPING_H */ 387#endif /* _ASM_DMA_MAPPING_H */