ION does not provide API to the kernel drivers.
Thus, ion_alloc_dmabuf() is introduced. To allocate a buffer from a
specific heap of ION, the client should query heaps to search proper
heap then allocate buffers with heap mask of the found heap. This
is tedious and error-prone task for drivers.
Let's allow drivers select a heap with heap name. The Exynos extension
to ION will find the heap with the given name and select the heap for
buffer allocation.
ion_alloc_dmabuf() returns dma_buf instead of fd. To deliver the
allocated dma_buf from ion_alloc_dmabuf() to the userspace, the client
driver should assign it to an unused fd by itself.
Change-Id: Iedc0f970fcc2ddcf4739a5d8c3ecec3cd137e280
Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
obj-$(CONFIG_ION_CHUNK_HEAP) += ion_chunk_heap.o
obj-$(CONFIG_ION_CMA_HEAP) += ion_cma_heap.o
obj-$(CONFIG_ION_TEST) += ion_test.o
-obj-$(CONFIG_ION_EXYNOS) += ion_fdt_exynos.o ion_buffer_protect.o
+obj-$(CONFIG_ION_EXYNOS) += ion_fdt_exynos.o ion_buffer_protect.o ion_exynos.o
.vunmap = ion_dma_buf_vunmap,
};
-int ion_alloc(size_t len, unsigned int heap_id_mask, unsigned int flags)
+struct dma_buf *__ion_alloc(size_t len, unsigned int heap_id_mask,
+ unsigned int flags)
{
struct ion_device *dev = internal_dev;
struct ion_buffer *buffer = NULL;
struct ion_heap *heap;
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
- int fd;
struct dma_buf *dmabuf;
pr_debug("%s: len %zu heap_id_mask %u flags %x\n", __func__,
len = PAGE_ALIGN(len);
if (!len)
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
down_read(&dev->lock);
plist_for_each_entry(heap, &dev->heaps, node) {
up_read(&dev->lock);
if (!buffer)
- return -ENODEV;
+ return ERR_PTR(-ENODEV);
if (IS_ERR(buffer))
- return PTR_ERR(buffer);
+ return ERR_CAST(buffer);
exp_info.ops = &dma_buf_ops;
exp_info.size = buffer->size;
exp_info.priv = buffer;
dmabuf = dma_buf_export(&exp_info);
- if (IS_ERR(dmabuf)) {
+ if (IS_ERR(dmabuf))
_ion_buffer_destroy(buffer);
+
+ return dmabuf;
+}
+
+int ion_alloc(size_t len, unsigned int heap_id_mask, unsigned int flags)
+{
+ struct dma_buf *dmabuf = __ion_alloc(len, heap_id_mask, flags);
+ int fd;
+
+ if (IS_ERR(dmabuf))
return PTR_ERR(dmabuf);
- }
fd = dma_buf_fd(dmabuf, O_CLOEXEC);
if (fd < 0)
return ret;
}
+struct ion_heap *ion_get_heap_by_name(const char *heap_name)
+{
+ struct ion_device *dev = internal_dev;
+ struct ion_heap *heap;
+
+ plist_for_each_entry(heap, &dev->heaps, node) {
+ if (strlen(heap_name) != strlen(heap->name))
+ continue;
+ if (strcmp(heap_name, heap->name) == 0)
+ return heap;
+ }
+
+ return NULL;
+}
+
static const struct file_operations ion_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = ion_ioctl,
--- /dev/null
+/*
+ * drivers/staging/android/ion/ion_exynos.c
+ *
+ * Copyright (C) 2018 Samsung Electronics Co., Ltd.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "ion.h"
+#include "ion_exynos.h"
+
+struct dma_buf *ion_alloc_dmabuf(const char *heap_name,
+ size_t len, unsigned int flags)
+{
+ struct ion_heap *heap = ion_get_heap_by_name(heap_name);
+
+ if (!heap) {
+ pr_err("%s: heap '%s' is not found\n", __func__, heap_name);
+ return ERR_PTR(-EINVAL);
+ }
+
+ return __ion_alloc(len, 1 << heap->id, flags);
+}
#define _ION_EXYNOS_H_
struct cma;
+struct dma_buf;
struct ion_heap;
struct ion_platform_heap;
#define ion_buffer_unprotect(priv) do { } while (0)
#endif
+struct ion_heap *ion_get_heap_by_name(const char *heap_name);
+struct dma_buf *__ion_alloc(size_t len, unsigned int heap_id_mask,
+ unsigned int flags);
#endif /* _ION_EXYNOS_H_ */
--- /dev/null
+/*
+ * include/linux/ion_exynos.h
+ *
+ * Copyright (C) 2018 Samsung Electronics Co., Ltd.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __LINUX_ION_EXYNOS_H__
+#define __LINUX_ION_EXYNOS_H__
+
+#define ION_FLAG_CACHED 1
+#define ION_FLAG_PROTECTED 16
+
+#ifdef CONFIG_ION_EXYNOS
+struct dma_buf *ion_alloc_dmabuf(const char *heap_name,
+ size_t len, unsigned int flags);
+#else
+static inline struct dma_buf *ion_alloc_dmabuf(const char *heap_name,
+ size_t len, unsigned int flags)
+{
+ return ERR_PTR(-ENODEV);
+}
+#endif
+
+#endif /* __LINUX_ION_EXYNOS_H__ */