diff --git a/drivers/staging/android/ion/ion-ioctl.c b/drivers/staging/android/ion/ion-ioctl.c index a8d3cc412fb9..d339a22aa8a2 100644 --- a/drivers/staging/android/ion/ion-ioctl.c +++ b/drivers/staging/android/ion/ion-ioctl.c @@ -13,6 +13,7 @@ union ion_ioctl_arg { struct ion_allocation_data allocation; struct ion_heap_query query; + struct ion_phys_data phys; }; static int validate_ioctl_arg(unsigned int cmd, union ion_ioctl_arg *arg) @@ -86,6 +87,9 @@ long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) case ION_IOC_HEAP_QUERY: ret = ion_query_heaps(&data.query); break; + case ION_IOC_GET_PHYS: + ret = ion_get_phys(&data.phys); + break; default: return -ENOTTY; } diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index d30ac35b80a2..c8f7cfd81d8a 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -746,6 +746,31 @@ out: return ret; } +int ion_get_phys(struct ion_phys_data *phys) +{ + struct dma_buf *dmabuf; + struct ion_buffer *buffer; + + if (IS_ERR_OR_NULL(phys)) + return -EINVAL; + + dmabuf = dma_buf_get(phys->fd); + if (IS_ERR_OR_NULL(dmabuf)) + return -ENOENT; + + phys->paddr = (__u64)-1; + buffer = dmabuf->priv; + if (!IS_ERR_OR_NULL(buffer) && + (buffer->heap->type == ION_HEAP_TYPE_SYSTEM_CONTIG || + buffer->heap->type == ION_HEAP_TYPE_DMA || + buffer->heap->type == ION_HEAP_TYPE_CARVEOUT)) + phys->paddr = sg_phys(buffer->sg_table->sgl); + + dma_buf_put(dmabuf); + + return 0; +} + static const struct file_operations ion_fops = { .owner = THIS_MODULE, .unlocked_ioctl = ion_ioctl, diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h index 7e9d096a6fe7..0305e93b9292 100644 --- a/drivers/staging/android/ion/ion.h +++ b/drivers/staging/android/ion/ion.h @@ -335,6 +335,7 @@ int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask, long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); int ion_query_heaps(struct ion_heap_query *query); +int ion_get_phys(struct ion_phys_data *phys); #ifdef CONFIG_ION_MODULE int ion_add_cma_heaps(void); diff --git a/drivers/staging/android/uapi/ion.h b/drivers/staging/android/uapi/ion.h index 50d312865730..d450b29dd77c 100644 --- a/drivers/staging/android/uapi/ion.h +++ b/drivers/staging/android/uapi/ion.h @@ -130,4 +130,13 @@ struct ion_heap_query { #define ION_IOC_HEAP_QUERY _IOWR(ION_IOC_MAGIC, 8, \ struct ion_heap_query) +struct ion_phys_data { + __u32 fd; + __u32 padding; + __u64 paddr; +}; + +#define ION_IOC_GET_PHYS _IOWR(ION_IOC_MAGIC, 9, \ + struct ion_phys_data) + #endif /* _UAPI_LINUX_ION_H */