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