mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 19:08:57 +09:00
dma-buf: heaps: system_heap: partial sync with sgtable from heap buffer
The dma-heap will allocate a scatterlist table at alloc time and store into the heap buffer. Usually a device should attach to the dmabuf and then map the dmabuf with the attachment, a new scatterlist table will be created and set during dma map. In the dma map, the sg_dma_address will be set for the first scatter of the scatterlist table, if the device has a iommu domain, sg_dma_address is set with the iova start address, else it will be set with a physical address. For a dmabuf hasn't been dma mapped, the sg_dma_address is a error value (-1 = DMA_MAPPING_ERROR). The partial sync hits the case that no device mapped to the dmabuf. It's not easy to support both iommu/no iommu devices for partial sync, this patch make the partial sync simple to implement for no iommu case. Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com> Change-Id: Ib5d0715c4bde95bc444d6fbb873456c94755f550
This commit is contained in:
@@ -272,8 +272,9 @@ system_heap_dma_buf_begin_cpu_access_partial(struct dma_buf *dmabuf,
|
||||
unsigned int len)
|
||||
{
|
||||
struct system_heap_buffer *buffer = dmabuf->priv;
|
||||
struct dma_heap_attachment *a;
|
||||
int ret = 0;
|
||||
struct dma_heap *heap = buffer->heap;
|
||||
struct sg_table *table = &buffer->sg_table;
|
||||
int ret;
|
||||
|
||||
if (direction == DMA_TO_DEVICE)
|
||||
return 0;
|
||||
@@ -282,25 +283,13 @@ system_heap_dma_buf_begin_cpu_access_partial(struct dma_buf *dmabuf,
|
||||
if (buffer->vmap_cnt)
|
||||
invalidate_kernel_vmap_range(buffer->vaddr, buffer->len);
|
||||
|
||||
if (buffer->uncached)
|
||||
goto unlock;
|
||||
|
||||
list_for_each_entry(a, &buffer->attachments, list) {
|
||||
if (!a->mapped)
|
||||
continue;
|
||||
|
||||
ret = system_heap_sgl_sync_range(a->dev, a->table, offset, len,
|
||||
direction, true);
|
||||
if (buffer->uncached) {
|
||||
mutex_unlock(&buffer->lock);
|
||||
return 0;
|
||||
}
|
||||
if (list_empty(&buffer->attachments)) {
|
||||
struct dma_heap *heap = buffer->heap;
|
||||
struct sg_table *table = &buffer->sg_table;
|
||||
|
||||
ret = system_heap_sgl_sync_range(dma_heap_get_dev(heap), table,
|
||||
offset, len,
|
||||
direction, true);
|
||||
}
|
||||
unlock:
|
||||
ret = system_heap_sgl_sync_range(dma_heap_get_dev(heap), table,
|
||||
offset, len, direction, true);
|
||||
mutex_unlock(&buffer->lock);
|
||||
|
||||
return ret;
|
||||
@@ -313,32 +302,21 @@ system_heap_dma_buf_end_cpu_access_partial(struct dma_buf *dmabuf,
|
||||
unsigned int len)
|
||||
{
|
||||
struct system_heap_buffer *buffer = dmabuf->priv;
|
||||
struct dma_heap_attachment *a;
|
||||
int ret = 0;
|
||||
struct dma_heap *heap = buffer->heap;
|
||||
struct sg_table *table = &buffer->sg_table;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&buffer->lock);
|
||||
if (buffer->vmap_cnt)
|
||||
flush_kernel_vmap_range(buffer->vaddr, buffer->len);
|
||||
|
||||
if (buffer->uncached)
|
||||
goto unlock;
|
||||
|
||||
list_for_each_entry(a, &buffer->attachments, list) {
|
||||
if (!a->mapped)
|
||||
continue;
|
||||
|
||||
ret = system_heap_sgl_sync_range(a->dev, a->table, offset, len,
|
||||
direction, false);
|
||||
if (buffer->uncached) {
|
||||
mutex_unlock(&buffer->lock);
|
||||
return 0;
|
||||
}
|
||||
if (list_empty(&buffer->attachments)) {
|
||||
struct dma_heap *heap = buffer->heap;
|
||||
struct sg_table *table = &buffer->sg_table;
|
||||
|
||||
ret = system_heap_sgl_sync_range(dma_heap_get_dev(heap), table,
|
||||
offset, len,
|
||||
direction, false);
|
||||
}
|
||||
unlock:
|
||||
ret = system_heap_sgl_sync_range(dma_heap_get_dev(heap), table,
|
||||
offset, len, direction, false);
|
||||
mutex_unlock(&buffer->lock);
|
||||
|
||||
return ret;
|
||||
|
||||
Reference in New Issue
Block a user