diff --git a/drivers/video/tegra/host/nvdla/nvdla_buffer.c b/drivers/video/tegra/host/nvdla/nvdla_buffer.c index d4777a8e..1abb6b99 100644 --- a/drivers/video/tegra/host/nvdla/nvdla_buffer.c +++ b/drivers/video/tegra/host/nvdla/nvdla_buffer.c @@ -140,7 +140,18 @@ static int nvdla_buffer_map(struct platform_device *pdev, goto buf_attach_err; } - sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); + if (desc->access_flags == NVDLA_MEM_ACCESS_READ) { + sgt = dma_buf_map_attachment(attach, DMA_TO_DEVICE); + } else if (desc->access_flags == NVDLA_MEM_ACCESS_READ_WRITE) { + sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); + } else { + err = -EINVAL; + dev_err(&pdev->dev, + "Invalid access permission: %u\n", + desc->access_flags); + goto buf_map_err; + } + if (IS_ERR_OR_NULL(sgt)) { err = PTR_ERR(sgt); dev_err(&pdev->dev, "dma mapping failed: %d\n", err); @@ -199,7 +210,11 @@ static void nvdla_buffer_unmap(struct nvdla_buffers *nvdla_buffers, if ((vm->user_map_count != 0) || (vm->submit_map_count != 0)) return; - dma_buf_unmap_attachment(vm->attach, vm->sgt, DMA_BIDIRECTIONAL); + if (vm->access_flags == NVDLA_MEM_ACCESS_READ) + dma_buf_unmap_attachment(vm->attach, vm->sgt, DMA_TO_DEVICE); + else + dma_buf_unmap_attachment(vm->attach, vm->sgt, DMA_BIDIRECTIONAL); + dma_buf_detach(vm->dmabuf, vm->attach); dma_buf_put(vm->dmabuf); diff --git a/include/uapi/linux/nvhost_nvdla_ioctl.h b/include/uapi/linux/nvhost_nvdla_ioctl.h index 18e4d594..32d9552c 100644 --- a/include/uapi/linux/nvhost_nvdla_ioctl.h +++ b/include/uapi/linux/nvhost_nvdla_ioctl.h @@ -75,6 +75,10 @@ struct nvdla_ping_args { struct nvdla_mem_share_handle { __u32 share_id; __u32 offset; +#define NVDLA_MEM_ACCESS_NONE (0U) +#define NVDLA_MEM_ACCESS_READ (1U << 0U) +#define NVDLA_MEM_ACCESS_WRITE (1U << 1U) +#define NVDLA_MEM_ACCESS_READ_WRITE (NVDLA_MEM_ACCESS_READ | NVDLA_MEM_ACCESS_WRITE) __u32 access_flags; __u32 import_id; };