diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c index 90602a77086b..2c0ba561957c 100644 --- a/drivers/dma-buf/heaps/cma_heap.c +++ b/drivers/dma-buf/heaps/cma_heap.c @@ -132,8 +132,11 @@ static void cma_heap_unmap_dma_buf(struct dma_buf_attachment *attachment, dma_unmap_sgtable(attachment->dev, table, direction, attrs); } -static int cma_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, - enum dma_data_direction direction) +static int +cma_heap_dma_buf_begin_cpu_access_partial(struct dma_buf *dmabuf, + enum dma_data_direction direction, + unsigned int offset, + unsigned int len) { struct cma_heap_buffer *buffer = dmabuf->priv; struct dma_heap_attachment *a; @@ -150,13 +153,24 @@ static int cma_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, continue; dma_sync_sgtable_for_cpu(a->dev, &a->table, direction); } + if (list_empty(&buffer->attachments)) { + phys_addr_t phys = page_to_phys(buffer->cma_pages); + + dma_sync_single_for_cpu(dma_heap_get_dev(buffer->heap->heap), + phys + offset, + len, + direction); + } mutex_unlock(&buffer->lock); return 0; } -static int cma_heap_dma_buf_end_cpu_access(struct dma_buf *dmabuf, - enum dma_data_direction direction) +static int +cma_heap_dma_buf_end_cpu_access_partial(struct dma_buf *dmabuf, + enum dma_data_direction direction, + unsigned int offset, + unsigned int len) { struct cma_heap_buffer *buffer = dmabuf->priv; struct dma_heap_attachment *a; @@ -173,11 +187,33 @@ static int cma_heap_dma_buf_end_cpu_access(struct dma_buf *dmabuf, continue; dma_sync_sgtable_for_device(a->dev, &a->table, direction); } + if (list_empty(&buffer->attachments)) { + phys_addr_t phys = page_to_phys(buffer->cma_pages); + + dma_sync_single_for_device(dma_heap_get_dev(buffer->heap->heap), + phys + offset, + len, + direction); + } mutex_unlock(&buffer->lock); return 0; } +static int cma_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, + enum dma_data_direction dir) +{ + return cma_heap_dma_buf_begin_cpu_access_partial(dmabuf, dir, 0, + dmabuf->size); +} + +static int cma_heap_dma_buf_end_cpu_access(struct dma_buf *dmabuf, + enum dma_data_direction dir) +{ + return cma_heap_dma_buf_end_cpu_access_partial(dmabuf, dir, 0, + dmabuf->size); +} + static vm_fault_t cma_heap_vm_fault(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; @@ -287,6 +323,8 @@ static const struct dma_buf_ops cma_heap_buf_ops = { .unmap_dma_buf = cma_heap_unmap_dma_buf, .begin_cpu_access = cma_heap_dma_buf_begin_cpu_access, .end_cpu_access = cma_heap_dma_buf_end_cpu_access, + .begin_cpu_access_partial = cma_heap_dma_buf_begin_cpu_access_partial, + .end_cpu_access_partial = cma_heap_dma_buf_end_cpu_access_partial, .mmap = cma_heap_mmap, .vmap = cma_heap_vmap, .vunmap = cma_heap_vunmap,