diff options
Diffstat (limited to 'drivers/media/v4l2-core/videobuf2-vmalloc.c')
| -rw-r--r-- | drivers/media/v4l2-core/videobuf2-vmalloc.c | 60 |
1 files changed, 58 insertions, 2 deletions
diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c b/drivers/media/v4l2-core/videobuf2-vmalloc.c index 94efa04d8d5..313d9771b2b 100644 --- a/drivers/media/v4l2-core/videobuf2-vmalloc.c +++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c @@ -30,15 +30,16 @@ struct vb2_vmalloc_buf { unsigned int n_pages; atomic_t refcount; struct vb2_vmarea_handler handler; + struct dma_buf *dbuf; }; static void vb2_vmalloc_put(void *buf_priv); -static void *vb2_vmalloc_alloc(void *alloc_ctx, unsigned long size) +static void *vb2_vmalloc_alloc(void *alloc_ctx, unsigned long size, gfp_t gfp_flags) { struct vb2_vmalloc_buf *buf; - buf = kzalloc(sizeof(*buf), GFP_KERNEL); + buf = kzalloc(sizeof(*buf), GFP_KERNEL | gfp_flags); if (!buf) return NULL; @@ -207,11 +208,66 @@ static int vb2_vmalloc_mmap(void *buf_priv, struct vm_area_struct *vma) return 0; } +/*********************************************/ +/* callbacks for DMABUF buffers */ +/*********************************************/ + +static int vb2_vmalloc_map_dmabuf(void *mem_priv) +{ + struct vb2_vmalloc_buf *buf = mem_priv; + + buf->vaddr = dma_buf_vmap(buf->dbuf); + + return buf->vaddr ? 0 : -EFAULT; +} + +static void vb2_vmalloc_unmap_dmabuf(void *mem_priv) +{ + struct vb2_vmalloc_buf *buf = mem_priv; + + dma_buf_vunmap(buf->dbuf, buf->vaddr); + buf->vaddr = NULL; +} + +static void vb2_vmalloc_detach_dmabuf(void *mem_priv) +{ + struct vb2_vmalloc_buf *buf = mem_priv; + + if (buf->vaddr) + dma_buf_vunmap(buf->dbuf, buf->vaddr); + + kfree(buf); +} + +static void *vb2_vmalloc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf, + unsigned long size, int write) +{ + struct vb2_vmalloc_buf *buf; + + if (dbuf->size < size) + return ERR_PTR(-EFAULT); + + buf = kzalloc(sizeof(*buf), GFP_KERNEL); + if (!buf) + return ERR_PTR(-ENOMEM); + + buf->dbuf = dbuf; + buf->write = write; + buf->size = size; + + return buf; +} + + const struct vb2_mem_ops vb2_vmalloc_memops = { .alloc = vb2_vmalloc_alloc, .put = vb2_vmalloc_put, .get_userptr = vb2_vmalloc_get_userptr, .put_userptr = vb2_vmalloc_put_userptr, + .map_dmabuf = vb2_vmalloc_map_dmabuf, + .unmap_dmabuf = vb2_vmalloc_unmap_dmabuf, + .attach_dmabuf = vb2_vmalloc_attach_dmabuf, + .detach_dmabuf = vb2_vmalloc_detach_dmabuf, .vaddr = vb2_vmalloc_vaddr, .mmap = vb2_vmalloc_mmap, .num_users = vb2_vmalloc_num_users, |
