aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/ion/ion_system_heap.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/gpu/ion/ion_system_heap.c
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/gpu/ion/ion_system_heap.c')
-rw-r--r--drivers/gpu/ion/ion_system_heap.c198
1 files changed, 198 insertions, 0 deletions
diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c
new file mode 100644
index 00000000000..c046cf1a321
--- /dev/null
+++ b/drivers/gpu/ion/ion_system_heap.c
@@ -0,0 +1,198 @@
1/*
2 * drivers/gpu/ion/ion_system_heap.c
3 *
4 * Copyright (C) 2011 Google, 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/ion.h>
19#include <linux/mm.h>
20#include <linux/scatterlist.h>
21#include <linux/slab.h>
22#include <linux/vmalloc.h>
23#include "ion_priv.h"
24
25static int ion_system_heap_allocate(struct ion_heap *heap,
26 struct ion_buffer *buffer,
27 unsigned long size, unsigned long align,
28 unsigned long flags)
29{
30 buffer->priv_virt = vmalloc_user(size);
31 if (!buffer->priv_virt)
32 return -ENOMEM;
33 return 0;
34}
35
36void ion_system_heap_free(struct ion_buffer *buffer)
37{
38 vfree(buffer->priv_virt);
39}
40
41struct scatterlist *ion_system_heap_map_dma(struct ion_heap *heap,
42 struct ion_buffer *buffer)
43{
44 struct scatterlist *sglist;
45 struct page *page;
46 int i;
47 int npages = PAGE_ALIGN(buffer->size) / PAGE_SIZE;
48 void *vaddr = buffer->priv_virt;
49
50 sglist = vmalloc(npages * sizeof(struct scatterlist));
51 if (!sglist)
52 return ERR_PTR(-ENOMEM);
53 memset(sglist, 0, npages * sizeof(struct scatterlist));
54 sg_init_table(sglist, npages);
55 for (i = 0; i < npages; i++) {
56 page = vmalloc_to_page(vaddr);
57 if (!page)
58 goto end;
59 sg_set_page(&sglist[i], page, PAGE_SIZE, 0);
60 vaddr += PAGE_SIZE;
61 }
62 /* XXX do cache maintenance for dma? */
63 return sglist;
64end:
65 vfree(sglist);
66 return NULL;
67}
68
69void ion_system_heap_unmap_dma(struct ion_heap *heap,
70 struct ion_buffer *buffer)
71{
72 /* XXX undo cache maintenance for dma? */
73 if (buffer->sglist)
74 vfree(buffer->sglist);
75}
76
77void *ion_system_heap_map_kernel(struct ion_heap *heap,
78 struct ion_buffer *buffer)
79{
80 return buffer->priv_virt;
81}
82
83void ion_system_heap_unmap_kernel(struct ion_heap *heap,
84 struct ion_buffer *buffer)
85{
86}
87
88int ion_system_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer,
89 struct vm_area_struct *vma)
90{
91 return remap_vmalloc_range(vma, buffer->priv_virt, vma->vm_pgoff);
92}
93
94static struct ion_heap_ops vmalloc_ops = {
95 .allocate = ion_system_heap_allocate,
96 .free = ion_system_heap_free,
97 .map_dma = ion_system_heap_map_dma,
98 .unmap_dma = ion_system_heap_unmap_dma,
99 .map_kernel = ion_system_heap_map_kernel,
100 .unmap_kernel = ion_system_heap_unmap_kernel,
101 .map_user = ion_system_heap_map_user,
102};
103
104struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused)
105{
106 struct ion_heap *heap;
107
108 heap = kzalloc(sizeof(struct ion_heap), GFP_KERNEL);
109 if (!heap)
110 return ERR_PTR(-ENOMEM);
111 heap->ops = &vmalloc_ops;
112 heap->type = ION_HEAP_TYPE_SYSTEM;
113 return heap;
114}
115
116void ion_system_heap_destroy(struct ion_heap *heap)
117{
118 kfree(heap);
119}
120
121static int ion_system_contig_heap_allocate(struct ion_heap *heap,
122 struct ion_buffer *buffer,
123 unsigned long len,
124 unsigned long align,
125 unsigned long flags)
126{
127 buffer->priv_virt = kzalloc(len, GFP_KERNEL);
128 if (!buffer->priv_virt)
129 return -ENOMEM;
130 return 0;
131}
132
133void ion_system_contig_heap_free(struct ion_buffer *buffer)
134{
135 kfree(buffer->priv_virt);
136}
137
138static int ion_system_contig_heap_phys(struct ion_heap *heap,
139 struct ion_buffer *buffer,
140 ion_phys_addr_t *addr, size_t *len)
141{
142 *addr = virt_to_phys(buffer->priv_virt);
143 *len = buffer->size;
144 return 0;
145}
146
147struct scatterlist *ion_system_contig_heap_map_dma(struct ion_heap *heap,
148 struct ion_buffer *buffer)
149{
150 struct scatterlist *sglist;
151
152 sglist = vmalloc(sizeof(struct scatterlist));
153 if (!sglist)
154 return ERR_PTR(-ENOMEM);
155 sg_init_table(sglist, 1);
156 sg_set_page(sglist, virt_to_page(buffer->priv_virt), buffer->size, 0);
157 return sglist;
158}
159
160int ion_system_contig_heap_map_user(struct ion_heap *heap,
161 struct ion_buffer *buffer,
162 struct vm_area_struct *vma)
163{
164 unsigned long pfn = __phys_to_pfn(virt_to_phys(buffer->priv_virt));
165 return remap_pfn_range(vma, vma->vm_start, pfn + vma->vm_pgoff,
166 vma->vm_end - vma->vm_start,
167 vma->vm_page_prot);
168
169}
170
171static struct ion_heap_ops kmalloc_ops = {
172 .allocate = ion_system_contig_heap_allocate,
173 .free = ion_system_contig_heap_free,
174 .phys = ion_system_contig_heap_phys,
175 .map_dma = ion_system_contig_heap_map_dma,
176 .unmap_dma = ion_system_heap_unmap_dma,
177 .map_kernel = ion_system_heap_map_kernel,
178 .unmap_kernel = ion_system_heap_unmap_kernel,
179 .map_user = ion_system_contig_heap_map_user,
180};
181
182struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *unused)
183{
184 struct ion_heap *heap;
185
186 heap = kzalloc(sizeof(struct ion_heap), GFP_KERNEL);
187 if (!heap)
188 return ERR_PTR(-ENOMEM);
189 heap->ops = &kmalloc_ops;
190 heap->type = ION_HEAP_TYPE_SYSTEM_CONTIG;
191 return heap;
192}
193
194void ion_system_contig_heap_destroy(struct ion_heap *heap)
195{
196 kfree(heap);
197}
198