Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eeeb9407 authored by Patrick Daly's avatar Patrick Daly
Browse files

ion: add snapshot of ion support for MSM



This is a snapshot of the ION support as of msm-3.10 commit
commit acdce027751d
("Merge "defconfig: arm64: Enable ONESHOT_SYNC for msm8994"")

Change-Id: I225616c1ef9e3bb2643b61a8870357e7bbece33e
Signed-off-by: default avatarKumar Gala <galak@codeaurora.org>
[mitchelh: dropped MSM changes to ion_chunk_heap, dropped MSM changes to
 ion_carveout_heap]
Signed-off-by: default avatarMitchel Humpherys <mitchelh@codeaurora.org>
[pdaly: deprecated ion_cma_secure_heap.c & msm_ion_priv.h]
Signed-off-by: default avatarPatrick Daly <pdaly@codeaurora.org>
parent 5581b1b3
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
menuconfig ION
	bool "Ion Memory Manager"
	depends on HAVE_MEMBLOCK && HAS_DMA && MMU
	depends on HAVE_MEMBLOCK && HAS_DMA && MMU && ION_MSM
	select GENERIC_ALLOCATOR
	select DMA_SHARED_BUFFER
	---help---
@@ -48,3 +48,20 @@ config ION_POOL_CACHE_POLICY
	help
	  Choose this option if need to explicity set cache policy of the
	  pages in the page pool.

config ION_MSM
	tristate "Ion for MSM"
	depends on ARCH_QCOM && CMA
	select MSM_SECURE_BUFFER
	help
	  Choose this option if you wish to use ion on an MSM target.
	  Features include allocating heaps from device tree, buffer
	  cache maintenance, and a custom ioctl/compat_ioctl. Enable
	  utility functions used by ion_system_heap.

config ALLOC_BUFFERS_IN_4K_CHUNKS
	bool "Turns off allocation optimization and allocate only 4K pages"
	depends on ARCH_QCOM && ION
	help
          Choose this option if you want ION to allocate buffers in
          only 4KB chunks.
+1 −1
Original line number Diff line number Diff line
@@ -4,8 +4,8 @@ obj-$(CONFIG_ION_TEST) += ion_test.o
ifdef CONFIG_COMPAT
obj-$(CONFIG_ION) += compat_ion.o
endif

obj-$(CONFIG_ION_DUMMY) += ion_dummy_driver.o
obj-$(CONFIG_ION_TEGRA) += tegra/
obj-$(CONFIG_ION_HISI) += hisilicon/

obj-$(CONFIG_ION_MSM) += msm/
+3 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@
 * drivers/staging/android/ion/compat_ion.h
 *
 * Copyright (C) 2013 Google, Inc.
 * Copyright (c) 2016, The Linux Foundation. All rights reserved.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
@@ -21,6 +22,8 @@

long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);

#define compat_ion_user_handle_t compat_int_t

#else

#define compat_ion_ioctl  NULL
+297 −30
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
 * drivers/staging/android/ion/ion.c
 *
 * Copyright (C) 2011 Google, Inc.
 * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
@@ -15,7 +16,6 @@
 *
 */

#include <linux/device.h>
#include <linux/err.h>
#include <linux/file.h>
#include <linux/freezer.h>
@@ -23,6 +23,7 @@
#include <linux/anon_inodes.h>
#include <linux/kthread.h>
#include <linux/list.h>
#include <linux/list_sort.h>
#include <linux/memblock.h>
#include <linux/miscdevice.h>
#include <linux/export.h>
@@ -36,6 +37,9 @@
#include <linux/debugfs.h>
#include <linux/dma-buf.h>
#include <linux/idr.h>
#include <linux/msm_ion.h>
#include <trace/events/kmem.h>


#include "ion.h"
#include "ion_priv.h"
@@ -88,7 +92,7 @@ struct ion_client {
	struct idr idr;
	/* Protects idr */
	struct mutex lock;
	const char *name;
	char *name;
	char *display_name;
	int display_serial;
	struct task_struct *task;
@@ -209,6 +213,8 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,

	buffer->dev = dev;
	buffer->size = len;
	buffer->flags = flags;
	INIT_LIST_HEAD(&buffer->vmas);

	table = heap->ops->map_dma(heap, buffer);
	if (WARN_ONCE(!table,
@@ -239,9 +245,6 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,
		}
	}

	buffer->dev = dev;
	buffer->size = len;
	INIT_LIST_HEAD(&buffer->vmas);
	mutex_init(&buffer->lock);
	/*
	 * this will set up dma addresses for the sglist -- it is not
@@ -257,6 +260,7 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,
		sg_dma_address(sg) = sg_phys(sg);
		sg_dma_len(sg) = sg->length;
	}

	mutex_lock(&dev->buffer_lock);
	ion_buffer_add(dev, buffer);
	mutex_unlock(&dev->buffer_lock);
@@ -276,6 +280,7 @@ void ion_buffer_destroy(struct ion_buffer *buffer)
	if (WARN_ON(buffer->kmap_cnt > 0))
		buffer->heap->ops->unmap_kernel(buffer->heap, buffer);
	buffer->heap->ops->unmap_dma(buffer->heap, buffer);

	buffer->heap->ops->free(buffer);
	vfree(buffer->pages);
	kfree(buffer);
@@ -398,7 +403,7 @@ static int ion_handle_put_nolock(struct ion_handle *handle)
	return ret;
}

static int ion_handle_put(struct ion_handle *handle)
int ion_handle_put(struct ion_handle *handle)
{
	struct ion_client *client = handle->client;
	int ret;
@@ -440,7 +445,7 @@ static struct ion_handle *ion_handle_get_by_id_nolock(struct ion_client *client,
	return handle ? handle : ERR_PTR(-EINVAL);
}

static struct ion_handle *ion_handle_get_by_id(struct ion_client *client,
struct ion_handle *ion_handle_get_by_id(struct ion_client *client,
					int id)
{
	struct ion_handle *handle;
@@ -499,6 +504,19 @@ struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
	struct ion_buffer *buffer = NULL;
	struct ion_heap *heap;
	int ret;
	const unsigned int MAX_DBG_STR_LEN = 64;
	char dbg_str[MAX_DBG_STR_LEN];
	unsigned int dbg_str_idx = 0;

	dbg_str[0] = '\0';

	/*
	 * For now, we don't want to fault in pages individually since
	 * clients are already doing manual cache maintenance. In
	 * other words, the implicit caching infrastructure is in
	 * place (in code) but should not be used.
	 */
	flags |= ION_FLAG_CACHED_NEEDS_SYNC;

	pr_debug("%s: len %zu align %zu heap_id_mask %u flags %x\n", __func__,
		 len, align, heap_id_mask, flags);
@@ -518,17 +536,53 @@ struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
		/* if the caller didn't specify this heap id */
		if (!((1 << heap->id) & heap_id_mask))
			continue;
		trace_ion_alloc_buffer_start(client->name, heap->name, len,
					     heap_id_mask, flags);
		buffer = ion_buffer_create(heap, dev, len, align, flags);
		trace_ion_alloc_buffer_end(client->name, heap->name, len,
					   heap_id_mask, flags);
		if (!IS_ERR(buffer))
			break;

		trace_ion_alloc_buffer_fallback(client->name, heap->name, len,
						heap_id_mask, flags,
						PTR_ERR(buffer));
		if (dbg_str_idx < MAX_DBG_STR_LEN) {
			unsigned int len_left;
			int ret_value;

			len_left = MAX_DBG_STR_LEN - dbg_str_idx - 1;
			ret_value = snprintf(&dbg_str[dbg_str_idx],
					     len_left, "%s ", heap->name);

			if (ret_value >= len_left) {
				/* overflow */
				dbg_str[MAX_DBG_STR_LEN - 1] = '\0';
				dbg_str_idx = MAX_DBG_STR_LEN;
			} else if (ret_value >= 0) {
				dbg_str_idx += ret_value;
			} else {
				/* error */
				dbg_str[MAX_DBG_STR_LEN - 1] = '\0';
			}
		}
	}
	up_read(&dev->lock);

	if (buffer == NULL)
	if (!buffer) {
		trace_ion_alloc_buffer_fail(client->name, dbg_str, len,
					    heap_id_mask, flags, -ENODEV);
		return ERR_PTR(-ENODEV);
	}

	if (IS_ERR(buffer))
	if (IS_ERR(buffer)) {
		trace_ion_alloc_buffer_fail(client->name, dbg_str, len,
					    heap_id_mask, flags,
					    PTR_ERR(buffer));
		pr_debug("ION is unable to allocate 0x%zx bytes (alignment: 0x%zx) from heap(s) %sfor client %s\n",
			 len, align, dbg_str, client->name);
		return ERR_CAST(buffer);
	}

	handle = ion_handle_create(client, buffer);

@@ -561,7 +615,6 @@ static void ion_free_nolock(struct ion_client *client,
	WARN_ON(client != handle->client);

	valid_handle = ion_handle_validate(client, handle);

	if (!valid_handle) {
		WARN(1, "%s: invalid handle passed to free.\n", __func__);
		return;
@@ -737,9 +790,10 @@ static int ion_debug_client_show(struct seq_file *s, void *unused)
{
	struct ion_client *client = s->private;
	struct rb_node *n;
	size_t sizes[ION_NUM_HEAP_IDS] = {0};
	const char *names[ION_NUM_HEAP_IDS] = {NULL};
	int i;

	seq_printf(s, "%16.16s: %16.16s : %16.16s : %12.12s\n",
		   "heap_name", "size_in_bytes", "handle refcount",
		   "buffer");

	mutex_lock(&debugfs_mutex);
	if (!is_client_alive(client)) {
@@ -753,21 +807,17 @@ static int ion_debug_client_show(struct seq_file *s, void *unused)
	for (n = rb_first(&client->handles); n; n = rb_next(n)) {
		struct ion_handle *handle = rb_entry(n, struct ion_handle,
						     node);
		unsigned int id = handle->buffer->heap->id;

		if (!names[id])
			names[id] = handle->buffer->heap->name;
		sizes[id] += handle->buffer->size;
		seq_printf(s, "%16.16s: %16zx : %16d : %12p",
			   handle->buffer->heap->name,
			   handle->buffer->size,
			   atomic_read(&handle->ref.refcount),
			   handle->buffer);

		seq_puts(s, "\n");
	}
	mutex_unlock(&client->lock);
	mutex_unlock(&debugfs_mutex);

	seq_printf(s, "%16.16s: %16.16s\n", "heap_name", "size_in_bytes");
	for (i = 0; i < ION_NUM_HEAP_IDS; i++) {
		if (!names[i])
			continue;
		seq_printf(s, "%16.16s: %16zu\n", names[i], sizes[i]);
	}
	return 0;
}

@@ -838,6 +888,7 @@ struct ion_client *ion_client_create(struct ion_device *dev,
	client->handles = RB_ROOT;
	idr_init(&client->idr);
	mutex_init(&client->lock);

	client->task = task;
	client->pid = pid;
	client->name = kstrdup(name, GFP_KERNEL);
@@ -911,6 +962,7 @@ void ion_client_destroy(struct ion_client *client)
		put_task_struct(client->task);
	rb_erase(&client->node, &dev->clients);
	debugfs_remove_recursive(client->debug_root);

	up_write(&dev->lock);

	kfree(client->display_name);
@@ -920,6 +972,50 @@ void ion_client_destroy(struct ion_client *client)
}
EXPORT_SYMBOL(ion_client_destroy);

int ion_handle_get_flags(struct ion_client *client, struct ion_handle *handle,
			 unsigned long *flags)
{
	struct ion_buffer *buffer;

	mutex_lock(&client->lock);
	if (!ion_handle_validate(client, handle)) {
		pr_err("%s: invalid handle passed to %s.\n",
		       __func__, __func__);
		mutex_unlock(&client->lock);
		return -EINVAL;
	}
	buffer = handle->buffer;
	mutex_lock(&buffer->lock);
	*flags = buffer->flags;
	mutex_unlock(&buffer->lock);
	mutex_unlock(&client->lock);

	return 0;
}
EXPORT_SYMBOL(ion_handle_get_flags);

int ion_handle_get_size(struct ion_client *client, struct ion_handle *handle,
			size_t *size)
{
	struct ion_buffer *buffer;

	mutex_lock(&client->lock);
	if (!ion_handle_validate(client, handle)) {
		pr_err("%s: invalid handle passed to %s.\n",
		       __func__, __func__);
		mutex_unlock(&client->lock);
		return -EINVAL;
	}
	buffer = handle->buffer;
	mutex_lock(&buffer->lock);
	*size = buffer->size;
	mutex_unlock(&buffer->lock);
	mutex_unlock(&client->lock);

	return 0;
}
EXPORT_SYMBOL(ion_handle_get_size);

struct sg_table *ion_sg_table(struct ion_client *client,
			      struct ion_handle *handle)
{
@@ -940,6 +1036,38 @@ struct sg_table *ion_sg_table(struct ion_client *client,
}
EXPORT_SYMBOL(ion_sg_table);

struct sg_table *ion_create_chunked_sg_table(phys_addr_t buffer_base,
					     size_t chunk_size,
					     size_t total_size)
{
	struct sg_table *table;
	int i, n_chunks, ret;
	struct scatterlist *sg;

	table = kzalloc(sizeof(*table), GFP_KERNEL);
	if (!table)
		return ERR_PTR(-ENOMEM);

	n_chunks = DIV_ROUND_UP(total_size, chunk_size);
	pr_debug("creating sg_table with %d chunks\n", n_chunks);

	ret = sg_alloc_table(table, n_chunks, GFP_KERNEL);
	if (ret)
		goto err0;

	for_each_sg(table->sgl, sg, table->nents, i) {
		dma_addr_t addr = buffer_base + i * chunk_size;

		sg_dma_address(sg) = addr;
		sg->length = chunk_size;
	}

	return table;
err0:
	kfree(table);
	return ERR_PTR(ret);
}

static void ion_buffer_sync_for_device(struct ion_buffer *buffer,
				       struct device *dev,
				       enum dma_data_direction direction);
@@ -1064,6 +1192,9 @@ static void ion_vm_close(struct vm_area_struct *vma)
		break;
	}
	mutex_unlock(&buffer->lock);

	if (buffer->heap->ops->unmap_user)
		buffer->heap->ops->unmap_user(buffer->heap, buffer);
}

static const struct vm_operations_struct ion_vma_ops = {
@@ -1088,6 +1219,7 @@ static int ion_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
							VM_DONTDUMP;
		vma->vm_private_data = buffer;
		vma->vm_ops = &ion_vma_ops;
		vma->vm_flags |= VM_MIXEDMAP;
		ion_vm_open(vma);
		return 0;
	}
@@ -1215,7 +1347,6 @@ int ion_share_dma_buf_fd(struct ion_client *client, struct ion_handle *handle)
	fd = dma_buf_fd(dmabuf, O_CLOEXEC);
	if (fd < 0)
		dma_buf_put(dmabuf);

	return fd;
}
EXPORT_SYMBOL(ion_share_dma_buf_fd);
@@ -1410,6 +1541,15 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
						data.custom.arg);
		break;
	}
	case ION_IOC_CLEAN_CACHES:
		return client->dev->custom_ioctl(client,
						ION_IOC_CLEAN_CACHES, arg);
	case ION_IOC_INV_CACHES:
		return client->dev->custom_ioctl(client,
						ION_IOC_INV_CACHES, arg);
	case ION_IOC_CLEAN_INV_CACHES:
		return client->dev->custom_ioctl(client,
						ION_IOC_CLEAN_INV_CACHES, arg);
	default:
		return -ENOTTY;
	}
@@ -1476,6 +1616,110 @@ static size_t ion_debug_heap_total(struct ion_client *client,
	return size;
}

/**
 * Create a mem_map of the heap.
 * @param s seq_file to log error message to.
 * @param heap The heap to create mem_map for.
 * @param mem_map The mem map to be created.
 */
void ion_debug_mem_map_create(struct seq_file *s, struct ion_heap *heap,
			      struct list_head *mem_map)
{
	struct ion_device *dev = heap->dev;
	struct rb_node *cnode;
	size_t size;
	struct ion_client *client;

	if (!heap->ops->phys)
		return;

	down_read(&dev->lock);
	for (cnode = rb_first(&dev->clients); cnode; cnode = rb_next(cnode)) {
		struct rb_node *hnode;

		client = rb_entry(cnode, struct ion_client, node);

		mutex_lock(&client->lock);
		for (hnode = rb_first(&client->handles);
		     hnode;
		     hnode = rb_next(hnode)) {
			struct ion_handle *handle = rb_entry(
				hnode, struct ion_handle, node);
			if (handle->buffer->heap == heap) {
				struct mem_map_data *data =
					kzalloc(sizeof(*data), GFP_KERNEL);
				if (!data)
					goto inner_error;
				heap->ops->phys(heap, handle->buffer,
						&data->addr, &size);
				data->size = (unsigned long)size;
				data->addr_end = data->addr + data->size - 1;
				data->client_name = kstrdup(client->name,
							GFP_KERNEL);
				if (!data->client_name) {
					kfree(data);
					goto inner_error;
				}
				list_add(&data->node, mem_map);
			}
		}
		mutex_unlock(&client->lock);
	}
	up_read(&dev->lock);
	return;

inner_error:
	seq_puts(s,
		 "ERROR: out of memory. Part of memory map will not be logged\n");
	mutex_unlock(&client->lock);
	up_read(&dev->lock);
}

/**
 * Free the memory allocated by ion_debug_mem_map_create
 * @param mem_map The mem map to free.
 */
static void ion_debug_mem_map_destroy(struct list_head *mem_map)
{
	if (mem_map) {
		struct mem_map_data *data, *tmp;

		list_for_each_entry_safe(data, tmp, mem_map, node) {
			list_del(&data->node);
			kfree(data->client_name);
			kfree(data);
		}
	}
}

static int mem_map_cmp(void *priv, struct list_head *a, struct list_head *b)
{
	struct mem_map_data *d1, *d2;

	d1 = list_entry(a, struct mem_map_data, node);
	d2 = list_entry(b, struct mem_map_data, node);
	if (d1->addr == d2->addr)
		return d1->size - d2->size;
	return d1->addr - d2->addr;
}

/**
 * Print heap debug information.
 * @param s seq_file to log message to.
 * @param heap pointer to heap that we will print debug information for.
 */
static void ion_heap_print_debug(struct seq_file *s, struct ion_heap *heap)
{
	if (heap->ops->print_debug) {
		struct list_head mem_map = LIST_HEAD_INIT(mem_map);

		ion_debug_mem_map_create(s, heap, &mem_map);
		list_sort(NULL, &mem_map, mem_map_cmp);
		heap->ops->print_debug(heap, s, &mem_map);
		ion_debug_mem_map_destroy(&mem_map);
	}
}

static int ion_debug_heap_show(struct seq_file *s, void *unused)
{
	struct ion_heap *heap = s->private;
@@ -1538,6 +1782,7 @@ static int ion_debug_heap_show(struct seq_file *s, void *unused)
	if (heap->debug_show)
		heap->debug_show(heap, s, unused);

	ion_heap_print_debug(s, heap);
	return 0;
}

@@ -1646,6 +1891,28 @@ void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap)
}
EXPORT_SYMBOL(ion_device_add_heap);

int ion_walk_heaps(struct ion_client *client, int heap_id, void *data,
		   int (*f)(struct ion_heap *heap, void *data))
{
	int ret_val = -EINVAL;
	struct ion_heap *heap;
	struct ion_device *dev = client->dev;
	/*
	 * traverse the list of heaps available in this system
	 * and find the heap that is specified.
	 */
	down_write(&dev->lock);
	plist_for_each_entry(heap, &dev->heaps, node) {
		if (ION_HEAP(heap->id) != heap_id)
			continue;
		ret_val = f(heap, data);
		break;
	}
	up_write(&dev->lock);
	return ret_val;
}
EXPORT_SYMBOL(ion_walk_heaps);

struct ion_device *ion_device_create(long (*custom_ioctl)
				     (struct ion_client *client,
				      unsigned int cmd,
@@ -1731,13 +1998,13 @@ void __init ion_reserve(struct ion_platform_data *data)
			int ret = memblock_reserve(data->heaps[i].base,
					       data->heaps[i].size);
			if (ret)
				pr_err("memblock reserve of %zx@%lx failed\n",
				pr_err("memblock reserve of %zx@%pa failed\n",
				       data->heaps[i].size,
				       data->heaps[i].base);
				       &data->heaps[i].base);
		}
		pr_info("%s: %s reserved base %lx size %zu\n", __func__,
		pr_info("%s: %s reserved base %pa size %zu\n", __func__,
			data->heaps[i].name,
			data->heaps[i].base,
			&data->heaps[i].base,
			data->heaps[i].size);
	}
}
+77 −5
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@
 * drivers/staging/android/ion/ion.h
 *
 * Copyright (C) 2011 Google, Inc.
 * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
@@ -17,8 +18,7 @@
#ifndef _LINUX_ION_H
#define _LINUX_ION_H

#include <linux/types.h>

#include <linux/err.h>
#include "../uapi/ion.h"

struct ion_handle;
@@ -34,7 +34,7 @@ struct ion_buffer;
 * be converted to phys_addr_t.  For the time being many kernel interfaces
 * do not accept phys_addr_t's that would have to
 */
#define ion_phys_addr_t unsigned long
#define ion_phys_addr_t dma_addr_t

/**
 * struct ion_platform_heap - defines a heap in the given platform
@@ -45,6 +45,9 @@ struct ion_buffer;
 * @name:	used for debug purposes
 * @base:	base address of heap in physical memory if applicable
 * @size:	size of the heap in bytes if applicable
 * @has_outer_cache:    set to 1 if outer cache is used, 0 otherwise.
 * @extra_data:	Extra data specific to each heap type
 * @priv:	heap private data
 * @align:	required alignment in physical memory if applicable
 * @priv:	private info passed from the board file
 *
@@ -56,22 +59,28 @@ struct ion_platform_heap {
	const char *name;
	ion_phys_addr_t base;
	size_t size;
	unsigned int has_outer_cache;
	void *extra_data;
	ion_phys_addr_t align;
	void *priv;
};

/**
 * struct ion_platform_data - array of platform heaps passed from board file
 * @has_outer_cache:    set to 1 if outer cache is used, 0 otherwise.
 * @nr:    number of structures in the array
 * @heaps: array of platform_heap structions
 *
 * Provided by the board file in the form of platform data to a platform device.
 */
struct ion_platform_data {
	unsigned int has_outer_cache;
	int nr;
	struct ion_platform_heap *heaps;
};

#ifdef CONFIG_ION

/**
 * ion_reserve() - reserve memory for ion heaps if applicable
 * @data:	platform data specifying starting physical address and
@@ -214,4 +223,67 @@ struct ion_handle *ion_import_dma_buf(struct ion_client *client,
 */
struct ion_handle *ion_import_dma_buf_fd(struct ion_client *client, int fd);

#else
static inline void ion_reserve(struct ion_platform_data *data) {}

static inline struct ion_client *ion_client_create(
	struct ion_device *dev, unsigned int heap_id_mask, const char *name)
{
	return ERR_PTR(-ENODEV);
}

static inline void ion_client_destroy(struct ion_client *client) {}

static inline struct ion_handle *ion_alloc(struct ion_client *client,
					   size_t len, size_t align,
					   unsigned int heap_id_mask,
					   unsigned int flags)
{
	return ERR_PTR(-ENODEV);
}

static inline void ion_free(struct ion_client *client,
			    struct ion_handle *handle) {}

static inline int ion_phys(struct ion_client *client, struct ion_handle *handle,
			   ion_phys_addr_t *addr, size_t *len)
{
	return -ENODEV;
}

static inline struct sg_table *ion_sg_table(struct ion_client *client,
					    struct ion_handle *handle)
{
	return ERR_PTR(-ENODEV);
}

static inline void *ion_map_kernel(struct ion_client *client,
				   struct ion_handle *handle)
{
	return ERR_PTR(-ENODEV);
}

static inline void ion_unmap_kernel(struct ion_client *client,
				    struct ion_handle *handle) {}

static inline int ion_share_dma_buf(struct ion_client *client,
				    struct ion_handle *handle)
{
	return -ENODEV;
}

static inline struct ion_handle *ion_import_dma_buf(struct ion_client *client,
						    int fd)
{
	return ERR_PTR(-ENODEV);
}

static inline int ion_handle_get_flags(struct ion_client *client,
				       struct ion_handle *handle,
				       unsigned long *flags)
{
	return -ENODEV;
}

#endif /* CONFIG_ION */
#endif /* _LINUX_ION_H */
Loading