ion_dummy_driver.c revision 630127f36784e59e995c206c37825a36a34d346c
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/init.h> 21#include <linux/bootmem.h> 22#include <linux/memblock.h> 23#include <linux/sizes.h> 24#include <linux/io.h> 25#include "ion.h" 26#include "ion_priv.h" 27 28struct ion_device *idev; 29struct ion_heap **heaps; 30 31void *carveout_ptr; 32void *chunk_ptr; 33 34struct ion_platform_heap dummy_heaps[] = { 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 }, 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 }, 59}; 60 61struct ion_platform_data dummy_ion_pdata = { 62 .nr = ARRAY_SIZE(dummy_heaps), 63 .heaps = dummy_heaps, 64}; 65 66static int __init ion_dummy_init(void) 67{ 68 int i, err; 69 70 idev = ion_device_create(NULL); 71 heaps = kzalloc(sizeof(struct ion_heap *) * dummy_ion_pdata.nr, 72 GFP_KERNEL); 73 if (!heaps) 74 return -ENOMEM; 75 76 77 /* Allocate a dummy carveout heap */ 78 carveout_ptr = alloc_pages_exact( 79 dummy_heaps[ION_HEAP_TYPE_CARVEOUT].size, 80 GFP_KERNEL); 81 if (carveout_ptr) 82 dummy_heaps[ION_HEAP_TYPE_CARVEOUT].base = 83 virt_to_phys(carveout_ptr); 84 else 85 pr_err("ion_dummy: Could not allocate carveout\n"); 86 87 /* Allocate a dummy chunk heap */ 88 chunk_ptr = alloc_pages_exact( 89 dummy_heaps[ION_HEAP_TYPE_CHUNK].size, 90 GFP_KERNEL); 91 if (chunk_ptr) 92 dummy_heaps[ION_HEAP_TYPE_CHUNK].base = virt_to_phys(chunk_ptr); 93 else 94 pr_err("ion_dummy: Could not allocate chunk\n"); 95 96 for (i = 0; i < dummy_ion_pdata.nr; i++) { 97 struct ion_platform_heap *heap_data = &dummy_ion_pdata.heaps[i]; 98 99 if (heap_data->type == ION_HEAP_TYPE_CARVEOUT && 100 !heap_data->base) 101 continue; 102 103 if (heap_data->type == ION_HEAP_TYPE_CHUNK && !heap_data->base) 104 continue; 105 106 heaps[i] = ion_heap_create(heap_data); 107 if (IS_ERR_OR_NULL(heaps[i])) { 108 err = PTR_ERR(heaps[i]); 109 goto err; 110 } 111 ion_device_add_heap(idev, heaps[i]); 112 } 113 return 0; 114err: 115 for (i = 0; i < dummy_ion_pdata.nr; i++) { 116 if (heaps[i]) 117 ion_heap_destroy(heaps[i]); 118 } 119 kfree(heaps); 120 121 if (carveout_ptr) { 122 free_pages_exact(carveout_ptr, 123 dummy_heaps[ION_HEAP_TYPE_CARVEOUT].size); 124 carveout_ptr = NULL; 125 } 126 if (chunk_ptr) { 127 free_pages_exact(chunk_ptr, 128 dummy_heaps[ION_HEAP_TYPE_CHUNK].size); 129 chunk_ptr = NULL; 130 } 131 return err; 132} 133device_initcall(ion_dummy_init); 134 135static 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 145 if (carveout_ptr) { 146 free_pages_exact(carveout_ptr, 147 dummy_heaps[ION_HEAP_TYPE_CARVEOUT].size); 148 carveout_ptr = NULL; 149 } 150 if (chunk_ptr) { 151 free_pages_exact(chunk_ptr, 152 dummy_heaps[ION_HEAP_TYPE_CHUNK].size); 153 chunk_ptr = NULL; 154 } 155 156 return; 157} 158__exitcall(ion_dummy_exit); 159