diff options
-rw-r--r-- | drivers/base/dma-mapping.c | 18 | ||||
-rw-r--r-- | include/asm-generic/dma-mapping-common.h | 18 | ||||
-rw-r--r-- | include/linux/dma-mapping.h | 3 |
3 files changed, 39 insertions, 0 deletions
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c index db5db02e885f..3fbedc75e7c5 100644 --- a/drivers/base/dma-mapping.c +++ b/drivers/base/dma-mapping.c | |||
@@ -218,6 +218,24 @@ void dmam_release_declared_memory(struct device *dev) | |||
218 | } | 218 | } |
219 | EXPORT_SYMBOL(dmam_release_declared_memory); | 219 | EXPORT_SYMBOL(dmam_release_declared_memory); |
220 | 220 | ||
221 | /* | ||
222 | * Create scatter-list for the already allocated DMA buffer. | ||
223 | */ | ||
224 | int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt, | ||
225 | void *cpu_addr, dma_addr_t handle, size_t size) | ||
226 | { | ||
227 | struct page *page = virt_to_page(cpu_addr); | ||
228 | int ret; | ||
229 | |||
230 | ret = sg_alloc_table(sgt, 1, GFP_KERNEL); | ||
231 | if (unlikely(ret)) | ||
232 | return ret; | ||
233 | |||
234 | sg_set_page(sgt->sgl, page, PAGE_ALIGN(size), 0); | ||
235 | return 0; | ||
236 | } | ||
237 | EXPORT_SYMBOL(dma_common_get_sgtable); | ||
238 | |||
221 | #endif | 239 | #endif |
222 | 240 | ||
223 | /* | 241 | /* |
diff --git a/include/asm-generic/dma-mapping-common.h b/include/asm-generic/dma-mapping-common.h index 9073aeb3bb1a..de8bf89940f8 100644 --- a/include/asm-generic/dma-mapping-common.h +++ b/include/asm-generic/dma-mapping-common.h | |||
@@ -213,4 +213,22 @@ static inline int dma_mmap_writecombine(struct device *dev, struct vm_area_struc | |||
213 | return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, &attrs); | 213 | return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, &attrs); |
214 | } | 214 | } |
215 | 215 | ||
216 | int | ||
217 | dma_common_get_sgtable(struct device *dev, struct sg_table *sgt, | ||
218 | void *cpu_addr, dma_addr_t dma_addr, size_t size); | ||
219 | |||
220 | static inline int | ||
221 | dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr, | ||
222 | dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs) | ||
223 | { | ||
224 | struct dma_map_ops *ops = get_dma_ops(dev); | ||
225 | BUG_ON(!ops); | ||
226 | if (ops->get_sgtable) | ||
227 | return ops->get_sgtable(dev, sgt, cpu_addr, dma_addr, size, | ||
228 | attrs); | ||
229 | return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size); | ||
230 | } | ||
231 | |||
232 | #define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, NULL) | ||
233 | |||
216 | #endif | 234 | #endif |
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index dfc099e56a66..94af41858513 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h | |||
@@ -18,6 +18,9 @@ struct dma_map_ops { | |||
18 | int (*mmap)(struct device *, struct vm_area_struct *, | 18 | int (*mmap)(struct device *, struct vm_area_struct *, |
19 | void *, dma_addr_t, size_t, struct dma_attrs *attrs); | 19 | void *, dma_addr_t, size_t, struct dma_attrs *attrs); |
20 | 20 | ||
21 | int (*get_sgtable)(struct device *dev, struct sg_table *sgt, void *, | ||
22 | dma_addr_t, size_t, struct dma_attrs *attrs); | ||
23 | |||
21 | dma_addr_t (*map_page)(struct device *dev, struct page *page, | 24 | dma_addr_t (*map_page)(struct device *dev, struct page *page, |
22 | unsigned long offset, size_t size, | 25 | unsigned long offset, size_t size, |
23 | enum dma_data_direction dir, | 26 | enum dma_data_direction dir, |