diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2014-11-18 09:51:01 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2014-11-25 08:55:32 -0200 |
commit | 0c3a14c177aa85afb991e7c2be3921aa9a52a893 (patch) | |
tree | de833b66ee640393292bc404e16c8f43a49ae89c /drivers/media/v4l2-core/videobuf2-dma-sg.c | |
parent | e5ae8fa739f8a1d5c292c5b13fa33ac64166e5a0 (diff) | |
download | lwn-0c3a14c177aa85afb991e7c2be3921aa9a52a893.tar.gz lwn-0c3a14c177aa85afb991e7c2be3921aa9a52a893.zip |
[media] vb2-dma-sg: add allocation context to dma-sg
Require that dma-sg also uses an allocation context. This is in preparation
for adding prepare/finish memops to sync the memory between DMA and CPU.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Acked-by: Pawel Osciak <pawel@osciak.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/v4l2-core/videobuf2-dma-sg.c')
-rw-r--r-- | drivers/media/v4l2-core/videobuf2-dma-sg.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c index 2529b831725b..2bf13dc4df34 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c @@ -30,7 +30,12 @@ module_param(debug, int, 0644); printk(KERN_DEBUG "vb2-dma-sg: " fmt, ## arg); \ } while (0) +struct vb2_dma_sg_conf { + struct device *dev; +}; + struct vb2_dma_sg_buf { + struct device *dev; void *vaddr; struct page **pages; int offset; @@ -89,10 +94,13 @@ static int vb2_dma_sg_alloc_compacted(struct vb2_dma_sg_buf *buf, static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, enum dma_data_direction dma_dir, gfp_t gfp_flags) { + struct vb2_dma_sg_conf *conf = alloc_ctx; struct vb2_dma_sg_buf *buf; int ret; int num_pages; + if (WARN_ON(alloc_ctx == NULL)) + return NULL; buf = kzalloc(sizeof *buf, GFP_KERNEL); if (!buf) return NULL; @@ -118,6 +126,8 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, if (ret) goto fail_table_alloc; + /* Prevent the device from being released while the buffer is used */ + buf->dev = get_device(conf->dev); buf->handler.refcount = &buf->refcount; buf->handler.put = vb2_dma_sg_put; buf->handler.arg = buf; @@ -153,6 +163,7 @@ static void vb2_dma_sg_put(void *buf_priv) while (--i >= 0) __free_page(buf->pages[i]); kfree(buf->pages); + put_device(buf->dev); kfree(buf); } } @@ -356,6 +367,27 @@ const struct vb2_mem_ops vb2_dma_sg_memops = { }; EXPORT_SYMBOL_GPL(vb2_dma_sg_memops); +void *vb2_dma_sg_init_ctx(struct device *dev) +{ + struct vb2_dma_sg_conf *conf; + + conf = kzalloc(sizeof(*conf), GFP_KERNEL); + if (!conf) + return ERR_PTR(-ENOMEM); + + conf->dev = dev; + + return conf; +} +EXPORT_SYMBOL_GPL(vb2_dma_sg_init_ctx); + +void vb2_dma_sg_cleanup_ctx(void *alloc_ctx) +{ + if (!IS_ERR_OR_NULL(alloc_ctx)) + kfree(alloc_ctx); +} +EXPORT_SYMBOL_GPL(vb2_dma_sg_cleanup_ctx); + MODULE_DESCRIPTION("dma scatter/gather memory handling routines for videobuf2"); MODULE_AUTHOR("Andrzej Pietrasiewicz"); MODULE_LICENSE("GPL"); |