dma-buf: dma-heap: heap ops supports get_phys

This patch makes the dma-heap device support to get physical address by
DMA_HEAP_IOCTL_GET_PHYS. The sub heaps can add a support to this ops.

Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com>
Change-Id: I1daf65f742ce48db5548aa3fb860bb3fb4e2291d
This commit is contained in:
Jianqun Xu
2022-05-12 16:17:16 +08:00
committed by Tao Huang
parent dcbfe3bd8c
commit 61a32e157e
4 changed files with 64 additions and 0 deletions

View File

@@ -155,8 +155,22 @@ static long dma_heap_ioctl_allocate(struct file *file, void *data)
return 0;
}
static int dma_heap_ioctl_get_phys(struct file *file, void *data)
{
#if IS_ENABLED(CONFIG_NO_GKI)
struct dma_heap *heap = file->private_data;
struct dma_heap_phys_data *phys = data;
if (heap->ops->get_phys)
return heap->ops->get_phys(heap, phys);
#endif
return -EINVAL;
}
static unsigned int dma_heap_ioctl_cmds[] = {
DMA_HEAP_IOCTL_ALLOC,
DMA_HEAP_IOCTL_GET_PHYS,
};
static long dma_heap_ioctl(struct file *file, unsigned int ucmd,
@@ -205,6 +219,9 @@ static long dma_heap_ioctl(struct file *file, unsigned int ucmd,
case DMA_HEAP_IOCTL_ALLOC:
ret = dma_heap_ioctl_allocate(file, kdata);
break;
case DMA_HEAP_IOCTL_GET_PHYS:
ret = dma_heap_ioctl_get_phys(file, kdata);
break;
default:
ret = -ENOTTY;
goto err;

View File

@@ -21,6 +21,7 @@
#include <linux/scatterlist.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <uapi/linux/dma-heap.h>
struct cma_heap {
@@ -440,8 +441,42 @@ static struct dma_buf *cma_heap_allocate(struct dma_heap *heap,
return cma_heap_do_allocate(heap, len, fd_flags, heap_flags, false);
}
static int cma_heap_get_phys(struct dma_heap *heap,
struct dma_heap_phys_data *phys)
{
struct cma_heap *cma_heap = dma_heap_get_drvdata(heap);
struct cma_heap_buffer *buffer;
struct dma_buf *dmabuf;
phys->paddr = (__u64)-1;
if (IS_ERR_OR_NULL(phys))
return -EINVAL;
dmabuf = dma_buf_get(phys->fd);
if (IS_ERR_OR_NULL(dmabuf))
return -EBADFD;
buffer = dmabuf->priv;
if (IS_ERR_OR_NULL(buffer))
goto err;
if (buffer->heap != cma_heap)
goto err;
phys->paddr = page_to_phys(buffer->cma_pages);
err:
dma_buf_put(dmabuf);
return (phys->paddr == (__u64)-1) ? -EINVAL : 0;
}
static const struct dma_heap_ops cma_heap_ops = {
.allocate = cma_heap_allocate,
#if IS_ENABLED(CONFIG_NO_GKI)
.get_phys = cma_heap_get_phys,
#endif
};
static struct dma_buf *cma_uncached_heap_allocate(struct dma_heap *heap,

View File

@@ -11,6 +11,7 @@
#include <linux/cdev.h>
#include <linux/types.h>
#include <uapi/linux/dma-heap.h>
struct dma_heap;
@@ -27,6 +28,9 @@ struct dma_heap_ops {
unsigned long fd_flags,
unsigned long heap_flags);
long (*get_pool_size)(struct dma_heap *heap);
#if IS_ENABLED(CONFIG_NO_GKI)
int (*get_phys)(struct dma_heap *heap, struct dma_heap_phys_data *phys);
#endif
};
/**

View File

@@ -39,6 +39,11 @@ struct dma_heap_allocation_data {
__u64 heap_flags;
};
struct dma_heap_phys_data {
__u64 paddr;
__u32 fd;
};
#define DMA_HEAP_IOC_MAGIC 'H'
/**
@@ -50,4 +55,7 @@ struct dma_heap_allocation_data {
#define DMA_HEAP_IOCTL_ALLOC _IOWR(DMA_HEAP_IOC_MAGIC, 0x0,\
struct dma_heap_allocation_data)
#define DMA_HEAP_IOCTL_GET_PHYS _IOWR(DMA_HEAP_IOC_MAGIC, 0x1, \
struct dma_heap_phys_data)
#endif /* _UAPI_LINUX_DMABUF_POOL_H */