mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +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;
|
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[] = {
|
static unsigned int dma_heap_ioctl_cmds[] = {
|
||||||
DMA_HEAP_IOCTL_ALLOC,
|
DMA_HEAP_IOCTL_ALLOC,
|
||||||
|
DMA_HEAP_IOCTL_GET_PHYS,
|
||||||
};
|
};
|
||||||
|
|
||||||
static long dma_heap_ioctl(struct file *file, unsigned int ucmd,
|
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:
|
case DMA_HEAP_IOCTL_ALLOC:
|
||||||
ret = dma_heap_ioctl_allocate(file, kdata);
|
ret = dma_heap_ioctl_allocate(file, kdata);
|
||||||
break;
|
break;
|
||||||
|
case DMA_HEAP_IOCTL_GET_PHYS:
|
||||||
|
ret = dma_heap_ioctl_get_phys(file, kdata);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ret = -ENOTTY;
|
ret = -ENOTTY;
|
||||||
goto err;
|
goto err;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include <linux/scatterlist.h>
|
#include <linux/scatterlist.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
|
#include <uapi/linux/dma-heap.h>
|
||||||
|
|
||||||
|
|
||||||
struct cma_heap {
|
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);
|
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 = {
|
static const struct dma_heap_ops cma_heap_ops = {
|
||||||
.allocate = cma_heap_allocate,
|
.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,
|
static struct dma_buf *cma_uncached_heap_allocate(struct dma_heap *heap,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <linux/cdev.h>
|
#include <linux/cdev.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
#include <uapi/linux/dma-heap.h>
|
||||||
|
|
||||||
struct dma_heap;
|
struct dma_heap;
|
||||||
|
|
||||||
@@ -27,6 +28,9 @@ struct dma_heap_ops {
|
|||||||
unsigned long fd_flags,
|
unsigned long fd_flags,
|
||||||
unsigned long heap_flags);
|
unsigned long heap_flags);
|
||||||
long (*get_pool_size)(struct dma_heap *heap);
|
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;
|
__u64 heap_flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct dma_heap_phys_data {
|
||||||
|
__u64 paddr;
|
||||||
|
__u32 fd;
|
||||||
|
};
|
||||||
|
|
||||||
#define DMA_HEAP_IOC_MAGIC 'H'
|
#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,\
|
#define DMA_HEAP_IOCTL_ALLOC _IOWR(DMA_HEAP_IOC_MAGIC, 0x0,\
|
||||||
struct dma_heap_allocation_data)
|
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 */
|
#endif /* _UAPI_LINUX_DMABUF_POOL_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user