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