diff options
Diffstat (limited to 'include/asm-powerpc/dma-mapping.h')
-rw-r--r-- | include/asm-powerpc/dma-mapping.h | 125 |
1 files changed, 95 insertions, 30 deletions
diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h index bbefb69bfb67..74c549780987 100644 --- a/include/asm-powerpc/dma-mapping.h +++ b/include/asm-powerpc/dma-mapping.h | |||
@@ -13,6 +13,7 @@ | |||
13 | /* need struct page definitions */ | 13 | /* need struct page definitions */ |
14 | #include <linux/mm.h> | 14 | #include <linux/mm.h> |
15 | #include <linux/scatterlist.h> | 15 | #include <linux/scatterlist.h> |
16 | #include <linux/dma-attrs.h> | ||
16 | #include <asm/io.h> | 17 | #include <asm/io.h> |
17 | 18 | ||
18 | #define DMA_ERROR_CODE (~(dma_addr_t)0x0) | 19 | #define DMA_ERROR_CODE (~(dma_addr_t)0x0) |
@@ -44,6 +45,15 @@ extern void __dma_sync_page(struct page *page, unsigned long offset, | |||
44 | #endif /* ! CONFIG_NOT_COHERENT_CACHE */ | 45 | #endif /* ! CONFIG_NOT_COHERENT_CACHE */ |
45 | 46 | ||
46 | #ifdef CONFIG_PPC64 | 47 | #ifdef CONFIG_PPC64 |
48 | |||
49 | static inline unsigned long device_to_mask(struct device *dev) | ||
50 | { | ||
51 | if (dev->dma_mask && *dev->dma_mask) | ||
52 | return *dev->dma_mask; | ||
53 | /* Assume devices without mask can take 32 bit addresses */ | ||
54 | return 0xfffffffful; | ||
55 | } | ||
56 | |||
47 | /* | 57 | /* |
48 | * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO | 58 | * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO |
49 | */ | 59 | */ |
@@ -53,13 +63,17 @@ struct dma_mapping_ops { | |||
53 | void (*free_coherent)(struct device *dev, size_t size, | 63 | void (*free_coherent)(struct device *dev, size_t size, |
54 | void *vaddr, dma_addr_t dma_handle); | 64 | void *vaddr, dma_addr_t dma_handle); |
55 | dma_addr_t (*map_single)(struct device *dev, void *ptr, | 65 | dma_addr_t (*map_single)(struct device *dev, void *ptr, |
56 | size_t size, enum dma_data_direction direction); | 66 | size_t size, enum dma_data_direction direction, |
67 | struct dma_attrs *attrs); | ||
57 | void (*unmap_single)(struct device *dev, dma_addr_t dma_addr, | 68 | void (*unmap_single)(struct device *dev, dma_addr_t dma_addr, |
58 | size_t size, enum dma_data_direction direction); | 69 | size_t size, enum dma_data_direction direction, |
70 | struct dma_attrs *attrs); | ||
59 | int (*map_sg)(struct device *dev, struct scatterlist *sg, | 71 | int (*map_sg)(struct device *dev, struct scatterlist *sg, |
60 | int nents, enum dma_data_direction direction); | 72 | int nents, enum dma_data_direction direction, |
73 | struct dma_attrs *attrs); | ||
61 | void (*unmap_sg)(struct device *dev, struct scatterlist *sg, | 74 | void (*unmap_sg)(struct device *dev, struct scatterlist *sg, |
62 | int nents, enum dma_data_direction direction); | 75 | int nents, enum dma_data_direction direction, |
76 | struct dma_attrs *attrs); | ||
63 | int (*dma_supported)(struct device *dev, u64 mask); | 77 | int (*dma_supported)(struct device *dev, u64 mask); |
64 | int (*set_dma_mask)(struct device *dev, u64 dma_mask); | 78 | int (*set_dma_mask)(struct device *dev, u64 dma_mask); |
65 | }; | 79 | }; |
@@ -109,6 +123,77 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask) | |||
109 | return 0; | 123 | return 0; |
110 | } | 124 | } |
111 | 125 | ||
126 | static inline dma_addr_t dma_map_single_attrs(struct device *dev, | ||
127 | void *cpu_addr, | ||
128 | size_t size, | ||
129 | enum dma_data_direction direction, | ||
130 | struct dma_attrs *attrs) | ||
131 | { | ||
132 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
133 | |||
134 | BUG_ON(!dma_ops); | ||
135 | return dma_ops->map_single(dev, cpu_addr, size, direction, attrs); | ||
136 | } | ||
137 | |||
138 | static inline void dma_unmap_single_attrs(struct device *dev, | ||
139 | dma_addr_t dma_addr, | ||
140 | size_t size, | ||
141 | enum dma_data_direction direction, | ||
142 | struct dma_attrs *attrs) | ||
143 | { | ||
144 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
145 | |||
146 | BUG_ON(!dma_ops); | ||
147 | dma_ops->unmap_single(dev, dma_addr, size, direction, attrs); | ||
148 | } | ||
149 | |||
150 | static inline dma_addr_t dma_map_page_attrs(struct device *dev, | ||
151 | struct page *page, | ||
152 | unsigned long offset, size_t size, | ||
153 | enum dma_data_direction direction, | ||
154 | struct dma_attrs *attrs) | ||
155 | { | ||
156 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
157 | |||
158 | BUG_ON(!dma_ops); | ||
159 | return dma_ops->map_single(dev, page_address(page) + offset, size, | ||
160 | direction, attrs); | ||
161 | } | ||
162 | |||
163 | static inline void dma_unmap_page_attrs(struct device *dev, | ||
164 | dma_addr_t dma_address, | ||
165 | size_t size, | ||
166 | enum dma_data_direction direction, | ||
167 | struct dma_attrs *attrs) | ||
168 | { | ||
169 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
170 | |||
171 | BUG_ON(!dma_ops); | ||
172 | dma_ops->unmap_single(dev, dma_address, size, direction, attrs); | ||
173 | } | ||
174 | |||
175 | static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, | ||
176 | int nents, enum dma_data_direction direction, | ||
177 | struct dma_attrs *attrs) | ||
178 | { | ||
179 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
180 | |||
181 | BUG_ON(!dma_ops); | ||
182 | return dma_ops->map_sg(dev, sg, nents, direction, attrs); | ||
183 | } | ||
184 | |||
185 | static inline void dma_unmap_sg_attrs(struct device *dev, | ||
186 | struct scatterlist *sg, | ||
187 | int nhwentries, | ||
188 | enum dma_data_direction direction, | ||
189 | struct dma_attrs *attrs) | ||
190 | { | ||
191 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
192 | |||
193 | BUG_ON(!dma_ops); | ||
194 | dma_ops->unmap_sg(dev, sg, nhwentries, direction, attrs); | ||
195 | } | ||
196 | |||
112 | static inline void *dma_alloc_coherent(struct device *dev, size_t size, | 197 | static inline void *dma_alloc_coherent(struct device *dev, size_t size, |
113 | dma_addr_t *dma_handle, gfp_t flag) | 198 | dma_addr_t *dma_handle, gfp_t flag) |
114 | { | 199 | { |
@@ -131,63 +216,43 @@ static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, | |||
131 | size_t size, | 216 | size_t size, |
132 | enum dma_data_direction direction) | 217 | enum dma_data_direction direction) |
133 | { | 218 | { |
134 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | 219 | return dma_map_single_attrs(dev, cpu_addr, size, direction, NULL); |
135 | |||
136 | BUG_ON(!dma_ops); | ||
137 | return dma_ops->map_single(dev, cpu_addr, size, direction); | ||
138 | } | 220 | } |
139 | 221 | ||
140 | static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, | 222 | static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, |
141 | size_t size, | 223 | size_t size, |
142 | enum dma_data_direction direction) | 224 | enum dma_data_direction direction) |
143 | { | 225 | { |
144 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | 226 | dma_unmap_single_attrs(dev, dma_addr, size, direction, NULL); |
145 | |||
146 | BUG_ON(!dma_ops); | ||
147 | dma_ops->unmap_single(dev, dma_addr, size, direction); | ||
148 | } | 227 | } |
149 | 228 | ||
150 | static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, | 229 | static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, |
151 | unsigned long offset, size_t size, | 230 | unsigned long offset, size_t size, |
152 | enum dma_data_direction direction) | 231 | enum dma_data_direction direction) |
153 | { | 232 | { |
154 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | 233 | return dma_map_page_attrs(dev, page, offset, size, direction, NULL); |
155 | |||
156 | BUG_ON(!dma_ops); | ||
157 | return dma_ops->map_single(dev, page_address(page) + offset, size, | ||
158 | direction); | ||
159 | } | 234 | } |
160 | 235 | ||
161 | static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address, | 236 | static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address, |
162 | size_t size, | 237 | size_t size, |
163 | enum dma_data_direction direction) | 238 | enum dma_data_direction direction) |
164 | { | 239 | { |
165 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | 240 | dma_unmap_page_attrs(dev, dma_address, size, direction, NULL); |
166 | |||
167 | BUG_ON(!dma_ops); | ||
168 | dma_ops->unmap_single(dev, dma_address, size, direction); | ||
169 | } | 241 | } |
170 | 242 | ||
171 | static inline int dma_map_sg(struct device *dev, struct scatterlist *sg, | 243 | static inline int dma_map_sg(struct device *dev, struct scatterlist *sg, |
172 | int nents, enum dma_data_direction direction) | 244 | int nents, enum dma_data_direction direction) |
173 | { | 245 | { |
174 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | 246 | return dma_map_sg_attrs(dev, sg, nents, direction, NULL); |
175 | |||
176 | BUG_ON(!dma_ops); | ||
177 | return dma_ops->map_sg(dev, sg, nents, direction); | ||
178 | } | 247 | } |
179 | 248 | ||
180 | static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg, | 249 | static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg, |
181 | int nhwentries, | 250 | int nhwentries, |
182 | enum dma_data_direction direction) | 251 | enum dma_data_direction direction) |
183 | { | 252 | { |
184 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | 253 | dma_unmap_sg_attrs(dev, sg, nhwentries, direction, NULL); |
185 | |||
186 | BUG_ON(!dma_ops); | ||
187 | dma_ops->unmap_sg(dev, sg, nhwentries, direction); | ||
188 | } | 254 | } |
189 | 255 | ||
190 | |||
191 | /* | 256 | /* |
192 | * Available generic sets of operations | 257 | * Available generic sets of operations |
193 | */ | 258 | */ |