1d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/*
2d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
3d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
4d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * Redistribution and use in source and binary forms, with or without
5d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * modification, are permitted provided that the following conditions are
6d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * met:
7d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *   * Redistributions of source code must retain the above copyright
8d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *     notice, this list of conditions and the following disclaimer.
9d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *   * Redistributions in binary form must reproduce the above
10d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *     copyright notice, this list of conditions and the following
11d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *     disclaimer in the documentation and/or other materials provided
12d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *     with the distribution.
13d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *   * Neither the name of The Linux Foundation nor the names of its
14d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *     contributors may be used to endorse or promote products derived
15d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *     from this software without specific prior written permission.
16d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *
17d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin */
29d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
30d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#define DEBUG 0
31d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
32d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <sys/ioctl.h>
33d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <sys/mman.h>
34d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <stdlib.h>
35d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <fcntl.h>
36d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <cutils/log.h>
37d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <errno.h>
38d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <utils/Trace.h>
39d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include "gralloc_priv.h"
40d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include "ionalloc.h"
41d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
42d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinusing gralloc::IonAlloc;
43d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
44d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#define ION_DEVICE "/dev/ion"
45d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
46d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint IonAlloc::open_device()
47d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
48d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(mIonFd == FD_INIT)
49d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        mIonFd = open(ION_DEVICE, O_RDONLY);
50d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
51d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(mIonFd < 0 ) {
52d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: Failed to open ion device - %s",
53d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin              __FUNCTION__, strerror(errno));
54d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        mIonFd = FD_INIT;
55d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return -errno;
56d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
57d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return 0;
58d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
59d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
60d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid IonAlloc::close_device()
61d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
62d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(mIonFd >= 0)
63d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        close(mIonFd);
64d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    mIonFd = FD_INIT;
65d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
66d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
67d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint IonAlloc::alloc_buffer(alloc_data& data)
68d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
69d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ATRACE_CALL();
70d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    Locker::Autolock _l(mLock);
71d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int err = 0;
72d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct ion_handle_data handle_data;
73d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct ion_fd_data fd_data;
74d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct ion_allocation_data ionAllocData;
75d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    void *base = 0;
76d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
77d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ionAllocData.len = data.size;
78d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ionAllocData.align = data.align;
79d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ionAllocData.heap_id_mask = data.heapId;
80d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ionAllocData.flags = data.flags;
81d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ionAllocData.flags |= data.uncached ? 0 : ION_FLAG_CACHED;
82d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    err = open_device();
83d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (err)
84d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return err;
85d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(ioctl(mIonFd, ION_IOC_ALLOC, &ionAllocData)) {
86d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        err = -errno;
87d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("ION_IOC_ALLOC failed with error - %s", strerror(errno));
88d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return err;
89d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
90d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
91d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    fd_data.handle = ionAllocData.handle;
92d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    handle_data.handle = ionAllocData.handle;
93d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(ioctl(mIonFd, ION_IOC_MAP, &fd_data)) {
94d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        err = -errno;
95d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: ION_IOC_MAP failed with error - %s",
96d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin              __FUNCTION__, strerror(errno));
97d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ioctl(mIonFd, ION_IOC_FREE, &handle_data);
98d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return err;
99d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
100d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
101d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(!(data.flags & ION_SECURE)) {
102d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        base = mmap(0, ionAllocData.len, PROT_READ|PROT_WRITE,
103d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                    MAP_SHARED, fd_data.fd, 0);
104d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if(base == MAP_FAILED) {
105d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            err = -errno;
106d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGE("%s: Failed to map the allocated memory: %s",
107d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                  __FUNCTION__, strerror(errno));
108d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ioctl(mIonFd, ION_IOC_FREE, &handle_data);
109d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            return err;
110d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
111d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
112d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
113d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    data.base = base;
114d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    data.fd = fd_data.fd;
115d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ioctl(mIonFd, ION_IOC_FREE, &handle_data);
116d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ALOGD_IF(DEBUG, "ion: Allocated buffer base:%p size:%zu fd:%d",
117d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin          data.base, ionAllocData.len, data.fd);
118d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return 0;
119d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
120d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
121d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
122d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint IonAlloc::free_buffer(void* base, unsigned int size, unsigned int offset,
123d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        int fd)
124d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
125d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ATRACE_CALL();
126d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    Locker::Autolock _l(mLock);
127d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ALOGD_IF(DEBUG, "ion: Freeing buffer base:%p size:%u fd:%d",
128d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin          base, size, fd);
129d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int err = 0;
130d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    err = open_device();
131d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (err)
132d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return err;
133d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
134d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(base)
135d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        err = unmap_buffer(base, size, offset);
136d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    close(fd);
137d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return err;
138d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
139d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
140d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint IonAlloc::map_buffer(void **pBase, unsigned int size, unsigned int offset,
141d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        int fd)
142d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
143d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ATRACE_CALL();
144d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int err = 0;
145d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    void *base = 0;
146d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // It is a (quirky) requirement of ION to have opened the
147d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // ion fd in the process that is doing the mapping
148d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    err = open_device();
149d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (err)
150d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return err;
151d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
152d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    base = mmap(0, size, PROT_READ| PROT_WRITE,
153d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                MAP_SHARED, fd, 0);
154d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    *pBase = base;
155d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(base == MAP_FAILED) {
156d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        err = -errno;
157d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("ion: Failed to map memory in the client: %s",
158d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin              strerror(errno));
159d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    } else {
160d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGD_IF(DEBUG, "ion: Mapped buffer base:%p size:%u offset:%u fd:%d",
161d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin              base, size, offset, fd);
162d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
163d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return err;
164d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
165d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
166d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint IonAlloc::unmap_buffer(void *base, unsigned int size,
167d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        unsigned int /*offset*/)
168d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
169d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ATRACE_CALL();
170d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ALOGD_IF(DEBUG, "ion: Unmapping buffer  base:%p size:%u", base, size);
171d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int err = 0;
172d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(munmap(base, size)) {
173d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        err = -errno;
174d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("ion: Failed to unmap memory at %p : %s",
175d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin              base, strerror(errno));
176d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
177d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return err;
178d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
179d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
180d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint IonAlloc::clean_buffer(void *base, unsigned int size, unsigned int offset,
181d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        int fd, int op)
182d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
183d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ATRACE_CALL();
184d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ATRACE_INT("operation id", op);
185d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct ion_flush_data flush_data;
186d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct ion_fd_data fd_data;
187d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct ion_handle_data handle_data;
188d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int err = 0;
189d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
190d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    err = open_device();
191d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (err)
192d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return err;
193d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
194d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    fd_data.fd = fd;
195d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (ioctl(mIonFd, ION_IOC_IMPORT, &fd_data)) {
196d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        err = -errno;
197d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: ION_IOC_IMPORT failed with error - %s",
198d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin              __FUNCTION__, strerror(errno));
199d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return err;
200d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
201d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
202d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    handle_data.handle = fd_data.handle;
203d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    flush_data.handle  = fd_data.handle;
204d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    flush_data.vaddr   = base;
205d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // offset and length are unsigned int
206d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    flush_data.offset  = offset;
207d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    flush_data.length  = size;
208d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
209d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct ion_custom_data d;
210d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    switch(op) {
211d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    case CACHE_CLEAN:
212d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        d.cmd = ION_IOC_CLEAN_CACHES;
213d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        break;
214d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    case CACHE_INVALIDATE:
215d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            d.cmd = ION_IOC_INV_CACHES;
216d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        break;
217d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    case CACHE_CLEAN_AND_INVALIDATE:
218d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    default:
219d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        d.cmd = ION_IOC_CLEAN_INV_CACHES;
220d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
221d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
222d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    d.arg = (unsigned long int)&flush_data;
223d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
224d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(ioctl(mIonFd, ION_IOC_CUSTOM, &d)) {
225d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        err = -errno;
226d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: ION_IOC_CLEAN_INV_CACHES failed with error - %s",
227d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
228d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin              __FUNCTION__, strerror(errno));
229d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ioctl(mIonFd, ION_IOC_FREE, &handle_data);
230d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return err;
231d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
232d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ioctl(mIonFd, ION_IOC_FREE, &handle_data);
233d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return 0;
234d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
235d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
236