1fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin/*
2fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin * Copyright (C) 2012 Samsung Electronics Co., Ltd.
3fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin *
4fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin * Licensed under the Apache License, Version 2.0 (the "License");
5fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin * you may not use this file except in compliance with the License.
6fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin * You may obtain a copy of the License at
7fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin *
8fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin *      http://www.apache.org/licenses/LICENSE-2.0
9fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin *
10fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin * Unless required by applicable law or agreed to in writing, software
11fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin * distributed under the License is distributed on an "AS IS" BASIS,
12fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin * See the License for the specific language governing permissions and
14fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin * limitations under the License.
15fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin */
16fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin
17fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin#include <ion.h>
18fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin#include <fcntl.h>
19fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin#include <sys/mman.h>
20fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin#include <sys/ioctl.h>
21eb42d13a54dda74f691c972d993dcbd10b6934b7Rebecca Schultz Zavin#include <cutils/log.h>
22fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin
23fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavintypedef unsigned long ion_handle;
24fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin
25fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavinstruct ion_allocation_data {
26fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    size_t len;
27fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    size_t align;
28eb42d13a54dda74f691c972d993dcbd10b6934b7Rebecca Schultz Zavin    unsigned int heap_mask;
29fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    unsigned int flags;
30fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    ion_handle handle;
31fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin};
32fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin
33fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavinstruct ion_fd_data {
34fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    ion_handle handle;
35fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    int fd;
36fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin};
37fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin
38fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavinstruct ion_handle_data {
39fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    ion_handle handle;
40fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin};
41fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin
42fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavinstruct ion_custom_data {
43fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    unsigned int cmd;
44fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    unsigned long arg;
45fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin};
46fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin
47fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin#define ION_IOC_MAGIC   'I'
48fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin#define ION_IOC_ALLOC   _IOWR(ION_IOC_MAGIC, 0, struct ion_allocation_data)
49fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin#define ION_IOC_FREE    _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data)
50fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin#define ION_IOC_MAP     _IOWR(ION_IOC_MAGIC, 2, struct ion_fd_data)
51fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin#define ION_IOC_SHARE   _IOWR(ION_IOC_MAGIC, 4, struct ion_fd_data)
52eb42d13a54dda74f691c972d993dcbd10b6934b7Rebecca Schultz Zavin#define ION_IOC_IMPORT  _IOWR(ION_IOC_MAGIC, 5, struct ion_fd_data)
53fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin#define ION_IOC_CUSTOM  _IOWR(ION_IOC_MAGIC, 6, struct ion_custom_data)
54eb42d13a54dda74f691c972d993dcbd10b6934b7Rebecca Schultz Zavin#define ION_IOC_SYNC	_IOWR(ION_IOC_MAGIC, 7, struct ion_fd_data)
55fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin
56fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavinstruct ion_msync_data {
57fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    long flags;
58fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    ion_buffer buf;
59fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    size_t size;
60fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    off_t offset;
61fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin};
62fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin
63fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavinenum ION_EXYNOS_CUSTOM_CMD {
64fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    ION_EXYNOS_CUSTOM_MSYNC
65fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin};
66fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin
67fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavinion_client ion_client_create(void)
68fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin{
69fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    return open("/dev/ion", O_RDWR);
70fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin}
71fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin
72fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavinvoid ion_client_destroy(ion_client client)
73fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin{
74fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    close(client);
75fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin}
76fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin
77fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavinion_buffer ion_alloc(ion_client client, size_t len, size_t align,
78eb42d13a54dda74f691c972d993dcbd10b6934b7Rebecca Schultz Zavin                     unsigned int heap_mask, unsigned int flags)
79fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin{
80fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    int ret;
81fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    struct ion_handle_data arg_free;
82fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    struct ion_fd_data arg_share;
83fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    struct ion_allocation_data arg_alloc;
84fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin
85fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    arg_alloc.len = len;
86fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    arg_alloc.align = align;
87eb42d13a54dda74f691c972d993dcbd10b6934b7Rebecca Schultz Zavin    arg_alloc.heap_mask = heap_mask;
88fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    arg_alloc.flags = flags;
89fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin
90fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    ret = ioctl(client, ION_IOC_ALLOC, &arg_alloc);
91fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    if (ret < 0)
92fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin        return ret;
93fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin
94fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    arg_share.handle = arg_alloc.handle;
95fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    ret = ioctl(client, ION_IOC_SHARE, &arg_share);
96fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin
97fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    arg_free.handle = arg_alloc.handle;
98fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    ioctl(client, ION_IOC_FREE, &arg_free);
99fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin
100fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    if (ret < 0)
101fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin        return ret;
102fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin
103fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    return arg_share.fd;
104fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin}
105fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin
106fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavinvoid ion_free(ion_buffer buffer)
107fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin{
108fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    close(buffer);
109fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin}
110fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin
111fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavinvoid *ion_map(ion_buffer buffer, size_t len, off_t offset)
112fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin{
113fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    return mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED,
114fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin                buffer, offset);
115fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin}
116fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin
117fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavinint ion_unmap(void *addr, size_t len)
118fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin{
119fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin    return munmap(addr, len);
120fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin}
121fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin
122eb42d13a54dda74f691c972d993dcbd10b6934b7Rebecca Schultz Zavinint ion_sync(ion_client client, ion_buffer buffer)
123fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin{
124eb42d13a54dda74f691c972d993dcbd10b6934b7Rebecca Schultz Zavin    struct ion_fd_data data;
125fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin
126eb42d13a54dda74f691c972d993dcbd10b6934b7Rebecca Schultz Zavin    data.fd = buffer;
127fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin
128eb42d13a54dda74f691c972d993dcbd10b6934b7Rebecca Schultz Zavin    return ioctl(client, ION_IOC_SYNC, &data);
129fc4b5d53de9334a8b5ee078788b6e4bbc36535c3Dima Zavin}
13057e0616607fc3022bf0dc5ee6e6453dba3c4e88eSeungBeom Kim
13157e0616607fc3022bf0dc5ee6e6453dba3c4e88eSeungBeom Kimint ion_incRef(int fd, int share_fd, unsigned long **handle)
13257e0616607fc3022bf0dc5ee6e6453dba3c4e88eSeungBeom Kim{
13357e0616607fc3022bf0dc5ee6e6453dba3c4e88eSeungBeom Kim    struct ion_fd_data data;
13457e0616607fc3022bf0dc5ee6e6453dba3c4e88eSeungBeom Kim
13557e0616607fc3022bf0dc5ee6e6453dba3c4e88eSeungBeom Kim    data.fd = share_fd;
13657e0616607fc3022bf0dc5ee6e6453dba3c4e88eSeungBeom Kim
13757e0616607fc3022bf0dc5ee6e6453dba3c4e88eSeungBeom Kim    int ret = ioctl(fd, ION_IOC_IMPORT, &data);
13857e0616607fc3022bf0dc5ee6e6453dba3c4e88eSeungBeom Kim    if (ret < 0)
13957e0616607fc3022bf0dc5ee6e6453dba3c4e88eSeungBeom Kim            return ret;
14057e0616607fc3022bf0dc5ee6e6453dba3c4e88eSeungBeom Kim    *handle = (unsigned long*)(data.handle);
14157e0616607fc3022bf0dc5ee6e6453dba3c4e88eSeungBeom Kim    return ret;
14257e0616607fc3022bf0dc5ee6e6453dba3c4e88eSeungBeom Kim}
14357e0616607fc3022bf0dc5ee6e6453dba3c4e88eSeungBeom Kim
14457e0616607fc3022bf0dc5ee6e6453dba3c4e88eSeungBeom Kimint ion_decRef(int fd, unsigned long *handle)
14557e0616607fc3022bf0dc5ee6e6453dba3c4e88eSeungBeom Kim{
14657e0616607fc3022bf0dc5ee6e6453dba3c4e88eSeungBeom Kim    struct ion_handle_data data;
14757e0616607fc3022bf0dc5ee6e6453dba3c4e88eSeungBeom Kim    data.handle = (ion_handle)handle;
14857e0616607fc3022bf0dc5ee6e6453dba3c4e88eSeungBeom Kim
14957e0616607fc3022bf0dc5ee6e6453dba3c4e88eSeungBeom Kim    return ioctl(fd, ION_IOC_FREE, &data);
15057e0616607fc3022bf0dc5ee6e6453dba3c4e88eSeungBeom Kim}
151