forked from mirrors/linux
		
	dma-buf: Add dma-buf heaps framework
This framework allows a unified userspace interface for dma-buf exporters, allowing userland to allocate specific types of memory for use in dma-buf sharing. Each heap is given its own device node, which a user can allocate a dma-buf fd from using the DMA_HEAP_IOC_ALLOC. This code is an evoluiton of the Android ION implementation, and a big thanks is due to its authors/maintainers over time for their effort: Rebecca Schultz Zavin, Colin Cross, Benjamin Gaignard, Laura Abbott, and many other contributors! Cc: Laura Abbott <labbott@redhat.com> Cc: Benjamin Gaignard <benjamin.gaignard@linaro.org> Cc: Sumit Semwal <sumit.semwal@linaro.org> Cc: Liam Mark <lmark@codeaurora.org> Cc: Pratik Patel <pratikp@codeaurora.org> Cc: Brian Starkey <Brian.Starkey@arm.com> Cc: Vincent Donnefort <Vincent.Donnefort@arm.com> Cc: Sudipto Paul <Sudipto.Paul@arm.com> Cc: Andrew F. Davis <afd@ti.com> Cc: Christoph Hellwig <hch@infradead.org> Cc: Chenbo Feng <fengc@google.com> Cc: Alistair Strachan <astrachan@google.com> Cc: Hridya Valsaraju <hridya@google.com> Cc: Hillf Danton <hdanton@sina.com> Cc: dri-devel@lists.freedesktop.org Reviewed-by: Benjamin Gaignard <benjamin.gaignard@linaro.org> Reviewed-by: Brian Starkey <brian.starkey@arm.com> Acked-by: Laura Abbott <labbott@redhat.com> Tested-by: Ayan Kumar Halder <ayan.halder@arm.com> Signed-off-by: Andrew F. Davis <afd@ti.com> Signed-off-by: John Stultz <john.stultz@linaro.org> Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20191021190310.85221-2-john.stultz@linaro.org
This commit is contained in:
		
							parent
							
								
									ea7d8c675e
								
							
						
					
					
						commit
						a69b0e855d
					
				
					 6 changed files with 411 additions and 0 deletions
				
			
		
							
								
								
									
										18
									
								
								MAINTAINERS
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								MAINTAINERS
									
									
									
									
									
								
							|  | @ -4942,6 +4942,24 @@ F:	include/linux/*fence.h | ||||||
| F:	Documentation/driver-api/dma-buf.rst | F:	Documentation/driver-api/dma-buf.rst | ||||||
| T:	git git://anongit.freedesktop.org/drm/drm-misc | T:	git git://anongit.freedesktop.org/drm/drm-misc | ||||||
| 
 | 
 | ||||||
|  | DMA-BUF HEAPS FRAMEWORK | ||||||
|  | M:	Sumit Semwal <sumit.semwal@linaro.org> | ||||||
|  | R:	Andrew F. Davis <afd@ti.com> | ||||||
|  | R:	Benjamin Gaignard <benjamin.gaignard@linaro.org> | ||||||
|  | R:	Liam Mark <lmark@codeaurora.org> | ||||||
|  | R:	Laura Abbott <labbott@redhat.com> | ||||||
|  | R:	Brian Starkey <Brian.Starkey@arm.com> | ||||||
|  | R:	John Stultz <john.stultz@linaro.org> | ||||||
|  | S:	Maintained | ||||||
|  | L:	linux-media@vger.kernel.org | ||||||
|  | L:	dri-devel@lists.freedesktop.org | ||||||
|  | L:	linaro-mm-sig@lists.linaro.org (moderated for non-subscribers) | ||||||
|  | F:	include/uapi/linux/dma-heap.h | ||||||
|  | F:	include/linux/dma-heap.h | ||||||
|  | F:	drivers/dma-buf/dma-heap.c | ||||||
|  | F:	drivers/dma-buf/heaps/* | ||||||
|  | T:	git git://anongit.freedesktop.org/drm/drm-misc | ||||||
|  | 
 | ||||||
| DMA GENERIC OFFLOAD ENGINE SUBSYSTEM | DMA GENERIC OFFLOAD ENGINE SUBSYSTEM | ||||||
| M:	Vinod Koul <vkoul@kernel.org> | M:	Vinod Koul <vkoul@kernel.org> | ||||||
| L:	dmaengine@vger.kernel.org | L:	dmaengine@vger.kernel.org | ||||||
|  |  | ||||||
|  | @ -44,4 +44,13 @@ config DMABUF_SELFTESTS | ||||||
| 	default n | 	default n | ||||||
| 	depends on DMA_SHARED_BUFFER | 	depends on DMA_SHARED_BUFFER | ||||||
| 
 | 
 | ||||||
|  | menuconfig DMABUF_HEAPS | ||||||
|  | 	bool "DMA-BUF Userland Memory Heaps" | ||||||
|  | 	select DMA_SHARED_BUFFER | ||||||
|  | 	help | ||||||
|  | 	  Choose this option to enable the DMA-BUF userland memory heaps. | ||||||
|  | 	  This options creates per heap chardevs in /dev/dma_heap/ which | ||||||
|  | 	  allows userspace to allocate dma-bufs that can be shared | ||||||
|  | 	  between drivers. | ||||||
|  | 
 | ||||||
| endmenu | endmenu | ||||||
|  |  | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| # SPDX-License-Identifier: GPL-2.0-only
 | # SPDX-License-Identifier: GPL-2.0-only
 | ||||||
| obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \
 | obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \
 | ||||||
| 	 dma-resv.o seqno-fence.o | 	 dma-resv.o seqno-fence.o | ||||||
|  | obj-$(CONFIG_DMABUF_HEAPS)	+= dma-heap.o | ||||||
| obj-$(CONFIG_SYNC_FILE)		+= sync_file.o | obj-$(CONFIG_SYNC_FILE)		+= sync_file.o | ||||||
| obj-$(CONFIG_SW_SYNC)		+= sw_sync.o sync_debug.o | obj-$(CONFIG_SW_SYNC)		+= sw_sync.o sync_debug.o | ||||||
| obj-$(CONFIG_UDMABUF)		+= udmabuf.o | obj-$(CONFIG_UDMABUF)		+= udmabuf.o | ||||||
|  |  | ||||||
							
								
								
									
										269
									
								
								drivers/dma-buf/dma-heap.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										269
									
								
								drivers/dma-buf/dma-heap.c
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,269 @@ | ||||||
|  | // SPDX-License-Identifier: GPL-2.0
 | ||||||
|  | /*
 | ||||||
|  |  * Framework for userspace DMA-BUF allocations | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2011 Google, Inc. | ||||||
|  |  * Copyright (C) 2019 Linaro Ltd. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <linux/cdev.h> | ||||||
|  | #include <linux/debugfs.h> | ||||||
|  | #include <linux/device.h> | ||||||
|  | #include <linux/dma-buf.h> | ||||||
|  | #include <linux/err.h> | ||||||
|  | #include <linux/xarray.h> | ||||||
|  | #include <linux/list.h> | ||||||
|  | #include <linux/slab.h> | ||||||
|  | #include <linux/uaccess.h> | ||||||
|  | #include <linux/syscalls.h> | ||||||
|  | #include <linux/dma-heap.h> | ||||||
|  | #include <uapi/linux/dma-heap.h> | ||||||
|  | 
 | ||||||
|  | #define DEVNAME "dma_heap" | ||||||
|  | 
 | ||||||
|  | #define NUM_HEAP_MINORS 128 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * struct dma_heap - represents a dmabuf heap in the system | ||||||
|  |  * @name:		used for debugging/device-node name | ||||||
|  |  * @ops:		ops struct for this heap | ||||||
|  |  * @minor		minor number of this heap device | ||||||
|  |  * @heap_devt		heap device node | ||||||
|  |  * @heap_cdev		heap char device | ||||||
|  |  * | ||||||
|  |  * Represents a heap of memory from which buffers can be made. | ||||||
|  |  */ | ||||||
|  | struct dma_heap { | ||||||
|  | 	const char *name; | ||||||
|  | 	const struct dma_heap_ops *ops; | ||||||
|  | 	void *priv; | ||||||
|  | 	unsigned int minor; | ||||||
|  | 	dev_t heap_devt; | ||||||
|  | 	struct list_head list; | ||||||
|  | 	struct cdev heap_cdev; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static LIST_HEAD(heap_list); | ||||||
|  | static DEFINE_MUTEX(heap_list_lock); | ||||||
|  | static dev_t dma_heap_devt; | ||||||
|  | static struct class *dma_heap_class; | ||||||
|  | static DEFINE_XARRAY_ALLOC(dma_heap_minors); | ||||||
|  | 
 | ||||||
|  | static int dma_heap_buffer_alloc(struct dma_heap *heap, size_t len, | ||||||
|  | 				 unsigned int fd_flags, | ||||||
|  | 				 unsigned int heap_flags) | ||||||
|  | { | ||||||
|  | 	/*
 | ||||||
|  | 	 * Allocations from all heaps have to begin | ||||||
|  | 	 * and end on page boundaries. | ||||||
|  | 	 */ | ||||||
|  | 	len = PAGE_ALIGN(len); | ||||||
|  | 	if (!len) | ||||||
|  | 		return -EINVAL; | ||||||
|  | 
 | ||||||
|  | 	return heap->ops->allocate(heap, len, fd_flags, heap_flags); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int dma_heap_open(struct inode *inode, struct file *file) | ||||||
|  | { | ||||||
|  | 	struct dma_heap *heap; | ||||||
|  | 
 | ||||||
|  | 	heap = xa_load(&dma_heap_minors, iminor(inode)); | ||||||
|  | 	if (!heap) { | ||||||
|  | 		pr_err("dma_heap: minor %d unknown.\n", iminor(inode)); | ||||||
|  | 		return -ENODEV; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* instance data as context */ | ||||||
|  | 	file->private_data = heap; | ||||||
|  | 	nonseekable_open(inode, file); | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static long dma_heap_ioctl_allocate(struct file *file, unsigned long arg) | ||||||
|  | { | ||||||
|  | 	struct dma_heap_allocation_data heap_allocation; | ||||||
|  | 	struct dma_heap *heap = file->private_data; | ||||||
|  | 	int fd; | ||||||
|  | 
 | ||||||
|  | 	if (copy_from_user(&heap_allocation, (void __user *)arg, | ||||||
|  | 			   sizeof(heap_allocation))) | ||||||
|  | 		return -EFAULT; | ||||||
|  | 
 | ||||||
|  | 	if (heap_allocation.fd || | ||||||
|  | 	    heap_allocation.reserved0 || | ||||||
|  | 	    heap_allocation.reserved1) { | ||||||
|  | 		pr_warn_once("dma_heap: ioctl data not valid\n"); | ||||||
|  | 		return -EINVAL; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (heap_allocation.fd_flags & ~DMA_HEAP_VALID_FD_FLAGS) { | ||||||
|  | 		pr_warn_once("dma_heap: fd_flags has invalid or unsupported flags set\n"); | ||||||
|  | 		return -EINVAL; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (heap_allocation.heap_flags & ~DMA_HEAP_VALID_HEAP_FLAGS) { | ||||||
|  | 		pr_warn_once("dma_heap: heap flags has invalid or unsupported flags set\n"); | ||||||
|  | 		return -EINVAL; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fd = dma_heap_buffer_alloc(heap, heap_allocation.len, | ||||||
|  | 				   heap_allocation.fd_flags, | ||||||
|  | 				   heap_allocation.heap_flags); | ||||||
|  | 	if (fd < 0) | ||||||
|  | 		return fd; | ||||||
|  | 
 | ||||||
|  | 	heap_allocation.fd = fd; | ||||||
|  | 
 | ||||||
|  | 	if (copy_to_user((void __user *)arg, &heap_allocation, | ||||||
|  | 			 sizeof(heap_allocation))) { | ||||||
|  | 		ksys_close(fd); | ||||||
|  | 		return -EFAULT; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static long dma_heap_ioctl(struct file *file, unsigned int cmd, | ||||||
|  | 			   unsigned long arg) | ||||||
|  | { | ||||||
|  | 	int ret = 0; | ||||||
|  | 
 | ||||||
|  | 	switch (cmd) { | ||||||
|  | 	case DMA_HEAP_IOC_ALLOC: | ||||||
|  | 		ret = dma_heap_ioctl_allocate(file, arg); | ||||||
|  | 		break; | ||||||
|  | 	default: | ||||||
|  | 		return -ENOTTY; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static const struct file_operations dma_heap_fops = { | ||||||
|  | 	.owner          = THIS_MODULE, | ||||||
|  | 	.open		= dma_heap_open, | ||||||
|  | 	.unlocked_ioctl = dma_heap_ioctl, | ||||||
|  | #ifdef CONFIG_COMPAT | ||||||
|  | 	.compat_ioctl	= dma_heap_ioctl, | ||||||
|  | #endif | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * dma_heap_get_drvdata() - get per-subdriver data for the heap | ||||||
|  |  * @heap: DMA-Heap to retrieve private data for | ||||||
|  |  * | ||||||
|  |  * Returns: | ||||||
|  |  * The per-subdriver data for the heap. | ||||||
|  |  */ | ||||||
|  | void *dma_heap_get_drvdata(struct dma_heap *heap) | ||||||
|  | { | ||||||
|  | 	return heap->priv; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info) | ||||||
|  | { | ||||||
|  | 	struct dma_heap *heap, *h, *err_ret; | ||||||
|  | 	struct device *dev_ret; | ||||||
|  | 	int ret; | ||||||
|  | 
 | ||||||
|  | 	if (!exp_info->name || !strcmp(exp_info->name, "")) { | ||||||
|  | 		pr_err("dma_heap: Cannot add heap without a name\n"); | ||||||
|  | 		return ERR_PTR(-EINVAL); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (!exp_info->ops || !exp_info->ops->allocate) { | ||||||
|  | 		pr_err("dma_heap: Cannot add heap with invalid ops struct\n"); | ||||||
|  | 		return ERR_PTR(-EINVAL); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* check the name is unique */ | ||||||
|  | 	mutex_lock(&heap_list_lock); | ||||||
|  | 	list_for_each_entry(h, &heap_list, list) { | ||||||
|  | 		if (!strcmp(h->name, exp_info->name)) { | ||||||
|  | 			mutex_unlock(&heap_list_lock); | ||||||
|  | 			pr_err("dma_heap: Already registered heap named %s\n", | ||||||
|  | 			       exp_info->name); | ||||||
|  | 			return ERR_PTR(-EINVAL); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	mutex_unlock(&heap_list_lock); | ||||||
|  | 
 | ||||||
|  | 	heap = kzalloc(sizeof(*heap), GFP_KERNEL); | ||||||
|  | 	if (!heap) | ||||||
|  | 		return ERR_PTR(-ENOMEM); | ||||||
|  | 
 | ||||||
|  | 	heap->name = exp_info->name; | ||||||
|  | 	heap->ops = exp_info->ops; | ||||||
|  | 	heap->priv = exp_info->priv; | ||||||
|  | 
 | ||||||
|  | 	/* Find unused minor number */ | ||||||
|  | 	ret = xa_alloc(&dma_heap_minors, &heap->minor, heap, | ||||||
|  | 		       XA_LIMIT(0, NUM_HEAP_MINORS - 1), GFP_KERNEL); | ||||||
|  | 	if (ret < 0) { | ||||||
|  | 		pr_err("dma_heap: Unable to get minor number for heap\n"); | ||||||
|  | 		err_ret = ERR_PTR(ret); | ||||||
|  | 		goto err0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* Create device */ | ||||||
|  | 	heap->heap_devt = MKDEV(MAJOR(dma_heap_devt), heap->minor); | ||||||
|  | 
 | ||||||
|  | 	cdev_init(&heap->heap_cdev, &dma_heap_fops); | ||||||
|  | 	ret = cdev_add(&heap->heap_cdev, heap->heap_devt, 1); | ||||||
|  | 	if (ret < 0) { | ||||||
|  | 		pr_err("dma_heap: Unable to add char device\n"); | ||||||
|  | 		err_ret = ERR_PTR(ret); | ||||||
|  | 		goto err1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	dev_ret = device_create(dma_heap_class, | ||||||
|  | 				NULL, | ||||||
|  | 				heap->heap_devt, | ||||||
|  | 				NULL, | ||||||
|  | 				heap->name); | ||||||
|  | 	if (IS_ERR(dev_ret)) { | ||||||
|  | 		pr_err("dma_heap: Unable to create device\n"); | ||||||
|  | 		err_ret = ERR_CAST(dev_ret); | ||||||
|  | 		goto err2; | ||||||
|  | 	} | ||||||
|  | 	/* Add heap to the list */ | ||||||
|  | 	mutex_lock(&heap_list_lock); | ||||||
|  | 	list_add(&heap->list, &heap_list); | ||||||
|  | 	mutex_unlock(&heap_list_lock); | ||||||
|  | 
 | ||||||
|  | 	return heap; | ||||||
|  | 
 | ||||||
|  | err2: | ||||||
|  | 	cdev_del(&heap->heap_cdev); | ||||||
|  | err1: | ||||||
|  | 	xa_erase(&dma_heap_minors, heap->minor); | ||||||
|  | err0: | ||||||
|  | 	kfree(heap); | ||||||
|  | 	return err_ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static char *dma_heap_devnode(struct device *dev, umode_t *mode) | ||||||
|  | { | ||||||
|  | 	return kasprintf(GFP_KERNEL, "dma_heap/%s", dev_name(dev)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int dma_heap_init(void) | ||||||
|  | { | ||||||
|  | 	int ret; | ||||||
|  | 
 | ||||||
|  | 	ret = alloc_chrdev_region(&dma_heap_devt, 0, NUM_HEAP_MINORS, DEVNAME); | ||||||
|  | 	if (ret) | ||||||
|  | 		return ret; | ||||||
|  | 
 | ||||||
|  | 	dma_heap_class = class_create(THIS_MODULE, DEVNAME); | ||||||
|  | 	if (IS_ERR(dma_heap_class)) { | ||||||
|  | 		unregister_chrdev_region(dma_heap_devt, NUM_HEAP_MINORS); | ||||||
|  | 		return PTR_ERR(dma_heap_class); | ||||||
|  | 	} | ||||||
|  | 	dma_heap_class->devnode = dma_heap_devnode; | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | subsys_initcall(dma_heap_init); | ||||||
							
								
								
									
										59
									
								
								include/linux/dma-heap.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								include/linux/dma-heap.h
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,59 @@ | ||||||
|  | /* SPDX-License-Identifier: GPL-2.0 */ | ||||||
|  | /*
 | ||||||
|  |  * DMABUF Heaps Allocation Infrastructure | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2011 Google, Inc. | ||||||
|  |  * Copyright (C) 2019 Linaro Ltd. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef _DMA_HEAPS_H | ||||||
|  | #define _DMA_HEAPS_H | ||||||
|  | 
 | ||||||
|  | #include <linux/cdev.h> | ||||||
|  | #include <linux/types.h> | ||||||
|  | 
 | ||||||
|  | struct dma_heap; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * struct dma_heap_ops - ops to operate on a given heap | ||||||
|  |  * @allocate:		allocate dmabuf and return fd | ||||||
|  |  * | ||||||
|  |  * allocate returns dmabuf fd  on success, -errno on error. | ||||||
|  |  */ | ||||||
|  | struct dma_heap_ops { | ||||||
|  | 	int (*allocate)(struct dma_heap *heap, | ||||||
|  | 			unsigned long len, | ||||||
|  | 			unsigned long fd_flags, | ||||||
|  | 			unsigned long heap_flags); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * struct dma_heap_export_info - information needed to export a new dmabuf heap | ||||||
|  |  * @name:	used for debugging/device-node name | ||||||
|  |  * @ops:	ops struct for this heap | ||||||
|  |  * @priv:	heap exporter private data | ||||||
|  |  * | ||||||
|  |  * Information needed to export a new dmabuf heap. | ||||||
|  |  */ | ||||||
|  | struct dma_heap_export_info { | ||||||
|  | 	const char *name; | ||||||
|  | 	const struct dma_heap_ops *ops; | ||||||
|  | 	void *priv; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * dma_heap_get_drvdata() - get per-heap driver data | ||||||
|  |  * @heap: DMA-Heap to retrieve private data for | ||||||
|  |  * | ||||||
|  |  * Returns: | ||||||
|  |  * The per-heap data for the heap. | ||||||
|  |  */ | ||||||
|  | void *dma_heap_get_drvdata(struct dma_heap *heap); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * dma_heap_add - adds a heap to dmabuf heaps | ||||||
|  |  * @exp_info:		information needed to register this heap | ||||||
|  |  */ | ||||||
|  | struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info); | ||||||
|  | 
 | ||||||
|  | #endif /* _DMA_HEAPS_H */ | ||||||
							
								
								
									
										55
									
								
								include/uapi/linux/dma-heap.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								include/uapi/linux/dma-heap.h
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,55 @@ | ||||||
|  | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ | ||||||
|  | /*
 | ||||||
|  |  * DMABUF Heaps Userspace API | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2011 Google, Inc. | ||||||
|  |  * Copyright (C) 2019 Linaro Ltd. | ||||||
|  |  */ | ||||||
|  | #ifndef _UAPI_LINUX_DMABUF_POOL_H | ||||||
|  | #define _UAPI_LINUX_DMABUF_POOL_H | ||||||
|  | 
 | ||||||
|  | #include <linux/ioctl.h> | ||||||
|  | #include <linux/types.h> | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * DOC: DMABUF Heaps Userspace API | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /* Valid FD_FLAGS are O_CLOEXEC, O_RDONLY, O_WRONLY, O_RDWR */ | ||||||
|  | #define DMA_HEAP_VALID_FD_FLAGS (O_CLOEXEC | O_ACCMODE) | ||||||
|  | 
 | ||||||
|  | /* Currently no heap flags */ | ||||||
|  | #define DMA_HEAP_VALID_HEAP_FLAGS (0) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * struct dma_heap_allocation_data - metadata passed from userspace for | ||||||
|  |  *                                      allocations | ||||||
|  |  * @len:		size of the allocation | ||||||
|  |  * @fd:			will be populated with a fd which provdes the | ||||||
|  |  *			handle to the allocated dma-buf | ||||||
|  |  * @fd_flags:		file descriptor flags used when allocating | ||||||
|  |  * @heap_flags:		flags passed to heap | ||||||
|  |  * | ||||||
|  |  * Provided by userspace as an argument to the ioctl | ||||||
|  |  */ | ||||||
|  | struct dma_heap_allocation_data { | ||||||
|  | 	__u64 len; | ||||||
|  | 	__u32 fd; | ||||||
|  | 	__u32 fd_flags; | ||||||
|  | 	__u64 heap_flags; | ||||||
|  | 	__u32 reserved0; | ||||||
|  | 	__u32 reserved1; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #define DMA_HEAP_IOC_MAGIC		'H' | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * DOC: DMA_HEAP_IOC_ALLOC - allocate memory from pool | ||||||
|  |  * | ||||||
|  |  * Takes an dma_heap_allocation_data struct and returns it with the fd field | ||||||
|  |  * populated with the dmabuf handle of the allocation. | ||||||
|  |  */ | ||||||
|  | #define DMA_HEAP_IOC_ALLOC	_IOWR(DMA_HEAP_IOC_MAGIC, 0, \ | ||||||
|  | 				      struct dma_heap_allocation_data) | ||||||
|  | 
 | ||||||
|  | #endif /* _UAPI_LINUX_DMABUF_POOL_H */ | ||||||
		Loading…
	
		Reference in a new issue
	
	 Andrew F. Davis
						Andrew F. Davis