aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/v4l2-core/videobuf2-dma-contig.c
diff options
context:
space:
mode:
authorSumit Semwal <sumit.semwal@ti.com>2012-06-14 09:37:45 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-11-25 14:18:44 -0500
commit8c417d03a840f6c0b15e141e6e721b16a5f5d81d (patch)
tree41c2412a804b8fe335341836756784ccccf344be /drivers/media/v4l2-core/videobuf2-dma-contig.c
parent199d101efdbae654ab86c5251e35a175f11ddaac (diff)
[media] v4l: vb2-dma-contig: add support for dma_buf importing
This patch makes changes for adding dma-contig as a dma_buf user. It provides function implementations for the {attach, detach, map, unmap}_dmabuf() mem_ops of DMABUF memory type. [author of the original patch] [integration with refactored dma-contig allocator] Signed-off-by: Sumit Semwal <sumit.semwal@ti.com> Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org> Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Tested-by: Mauro Carvalho Chehab <mchehab@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/v4l2-core/videobuf2-dma-contig.c')
-rw-r--r--drivers/media/v4l2-core/videobuf2-dma-contig.c120
1 files changed, 118 insertions, 2 deletions
diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 494a824f57c4..a5804cf12c7c 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -10,6 +10,7 @@
10 * the Free Software Foundation. 10 * the Free Software Foundation.
11 */ 11 */
12 12
13#include <linux/dma-buf.h>
13#include <linux/module.h> 14#include <linux/module.h>
14#include <linux/scatterlist.h> 15#include <linux/scatterlist.h>
15#include <linux/sched.h> 16#include <linux/sched.h>
@@ -38,6 +39,9 @@ struct vb2_dc_buf {
38 39
39 /* USERPTR related */ 40 /* USERPTR related */
40 struct vm_area_struct *vma; 41 struct vm_area_struct *vma;
42
43 /* DMABUF related */
44 struct dma_buf_attachment *db_attach;
41}; 45};
42 46
43/*********************************************/ 47/*********************************************/
@@ -108,7 +112,8 @@ static void vb2_dc_prepare(void *buf_priv)
108 struct vb2_dc_buf *buf = buf_priv; 112 struct vb2_dc_buf *buf = buf_priv;
109 struct sg_table *sgt = buf->dma_sgt; 113 struct sg_table *sgt = buf->dma_sgt;
110 114
111 if (!sgt) 115 /* DMABUF exporter will flush the cache for us */
116 if (!sgt || buf->db_attach)
112 return; 117 return;
113 118
114 dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); 119 dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
@@ -119,7 +124,8 @@ static void vb2_dc_finish(void *buf_priv)
119 struct vb2_dc_buf *buf = buf_priv; 124 struct vb2_dc_buf *buf = buf_priv;
120 struct sg_table *sgt = buf->dma_sgt; 125 struct sg_table *sgt = buf->dma_sgt;
121 126
122 if (!sgt) 127 /* DMABUF exporter will flush the cache for us */
128 if (!sgt || buf->db_attach)
123 return; 129 return;
124 130
125 dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); 131 dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
@@ -377,6 +383,112 @@ fail_buf:
377} 383}
378 384
379/*********************************************/ 385/*********************************************/
386/* callbacks for DMABUF buffers */
387/*********************************************/
388
389static int vb2_dc_map_dmabuf(void *mem_priv)
390{
391 struct vb2_dc_buf *buf = mem_priv;
392 struct sg_table *sgt;
393 unsigned long contig_size;
394
395 if (WARN_ON(!buf->db_attach)) {
396 pr_err("trying to pin a non attached buffer\n");
397 return -EINVAL;
398 }
399
400 if (WARN_ON(buf->dma_sgt)) {
401 pr_err("dmabuf buffer is already pinned\n");
402 return 0;
403 }
404
405 /* get the associated scatterlist for this buffer */
406 sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir);
407 if (IS_ERR_OR_NULL(sgt)) {
408 pr_err("Error getting dmabuf scatterlist\n");
409 return -EINVAL;
410 }
411
412 /* checking if dmabuf is big enough to store contiguous chunk */
413 contig_size = vb2_dc_get_contiguous_size(sgt);
414 if (contig_size < buf->size) {
415 pr_err("contiguous chunk is too small %lu/%lu b\n",
416 contig_size, buf->size);
417 dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
418 return -EFAULT;
419 }
420
421 buf->dma_addr = sg_dma_address(sgt->sgl);
422 buf->dma_sgt = sgt;
423
424 return 0;
425}
426
427static void vb2_dc_unmap_dmabuf(void *mem_priv)
428{
429 struct vb2_dc_buf *buf = mem_priv;
430 struct sg_table *sgt = buf->dma_sgt;
431
432 if (WARN_ON(!buf->db_attach)) {
433 pr_err("trying to unpin a not attached buffer\n");
434 return;
435 }
436
437 if (WARN_ON(!sgt)) {
438 pr_err("dmabuf buffer is already unpinned\n");
439 return;
440 }
441
442 dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
443
444 buf->dma_addr = 0;
445 buf->dma_sgt = NULL;
446}
447
448static void vb2_dc_detach_dmabuf(void *mem_priv)
449{
450 struct vb2_dc_buf *buf = mem_priv;
451
452 /* if vb2 works correctly you should never detach mapped buffer */
453 if (WARN_ON(buf->dma_addr))
454 vb2_dc_unmap_dmabuf(buf);
455
456 /* detach this attachment */
457 dma_buf_detach(buf->db_attach->dmabuf, buf->db_attach);
458 kfree(buf);
459}
460
461static void *vb2_dc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf,
462 unsigned long size, int write)
463{
464 struct vb2_dc_conf *conf = alloc_ctx;
465 struct vb2_dc_buf *buf;
466 struct dma_buf_attachment *dba;
467
468 if (dbuf->size < size)
469 return ERR_PTR(-EFAULT);
470
471 buf = kzalloc(sizeof(*buf), GFP_KERNEL);
472 if (!buf)
473 return ERR_PTR(-ENOMEM);
474
475 buf->dev = conf->dev;
476 /* create attachment for the dmabuf with the user device */
477 dba = dma_buf_attach(dbuf, buf->dev);
478 if (IS_ERR(dba)) {
479 pr_err("failed to attach dmabuf\n");
480 kfree(buf);
481 return dba;
482 }
483
484 buf->dma_dir = write ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
485 buf->size = size;
486 buf->db_attach = dba;
487
488 return buf;
489}
490
491/*********************************************/
380/* DMA CONTIG exported functions */ 492/* DMA CONTIG exported functions */
381/*********************************************/ 493/*********************************************/
382 494
@@ -390,6 +502,10 @@ const struct vb2_mem_ops vb2_dma_contig_memops = {
390 .put_userptr = vb2_dc_put_userptr, 502 .put_userptr = vb2_dc_put_userptr,
391 .prepare = vb2_dc_prepare, 503 .prepare = vb2_dc_prepare,
392 .finish = vb2_dc_finish, 504 .finish = vb2_dc_finish,
505 .map_dmabuf = vb2_dc_map_dmabuf,
506 .unmap_dmabuf = vb2_dc_unmap_dmabuf,
507 .attach_dmabuf = vb2_dc_attach_dmabuf,
508 .detach_dmabuf = vb2_dc_detach_dmabuf,
393 .num_users = vb2_dc_num_users, 509 .num_users = vb2_dc_num_users,
394}; 510};
395EXPORT_SYMBOL_GPL(vb2_dma_contig_memops); 511EXPORT_SYMBOL_GPL(vb2_dma_contig_memops);