0a1fc49a80c739d57095c0e9833eec5c94c9147d
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / ion / ion_system_mapper.c
1 /*
2  * drivers/gpu/ion/ion_system_mapper.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/memory.h>
20 #include <linux/mm.h>
21 #include <linux/slab.h>
22 #include <linux/vmalloc.h>
23 #include "ion_priv.h"
24 /*
25  * This mapper is valid for any heap that allocates memory that already has
26  * a kernel mapping, this includes vmalloc'd memory, kmalloc'd memory,
27  * pages obtained via io_remap, etc.
28  */
29 static void *ion_kernel_mapper_map(struct ion_mapper *mapper,
30                                    struct ion_buffer *buffer,
31                                    struct ion_mapping **mapping)
32 {
33         if (!((1 << buffer->heap->type) & mapper->heap_mask)) {
34                 pr_err("%s: attempting to map an unsupported heap\n", __func__);
35                 return ERR_PTR(-EINVAL);
36         }
37         /* XXX REVISIT ME!!! */
38         *((unsigned long *)mapping) = (unsigned long)buffer->priv;
39         return buffer->priv;
40 }
41
42 static void ion_kernel_mapper_unmap(struct ion_mapper *mapper,
43                                     struct ion_buffer *buffer,
44                                     struct ion_mapping *mapping)
45 {
46         if (!((1 << buffer->heap->type) & mapper->heap_mask))
47                 pr_err("%s: attempting to unmap an unsupported heap\n",
48                        __func__);
49 }
50
51 static void *ion_kernel_mapper_map_kernel(struct ion_mapper *mapper,
52                                         struct ion_buffer *buffer,
53                                         struct ion_mapping *mapping)
54 {
55         if (!((1 << buffer->heap->type) & mapper->heap_mask)) {
56                 pr_err("%s: attempting to unmap an unsupported heap\n",
57                        __func__);
58                 return ERR_PTR(-EINVAL);
59         }
60         return buffer->priv;
61 }
62
63 static int ion_kernel_mapper_map_user(struct ion_mapper *mapper,
64                                       struct ion_buffer *buffer,
65                                       struct vm_area_struct *vma,
66                                       struct ion_mapping *mapping,
67                                       unsigned long flags)
68 {
69         int ret;
70
71         switch (buffer->heap->type) {
72         case ION_HEAP_KMALLOC:
73         {
74                 unsigned long pfn = __phys_to_pfn(virt_to_phys(buffer->priv));
75                 ret = remap_pfn_range(vma, vma->vm_start, pfn + vma->vm_pgoff,
76                                       vma->vm_end - vma->vm_start,
77                                       vma->vm_page_prot);
78                 break;
79         }
80         case ION_HEAP_VMALLOC:
81                 ret = remap_vmalloc_range(vma, buffer->priv, vma->vm_pgoff);
82                 break;
83         default:
84                 pr_err("%s: attempting to map unsupported heap to userspace\n",
85                        __func__);
86                 return -EINVAL;
87         }
88
89         return ret;
90 }
91
92 static struct ion_mapper_ops ops = {
93         .map = ion_kernel_mapper_map,
94         .map_kernel = ion_kernel_mapper_map_kernel,
95         .map_user = ion_kernel_mapper_map_user,
96         .unmap = ion_kernel_mapper_unmap,
97 };
98
99 struct ion_mapper *ion_system_mapper_create(void)
100 {
101         struct ion_mapper *mapper;
102         mapper = kzalloc(sizeof(struct ion_mapper), GFP_KERNEL);
103         if (!mapper)
104                 return ERR_PTR(-ENOMEM);
105         mapper->type = ION_SYSTEM_MAPPER;
106         mapper->ops = &ops;
107         mapper->heap_mask = (1 << ION_HEAP_VMALLOC) | (1 << ION_HEAP_KMALLOC);
108         return mapper;
109 }
110
111 void ion_system_mapper_destroy(struct ion_mapper *mapper)
112 {
113         kfree(mapper);
114 }
115