Commit | Line | Data |
---|---|---|
1184ead8 JS |
1 | /* |
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> | |
102f1a2a | 20 | #include <linux/init.h> |
1184ead8 JS |
21 | #include <linux/bootmem.h> |
22 | #include <linux/memblock.h> | |
23 | #include <linux/sizes.h> | |
10f6f9c3 | 24 | #include <linux/io.h> |
1184ead8 JS |
25 | #include "ion.h" |
26 | #include "ion_priv.h" | |
27 | ||
3a915dd2 WY |
28 | static struct ion_device *idev; |
29 | static struct ion_heap **heaps; | |
1184ead8 | 30 | |
3a915dd2 WY |
31 | static void *carveout_ptr; |
32 | static void *chunk_ptr; | |
4c45b1a8 | 33 | |
3a915dd2 | 34 | static struct ion_platform_heap dummy_heaps[] = { |
1184ead8 JS |
35 | { |
36 | .id = ION_HEAP_TYPE_SYSTEM, | |
37 | .type = ION_HEAP_TYPE_SYSTEM, | |
38 | .name = "system", | |
39 | }, | |
40 | { | |
41 | .id = ION_HEAP_TYPE_SYSTEM_CONTIG, | |
42 | .type = ION_HEAP_TYPE_SYSTEM_CONTIG, | |
43 | .name = "system contig", | |
44 | }, | |
4c45b1a8 JS |
45 | { |
46 | .id = ION_HEAP_TYPE_CARVEOUT, | |
47 | .type = ION_HEAP_TYPE_CARVEOUT, | |
48 | .name = "carveout", | |
49 | .size = SZ_4M, | |
50 | }, | |
51 | { | |
52 | .id = ION_HEAP_TYPE_CHUNK, | |
53 | .type = ION_HEAP_TYPE_CHUNK, | |
54 | .name = "chunk", | |
55 | .size = SZ_4M, | |
56 | .align = SZ_16K, | |
57 | .priv = (void *)(SZ_16K), | |
58 | }, | |
1184ead8 JS |
59 | }; |
60 | ||
3a915dd2 | 61 | static struct ion_platform_data dummy_ion_pdata = { |
18691f53 | 62 | .nr = ARRAY_SIZE(dummy_heaps), |
1184ead8 JS |
63 | .heaps = dummy_heaps, |
64 | }; | |
65 | ||
66 | static int __init ion_dummy_init(void) | |
67 | { | |
68 | int i, err; | |
69 | ||
70 | idev = ion_device_create(NULL); | |
9f563f1a SM |
71 | if (IS_ERR(idev)) |
72 | return PTR_ERR(idev); | |
d320c455 | 73 | heaps = kcalloc(dummy_ion_pdata.nr, sizeof(struct ion_heap *), |
1184ead8 JS |
74 | GFP_KERNEL); |
75 | if (!heaps) | |
630127f3 | 76 | return -ENOMEM; |
1184ead8 | 77 | |
4c45b1a8 JS |
78 | |
79 | /* Allocate a dummy carveout heap */ | |
80 | carveout_ptr = alloc_pages_exact( | |
81 | dummy_heaps[ION_HEAP_TYPE_CARVEOUT].size, | |
82 | GFP_KERNEL); | |
83 | if (carveout_ptr) | |
84 | dummy_heaps[ION_HEAP_TYPE_CARVEOUT].base = | |
85 | virt_to_phys(carveout_ptr); | |
86 | else | |
87 | pr_err("ion_dummy: Could not allocate carveout\n"); | |
88 | ||
89 | /* Allocate a dummy chunk heap */ | |
90 | chunk_ptr = alloc_pages_exact( | |
91 | dummy_heaps[ION_HEAP_TYPE_CHUNK].size, | |
92 | GFP_KERNEL); | |
93 | if (chunk_ptr) | |
94 | dummy_heaps[ION_HEAP_TYPE_CHUNK].base = virt_to_phys(chunk_ptr); | |
95 | else | |
96 | pr_err("ion_dummy: Could not allocate chunk\n"); | |
97 | ||
1184ead8 JS |
98 | for (i = 0; i < dummy_ion_pdata.nr; i++) { |
99 | struct ion_platform_heap *heap_data = &dummy_ion_pdata.heaps[i]; | |
100 | ||
4c45b1a8 | 101 | if (heap_data->type == ION_HEAP_TYPE_CARVEOUT && |
679011bd | 102 | !heap_data->base) |
4c45b1a8 JS |
103 | continue; |
104 | ||
105 | if (heap_data->type == ION_HEAP_TYPE_CHUNK && !heap_data->base) | |
106 | continue; | |
107 | ||
1184ead8 JS |
108 | heaps[i] = ion_heap_create(heap_data); |
109 | if (IS_ERR_OR_NULL(heaps[i])) { | |
110 | err = PTR_ERR(heaps[i]); | |
111 | goto err; | |
112 | } | |
113 | ion_device_add_heap(idev, heaps[i]); | |
114 | } | |
115 | return 0; | |
116 | err: | |
698f140d ME |
117 | for (i = 0; i < dummy_ion_pdata.nr; ++i) |
118 | ion_heap_destroy(heaps[i]); | |
1184ead8 JS |
119 | kfree(heaps); |
120 | ||
4c45b1a8 JS |
121 | if (carveout_ptr) { |
122 | free_pages_exact(carveout_ptr, | |
679011bd | 123 | dummy_heaps[ION_HEAP_TYPE_CARVEOUT].size); |
4c45b1a8 JS |
124 | carveout_ptr = NULL; |
125 | } | |
126 | if (chunk_ptr) { | |
127 | free_pages_exact(chunk_ptr, | |
679011bd | 128 | dummy_heaps[ION_HEAP_TYPE_CHUNK].size); |
4c45b1a8 JS |
129 | chunk_ptr = NULL; |
130 | } | |
1184ead8 JS |
131 | return err; |
132 | } | |
102f1a2a | 133 | device_initcall(ion_dummy_init); |
1184ead8 JS |
134 | |
135 | static void __exit ion_dummy_exit(void) | |
136 | { | |
137 | int i; | |
138 | ||
139 | ion_device_destroy(idev); | |
140 | ||
141 | for (i = 0; i < dummy_ion_pdata.nr; i++) | |
142 | ion_heap_destroy(heaps[i]); | |
143 | kfree(heaps); | |
144 | ||
4c45b1a8 JS |
145 | if (carveout_ptr) { |
146 | free_pages_exact(carveout_ptr, | |
679011bd | 147 | dummy_heaps[ION_HEAP_TYPE_CARVEOUT].size); |
4c45b1a8 JS |
148 | carveout_ptr = NULL; |
149 | } | |
150 | if (chunk_ptr) { | |
151 | free_pages_exact(chunk_ptr, | |
679011bd | 152 | dummy_heaps[ION_HEAP_TYPE_CHUNK].size); |
4c45b1a8 JS |
153 | chunk_ptr = NULL; |
154 | } | |
1184ead8 | 155 | } |
102f1a2a | 156 | __exitcall(ion_dummy_exit); |