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