blob: 1991626e2d935ecc50045c9192067c094ee611be [file] [log] [blame]
John Stultz1184ead2014-01-09 21:08:37 -08001/*
2 * drivers/gpu/ion/ion_dummy_driver.c
3 *
4 * Copyright (C) 2013 Linaro, Inc
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/err.h>
18#include <linux/platform_device.h>
19#include <linux/slab.h>
Paul Gortmaker102f1a22014-01-21 16:22:12 -050020#include <linux/init.h>
John Stultz1184ead2014-01-09 21:08:37 -080021#include <linux/bootmem.h>
22#include <linux/memblock.h>
23#include <linux/sizes.h>
Chen Gang10f6f9c2014-01-18 17:04:06 +080024#include <linux/io.h>
John Stultz1184ead2014-01-09 21:08:37 -080025#include "ion.h"
26#include "ion_priv.h"
27
Wei Yongjun3a915dd2014-01-14 10:04:49 +080028static struct ion_device *idev;
29static struct ion_heap **heaps;
John Stultz1184ead2014-01-09 21:08:37 -080030
Wei Yongjun3a915dd2014-01-14 10:04:49 +080031static void *carveout_ptr;
32static void *chunk_ptr;
John Stultz4c45b1a2014-01-09 21:08:38 -080033
Wei Yongjun3a915dd2014-01-14 10:04:49 +080034static struct ion_platform_heap dummy_heaps[] = {
John Stultz1184ead2014-01-09 21:08:37 -080035 {
36 .id = ION_HEAP_TYPE_SYSTEM,
37 .type = ION_HEAP_TYPE_SYSTEM,
38 .name = "system",
39 },
40 {
John Stultz4c45b1a2014-01-09 21:08:38 -080041 .id = ION_HEAP_TYPE_CARVEOUT,
42 .type = ION_HEAP_TYPE_CARVEOUT,
43 .name = "carveout",
44 .size = SZ_4M,
45 },
46 {
47 .id = ION_HEAP_TYPE_CHUNK,
48 .type = ION_HEAP_TYPE_CHUNK,
49 .name = "chunk",
50 .size = SZ_4M,
51 .align = SZ_16K,
52 .priv = (void *)(SZ_16K),
53 },
John Stultz1184ead2014-01-09 21:08:37 -080054};
55
Wei Yongjun3a915dd2014-01-14 10:04:49 +080056static struct ion_platform_data dummy_ion_pdata = {
Tomas Winkler18691f52014-01-22 19:15:55 +020057 .nr = ARRAY_SIZE(dummy_heaps),
John Stultz1184ead2014-01-09 21:08:37 -080058 .heaps = dummy_heaps,
59};
60
61static int __init ion_dummy_init(void)
62{
63 int i, err;
64
65 idev = ion_device_create(NULL);
Sudip Mukherjee9f563f12016-04-07 22:02:25 +053066 if (IS_ERR(idev))
67 return PTR_ERR(idev);
Phong Trand320c452014-08-13 20:37:04 +070068 heaps = kcalloc(dummy_ion_pdata.nr, sizeof(struct ion_heap *),
John Stultz1184ead2014-01-09 21:08:37 -080069 GFP_KERNEL);
70 if (!heaps)
Dan Carpenter630127f2014-01-20 13:30:01 +030071 return -ENOMEM;
John Stultz1184ead2014-01-09 21:08:37 -080072
John Stultz4c45b1a2014-01-09 21:08:38 -080073
John Stultz1184ead2014-01-09 21:08:37 -080074 for (i = 0; i < dummy_ion_pdata.nr; i++) {
75 struct ion_platform_heap *heap_data = &dummy_ion_pdata.heaps[i];
76
John Stultz45733002019-02-13 12:44:18 -080077 if (heap_data->type == ION_HEAP_TYPE_CARVEOUT) {
78 /* Allocate a dummy carveout heap */
79 carveout_ptr = alloc_pages_exact(heap_data->size,
80 GFP_KERNEL);
81 if (!carveout_ptr) {
82 pr_err("ion_dummy: Could not allocate carveout\n");
83 continue;
84 }
85 heap_data->base = virt_to_phys(carveout_ptr);
86 }
John Stultz4c45b1a2014-01-09 21:08:38 -080087
John Stultz45733002019-02-13 12:44:18 -080088 if (heap_data->type == ION_HEAP_TYPE_CHUNK) {
89 /* Allocate a dummy chunk heap */
90 chunk_ptr = alloc_pages_exact(heap_data->size,
91 GFP_KERNEL);
92 if (!chunk_ptr) {
93 pr_err("ion_dummy: Could not allocate chunk\n");
94 continue;
95 }
96 heap_data->base = virt_to_phys(chunk_ptr);
97 }
John Stultz4c45b1a2014-01-09 21:08:38 -080098
John Stultz1184ead2014-01-09 21:08:37 -080099 heaps[i] = ion_heap_create(heap_data);
100 if (IS_ERR_OR_NULL(heaps[i])) {
101 err = PTR_ERR(heaps[i]);
102 goto err;
103 }
104 ion_device_add_heap(idev, heaps[i]);
105 }
106 return 0;
107err:
John Stultza53fdae2019-02-13 13:59:12 -0800108 for (i = 0; i < dummy_ion_pdata.nr; ++i) {
John Stultz45733002019-02-13 12:44:18 -0800109 struct ion_platform_heap *heap_data = &dummy_ion_pdata.heaps[i];
110
John Stultza53fdae2019-02-13 13:59:12 -0800111 if (!IS_ERR_OR_NULL(heaps[i]))
112 ion_heap_destroy(heaps[i]);
John Stultz45733002019-02-13 12:44:18 -0800113
114 if (heap_data->type == ION_HEAP_TYPE_CARVEOUT) {
115 if (carveout_ptr) {
116 free_pages_exact(carveout_ptr,
117 heap_data->size);
118 }
119 carveout_ptr = NULL;
120 }
121 if (heap_data->type == ION_HEAP_TYPE_CHUNK) {
122 if (chunk_ptr) {
123 free_pages_exact(chunk_ptr, heap_data->size);
124 }
125 chunk_ptr = NULL;
126 }
John Stultza53fdae2019-02-13 13:59:12 -0800127 }
John Stultz1184ead2014-01-09 21:08:37 -0800128 kfree(heaps);
129
130 return err;
131}
Paul Gortmaker102f1a22014-01-21 16:22:12 -0500132device_initcall(ion_dummy_init);
John Stultz1184ead2014-01-09 21:08:37 -0800133
134static void __exit ion_dummy_exit(void)
135{
136 int i;
137
138 ion_device_destroy(idev);
139
John Stultz45733002019-02-13 12:44:18 -0800140 for (i = 0; i < dummy_ion_pdata.nr; ++i) {
141 struct ion_platform_heap *heap_data = &dummy_ion_pdata.heaps[i];
142
John Stultza53fdae2019-02-13 13:59:12 -0800143 if (!IS_ERR_OR_NULL(heaps[i]))
144 ion_heap_destroy(heaps[i]);
John Stultz45733002019-02-13 12:44:18 -0800145
146 if (heap_data->type == ION_HEAP_TYPE_CARVEOUT) {
147 if (carveout_ptr) {
148 free_pages_exact(carveout_ptr,
149 heap_data->size);
150 }
151 carveout_ptr = NULL;
152 }
153 if (heap_data->type == ION_HEAP_TYPE_CHUNK) {
154 if (chunk_ptr) {
155 free_pages_exact(chunk_ptr, heap_data->size);
156 }
157 chunk_ptr = NULL;
158 }
John Stultza53fdae2019-02-13 13:59:12 -0800159 }
John Stultz1184ead2014-01-09 21:08:37 -0800160 kfree(heaps);
John Stultz1184ead2014-01-09 21:08:37 -0800161}
Paul Gortmaker102f1a22014-01-21 16:22:12 -0500162__exitcall(ion_dummy_exit);