mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
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:
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user