1202a77d28ac251545f6f998a974690212309b927Iliyan Malchev/* 2a43fb8fce6d9be5577de1e0f49c99bd4fe2f6d44Duy Truong * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. 3202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 4202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * Redistribution and use in source and binary forms, with or without 5202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * modification, are permitted provided that the following conditions are 6202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * met: 7202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * * Redistributions of source code must retain the above copyright 8202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * notice, this list of conditions and the following disclaimer. 9202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * * Redistributions in binary form must reproduce the above 10202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * copyright notice, this list of conditions and the following 11202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * disclaimer in the documentation and/or other materials provided 12202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * with the distribution. 13a43fb8fce6d9be5577de1e0f49c99bd4fe2f6d44Duy Truong * * Neither the name of The Linux Foundation nor the names of its 14202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * contributors may be used to endorse or promote products derived 15202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * from this software without specific prior written permission. 16202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * 17202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28202a77d28ac251545f6f998a974690212309b927Iliyan Malchev */ 29202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 3001d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed#define DEBUG 0 31202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <linux/ioctl.h> 32202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <sys/mman.h> 33202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <stdlib.h> 34202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <fcntl.h> 35202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <cutils/log.h> 36202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <errno.h> 37202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "gralloc_priv.h" 38202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "ionalloc.h" 39202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 40202a77d28ac251545f6f998a974690212309b927Iliyan Malchevusing gralloc::IonAlloc; 41202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 42202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#define ION_DEVICE "/dev/ion" 43202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 44202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint IonAlloc::open_device() 45202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{ 46202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if(mIonFd == FD_INIT) 47202a77d28ac251545f6f998a974690212309b927Iliyan Malchev mIonFd = open(ION_DEVICE, O_RDONLY); 48202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 49202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if(mIonFd < 0 ) { 50202a77d28ac251545f6f998a974690212309b927Iliyan Malchev ALOGE("%s: Failed to open ion device - %s", 5129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed __FUNCTION__, strerror(errno)); 52202a77d28ac251545f6f998a974690212309b927Iliyan Malchev mIonFd = FD_INIT; 53202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return -errno; 54202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 55202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return 0; 56202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 57202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 58202a77d28ac251545f6f998a974690212309b927Iliyan Malchevvoid IonAlloc::close_device() 59202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{ 60202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if(mIonFd >= 0) 61202a77d28ac251545f6f998a974690212309b927Iliyan Malchev close(mIonFd); 62202a77d28ac251545f6f998a974690212309b927Iliyan Malchev mIonFd = FD_INIT; 63202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 64202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 65202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint IonAlloc::alloc_buffer(alloc_data& data) 66202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{ 6729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed Locker::Autolock _l(mLock); 68202a77d28ac251545f6f998a974690212309b927Iliyan Malchev int err = 0; 69202a77d28ac251545f6f998a974690212309b927Iliyan Malchev struct ion_handle_data handle_data; 70202a77d28ac251545f6f998a974690212309b927Iliyan Malchev struct ion_fd_data fd_data; 71202a77d28ac251545f6f998a974690212309b927Iliyan Malchev struct ion_allocation_data ionAllocData; 72202a77d28ac251545f6f998a974690212309b927Iliyan Malchev void *base = 0; 73202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 74202a77d28ac251545f6f998a974690212309b927Iliyan Malchev ionAllocData.len = data.size; 75202a77d28ac251545f6f998a974690212309b927Iliyan Malchev ionAllocData.align = data.align; 767378bd716c3e4c06e3d9b32788ad5887413a529fAmara Venkata Mastan Manoj Kumar ionAllocData.heap_mask = data.flags & ~ION_SECURE; 77c402f7c331fc3cf396d5e2ade7e5b7f23959c9deSaurabh Shah ionAllocData.flags = data.uncached ? 0 : ION_FLAG_CACHED; 787378bd716c3e4c06e3d9b32788ad5887413a529fAmara Venkata Mastan Manoj Kumar // ToDo: replace usage of alloc data structure with 797378bd716c3e4c06e3d9b32788ad5887413a529fAmara Venkata Mastan Manoj Kumar // ionallocdata structure. 807378bd716c3e4c06e3d9b32788ad5887413a529fAmara Venkata Mastan Manoj Kumar if (data.flags & ION_SECURE) 817378bd716c3e4c06e3d9b32788ad5887413a529fAmara Venkata Mastan Manoj Kumar ionAllocData.flags |= ION_SECURE; 827378bd716c3e4c06e3d9b32788ad5887413a529fAmara Venkata Mastan Manoj Kumar 83202a77d28ac251545f6f998a974690212309b927Iliyan Malchev err = open_device(); 84202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if (err) 85202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return err; 86c402f7c331fc3cf396d5e2ade7e5b7f23959c9deSaurabh Shah if(ioctl(mIonFd, ION_IOC_ALLOC, &ionAllocData)) { 87202a77d28ac251545f6f998a974690212309b927Iliyan Malchev err = -errno; 88202a77d28ac251545f6f998a974690212309b927Iliyan Malchev ALOGE("ION_IOC_ALLOC failed with error - %s", strerror(errno)); 89202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return err; 90202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 91202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 92202a77d28ac251545f6f998a974690212309b927Iliyan Malchev fd_data.handle = ionAllocData.handle; 93202a77d28ac251545f6f998a974690212309b927Iliyan Malchev handle_data.handle = ionAllocData.handle; 94c402f7c331fc3cf396d5e2ade7e5b7f23959c9deSaurabh Shah if(ioctl(mIonFd, ION_IOC_MAP, &fd_data)) { 95202a77d28ac251545f6f998a974690212309b927Iliyan Malchev err = -errno; 96202a77d28ac251545f6f998a974690212309b927Iliyan Malchev ALOGE("%s: ION_IOC_MAP failed with error - %s", 9729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed __FUNCTION__, strerror(errno)); 98202a77d28ac251545f6f998a974690212309b927Iliyan Malchev ioctl(mIonFd, ION_IOC_FREE, &handle_data); 99202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return err; 100202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 101202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 10201d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed if(!(data.flags & ION_SECURE)) { 103202a77d28ac251545f6f998a974690212309b927Iliyan Malchev base = mmap(0, ionAllocData.len, PROT_READ|PROT_WRITE, 10429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed MAP_SHARED, fd_data.fd, 0); 105202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if(base == MAP_FAILED) { 106202a77d28ac251545f6f998a974690212309b927Iliyan Malchev err = -errno; 107202a77d28ac251545f6f998a974690212309b927Iliyan Malchev ALOGE("%s: Failed to map the allocated memory: %s", 10829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed __FUNCTION__, strerror(errno)); 109202a77d28ac251545f6f998a974690212309b927Iliyan Malchev ioctl(mIonFd, ION_IOC_FREE, &handle_data); 110202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return err; 111202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 112202a77d28ac251545f6f998a974690212309b927Iliyan Malchev memset(base, 0, ionAllocData.len); 113202a77d28ac251545f6f998a974690212309b927Iliyan Malchev // Clean cache after memset 1140b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed clean_buffer(base, data.size, data.offset, fd_data.fd, 1150b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed CACHE_CLEAN_AND_INVALIDATE); 116202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 117202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 118202a77d28ac251545f6f998a974690212309b927Iliyan Malchev data.base = base; 119202a77d28ac251545f6f998a974690212309b927Iliyan Malchev data.fd = fd_data.fd; 120202a77d28ac251545f6f998a974690212309b927Iliyan Malchev ioctl(mIonFd, ION_IOC_FREE, &handle_data); 12101d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed ALOGD_IF(DEBUG, "ion: Allocated buffer base:%p size:%d fd:%d", 12229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed data.base, ionAllocData.len, data.fd); 123202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return 0; 124202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 125202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 126202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 127202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint IonAlloc::free_buffer(void* base, size_t size, int offset, int fd) 128202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{ 12929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed Locker::Autolock _l(mLock); 13001d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed ALOGD_IF(DEBUG, "ion: Freeing buffer base:%p size:%d fd:%d", 13129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed base, size, fd); 132202a77d28ac251545f6f998a974690212309b927Iliyan Malchev int err = 0; 133202a77d28ac251545f6f998a974690212309b927Iliyan Malchev err = open_device(); 134202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if (err) 135202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return err; 136202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 137202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if(base) 138202a77d28ac251545f6f998a974690212309b927Iliyan Malchev err = unmap_buffer(base, size, offset); 139202a77d28ac251545f6f998a974690212309b927Iliyan Malchev close(fd); 140202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return err; 141202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 142202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 143202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint IonAlloc::map_buffer(void **pBase, size_t size, int offset, int fd) 144202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{ 145202a77d28ac251545f6f998a974690212309b927Iliyan Malchev int err = 0; 146202a77d28ac251545f6f998a974690212309b927Iliyan Malchev void *base = 0; 147202a77d28ac251545f6f998a974690212309b927Iliyan Malchev // It is a (quirky) requirement of ION to have opened the 148202a77d28ac251545f6f998a974690212309b927Iliyan Malchev // ion fd in the process that is doing the mapping 149202a77d28ac251545f6f998a974690212309b927Iliyan Malchev err = open_device(); 150202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if (err) 151202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return err; 152202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 153202a77d28ac251545f6f998a974690212309b927Iliyan Malchev base = mmap(0, size, PROT_READ| PROT_WRITE, 15429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed MAP_SHARED, fd, 0); 155202a77d28ac251545f6f998a974690212309b927Iliyan Malchev *pBase = base; 156202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if(base == MAP_FAILED) { 157202a77d28ac251545f6f998a974690212309b927Iliyan Malchev err = -errno; 15801d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed ALOGE("ion: Failed to map memory in the client: %s", 15929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed strerror(errno)); 160202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } else { 16101d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed ALOGD_IF(DEBUG, "ion: Mapped buffer base:%p size:%d offset:%d fd:%d", 16229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed base, size, offset, fd); 163202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 164202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return err; 165202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 166202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 167202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint IonAlloc::unmap_buffer(void *base, size_t size, int offset) 168202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{ 16901d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed ALOGD_IF(DEBUG, "ion: Unmapping buffer base:%p size:%d", base, size); 170202a77d28ac251545f6f998a974690212309b927Iliyan Malchev int err = 0; 171202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if(munmap(base, size)) { 172202a77d28ac251545f6f998a974690212309b927Iliyan Malchev err = -errno; 173202a77d28ac251545f6f998a974690212309b927Iliyan Malchev ALOGE("ion: Failed to unmap memory at %p : %s", 17429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed base, strerror(errno)); 175202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 176202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return err; 177202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 178202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 1790b5054e40d055687b036b626538e79bf160beebbNaseer Ahmedint IonAlloc::clean_buffer(void *base, size_t size, int offset, int fd, int op) 180202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{ 181202a77d28ac251545f6f998a974690212309b927Iliyan Malchev struct ion_flush_data flush_data; 182202a77d28ac251545f6f998a974690212309b927Iliyan Malchev struct ion_fd_data fd_data; 183202a77d28ac251545f6f998a974690212309b927Iliyan Malchev struct ion_handle_data handle_data; 184202a77d28ac251545f6f998a974690212309b927Iliyan Malchev struct ion_handle* handle; 185202a77d28ac251545f6f998a974690212309b927Iliyan Malchev int err = 0; 186202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 187202a77d28ac251545f6f998a974690212309b927Iliyan Malchev err = open_device(); 188202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if (err) 189202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return err; 190202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 191202a77d28ac251545f6f998a974690212309b927Iliyan Malchev fd_data.fd = fd; 192202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if (ioctl(mIonFd, ION_IOC_IMPORT, &fd_data)) { 193202a77d28ac251545f6f998a974690212309b927Iliyan Malchev err = -errno; 194202a77d28ac251545f6f998a974690212309b927Iliyan Malchev ALOGE("%s: ION_IOC_IMPORT failed with error - %s", 19529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed __FUNCTION__, strerror(errno)); 196202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return err; 197202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 198202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 199202a77d28ac251545f6f998a974690212309b927Iliyan Malchev handle_data.handle = fd_data.handle; 200202a77d28ac251545f6f998a974690212309b927Iliyan Malchev flush_data.handle = fd_data.handle; 201202a77d28ac251545f6f998a974690212309b927Iliyan Malchev flush_data.vaddr = base; 202202a77d28ac251545f6f998a974690212309b927Iliyan Malchev flush_data.offset = offset; 203202a77d28ac251545f6f998a974690212309b927Iliyan Malchev flush_data.length = size; 20462aa1e0fdc80b7f64d2415090ef527c3fe7e7b12Saurabh Shah 20562aa1e0fdc80b7f64d2415090ef527c3fe7e7b12Saurabh Shah struct ion_custom_data d; 2060b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed switch(op) { 2070b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed case CACHE_CLEAN: 2080b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed d.cmd = ION_IOC_CLEAN_CACHES; 2090b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed break; 2100b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed case CACHE_INVALIDATE: 2110b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed d.cmd = ION_IOC_INV_CACHES; 2120b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed break; 2130b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed case CACHE_CLEAN_AND_INVALIDATE: 2140b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed default: 2150b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed d.cmd = ION_IOC_CLEAN_INV_CACHES; 2160b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed } 2170b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed 21862aa1e0fdc80b7f64d2415090ef527c3fe7e7b12Saurabh Shah d.arg = (unsigned long int)&flush_data; 21962aa1e0fdc80b7f64d2415090ef527c3fe7e7b12Saurabh Shah 22062aa1e0fdc80b7f64d2415090ef527c3fe7e7b12Saurabh Shah if(ioctl(mIonFd, ION_IOC_CUSTOM, &d)) { 221202a77d28ac251545f6f998a974690212309b927Iliyan Malchev err = -errno; 222202a77d28ac251545f6f998a974690212309b927Iliyan Malchev ALOGE("%s: ION_IOC_CLEAN_INV_CACHES failed with error - %s", 22362aa1e0fdc80b7f64d2415090ef527c3fe7e7b12Saurabh Shah 22429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed __FUNCTION__, strerror(errno)); 225202a77d28ac251545f6f998a974690212309b927Iliyan Malchev ioctl(mIonFd, ION_IOC_FREE, &handle_data); 226202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return err; 227202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 228202a77d28ac251545f6f998a974690212309b927Iliyan Malchev ioctl(mIonFd, ION_IOC_FREE, &handle_data); 229202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return 0; 230202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 231202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 232