/*
 * Copyright (C) 2010 ARM Limited. All rights reserved.
 *
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <cstdlib>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <cutils/log.h>
#include <cutils/atomic.h>
#include <hardware/hardware.h>
#include <hardware/gralloc.h>

#include <sys/ioctl.h>

#include "alloc_device.h"
#include "gralloc_priv.h"
#include "gralloc_helper.h"
#include "framebuffer_device.h"

#if GRALLOC_ARM_UMP_MODULE
#include <ump/ump.h>
#include <ump/ump_ref_drv.h>
#endif

#if GRALLOC_ARM_DMA_BUF_MODULE
#include <ion/ion.h>
#include "ion_4.12.h"
#include "dma-heap.h"

#define ION_SYSTEM	(char*)"ion_system_heap"
#define ION_CMA		(char*)"linux,cma"

#define DMABUF_SYSTEM	(char*)"system"
#define DMABUF_CMA	(char*)"linux,cma"
static enum {
	INTERFACE_UNKNOWN,
	INTERFACE_ION_LEGACY,
	INTERFACE_ION_MODERN,
	INTERFACE_DMABUF_HEAPS
} interface_ver;

static int system_heap_id;
static int cma_heap_id;
#endif

#if GRALLOC_SIMULATE_FAILURES
#include <cutils/properties.h>

/* system property keys for controlling simulated UMP allocation failures */
#define PROP_MALI_TEST_GRALLOC_FAIL_FIRST     "mali.test.gralloc.fail_first"
#define PROP_MALI_TEST_GRALLOC_FAIL_INTERVAL  "mali.test.gralloc.fail_interval"

static int __ump_alloc_should_fail()
{

	static unsigned int call_count  = 0;
	unsigned int        first_fail  = 0;
	int                 fail_period = 0;
	int                 fail        = 0;

	++call_count;

	/* read the system properties that control failure simulation */
	{
		char prop_value[PROPERTY_VALUE_MAX];

		if (property_get(PROP_MALI_TEST_GRALLOC_FAIL_FIRST, prop_value, "0") > 0)
		{
			sscanf(prop_value, "%11u", &first_fail);
		}

		if (property_get(PROP_MALI_TEST_GRALLOC_FAIL_INTERVAL, prop_value, "0") > 0)
		{
			sscanf(prop_value, "%11u", &fail_period);
		}
	}

	/* failure simulation is enabled by setting the first_fail property to non-zero */
	if (first_fail > 0)
	{
		LOGI("iteration %u (fail=%u, period=%u)\n", call_count, first_fail, fail_period);

		fail = (call_count == first_fail) ||
		       (call_count > first_fail && fail_period > 0 && 0 == (call_count - first_fail) % fail_period);

		if (fail)
		{
			AERR("failed ump_ref_drv_allocate on iteration #%d\n", call_count);
		}
	}

	return fail;
}
#endif

#ifdef FBIOGET_DMABUF
static int fb_get_framebuffer_dmabuf(private_module_t *m, private_handle_t *hnd)
{
	struct fb_dmabuf_export fb_dma_buf;
	int res;
	res = ioctl(m->framebuffer->fd, FBIOGET_DMABUF, &fb_dma_buf);

	if (res == 0)
	{
		hnd->share_fd = fb_dma_buf.fd;
		return 0;
	}
	else
	{
		AINF("FBIOGET_DMABUF ioctl failed(%d). See gralloc_priv.h and the integration manual for vendor framebuffer "
		     "integration",
		     res);
		return -1;
	}
}
#endif

#if GRALLOC_ARM_DMA_BUF_MODULE
#define DEVPATH "/dev/dma_heap"
int dma_heap_open(const char* name)
{
	int ret, fd;
	char buf[256];

	ret = sprintf(buf, "%s/%s", DEVPATH, name);
	if (ret < 0) {
		AERR("sprintf failed!\n");
		return ret;
	}

	fd = open(buf, O_RDWR);
	if (fd < 0)
		AERR("open %s failed!\n", buf);
	return fd;
}

int dma_heap_alloc(int fd, size_t len, unsigned int flags, int *dmabuf_fd)
{
	struct dma_heap_allocation_data data = {
		.len = len,
		.fd_flags = O_RDWR | O_CLOEXEC,
		.heap_flags = flags,
	};
	int ret;

	if (dmabuf_fd == NULL)
		return -EINVAL;

	ret = ioctl(fd, DMA_HEAP_IOCTL_ALLOC, &data);
	if (ret < 0)
		return ret;
	*dmabuf_fd = (int)data.fd;
	return ret;
}

static int alloc_ion_fd(int ion_fd, size_t size, unsigned int heap_mask, unsigned int flags, int *shared_fd)
{
	int heap;

	if (interface_ver == INTERFACE_DMABUF_HEAPS) {
		int fd = system_heap_id;
		unsigned long flg = 0;
		if (heap_mask == ION_HEAP_TYPE_DMA_MASK)
			fd = cma_heap_id;

		return dma_heap_alloc(fd, size, flg, shared_fd);
	}

	if (interface_ver == INTERFACE_ION_MODERN) {
		heap = 1 << system_heap_id;
		if (heap_mask == ION_HEAP_TYPE_DMA_MASK)
			heap = 1 << cma_heap_id;
	} else {
		heap = heap_mask;
	}
	return ion_alloc_fd(ion_fd, size, 0, heap, flags, shared_fd);
}
#endif

static int gralloc_alloc_buffer(alloc_device_t *dev, size_t size, int usage, buffer_handle_t *pHandle)
{
#if GRALLOC_ARM_DMA_BUF_MODULE
	{
		private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
		void *cpu_ptr = MAP_FAILED;
		int shared_fd;
		int ret;
		unsigned int heap_mask;
		int lock_state = 0;
		int map_mask = 0;

		if (usage & GRALLOC_USAGE_PROTECTED) {
#if defined(ION_HEAP_SECURE_MASK)
			heap_mask = ION_HEAP_SECURE_MASK;
#else
			AERR("The platform does NOT support protected ION memory.");
			return -1;
#endif
		}
		else if (usage & GRALLOC_USAGE_HW_FB) {
			heap_mask = ION_HEAP_TYPE_DMA_MASK;
		}
		else {
			heap_mask = ION_HEAP_SYSTEM_MASK;
		}

		ret = alloc_ion_fd(m->ion_client, size, heap_mask, 0, &shared_fd);
		if (ret != 0) {
			AERR("Failed to ion_alloc_fd from ion_client:%d", m->ion_client);
			return -1;
		}

		if (!(usage & GRALLOC_USAGE_PROTECTED))
		{
			map_mask = PROT_READ | PROT_WRITE;
		}
		else
		{
			map_mask = PROT_WRITE;
		}

		cpu_ptr = mmap(NULL, size, map_mask, MAP_SHARED, shared_fd, 0);

		if (MAP_FAILED == cpu_ptr)
		{
			AERR("ion_map( %d ) failed", m->ion_client);

			close(shared_fd);
			return -1;
		}

		lock_state = private_handle_t::LOCK_STATE_MAPPED;

		private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_USES_ION, usage, size, cpu_ptr, lock_state);

		if (NULL != hnd)
		{
			hnd->share_fd = shared_fd;
			*pHandle = hnd;
			return 0;
		}
		else
		{
			AERR("Gralloc out of mem for ion_client:%d", m->ion_client);
		}

		close(shared_fd);

		ret = munmap(cpu_ptr, size);

		if (0 != ret)
		{
			AERR("munmap failed for base:%p size: %lu", cpu_ptr, (unsigned long)size);
		}

		return -1;
	}
#endif

#if GRALLOC_ARM_UMP_MODULE
	MALI_IGNORE(dev);
	{
		ump_handle ump_mem_handle;
		void *cpu_ptr;
		ump_secure_id ump_id;
		ump_alloc_constraints constraints;

		size = round_up_to_page_size(size);

		if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN)
		{
			constraints =  UMP_REF_DRV_CONSTRAINT_USE_CACHE;
		}
		else
		{
			constraints = UMP_REF_DRV_CONSTRAINT_NONE;
		}

#ifdef GRALLOC_SIMULATE_FAILURES

		/* if the failure condition matches, fail this iteration */
		if (__ump_alloc_should_fail())
		{
			ump_mem_handle = UMP_INVALID_MEMORY_HANDLE;
		}
		else
#endif
		{
			if (usage & GRALLOC_USAGE_PROTECTED)
			{
				AERR("gralloc_alloc_buffer() does not support to allocate protected UMP memory.");
			}
			else
			{
				ump_mem_handle = ump_ref_drv_allocate(size, constraints);

				if (UMP_INVALID_MEMORY_HANDLE != ump_mem_handle)
				{
					cpu_ptr = ump_mapped_pointer_get(ump_mem_handle);

					if (NULL != cpu_ptr)
					{
						ump_id = ump_secure_id_get(ump_mem_handle);

						if (UMP_INVALID_SECURE_ID != ump_id)
						{
							private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_USES_UMP, usage, size, cpu_ptr,
							        private_handle_t::LOCK_STATE_MAPPED, ump_id, ump_mem_handle);

							if (NULL != hnd)
							{
								*pHandle = hnd;
								return 0;
							}
							else
							{
								AERR("gralloc_alloc_buffer() failed to allocate handle. ump_handle = %p, ump_id = %d", ump_mem_handle, ump_id);
							}
						}
						else
						{
							AERR("gralloc_alloc_buffer() failed to retrieve valid secure id. ump_handle = %p", ump_mem_handle);
						}

						ump_mapped_pointer_release(ump_mem_handle);
					}
					else
					{
						AERR("gralloc_alloc_buffer() failed to map UMP memory. ump_handle = %p", ump_mem_handle);
					}

					ump_reference_release(ump_mem_handle);
				}
				else
				{
					AERR("gralloc_alloc_buffer() failed to allocate UMP memory. size:%d constraints: %d", size, constraints);
				}
			}
		}

		return -1;
	}
#endif

}

#ifndef DISABLE_FRAMEBUFFER_HAL
static int gralloc_alloc_framebuffer_locked(alloc_device_t *dev, size_t size, int usage, buffer_handle_t *pHandle)
{
	private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);

	// allocate the framebuffer
	if (m->framebuffer == NULL)
	{
		// initialize the framebuffer, the framebuffer is mapped once and forever.
		int err = init_frame_buffer_locked(m);

		if (err < 0)
		{
			return err;
		}
	}

	uint32_t bufferMask = m->bufferMask;
	const uint32_t numBuffers = m->numBuffers;
	const size_t bufferSize = m->finfo.line_length * m->info.yres;

	if (numBuffers == 1)
	{
		// If we have only one buffer, we never use page-flipping. Instead,
		// we return a regular buffer which will be memcpy'ed to the main
		// screen when post is called.
		int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
		AERR("fallback to single buffering. Virtual Y-res too small %d", m->info.yres);
		return gralloc_alloc_buffer(dev, bufferSize, newUsage, pHandle);
	}

	if (bufferMask >= ((1LU << numBuffers) - 1))
	{
		// We ran out of buffers, reset bufferMask.
		bufferMask = 0;
		m->bufferMask = 0;
	}

	void *vaddr = m->framebuffer->base;

	// find a free slot
	for (uint32_t i = 0 ; i < numBuffers ; i++)
	{
		if ((bufferMask & (1LU << i)) == 0)
		{
			m->bufferMask |= (1LU << i);
			break;
		}

		vaddr = (void *)((uintptr_t)vaddr + bufferSize);
	}

	// The entire framebuffer memory is already mapped, now create a buffer object for parts of this memory
	private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_FRAMEBUFFER, usage, size, vaddr,
	        0, m->framebuffer->fd, (uintptr_t)vaddr - (uintptr_t) m->framebuffer->base, m->framebuffer->fb_paddr);
	
#if GRALLOC_ARM_UMP_MODULE
	hnd->ump_id = m->framebuffer->ump_id;

	/* create a backing ump memory handle if the framebuffer is exposed as a secure ID */
	if ((int)UMP_INVALID_SECURE_ID != hnd->ump_id)
	{
		hnd->ump_mem_handle = (int)ump_handle_create_from_secure_id(hnd->ump_id);

		if ((int)UMP_INVALID_MEMORY_HANDLE == hnd->ump_mem_handle)
		{
			AINF("warning: unable to create UMP handle from secure ID %i\n", hnd->ump_id);
		}
	}

#endif

#if GRALLOC_ARM_DMA_BUF_MODULE
	{
#ifdef FBIOGET_DMABUF
		/*
		 * Perform allocator specific actions. If these fail we fall back to a regular buffer
		 * which will be memcpy'ed to the main screen when fb_post is called.
		 */
		if (fb_get_framebuffer_dmabuf(m, hnd) == -1)
		{
			int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;

			AINF("Fallback to single buffering. Unable to map framebuffer memory to handle:%p", hnd);
			return gralloc_alloc_buffer(dev, bufferSize, newUsage, pHandle);
		}
#endif
	}

	// correct numFds/numInts when there is no dmabuf fd
	if (hnd->share_fd < 0)
	{
		hnd->numFds--;
		hnd->numInts++;
	}
#endif

	*pHandle = hnd;

	return 0;
}

static int gralloc_alloc_framebuffer(alloc_device_t *dev, size_t size, int usage, buffer_handle_t *pHandle)
{
	private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
	pthread_mutex_lock(&m->lock);
	int err = gralloc_alloc_framebuffer_locked(dev, size, usage, pHandle);
	pthread_mutex_unlock(&m->lock);
	return err;
}
#endif /* DISABLE_FRAMEBUFFER_HAL */

static int alloc_device_alloc(alloc_device_t *dev, int w, int h, int format, int usage, buffer_handle_t *pHandle, int *pStride)
{
	if (!pHandle || !pStride)
	{
		return -EINVAL;
	}

	size_t size;
	size_t stride;
	int bpp = 1;

	if (format == HAL_PIXEL_FORMAT_YCrCb_420_SP || format == HAL_PIXEL_FORMAT_YV12
	        /* HAL_PIXEL_FORMAT_YCbCr_420_SP, HAL_PIXEL_FORMAT_YCbCr_420_P, HAL_PIXEL_FORMAT_YCbCr_422_I are not defined in Android.
	         * To enable Mali DDK EGLImage support for those formats, firstly, you have to add them in Android system/core/include/system/graphics.h.
	         * Then, define SUPPORT_LEGACY_FORMAT in the same header file(Mali DDK will also check this definition).
	         */
#ifdef SUPPORT_LEGACY_FORMAT
	        || format == HAL_PIXEL_FORMAT_YCbCr_420_SP || format == HAL_PIXEL_FORMAT_YCbCr_420_P || format == HAL_PIXEL_FORMAT_YCbCr_422_I
#endif
	   )
	{
		switch (format)
		{
			case HAL_PIXEL_FORMAT_YCrCb_420_SP:
				stride = GRALLOC_ALIGN(w, 16);
				size = GRALLOC_ALIGN(h, 16) * (stride + GRALLOC_ALIGN(stride / 2, 16));
				break;

			case HAL_PIXEL_FORMAT_YV12:
#ifdef SUPPORT_LEGACY_FORMAT
			case HAL_PIXEL_FORMAT_YCbCr_420_P:
#endif
				/*
				 * Since Utgard has limitation that "64-byte alignment is enforced on texture and mipmap addresses", here to make sure
				 * the v, u plane start addresses are 64-byte aligned.
				 */
				stride = GRALLOC_ALIGN(w, (h % 8 == 0) ? GRALLOC_ALIGN_BASE_16 :
										 ((h % 4 == 0) ? GRALLOC_ALIGN_BASE_64 : GRALLOC_ALIGN_BASE_128));
				size = GRALLOC_ALIGN(h, 2) * (stride + GRALLOC_ALIGN(stride / 2, 16));

				break;
#ifdef SUPPORT_LEGACY_FORMAT

			case HAL_PIXEL_FORMAT_YCbCr_420_SP:
				stride = GRALLOC_ALIGN(w, 16);
				size = GRALLOC_ALIGN(h, 16) * (stride + GRALLOC_ALIGN(stride / 2, 16));
				break;

			case HAL_PIXEL_FORMAT_YCbCr_422_I:
				stride = GRALLOC_ALIGN(w, 16);
				size = h * stride * 2;

				break;
#endif

			default:
				return -EINVAL;
		}
	}
	else
	{

		switch (format)
		{
			case HAL_PIXEL_FORMAT_RGBA_8888:
			case HAL_PIXEL_FORMAT_RGBX_8888:
			case HAL_PIXEL_FORMAT_BGRA_8888:
				bpp = 4;
				break;

			case HAL_PIXEL_FORMAT_RGB_888:
				bpp = 3;
				break;

			case HAL_PIXEL_FORMAT_RGB_565:
#if PLATFORM_SDK_VERSION < 19
			case HAL_PIXEL_FORMAT_RGBA_5551:
			case HAL_PIXEL_FORMAT_RGBA_4444:
#endif
				bpp = 2;
				break;

			case HAL_PIXEL_FORMAT_BLOB:
				if (h != 1) {
					AERR("Height for HAL_PIXEL_FORMAT_BLOB must be 1. h=%d", h);
					return -EINVAL;
				}
				break;

			default:
				AERR("The format is not supported yet: format=%d\n",  format);
				return -EINVAL;
		}

		if (format == HAL_PIXEL_FORMAT_BLOB) {
			stride = 0; /* No 'rows', it's effectively a long one dimensional array */
			size = w;
		}else{
			size_t bpr = GRALLOC_ALIGN(w * bpp, 64);
			size = bpr * h;
			stride = bpr / bpp;
		}
	}

	int err;

#ifndef DISABLE_FRAMEBUFFER_HAL

	if (usage & GRALLOC_USAGE_HW_FB)
	{
		err = gralloc_alloc_framebuffer(dev, size, usage, pHandle);
	}
	else
#endif

	{
		err = gralloc_alloc_buffer(dev, size, usage, pHandle);
	}

	if (err < 0)
	{
		return err;
	}

	/* match the framebuffer format */
	if (usage & GRALLOC_USAGE_HW_FB)
	{
#ifdef GRALLOC_16_BITS
		format = HAL_PIXEL_FORMAT_RGB_565;
#else
		format = HAL_PIXEL_FORMAT_BGRA_8888;
#endif
	}

	private_handle_t *hnd = (private_handle_t *)*pHandle;
	int               private_usage = usage & (GRALLOC_USAGE_PRIVATE_0 |
	                                  GRALLOC_USAGE_PRIVATE_1);

	switch (private_usage)
	{
		case 0:
			hnd->yuv_info = MALI_YUV_BT601_NARROW;
			break;

		case GRALLOC_USAGE_PRIVATE_1:
			hnd->yuv_info = MALI_YUV_BT601_WIDE;
			break;

		case GRALLOC_USAGE_PRIVATE_0:
			hnd->yuv_info = MALI_YUV_BT709_NARROW;
			break;

		case (GRALLOC_USAGE_PRIVATE_0 | GRALLOC_USAGE_PRIVATE_1):
			hnd->yuv_info = MALI_YUV_BT709_WIDE;
			break;
	}

	hnd->width = w;
	hnd->height = h;
	hnd->format = format;
	hnd->stride = stride;
	hnd->byte_stride = GRALLOC_ALIGN(w*bpp,64);
	*pStride = stride;
	return 0;
}

static int alloc_device_free(alloc_device_t __unused *dev, buffer_handle_t handle)
{
	if (private_handle_t::validate(handle) < 0)
	{
		return -EINVAL;
	}

	private_handle_t const *hnd = reinterpret_cast<private_handle_t const *>(handle);

	if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
	{
#if GRALLOC_ARM_UMP_MODULE

		if ((int)UMP_INVALID_MEMORY_HANDLE != hnd->ump_mem_handle)
		{
			ump_reference_release((ump_handle)hnd->ump_mem_handle);
		}

#endif
	}
	else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP)
	{
#if GRALLOC_ARM_UMP_MODULE

		/* Buffer might be unregistered so we need to check for invalid ump handle*/
		if ((int)UMP_INVALID_MEMORY_HANDLE != hnd->ump_mem_handle)
		{
			ump_mapped_pointer_release((ump_handle)hnd->ump_mem_handle);
			ump_reference_release((ump_handle)hnd->ump_mem_handle);
		}

#else
		AERR("Can't free ump memory for handle:%p. Not supported.", hnd);
#endif
	}
	else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
	{
#if GRALLOC_ARM_DMA_BUF_MODULE
		/* Buffer might be unregistered so we need to check for invalid ump handle*/
		if (0 != hnd->base)
		{
			if (0 != munmap((void *)hnd->base, hnd->size))
			{
				AERR("Failed to munmap handle %p", hnd);
			}
		}

		close(hnd->share_fd);

		memset((void *)hnd, 0, sizeof(*hnd));
#else
		AERR("Can't free dma_buf memory for handle:0x%x. Not supported.", (unsigned int)hnd);
#endif

	}

	delete hnd;

	return 0;
}

static int alloc_device_close(struct hw_device_t *device)
{
	alloc_device_t *dev = reinterpret_cast<alloc_device_t *>(device);

	if (dev)
	{
#if GRALLOC_ARM_DMA_BUF_MODULE
		private_module_t *m = reinterpret_cast<private_module_t *>(device);

		if (0 != ion_close(m->ion_client))
		{
			AERR("Failed to close ion_client: %d", m->ion_client);
		}

		close(m->ion_client);
#endif
		delete dev;
#if GRALLOC_ARM_UMP_MODULE
		ump_close(); // Our UMP memory refs will be released automatically here...
#endif
	}

	return 0;
}

#if GRALLOC_ARM_DMA_BUF_MODULE
static int find_heap_id(int ion_client, char* name)
{
	int i, ret, cnt, heap_id = -1;
	struct ion_heap_data *data;

	ret = ion_query_heap_cnt(ion_client, &cnt);

	if (ret)
	{
		AERR("ion count query failed with %s", strerror(errno));
		return -1;
	}

	data = (struct ion_heap_data *)malloc(cnt * sizeof(*data));
	if (!data)
	{
		AERR("Error allocating data %s\n", strerror(errno));
		return -1;
	}

	ret = ion_query_get_heaps(ion_client, cnt, data);
	if (ret)
	{
		AERR("Error querying heaps from ion %s", strerror(errno));
	}
	else
	{
		for (i = 0; i < cnt; i++) {
			struct ion_heap_data *dat = (struct ion_heap_data *)data;
			if (strcmp(dat[i].name, name) == 0) {
				heap_id = dat[i].heap_id;
				break;
			}
		}

		if (i > cnt)
		{
			AERR("No System Heap Found amongst %d heaps\n", cnt);
			heap_id = -1;
		}
	}

	free(data);
	return heap_id;
}
#endif

static int initialize_interface(private_module_t *m)
{
	int fd;

	if (interface_ver != INTERFACE_UNKNOWN)
		return 0;

	/* test for dma-heaps*/
	fd = dma_heap_open(DMABUF_SYSTEM);
	if (fd >= 0) {
		AINF("Using DMA-BUF Heaps.\n");
		interface_ver = INTERFACE_DMABUF_HEAPS;
		system_heap_id = fd;
		cma_heap_id = dma_heap_open(DMABUF_CMA);
		/* Open other dma heaps here */
		return 0;
	}

	/* test for modern vs legacy ION */
	m->ion_client = ion_open();
	if (m->ion_client < 0) {
		AERR("ion_open failed with %s", strerror(errno));
		return -1;
	}
	if (!ion_is_legacy(m->ion_client)) {
		system_heap_id = find_heap_id(m->ion_client, ION_SYSTEM);
		cma_heap_id = find_heap_id(m->ion_client, ION_CMA);
		if (system_heap_id < 0) {
			ion_close(m->ion_client);
			m->ion_client = -1;
			AERR( "ion_open failed: no system heap found" );
			return -1;
		}
		if (cma_heap_id < 0) {
			AERR("No cma heap found, falling back to system");
			cma_heap_id = system_heap_id;
		}
		AINF("Using ION Modern interface.\n");
		interface_ver = INTERFACE_ION_MODERN;
	} else {
		AINF("Using ION Legacy interface.\n");
		interface_ver = INTERFACE_ION_LEGACY;
	}
	return 0;
}

int alloc_device_open(hw_module_t const *module, const char *name, hw_device_t **device)
{
	MALI_IGNORE(name);
	alloc_device_t *dev;

	dev = new alloc_device_t;

	if (NULL == dev)
	{
		return -1;
	}

#if GRALLOC_ARM_UMP_MODULE
	ump_result ump_res = ump_open();

	if (UMP_OK != ump_res)
	{
		AERR("UMP open failed with %d", ump_res);
		delete dev;
		return -1;
	}

#endif

	/* initialize our state here */
	memset(dev, 0, sizeof(*dev));

	/* initialize the procs */
	dev->common.tag = HARDWARE_DEVICE_TAG;
	dev->common.version = 0;
	dev->common.module = const_cast<hw_module_t *>(module);
	dev->common.close = alloc_device_close;
	dev->alloc = alloc_device_alloc;
	dev->free = alloc_device_free;

#if GRALLOC_ARM_DMA_BUF_MODULE
	private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);

	if (initialize_interface(m) < 0) {
		delete dev;
		return -1;
	}
#endif

	*device = &dev->common;

	return 0;
}
