]> Git Repo - linux.git/blob - drivers/gpu/drm/udl/udl_gem.c
Merge tag 'zonefs-5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal...
[linux.git] / drivers / gpu / drm / udl / udl_gem.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2012 Red Hat
4  */
5
6 #include <linux/dma-buf.h>
7 #include <linux/vmalloc.h>
8
9 #include <drm/drm_drv.h>
10 #include <drm/drm_gem_shmem_helper.h>
11 #include <drm/drm_mode.h>
12 #include <drm/drm_prime.h>
13
14 #include "udl_drv.h"
15
16 /*
17  * GEM object funcs
18  */
19
20 static int udl_gem_object_mmap(struct drm_gem_object *obj,
21                                struct vm_area_struct *vma)
22 {
23         int ret;
24
25         ret = drm_gem_shmem_mmap(obj, vma);
26         if (ret)
27                 return ret;
28
29         vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
30         if (obj->import_attach)
31                 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
32         vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
33
34         return 0;
35 }
36
37 static void *udl_gem_object_vmap(struct drm_gem_object *obj)
38 {
39         struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
40         int ret;
41
42         ret = mutex_lock_interruptible(&shmem->vmap_lock);
43         if (ret)
44                 return ERR_PTR(ret);
45
46         if (shmem->vmap_use_count++ > 0)
47                 goto out;
48
49         ret = drm_gem_shmem_get_pages(shmem);
50         if (ret)
51                 goto err_zero_use;
52
53         if (obj->import_attach)
54                 shmem->vaddr = dma_buf_vmap(obj->import_attach->dmabuf);
55         else
56                 shmem->vaddr = vmap(shmem->pages, obj->size >> PAGE_SHIFT,
57                                     VM_MAP, PAGE_KERNEL);
58
59         if (!shmem->vaddr) {
60                 DRM_DEBUG_KMS("Failed to vmap pages\n");
61                 ret = -ENOMEM;
62                 goto err_put_pages;
63         }
64
65 out:
66         mutex_unlock(&shmem->vmap_lock);
67         return shmem->vaddr;
68
69 err_put_pages:
70         drm_gem_shmem_put_pages(shmem);
71 err_zero_use:
72         shmem->vmap_use_count = 0;
73         mutex_unlock(&shmem->vmap_lock);
74         return ERR_PTR(ret);
75 }
76
77 static const struct drm_gem_object_funcs udl_gem_object_funcs = {
78         .free = drm_gem_shmem_free_object,
79         .print_info = drm_gem_shmem_print_info,
80         .pin = drm_gem_shmem_pin,
81         .unpin = drm_gem_shmem_unpin,
82         .get_sg_table = drm_gem_shmem_get_sg_table,
83         .vmap = udl_gem_object_vmap,
84         .vunmap = drm_gem_shmem_vunmap,
85         .mmap = udl_gem_object_mmap,
86 };
87
88 /*
89  * Helpers for struct drm_driver
90  */
91
92 struct drm_gem_object *udl_driver_gem_create_object(struct drm_device *dev,
93                                                     size_t size)
94 {
95         struct drm_gem_shmem_object *shmem;
96         struct drm_gem_object *obj;
97
98         shmem = kzalloc(sizeof(*shmem), GFP_KERNEL);
99         if (!shmem)
100                 return NULL;
101
102         obj = &shmem->base;
103         obj->funcs = &udl_gem_object_funcs;
104
105         return obj;
106 }
This page took 0.038671 seconds and 4 git commands to generate.