692458e07b5e8b8b29e7d9a023159bcd70bd3c06
[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 {
68         int ret;
69
70         switch (buffer->heap->type) {
71         case ION_HEAP_KMALLOC:
72         {
73                 unsigned long pfn = __phys_to_pfn(virt_to_phys(buffer->priv));
74                 ret = remap_pfn_range(vma, vma->vm_start, pfn + vma->vm_pgoff,
75                                       vma->vm_end - vma->vm_start,
76                                       vma->vm_page_prot);
77                 break;
78         }
79         case ION_HEAP_VMALLOC:
80                 ret = remap_vmalloc_range(vma, buffer->priv, vma->vm_pgoff);
81                 break;
82         default:
83                 pr_err("%s: attempting to map unsupported heap to userspace\n",
84                        __func__);
85                 return -EINVAL;
86         }
87
88         return ret;
89 }
90
91 static struct ion_mapper_ops ops = {
92         .map = ion_kernel_mapper_map,
93         .map_kernel = ion_kernel_mapper_map_kernel,
94         .map_user = ion_kernel_mapper_map_user,
95         .unmap = ion_kernel_mapper_unmap,
96 };
97
98 struct ion_mapper *ion_system_mapper_create(void)
99 {
100         struct ion_mapper *mapper;
101         mapper = kzalloc(sizeof(struct ion_mapper), GFP_KERNEL);
102         if (!mapper)
103                 return ERR_PTR(-ENOMEM);
104         mapper->type = ION_SYSTEM_MAPPER;
105         mapper->ops = &ops;
106         mapper->heap_mask = (1 << ION_HEAP_VMALLOC) | (1 << ION_HEAP_KMALLOC);
107         return mapper;
108 }
109
110 void ion_system_mapper_destroy(struct ion_mapper *mapper)
111 {
112         kfree(mapper);
113 }
114