Home | History | Annotate | Download | only in gralloc960
      1 /*
      2  * Copyright (C) 2016-2017 ARM Limited. All rights reserved.
      3  *
      4  * Copyright (C) 2008 The Android Open Source Project
      5  *
      6  * Licensed under the Apache License, Version 2.0 (the "License");
      7  * you may not use this file except in compliance with the License.
      8  * You may obtain a copy of the License at
      9  *
     10  *      http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  * Unless required by applicable law or agreed to in writing, software
     13  * distributed under the License is distributed on an "AS IS" BASIS,
     14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  * See the License for the specific language governing permissions and
     16  * limitations under the License.
     17  */
     18 
     19 #include <cstdlib>
     20 #include <string.h>
     21 #include <errno.h>
     22 #include <inttypes.h>
     23 #include <pthread.h>
     24 
     25 #include <log/log.h>
     26 #include <cutils/atomic.h>
     27 
     28 #include <ion/ion.h>
     29 #include <sys/ioctl.h>
     30 
     31 #include <hardware/hardware.h>
     32 
     33 #if GRALLOC_USE_GRALLOC1_API == 1
     34 #include <hardware/gralloc1.h>
     35 #else
     36 #include <hardware/gralloc.h>
     37 #endif
     38 
     39 #include "mali_gralloc_module.h"
     40 #include "mali_gralloc_private_interface_types.h"
     41 #include "mali_gralloc_buffer.h"
     42 #include "gralloc_helper.h"
     43 #include "framebuffer_device.h"
     44 #include "mali_gralloc_formats.h"
     45 #include "mali_gralloc_usages.h"
     46 #include "mali_gralloc_bufferdescriptor.h"
     47 #include "ion_4.12.h"
     48 
     49 
     50 
     51 #define ION_SYSTEM     (char*)"ion_system_heap"
     52 #define ION_CMA        (char*)"linux,cma"
     53 static bool gralloc_legacy_ion;
     54 static int system_heap_id;
     55 static int cma_heap_id;
     56 
     57 static void mali_gralloc_ion_free_internal(buffer_handle_t *pHandle, uint32_t num_hnds);
     58 
     59 static void init_afbc(uint8_t *buf, uint64_t internal_format, int w, int h)
     60 {
     61 	uint32_t n_headers = (w * h) / 256;
     62 	uint32_t body_offset = n_headers * 16;
     63 	uint32_t headers[][4] = {
     64 		{ body_offset, 0x1, 0x10000, 0x0 }, /* Layouts 0, 3, 4 */
     65 		{ (body_offset + (1 << 28)), 0x80200040, 0x1004000, 0x20080 } /* Layouts 1, 5 */
     66 	};
     67 	uint32_t i, layout;
     68 
     69 	/* For AFBC 1.2, header buffer can be initilized to 0 for Layouts 0, 3, 4 */
     70 	if (internal_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS)
     71 	{
     72 		memset(headers[0], 0, sizeof(uint32_t) * 4);
     73 	}
     74 	/* map format if necessary (also removes internal extension bits) */
     75 	uint64_t base_format = internal_format & MALI_GRALLOC_INTFMT_FMT_MASK;
     76 
     77 	switch (base_format)
     78 	{
     79 	case MALI_GRALLOC_FORMAT_INTERNAL_RGBA_8888:
     80 	case MALI_GRALLOC_FORMAT_INTERNAL_RGBX_8888:
     81 	case MALI_GRALLOC_FORMAT_INTERNAL_RGB_888:
     82 	case MALI_GRALLOC_FORMAT_INTERNAL_RGB_565:
     83 	case MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888:
     84 		layout = 0;
     85 		break;
     86 
     87 	case MALI_GRALLOC_FORMAT_INTERNAL_YV12:
     88 	case MALI_GRALLOC_FORMAT_INTERNAL_NV12:
     89 	case MALI_GRALLOC_FORMAT_INTERNAL_NV21:
     90 		layout = 1;
     91 		break;
     92 
     93 	default:
     94 		layout = 0;
     95 	}
     96 
     97 	ALOGV("Writing AFBC header layout %d for format %" PRIu64, layout, base_format);
     98 
     99 	for (i = 0; i < n_headers; i++)
    100 	{
    101 		memcpy(buf, headers[layout], sizeof(headers[layout]));
    102 		buf += sizeof(headers[layout]);
    103 	}
    104 }
    105 
    106 
    107 
    108 static int find_heap_id(int ion_client, char *name)
    109 {
    110 	int i, ret, cnt, heap_id = -1;
    111 	struct ion_heap_data *data;
    112 
    113 	ret = ion_query_heap_cnt(ion_client, &cnt);
    114 
    115 	if (ret)
    116 	{
    117 		AERR("ion count query failed with %s", strerror(errno));
    118 		return -1;
    119 	}
    120 
    121 	data = (struct ion_heap_data *)malloc(cnt * sizeof(*data));
    122 	if (!data)
    123 	{
    124 		AERR("Error allocating data %s\n", strerror(errno));
    125 		return -1;
    126 	}
    127 
    128 	ret = ion_query_get_heaps(ion_client, cnt, data);
    129 	if (ret)
    130 	{
    131 		AERR("Error querying heaps from ion %s", strerror(errno));
    132 	}
    133 	else
    134 	{
    135 		for (i = 0; i < cnt; i++) {
    136 			if (strcmp(data[i].name, name) == 0) {
    137 				heap_id = data[i].heap_id;
    138 				break;
    139 			}
    140 		}
    141 
    142 		if (i == cnt)
    143 		{
    144 			AERR("No %s Heap Found amongst %d heaps\n", name, cnt);
    145 			heap_id = -1;
    146 		}
    147 	}
    148 
    149 	free(data);
    150 	return heap_id;
    151 }
    152 
    153 
    154 static int alloc_from_ion_heap(int ion_fd, size_t size, unsigned int heap_mask, unsigned int flags, int *min_pgsz)
    155 {
    156 	ion_user_handle_t ion_hnd = -1;
    157 	int shared_fd, ret;
    158 
    159 	if ((ion_fd < 0) || (size <= 0) || (heap_mask == 0) || (min_pgsz == NULL))
    160 	{
    161 		return -1;
    162 	}
    163 
    164 	/**
    165 	 * step 1: ion_alloc new ion_hnd
    166 	 * step 2: ion_share from ion_hnd and get shared_fd
    167 	 * step 3: ion free the given ion_hnd
    168 	 * step 4: when we need to free this ion buffer, just close the shared_fd,
    169 	 *            kernel will count the reference of file struct, so it's safe to
    170 	 *            be transfered between processes.
    171 	 */
    172 	ret = ion_alloc(ion_fd, size, 0, heap_mask, flags, &ion_hnd);
    173 
    174 	if (ret < 0)
    175 	{
    176 #if defined(ION_HEAP_SECURE_MASK)
    177 
    178 		if (heap_mask == ION_HEAP_SECURE_MASK)
    179 		{
    180 			return -1;
    181 		}
    182 		else
    183 #endif
    184 		{
    185 			/* If everything else failed try system heap */
    186 			flags = 0; /* Fallback option flags are not longer valid */
    187 			heap_mask = ION_HEAP_SYSTEM_MASK;
    188 			ret = ion_alloc(ion_fd, size, 0, heap_mask, flags, &ion_hnd);
    189 		}
    190 	}
    191 
    192 	ret = ion_share(ion_fd, ion_hnd, &shared_fd);
    193 
    194 	if (ret != 0)
    195 	{
    196 		AERR("ion_share( %d ) failed", ion_fd);
    197 		shared_fd = -1;
    198 	}
    199 
    200 	ret = ion_free(ion_fd, ion_hnd);
    201 
    202 	if (0 != ret)
    203 	{
    204 		AERR("ion_free( %d ) failed", ion_fd);
    205 		close(shared_fd);
    206 		shared_fd = -1;
    207 	}
    208 
    209 	if (ret >= 0)
    210 	{
    211 		switch (heap_mask)
    212 		{
    213 		case ION_HEAP_SYSTEM_MASK:
    214 			*min_pgsz = SZ_4K;
    215 			break;
    216 
    217 		case ION_HEAP_SYSTEM_CONTIG_MASK:
    218 		case ION_HEAP_CARVEOUT_MASK:
    219 #ifdef ION_HEAP_TYPE_DMA_MASK
    220 		case ION_HEAP_TYPE_DMA_MASK:
    221 #endif
    222 			*min_pgsz = size;
    223 			break;
    224 #ifdef ION_HEAP_CHUNK_MASK
    225 
    226 		/* NOTE: if have this heap make sure your ION chunk size is 2M*/
    227 		case ION_HEAP_CHUNK_MASK:
    228 			*min_pgsz = SZ_2M;
    229 			break;
    230 #endif
    231 #ifdef ION_HEAP_COMPOUND_PAGE_MASK
    232 
    233 		case ION_HEAP_COMPOUND_PAGE_MASK:
    234 			*min_pgsz = SZ_2M;
    235 			break;
    236 #endif
    237 /* If have customized heap please set the suitable pg type according to
    238 		 * the customized ION implementation
    239 		 */
    240 #ifdef ION_HEAP_CUSTOM_MASK
    241 
    242 		case ION_HEAP_CUSTOM_MASK:
    243 			*min_pgsz = SZ_4K;
    244 			break;
    245 #endif
    246 
    247 		default:
    248 			*min_pgsz = SZ_4K;
    249 			break;
    250 		}
    251 	}
    252 
    253 	return shared_fd;
    254 }
    255 
    256 unsigned int pick_ion_heap(uint64_t usage)
    257 {
    258 	unsigned int heap_mask;
    259 
    260 	if (usage & GRALLOC_USAGE_PROTECTED)
    261 	{
    262 #if defined(ION_HEAP_SECURE_MASK)
    263 		heap_mask = ION_HEAP_SECURE_MASK;
    264 #else
    265 		AERR("Protected ION memory is not supported on this platform.");
    266 		return 0;
    267 #endif
    268 	}
    269 
    270 #if defined(ION_HEAP_TYPE_COMPOUND_PAGE_MASK) && GRALLOC_USE_ION_COMPOUND_PAGE_HEAP
    271 	else if (!(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) && (usage & (GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_COMPOSER)))
    272 	{
    273 		heap_mask = ION_HEAP_TYPE_COMPOUND_PAGE_MASK;
    274 	}
    275 
    276 #elif defined(ION_HEAP_TYPE_DMA_MASK) && GRALLOC_USE_ION_DMA_HEAP
    277 	else if (!(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) && (usage & (GRALLOC_USAGE_HW_FB)))
    278 	{
    279 		heap_mask = ION_HEAP_TYPE_DMA_MASK;
    280 	}
    281 
    282 #endif
    283 	else
    284 	{
    285 		heap_mask = ION_HEAP_SYSTEM_MASK;
    286 	}
    287 
    288 	return heap_mask;
    289 }
    290 
    291 void set_ion_flags(unsigned int heap_mask, uint64_t usage, unsigned int *priv_heap_flag, int *ion_flags)
    292 {
    293 #if !GRALLOC_USE_ION_DMA_HEAP
    294 	GRALLOC_UNUSED(heap_mask);
    295 #endif
    296 
    297 	if (priv_heap_flag)
    298 	{
    299 #if defined(ION_HEAP_TYPE_DMA_MASK) && GRALLOC_USE_ION_DMA_HEAP
    300 
    301 		if (heap_mask == ION_HEAP_TYPE_DMA_MASK)
    302 		{
    303 			*priv_heap_flag = private_handle_t::PRIV_FLAGS_USES_ION_DMA_HEAP;
    304 		}
    305 
    306 #endif
    307 	}
    308 
    309 	if (ion_flags)
    310 	{
    311 #if defined(ION_HEAP_TYPE_DMA_MASK) && GRALLOC_USE_ION_DMA_HEAP
    312 
    313 		if (heap_mask != ION_HEAP_TYPE_DMA_MASK)
    314 		{
    315 #endif
    316 
    317 			if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN)
    318 			{
    319 				*ion_flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC;
    320 			}
    321 
    322 #if defined(ION_HEAP_TYPE_DMA_MASK) && GRALLOC_USE_ION_DMA_HEAP
    323 		}
    324 
    325 #endif
    326 	}
    327 }
    328 
    329 static bool check_buffers_sharable(const gralloc_buffer_descriptor_t *descriptors, uint32_t numDescriptors)
    330 {
    331 	unsigned int shared_backend_heap_mask = 0;
    332 	int shared_ion_flags = 0;
    333 	uint64_t usage;
    334 	uint32_t i;
    335 
    336 	if (numDescriptors <= 1)
    337 	{
    338 		return false;
    339 	}
    340 
    341 	for (i = 0; i < numDescriptors; i++)
    342 	{
    343 		unsigned int heap_mask;
    344 		int ion_flags;
    345 		buffer_descriptor_t *bufDescriptor = (buffer_descriptor_t *)descriptors[i];
    346 
    347 		usage = bufDescriptor->consumer_usage | bufDescriptor->producer_usage;
    348 		heap_mask = pick_ion_heap(usage);
    349 
    350 		if (0 == heap_mask)
    351 		{
    352 			return false;
    353 		}
    354 
    355 		set_ion_flags(heap_mask, usage, NULL, &ion_flags);
    356 
    357 		if (0 != shared_backend_heap_mask)
    358 		{
    359 			if (shared_backend_heap_mask != heap_mask || shared_ion_flags != ion_flags)
    360 			{
    361 				return false;
    362 			}
    363 		}
    364 		else
    365 		{
    366 			shared_backend_heap_mask = heap_mask;
    367 			shared_ion_flags = ion_flags;
    368 		}
    369 	}
    370 
    371 	return true;
    372 }
    373 
    374 static int get_max_buffer_descriptor_index(const gralloc_buffer_descriptor_t *descriptors, uint32_t numDescriptors)
    375 {
    376 	uint32_t i, max_buffer_index = 0;
    377 	size_t max_buffer_size = 0;
    378 
    379 	for (i = 0; i < numDescriptors; i++)
    380 	{
    381 		buffer_descriptor_t *bufDescriptor = (buffer_descriptor_t *)descriptors[i];
    382 
    383 		if (max_buffer_size < bufDescriptor->size)
    384 		{
    385 			max_buffer_index = i;
    386 			max_buffer_size = bufDescriptor->size;
    387 		}
    388 	}
    389 
    390 	return max_buffer_index;
    391 }
    392 
    393 int mali_gralloc_ion_allocate(mali_gralloc_module *m, const gralloc_buffer_descriptor_t *descriptors,
    394                               uint32_t numDescriptors, buffer_handle_t *pHandle, bool *shared_backend)
    395 {
    396 	static int support_protected = 1; /* initially, assume we support protected memory */
    397 	unsigned int heap_mask, priv_heap_flag = 0;
    398 	unsigned char *cpu_ptr = NULL;
    399 	uint64_t usage;
    400 	uint32_t i, max_buffer_index = 0;
    401 	int shared_fd, ret, ion_flags = 0;
    402 	int min_pgsz = 0;
    403 
    404 	if (m->ion_client < 0)
    405 	{
    406 		m->ion_client = ion_open();
    407 
    408 		if (m->ion_client < 0)
    409 		{
    410 			AERR("ion_open failed with %s", strerror(errno));
    411 			return -1;
    412 		}
    413 
    414 		gralloc_legacy_ion = ion_is_legacy(m->ion_client);
    415 		if (!gralloc_legacy_ion)
    416 		{
    417 			system_heap_id = find_heap_id(m->ion_client, ION_SYSTEM);
    418 			cma_heap_id = find_heap_id(m->ion_client, ION_CMA);
    419 			if (system_heap_id < 0)
    420 			{
    421 				ion_close(m->ion_client);
    422 				m->ion_client = -1;
    423 				AERR( "ion_open failed: no system heap found" );
    424 				return -1;
    425 			}
    426 			if (cma_heap_id < 0) {
    427 				AERR("No cma heap found, falling back to system");
    428 				cma_heap_id = system_heap_id;
    429 			}
    430 		}
    431 	}
    432 
    433 	*shared_backend = check_buffers_sharable(descriptors, numDescriptors);
    434 
    435 	if (*shared_backend)
    436 	{
    437 		buffer_descriptor_t *max_bufDescriptor;
    438 
    439 		max_buffer_index = get_max_buffer_descriptor_index(descriptors, numDescriptors);
    440 		max_bufDescriptor = (buffer_descriptor_t *)(descriptors[max_buffer_index]);
    441 		usage = max_bufDescriptor->consumer_usage | max_bufDescriptor->producer_usage;
    442 
    443 		heap_mask = pick_ion_heap(usage);
    444 
    445 		if (heap_mask == 0)
    446 		{
    447 			AERR("Failed to find an appropriate ion heap");
    448 			return -1;
    449 		}
    450 
    451 		set_ion_flags(heap_mask, usage, &priv_heap_flag, &ion_flags);
    452 		if (gralloc_legacy_ion)
    453 		{
    454 			shared_fd = alloc_from_ion_heap(m->ion_client, max_bufDescriptor->size, heap_mask, ion_flags, &min_pgsz);
    455 		}
    456 		else
    457 		{
    458 			int heap = 1 << system_heap_id;
    459 			if (heap_mask == ION_HEAP_TYPE_DMA_MASK)
    460 				heap = 1 << cma_heap_id;
    461 
    462 			ret = ion_alloc_fd(m->ion_client, max_bufDescriptor->size, 0, heap, 0, &(shared_fd));
    463 			if (ret != 0)
    464 			{
    465 				AERR("Failed to ion_alloc_fd from ion_client:%d", m->ion_client);
    466 				return -1;
    467 			}
    468 			min_pgsz = SZ_4K;
    469 		}
    470 
    471 		if (shared_fd < 0)
    472 		{
    473 			AERR("ion_alloc failed form client: ( %d )", m->ion_client);
    474 			return -1;
    475 		}
    476 
    477 		for (i = 0; i < numDescriptors; i++)
    478 		{
    479 			buffer_descriptor_t *bufDescriptor = (buffer_descriptor_t *)(descriptors[i]);
    480 			int tmp_fd;
    481 
    482 			if (i != max_buffer_index)
    483 			{
    484 				tmp_fd = dup(shared_fd);
    485 
    486 				if (tmp_fd < 0)
    487 				{
    488 					/* need to free already allocated memory. */
    489 					mali_gralloc_ion_free_internal(pHandle, numDescriptors);
    490 					return -1;
    491 				}
    492 			}
    493 			else
    494 			{
    495 				tmp_fd = shared_fd;
    496 			}
    497 
    498 			private_handle_t *hnd = new private_handle_t(
    499 			    private_handle_t::PRIV_FLAGS_USES_ION | priv_heap_flag, bufDescriptor->size, min_pgsz,
    500 			    bufDescriptor->consumer_usage, bufDescriptor->producer_usage, tmp_fd, bufDescriptor->hal_format,
    501 			    bufDescriptor->internal_format, bufDescriptor->byte_stride, bufDescriptor->width, bufDescriptor->height,
    502 			    bufDescriptor->pixel_stride, bufDescriptor->internalWidth, bufDescriptor->internalHeight,
    503 			    max_bufDescriptor->size);
    504 
    505 			if (NULL == hnd)
    506 			{
    507 				mali_gralloc_ion_free_internal(pHandle, numDescriptors);
    508 				return -1;
    509 			}
    510 
    511 			pHandle[i] = hnd;
    512 		}
    513 	}
    514 	else
    515 	{
    516 		for (i = 0; i < numDescriptors; i++)
    517 		{
    518 			buffer_descriptor_t *bufDescriptor = (buffer_descriptor_t *)(descriptors[i]);
    519 			usage = bufDescriptor->consumer_usage | bufDescriptor->producer_usage;
    520 
    521 			heap_mask = pick_ion_heap(usage);
    522 
    523 			if (heap_mask == 0)
    524 			{
    525 				AERR("Failed to find an appropriate ion heap");
    526 				mali_gralloc_ion_free_internal(pHandle, numDescriptors);
    527 				return -1;
    528 			}
    529 
    530 			set_ion_flags(heap_mask, usage, &priv_heap_flag, &ion_flags);
    531 			if (gralloc_legacy_ion)
    532 			{
    533 				shared_fd = alloc_from_ion_heap(m->ion_client, bufDescriptor->size, heap_mask, ion_flags, &min_pgsz);
    534 			}
    535 			else
    536 			{
    537 				int heap = 1 << system_heap_id;
    538 				if (heap_mask == ION_HEAP_TYPE_DMA_MASK)
    539 					heap = 1 << cma_heap_id;
    540 
    541 				ret = ion_alloc_fd(m->ion_client, bufDescriptor->size, 0, heap, 0, &(shared_fd));
    542 				if (ret != 0)
    543 				{
    544 					AERR("Failed to ion_alloc_fd from ion_client:%d", m->ion_client);
    545 					mali_gralloc_ion_free_internal(pHandle, numDescriptors);
    546 					return -1;
    547 				}
    548 				min_pgsz = SZ_4K;
    549 			}
    550 
    551 			if (shared_fd < 0)
    552 			{
    553 				AERR("ion_alloc failed from client ( %d )", m->ion_client);
    554 
    555 				/* need to free already allocated memory. not just this one */
    556 				mali_gralloc_ion_free_internal(pHandle, numDescriptors);
    557 
    558 				return -1;
    559 			}
    560 
    561 			private_handle_t *hnd = new private_handle_t(
    562 			    private_handle_t::PRIV_FLAGS_USES_ION | priv_heap_flag, bufDescriptor->size, min_pgsz,
    563 			    bufDescriptor->consumer_usage, bufDescriptor->producer_usage, shared_fd, bufDescriptor->hal_format,
    564 			    bufDescriptor->internal_format, bufDescriptor->byte_stride, bufDescriptor->width, bufDescriptor->height,
    565 			    bufDescriptor->pixel_stride, bufDescriptor->internalWidth, bufDescriptor->internalHeight,
    566 			    bufDescriptor->size);
    567 
    568 			if (NULL == hnd)
    569 			{
    570 				mali_gralloc_ion_free_internal(pHandle, numDescriptors);
    571 				return -1;
    572 			}
    573 
    574 			pHandle[i] = hnd;
    575 		}
    576 	}
    577 
    578 	for (i = 0; i < numDescriptors; i++)
    579 	{
    580 		buffer_descriptor_t *bufDescriptor = (buffer_descriptor_t *)(descriptors[i]);
    581 		private_handle_t *hnd = (private_handle_t *)(pHandle[i]);
    582 
    583 		usage = bufDescriptor->consumer_usage | bufDescriptor->producer_usage;
    584 
    585 		if (!(usage & GRALLOC_USAGE_PROTECTED))
    586 		{
    587 			cpu_ptr =
    588 			    (unsigned char *)mmap(NULL, bufDescriptor->size, PROT_READ | PROT_WRITE, MAP_SHARED, hnd->share_fd, 0);
    589 
    590 			if (MAP_FAILED == cpu_ptr)
    591 			{
    592 				AERR("mmap failed from client ( %d ), fd ( %d )", m->ion_client, hnd->share_fd);
    593 				mali_gralloc_ion_free_internal(pHandle, numDescriptors);
    594 				return -1;
    595 			}
    596 
    597 #if GRALLOC_INIT_AFBC == 1
    598 
    599 			if ((bufDescriptor->internal_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK) && (!(*shared_backend)))
    600 			{
    601 				init_afbc(cpu_ptr, bufDescriptor->internal_format, bufDescriptor->width, bufDescriptor->height);
    602 			}
    603 
    604 #endif
    605 			hnd->base = cpu_ptr;
    606 		}
    607 	}
    608 
    609 	return 0;
    610 }
    611 
    612 void mali_gralloc_ion_free(private_handle_t const *hnd)
    613 {
    614 	if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
    615 	{
    616 		return;
    617 	}
    618 	else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
    619 	{
    620 		/* Buffer might be unregistered already so we need to assure we have a valid handle*/
    621 		if (0 != hnd->base)
    622 		{
    623 			if (0 != munmap((void *)hnd->base, hnd->size))
    624 			{
    625 				AERR("Failed to munmap handle %p", hnd);
    626 			}
    627 		}
    628 
    629 		close(hnd->share_fd);
    630 		memset((void *)hnd, 0, sizeof(*hnd));
    631 	}
    632 }
    633 
    634 static void mali_gralloc_ion_free_internal(buffer_handle_t *pHandle, uint32_t num_hnds)
    635 {
    636 	uint32_t i = 0;
    637 
    638 	for (i = 0; i < num_hnds; i++)
    639 	{
    640 		if (NULL != pHandle[i])
    641 		{
    642 			mali_gralloc_ion_free((private_handle_t *)(pHandle[i]));
    643 		}
    644 	}
    645 
    646 	return;
    647 }
    648 
    649 void mali_gralloc_ion_sync(const mali_gralloc_module *m, private_handle_t *hnd)
    650 {
    651 	if (!gralloc_legacy_ion)
    652 		return;
    653 
    654 	if (m != NULL && hnd != NULL)
    655 	{
    656 		switch (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
    657 		{
    658 		case private_handle_t::PRIV_FLAGS_USES_ION:
    659 			if (!(hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION_DMA_HEAP))
    660 			{
    661 				ion_sync_fd(m->ion_client, hnd->share_fd);
    662 			}
    663 
    664 			break;
    665 		}
    666 	}
    667 }
    668 
    669 int mali_gralloc_ion_map(private_handle_t *hnd)
    670 {
    671 	int retval = -EINVAL;
    672 
    673 	switch (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
    674 	{
    675 	case private_handle_t::PRIV_FLAGS_USES_ION:
    676 		unsigned char *mappedAddress;
    677 		size_t size = hnd->size;
    678 		hw_module_t *pmodule = NULL;
    679 		private_module_t *m = NULL;
    680 
    681 		if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&pmodule) == 0)
    682 		{
    683 			m = reinterpret_cast<private_module_t *>(pmodule);
    684 		}
    685 		else
    686 		{
    687 			AERR("Could not get gralloc module for handle: %p", hnd);
    688 			retval = -errno;
    689 			break;
    690 		}
    691 
    692 		/* the test condition is set to m->ion_client <= 0 here, because:
    693 		 * 1) module structure are initialized to 0 if no initial value is applied
    694 		 * 2) a second user process should get a ion fd greater than 0.
    695 		 */
    696 		if (m->ion_client <= 0)
    697 		{
    698 			/* a second user process must obtain a client handle first via ion_open before it can obtain the shared ion buffer*/
    699 			m->ion_client = ion_open();
    700 
    701 			if (m->ion_client < 0)
    702 			{
    703 				AERR("Could not open ion device for handle: %p", hnd);
    704 				retval = -errno;
    705 				break;
    706 			}
    707 		}
    708 
    709 		mappedAddress = (unsigned char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, hnd->share_fd, 0);
    710 
    711 		if (MAP_FAILED == mappedAddress)
    712 		{
    713 			AERR("mmap( share_fd:%d ) failed with %s", hnd->share_fd, strerror(errno));
    714 			retval = -errno;
    715 			break;
    716 		}
    717 
    718 		hnd->base = (void *)(uintptr_t(mappedAddress) + hnd->offset);
    719 		retval = 0;
    720 		break;
    721 	}
    722 
    723 	return retval;
    724 }
    725 
    726 void mali_gralloc_ion_unmap(private_handle_t *hnd)
    727 {
    728 	switch (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
    729 	{
    730 	case private_handle_t::PRIV_FLAGS_USES_ION:
    731 		void *base = (void *)hnd->base;
    732 		size_t size = hnd->size;
    733 
    734 		if (munmap(base, size) < 0)
    735 		{
    736 			AERR("Could not munmap base:%p size:%zd '%s'", base, size, strerror(errno));
    737 		}
    738 
    739 		break;
    740 	}
    741 }
    742 
    743 int mali_gralloc_ion_device_close(struct hw_device_t *device)
    744 {
    745 #if GRALLOC_USE_GRALLOC1_API == 1
    746 	gralloc1_device_t *dev = reinterpret_cast<gralloc1_device_t *>(device);
    747 #else
    748 	alloc_device_t *dev = reinterpret_cast<alloc_device_t *>(device);
    749 #endif
    750 
    751 	if (dev)
    752 	{
    753 		private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
    754 
    755 		if (m->ion_client != -1)
    756 		{
    757 			if (0 != ion_close(m->ion_client))
    758 			{
    759 				AERR("Failed to close ion_client: %d err=%s", m->ion_client, strerror(errno));
    760 			}
    761 
    762 			m->ion_client = -1;
    763 		}
    764 
    765 		delete dev;
    766 	}
    767 
    768 	return 0;
    769 }
    770