diff options
Diffstat (limited to 'drivers/media/common/videobuf2/videobuf2-dma-contig.c')
-rw-r--r-- | drivers/media/common/videobuf2/videobuf2-dma-contig.c | 28 |
1 files changed, 12 insertions, 16 deletions
diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c index 678b359717c4..5f1175f8b349 100644 --- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c +++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c @@ -11,6 +11,7 @@ */ #include <linux/dma-buf.h> +#include <linux/dma-resv.h> #include <linux/module.h> #include <linux/refcount.h> #include <linux/scatterlist.h> @@ -101,7 +102,7 @@ static void *vb2_dc_vaddr(struct vb2_buffer *vb, void *buf_priv) if (buf->db_attach) { struct iosys_map map; - if (!dma_buf_vmap(buf->db_attach->dmabuf, &map)) + if (!dma_buf_vmap_unlocked(buf->db_attach->dmabuf, &map)) buf->vaddr = map.vaddr; return buf->vaddr; @@ -382,18 +383,12 @@ static struct sg_table *vb2_dc_dmabuf_ops_map( struct dma_buf_attachment *db_attach, enum dma_data_direction dma_dir) { struct vb2_dc_attachment *attach = db_attach->priv; - /* stealing dmabuf mutex to serialize map/unmap operations */ - struct mutex *lock = &db_attach->dmabuf->lock; struct sg_table *sgt; - mutex_lock(lock); - sgt = &attach->sgt; /* return previously mapped sg table */ - if (attach->dma_dir == dma_dir) { - mutex_unlock(lock); + if (attach->dma_dir == dma_dir) return sgt; - } /* release any previous cache */ if (attach->dma_dir != DMA_NONE) { @@ -409,14 +404,11 @@ static struct sg_table *vb2_dc_dmabuf_ops_map( if (dma_map_sgtable(db_attach->dev, sgt, dma_dir, DMA_ATTR_SKIP_CPU_SYNC)) { pr_err("failed to map scatterlist\n"); - mutex_unlock(lock); return ERR_PTR(-EIO); } attach->dma_dir = dma_dir; - mutex_unlock(lock); - return sgt; } @@ -464,6 +456,8 @@ static int vb2_dc_dmabuf_ops_vmap(struct dma_buf *dbuf, struct iosys_map *map) static int vb2_dc_dmabuf_ops_mmap(struct dma_buf *dbuf, struct vm_area_struct *vma) { + dma_resv_assert_held(dbuf->resv); + return vb2_dc_mmap(dbuf->priv, vma); } @@ -603,7 +597,8 @@ static void *vb2_dc_get_userptr(struct vb2_buffer *vb, struct device *dev, buf->vb = vb; offset = lower_32_bits(offset_in_page(vaddr)); - vec = vb2_create_framevec(vaddr, size); + vec = vb2_create_framevec(vaddr, size, buf->dma_dir == DMA_FROM_DEVICE || + buf->dma_dir == DMA_BIDIRECTIONAL); if (IS_ERR(vec)) { ret = PTR_ERR(vec); goto fail_buf; @@ -711,7 +706,7 @@ static int vb2_dc_map_dmabuf(void *mem_priv) } /* get the associated scatterlist for this buffer */ - sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir); + sgt = dma_buf_map_attachment_unlocked(buf->db_attach, buf->dma_dir); if (IS_ERR(sgt)) { pr_err("Error getting dmabuf scatterlist\n"); return -EINVAL; @@ -722,7 +717,8 @@ static int vb2_dc_map_dmabuf(void *mem_priv) if (contig_size < buf->size) { pr_err("contiguous chunk is too small %lu/%lu\n", contig_size, buf->size); - dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir); + dma_buf_unmap_attachment_unlocked(buf->db_attach, sgt, + buf->dma_dir); return -EFAULT; } @@ -750,10 +746,10 @@ static void vb2_dc_unmap_dmabuf(void *mem_priv) } if (buf->vaddr) { - dma_buf_vunmap(buf->db_attach->dmabuf, &map); + dma_buf_vunmap_unlocked(buf->db_attach->dmabuf, &map); buf->vaddr = NULL; } - dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir); + dma_buf_unmap_attachment_unlocked(buf->db_attach, sgt, buf->dma_dir); buf->dma_addr = 0; buf->dma_sgt = NULL; |