1 1.1 riastrad /* $NetBSD: vgem_drv.c,v 1.3 2021/12/18 23:45:44 riastradh Exp $ */ 2 1.1 riastrad 3 1.1 riastrad /* 4 1.1 riastrad * Copyright 2011 Red Hat, Inc. 5 1.1 riastrad * Copyright 2014 The Chromium OS Authors 6 1.1 riastrad * 7 1.1 riastrad * Permission is hereby granted, free of charge, to any person obtaining a 8 1.1 riastrad * copy of this software and associated documentation files (the "Software") 9 1.1 riastrad * to deal in the software without restriction, including without limitation 10 1.1 riastrad * on the rights to use, copy, modify, merge, publish, distribute, sub 11 1.1 riastrad * license, and/or sell copies of the Software, and to permit persons to whom 12 1.1 riastrad * them Software is furnished to do so, subject to the following conditions: 13 1.1 riastrad * 14 1.1 riastrad * The above copyright notice and this permission notice (including the next 15 1.1 riastrad * paragraph) shall be included in all copies or substantial portions of the 16 1.1 riastrad * Software. 17 1.1 riastrad * 18 1.1 riastrad * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 1.1 riastrad * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTIBILITY, 20 1.1 riastrad * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 21 1.1 riastrad * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER 22 1.1 riastrad * IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 1.1 riastrad * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 1.1 riastrad * 25 1.1 riastrad * Authors: 26 1.1 riastrad * Adam Jackson <ajax (at) redhat.com> 27 1.1 riastrad * Ben Widawsky <ben (at) bwidawsk.net> 28 1.1 riastrad */ 29 1.1 riastrad 30 1.1 riastrad /** 31 1.1 riastrad * This is vgem, a (non-hardware-backed) GEM service. This is used by Mesa's 32 1.1 riastrad * software renderer and the X server for efficient buffer sharing. 33 1.1 riastrad */ 34 1.1 riastrad 35 1.1 riastrad #include <sys/cdefs.h> 36 1.1 riastrad __KERNEL_RCSID(0, "$NetBSD: vgem_drv.c,v 1.3 2021/12/18 23:45:44 riastradh Exp $"); 37 1.1 riastrad 38 1.3 riastrad #include <linux/dma-buf.h> 39 1.1 riastrad #include <linux/module.h> 40 1.3 riastrad #include <linux/platform_device.h> 41 1.1 riastrad #include <linux/shmem_fs.h> 42 1.3 riastrad #include <linux/vmalloc.h> 43 1.3 riastrad 44 1.3 riastrad #include <drm/drm_drv.h> 45 1.3 riastrad #include <drm/drm_file.h> 46 1.3 riastrad #include <drm/drm_ioctl.h> 47 1.3 riastrad #include <drm/drm_prime.h> 48 1.3 riastrad 49 1.1 riastrad #include "vgem_drv.h" 50 1.1 riastrad 51 1.1 riastrad #define DRIVER_NAME "vgem" 52 1.1 riastrad #define DRIVER_DESC "Virtual GEM provider" 53 1.1 riastrad #define DRIVER_DATE "20120112" 54 1.1 riastrad #define DRIVER_MAJOR 1 55 1.1 riastrad #define DRIVER_MINOR 0 56 1.1 riastrad 57 1.3 riastrad static struct vgem_device { 58 1.3 riastrad struct drm_device drm; 59 1.3 riastrad struct platform_device *platform; 60 1.3 riastrad } *vgem_device; 61 1.1 riastrad 62 1.1 riastrad static void vgem_gem_free_object(struct drm_gem_object *obj) 63 1.1 riastrad { 64 1.1 riastrad struct drm_vgem_gem_object *vgem_obj = to_vgem_bo(obj); 65 1.1 riastrad 66 1.3 riastrad kvfree(vgem_obj->pages); 67 1.3 riastrad mutex_destroy(&vgem_obj->pages_lock); 68 1.1 riastrad 69 1.3 riastrad if (obj->import_attach) 70 1.3 riastrad drm_prime_gem_destroy(obj, vgem_obj->table); 71 1.1 riastrad 72 1.1 riastrad drm_gem_object_release(obj); 73 1.1 riastrad kfree(vgem_obj); 74 1.1 riastrad } 75 1.1 riastrad 76 1.3 riastrad static vm_fault_t vgem_gem_fault(struct vm_fault *vmf) 77 1.1 riastrad { 78 1.3 riastrad struct vm_area_struct *vma = vmf->vma; 79 1.1 riastrad struct drm_vgem_gem_object *obj = vma->vm_private_data; 80 1.3 riastrad /* We don't use vmf->pgoff since that has the fake offset */ 81 1.3 riastrad unsigned long vaddr = vmf->address; 82 1.3 riastrad vm_fault_t ret = VM_FAULT_SIGBUS; 83 1.1 riastrad loff_t num_pages; 84 1.1 riastrad pgoff_t page_offset; 85 1.3 riastrad page_offset = (vaddr - vma->vm_start) >> PAGE_SHIFT; 86 1.1 riastrad 87 1.1 riastrad num_pages = DIV_ROUND_UP(obj->base.size, PAGE_SIZE); 88 1.1 riastrad 89 1.3 riastrad if (page_offset >= num_pages) 90 1.1 riastrad return VM_FAULT_SIGBUS; 91 1.1 riastrad 92 1.3 riastrad mutex_lock(&obj->pages_lock); 93 1.3 riastrad if (obj->pages) { 94 1.3 riastrad get_page(obj->pages[page_offset]); 95 1.3 riastrad vmf->page = obj->pages[page_offset]; 96 1.3 riastrad ret = 0; 97 1.3 riastrad } 98 1.3 riastrad mutex_unlock(&obj->pages_lock); 99 1.3 riastrad if (ret) { 100 1.3 riastrad struct page *page; 101 1.3 riastrad 102 1.3 riastrad page = shmem_read_mapping_page( 103 1.3 riastrad file_inode(obj->base.filp)->i_mapping, 104 1.3 riastrad page_offset); 105 1.3 riastrad if (!IS_ERR(page)) { 106 1.3 riastrad vmf->page = page; 107 1.3 riastrad ret = 0; 108 1.3 riastrad } else switch (PTR_ERR(page)) { 109 1.3 riastrad case -ENOSPC: 110 1.3 riastrad case -ENOMEM: 111 1.3 riastrad ret = VM_FAULT_OOM; 112 1.3 riastrad break; 113 1.3 riastrad case -EBUSY: 114 1.3 riastrad ret = VM_FAULT_RETRY; 115 1.3 riastrad break; 116 1.3 riastrad case -EFAULT: 117 1.3 riastrad case -EINVAL: 118 1.3 riastrad ret = VM_FAULT_SIGBUS; 119 1.3 riastrad break; 120 1.3 riastrad default: 121 1.3 riastrad WARN_ON(PTR_ERR(page)); 122 1.3 riastrad ret = VM_FAULT_SIGBUS; 123 1.3 riastrad break; 124 1.3 riastrad } 125 1.1 riastrad 126 1.1 riastrad } 127 1.3 riastrad return ret; 128 1.1 riastrad } 129 1.1 riastrad 130 1.1 riastrad static const struct vm_operations_struct vgem_gem_vm_ops = { 131 1.1 riastrad .fault = vgem_gem_fault, 132 1.1 riastrad .open = drm_gem_vm_open, 133 1.1 riastrad .close = drm_gem_vm_close, 134 1.1 riastrad }; 135 1.1 riastrad 136 1.3 riastrad static int vgem_open(struct drm_device *dev, struct drm_file *file) 137 1.3 riastrad { 138 1.3 riastrad struct vgem_file *vfile; 139 1.3 riastrad int ret; 140 1.3 riastrad 141 1.3 riastrad vfile = kzalloc(sizeof(*vfile), GFP_KERNEL); 142 1.3 riastrad if (!vfile) 143 1.3 riastrad return -ENOMEM; 144 1.3 riastrad 145 1.3 riastrad file->driver_priv = vfile; 146 1.3 riastrad 147 1.3 riastrad ret = vgem_fence_open(vfile); 148 1.3 riastrad if (ret) { 149 1.3 riastrad kfree(vfile); 150 1.3 riastrad return ret; 151 1.3 riastrad } 152 1.3 riastrad 153 1.3 riastrad return 0; 154 1.3 riastrad } 155 1.3 riastrad 156 1.3 riastrad static void vgem_postclose(struct drm_device *dev, struct drm_file *file) 157 1.3 riastrad { 158 1.3 riastrad struct vgem_file *vfile = file->driver_priv; 159 1.1 riastrad 160 1.3 riastrad vgem_fence_close(vfile); 161 1.3 riastrad kfree(vfile); 162 1.3 riastrad } 163 1.3 riastrad 164 1.3 riastrad static struct drm_vgem_gem_object *__vgem_gem_create(struct drm_device *dev, 165 1.3 riastrad unsigned long size) 166 1.1 riastrad { 167 1.1 riastrad struct drm_vgem_gem_object *obj; 168 1.3 riastrad int ret; 169 1.1 riastrad 170 1.1 riastrad obj = kzalloc(sizeof(*obj), GFP_KERNEL); 171 1.1 riastrad if (!obj) 172 1.1 riastrad return ERR_PTR(-ENOMEM); 173 1.1 riastrad 174 1.3 riastrad ret = drm_gem_object_init(dev, &obj->base, roundup(size, PAGE_SIZE)); 175 1.3 riastrad if (ret) { 176 1.3 riastrad kfree(obj); 177 1.3 riastrad return ERR_PTR(ret); 178 1.3 riastrad } 179 1.1 riastrad 180 1.3 riastrad mutex_init(&obj->pages_lock); 181 1.1 riastrad 182 1.3 riastrad return obj; 183 1.3 riastrad } 184 1.3 riastrad 185 1.3 riastrad static void __vgem_gem_destroy(struct drm_vgem_gem_object *obj) 186 1.3 riastrad { 187 1.3 riastrad drm_gem_object_release(&obj->base); 188 1.3 riastrad kfree(obj); 189 1.3 riastrad } 190 1.1 riastrad 191 1.3 riastrad static struct drm_gem_object *vgem_gem_create(struct drm_device *dev, 192 1.3 riastrad struct drm_file *file, 193 1.3 riastrad unsigned int *handle, 194 1.3 riastrad unsigned long size) 195 1.3 riastrad { 196 1.3 riastrad struct drm_vgem_gem_object *obj; 197 1.3 riastrad int ret; 198 1.1 riastrad 199 1.3 riastrad obj = __vgem_gem_create(dev, size); 200 1.3 riastrad if (IS_ERR(obj)) 201 1.3 riastrad return ERR_CAST(obj); 202 1.3 riastrad 203 1.3 riastrad ret = drm_gem_handle_create(file, &obj->base, handle); 204 1.3 riastrad if (ret) { 205 1.3 riastrad drm_gem_object_put_unlocked(&obj->base); 206 1.3 riastrad return ERR_PTR(ret); 207 1.3 riastrad } 208 1.1 riastrad 209 1.3 riastrad return &obj->base; 210 1.1 riastrad } 211 1.1 riastrad 212 1.1 riastrad static int vgem_gem_dumb_create(struct drm_file *file, struct drm_device *dev, 213 1.1 riastrad struct drm_mode_create_dumb *args) 214 1.1 riastrad { 215 1.1 riastrad struct drm_gem_object *gem_object; 216 1.3 riastrad u64 pitch, size; 217 1.1 riastrad 218 1.3 riastrad pitch = args->width * DIV_ROUND_UP(args->bpp, 8); 219 1.1 riastrad size = args->height * pitch; 220 1.1 riastrad if (size == 0) 221 1.1 riastrad return -EINVAL; 222 1.1 riastrad 223 1.1 riastrad gem_object = vgem_gem_create(dev, file, &args->handle, size); 224 1.3 riastrad if (IS_ERR(gem_object)) 225 1.1 riastrad return PTR_ERR(gem_object); 226 1.1 riastrad 227 1.1 riastrad args->size = gem_object->size; 228 1.1 riastrad args->pitch = pitch; 229 1.1 riastrad 230 1.3 riastrad drm_gem_object_put_unlocked(gem_object); 231 1.3 riastrad 232 1.3 riastrad DRM_DEBUG("Created object of size %llu\n", args->size); 233 1.1 riastrad 234 1.1 riastrad return 0; 235 1.1 riastrad } 236 1.1 riastrad 237 1.3 riastrad static int vgem_gem_dumb_map(struct drm_file *file, struct drm_device *dev, 238 1.3 riastrad uint32_t handle, uint64_t *offset) 239 1.1 riastrad { 240 1.1 riastrad struct drm_gem_object *obj; 241 1.3 riastrad int ret; 242 1.1 riastrad 243 1.3 riastrad obj = drm_gem_object_lookup(file, handle); 244 1.3 riastrad if (!obj) 245 1.3 riastrad return -ENOENT; 246 1.1 riastrad 247 1.3 riastrad if (!obj->filp) { 248 1.3 riastrad ret = -EINVAL; 249 1.3 riastrad goto unref; 250 1.1 riastrad } 251 1.1 riastrad 252 1.3 riastrad ret = drm_gem_create_mmap_offset(obj); 253 1.1 riastrad if (ret) 254 1.3 riastrad goto unref; 255 1.1 riastrad 256 1.1 riastrad *offset = drm_vma_node_offset_addr(&obj->vma_node); 257 1.3 riastrad unref: 258 1.3 riastrad drm_gem_object_put_unlocked(obj); 259 1.1 riastrad 260 1.1 riastrad return ret; 261 1.1 riastrad } 262 1.1 riastrad 263 1.1 riastrad static struct drm_ioctl_desc vgem_ioctls[] = { 264 1.3 riastrad DRM_IOCTL_DEF_DRV(VGEM_FENCE_ATTACH, vgem_fence_attach_ioctl, DRM_RENDER_ALLOW), 265 1.3 riastrad DRM_IOCTL_DEF_DRV(VGEM_FENCE_SIGNAL, vgem_fence_signal_ioctl, DRM_RENDER_ALLOW), 266 1.1 riastrad }; 267 1.1 riastrad 268 1.3 riastrad static int vgem_mmap(struct file *filp, struct vm_area_struct *vma) 269 1.3 riastrad { 270 1.3 riastrad unsigned long flags = vma->vm_flags; 271 1.3 riastrad int ret; 272 1.3 riastrad 273 1.3 riastrad ret = drm_gem_mmap(filp, vma); 274 1.3 riastrad if (ret) 275 1.3 riastrad return ret; 276 1.3 riastrad 277 1.3 riastrad /* Keep the WC mmaping set by drm_gem_mmap() but our pages 278 1.3 riastrad * are ordinary and not special. 279 1.3 riastrad */ 280 1.3 riastrad vma->vm_flags = flags | VM_DONTEXPAND | VM_DONTDUMP; 281 1.3 riastrad return 0; 282 1.3 riastrad } 283 1.3 riastrad 284 1.1 riastrad static const struct file_operations vgem_driver_fops = { 285 1.1 riastrad .owner = THIS_MODULE, 286 1.1 riastrad .open = drm_open, 287 1.3 riastrad .mmap = vgem_mmap, 288 1.1 riastrad .poll = drm_poll, 289 1.1 riastrad .read = drm_read, 290 1.1 riastrad .unlocked_ioctl = drm_ioctl, 291 1.3 riastrad .compat_ioctl = drm_compat_ioctl, 292 1.1 riastrad .release = drm_release, 293 1.1 riastrad }; 294 1.1 riastrad 295 1.3 riastrad static struct page **vgem_pin_pages(struct drm_vgem_gem_object *bo) 296 1.3 riastrad { 297 1.3 riastrad mutex_lock(&bo->pages_lock); 298 1.3 riastrad if (bo->pages_pin_count++ == 0) { 299 1.3 riastrad struct page **pages; 300 1.3 riastrad 301 1.3 riastrad pages = drm_gem_get_pages(&bo->base); 302 1.3 riastrad if (IS_ERR(pages)) { 303 1.3 riastrad bo->pages_pin_count--; 304 1.3 riastrad mutex_unlock(&bo->pages_lock); 305 1.3 riastrad return pages; 306 1.3 riastrad } 307 1.3 riastrad 308 1.3 riastrad bo->pages = pages; 309 1.3 riastrad } 310 1.3 riastrad mutex_unlock(&bo->pages_lock); 311 1.3 riastrad 312 1.3 riastrad return bo->pages; 313 1.3 riastrad } 314 1.3 riastrad 315 1.3 riastrad static void vgem_unpin_pages(struct drm_vgem_gem_object *bo) 316 1.3 riastrad { 317 1.3 riastrad mutex_lock(&bo->pages_lock); 318 1.3 riastrad if (--bo->pages_pin_count == 0) { 319 1.3 riastrad drm_gem_put_pages(&bo->base, bo->pages, true, true); 320 1.3 riastrad bo->pages = NULL; 321 1.3 riastrad } 322 1.3 riastrad mutex_unlock(&bo->pages_lock); 323 1.3 riastrad } 324 1.3 riastrad 325 1.3 riastrad static int vgem_prime_pin(struct drm_gem_object *obj) 326 1.3 riastrad { 327 1.3 riastrad struct drm_vgem_gem_object *bo = to_vgem_bo(obj); 328 1.3 riastrad long n_pages = obj->size >> PAGE_SHIFT; 329 1.3 riastrad struct page **pages; 330 1.3 riastrad 331 1.3 riastrad pages = vgem_pin_pages(bo); 332 1.3 riastrad if (IS_ERR(pages)) 333 1.3 riastrad return PTR_ERR(pages); 334 1.3 riastrad 335 1.3 riastrad /* Flush the object from the CPU cache so that importers can rely 336 1.3 riastrad * on coherent indirect access via the exported dma-address. 337 1.3 riastrad */ 338 1.3 riastrad drm_clflush_pages(pages, n_pages); 339 1.3 riastrad 340 1.3 riastrad return 0; 341 1.3 riastrad } 342 1.3 riastrad 343 1.3 riastrad static void vgem_prime_unpin(struct drm_gem_object *obj) 344 1.3 riastrad { 345 1.3 riastrad struct drm_vgem_gem_object *bo = to_vgem_bo(obj); 346 1.3 riastrad 347 1.3 riastrad vgem_unpin_pages(bo); 348 1.3 riastrad } 349 1.3 riastrad 350 1.3 riastrad static struct sg_table *vgem_prime_get_sg_table(struct drm_gem_object *obj) 351 1.3 riastrad { 352 1.3 riastrad struct drm_vgem_gem_object *bo = to_vgem_bo(obj); 353 1.3 riastrad 354 1.3 riastrad return drm_prime_pages_to_sg(bo->pages, bo->base.size >> PAGE_SHIFT); 355 1.3 riastrad } 356 1.3 riastrad 357 1.3 riastrad static struct drm_gem_object* vgem_prime_import(struct drm_device *dev, 358 1.3 riastrad struct dma_buf *dma_buf) 359 1.3 riastrad { 360 1.3 riastrad struct vgem_device *vgem = container_of(dev, typeof(*vgem), drm); 361 1.3 riastrad 362 1.3 riastrad return drm_gem_prime_import_dev(dev, dma_buf, &vgem->platform->dev); 363 1.3 riastrad } 364 1.3 riastrad 365 1.3 riastrad static struct drm_gem_object *vgem_prime_import_sg_table(struct drm_device *dev, 366 1.3 riastrad struct dma_buf_attachment *attach, struct sg_table *sg) 367 1.3 riastrad { 368 1.3 riastrad struct drm_vgem_gem_object *obj; 369 1.3 riastrad int npages; 370 1.3 riastrad 371 1.3 riastrad obj = __vgem_gem_create(dev, attach->dmabuf->size); 372 1.3 riastrad if (IS_ERR(obj)) 373 1.3 riastrad return ERR_CAST(obj); 374 1.3 riastrad 375 1.3 riastrad npages = PAGE_ALIGN(attach->dmabuf->size) / PAGE_SIZE; 376 1.3 riastrad 377 1.3 riastrad obj->table = sg; 378 1.3 riastrad obj->pages = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); 379 1.3 riastrad if (!obj->pages) { 380 1.3 riastrad __vgem_gem_destroy(obj); 381 1.3 riastrad return ERR_PTR(-ENOMEM); 382 1.3 riastrad } 383 1.3 riastrad 384 1.3 riastrad obj->pages_pin_count++; /* perma-pinned */ 385 1.3 riastrad drm_prime_sg_to_page_addr_arrays(obj->table, obj->pages, NULL, 386 1.3 riastrad npages); 387 1.3 riastrad return &obj->base; 388 1.3 riastrad } 389 1.3 riastrad 390 1.3 riastrad static void *vgem_prime_vmap(struct drm_gem_object *obj) 391 1.3 riastrad { 392 1.3 riastrad struct drm_vgem_gem_object *bo = to_vgem_bo(obj); 393 1.3 riastrad long n_pages = obj->size >> PAGE_SHIFT; 394 1.3 riastrad struct page **pages; 395 1.3 riastrad 396 1.3 riastrad pages = vgem_pin_pages(bo); 397 1.3 riastrad if (IS_ERR(pages)) 398 1.3 riastrad return NULL; 399 1.3 riastrad 400 1.3 riastrad return vmap(pages, n_pages, 0, pgprot_writecombine(PAGE_KERNEL)); 401 1.3 riastrad } 402 1.3 riastrad 403 1.3 riastrad static void vgem_prime_vunmap(struct drm_gem_object *obj, void *vaddr) 404 1.3 riastrad { 405 1.3 riastrad struct drm_vgem_gem_object *bo = to_vgem_bo(obj); 406 1.3 riastrad 407 1.3 riastrad vunmap(vaddr); 408 1.3 riastrad vgem_unpin_pages(bo); 409 1.3 riastrad } 410 1.3 riastrad 411 1.3 riastrad static int vgem_prime_mmap(struct drm_gem_object *obj, 412 1.3 riastrad struct vm_area_struct *vma) 413 1.3 riastrad { 414 1.3 riastrad int ret; 415 1.3 riastrad 416 1.3 riastrad if (obj->size < vma->vm_end - vma->vm_start) 417 1.3 riastrad return -EINVAL; 418 1.3 riastrad 419 1.3 riastrad if (!obj->filp) 420 1.3 riastrad return -ENODEV; 421 1.3 riastrad 422 1.3 riastrad ret = call_mmap(obj->filp, vma); 423 1.3 riastrad if (ret) 424 1.3 riastrad return ret; 425 1.3 riastrad 426 1.3 riastrad fput(vma->vm_file); 427 1.3 riastrad vma->vm_file = get_file(obj->filp); 428 1.3 riastrad vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; 429 1.3 riastrad vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); 430 1.3 riastrad 431 1.3 riastrad return 0; 432 1.3 riastrad } 433 1.3 riastrad 434 1.3 riastrad static void vgem_release(struct drm_device *dev) 435 1.3 riastrad { 436 1.3 riastrad struct vgem_device *vgem = container_of(dev, typeof(*vgem), drm); 437 1.3 riastrad 438 1.3 riastrad platform_device_unregister(vgem->platform); 439 1.3 riastrad drm_dev_fini(&vgem->drm); 440 1.3 riastrad 441 1.3 riastrad kfree(vgem); 442 1.3 riastrad } 443 1.3 riastrad 444 1.1 riastrad static struct drm_driver vgem_driver = { 445 1.3 riastrad .driver_features = DRIVER_GEM | DRIVER_RENDER, 446 1.3 riastrad .release = vgem_release, 447 1.3 riastrad .open = vgem_open, 448 1.3 riastrad .postclose = vgem_postclose, 449 1.3 riastrad .gem_free_object_unlocked = vgem_gem_free_object, 450 1.1 riastrad .gem_vm_ops = &vgem_gem_vm_ops, 451 1.1 riastrad .ioctls = vgem_ioctls, 452 1.3 riastrad .num_ioctls = ARRAY_SIZE(vgem_ioctls), 453 1.1 riastrad .fops = &vgem_driver_fops, 454 1.3 riastrad 455 1.1 riastrad .dumb_create = vgem_gem_dumb_create, 456 1.1 riastrad .dumb_map_offset = vgem_gem_dumb_map, 457 1.3 riastrad 458 1.3 riastrad .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 459 1.3 riastrad .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 460 1.3 riastrad .gem_prime_pin = vgem_prime_pin, 461 1.3 riastrad .gem_prime_unpin = vgem_prime_unpin, 462 1.3 riastrad .gem_prime_import = vgem_prime_import, 463 1.3 riastrad .gem_prime_import_sg_table = vgem_prime_import_sg_table, 464 1.3 riastrad .gem_prime_get_sg_table = vgem_prime_get_sg_table, 465 1.3 riastrad .gem_prime_vmap = vgem_prime_vmap, 466 1.3 riastrad .gem_prime_vunmap = vgem_prime_vunmap, 467 1.3 riastrad .gem_prime_mmap = vgem_prime_mmap, 468 1.3 riastrad 469 1.1 riastrad .name = DRIVER_NAME, 470 1.1 riastrad .desc = DRIVER_DESC, 471 1.1 riastrad .date = DRIVER_DATE, 472 1.1 riastrad .major = DRIVER_MAJOR, 473 1.1 riastrad .minor = DRIVER_MINOR, 474 1.1 riastrad }; 475 1.1 riastrad 476 1.1 riastrad static int __init vgem_init(void) 477 1.1 riastrad { 478 1.1 riastrad int ret; 479 1.1 riastrad 480 1.3 riastrad vgem_device = kzalloc(sizeof(*vgem_device), GFP_KERNEL); 481 1.3 riastrad if (!vgem_device) 482 1.3 riastrad return -ENOMEM; 483 1.3 riastrad 484 1.3 riastrad vgem_device->platform = 485 1.3 riastrad platform_device_register_simple("vgem", -1, NULL, 0); 486 1.3 riastrad if (IS_ERR(vgem_device->platform)) { 487 1.3 riastrad ret = PTR_ERR(vgem_device->platform); 488 1.3 riastrad goto out_free; 489 1.1 riastrad } 490 1.1 riastrad 491 1.3 riastrad dma_coerce_mask_and_coherent(&vgem_device->platform->dev, 492 1.3 riastrad DMA_BIT_MASK(64)); 493 1.3 riastrad ret = drm_dev_init(&vgem_device->drm, &vgem_driver, 494 1.3 riastrad &vgem_device->platform->dev); 495 1.3 riastrad if (ret) 496 1.3 riastrad goto out_unregister; 497 1.1 riastrad 498 1.3 riastrad /* Final step: expose the device/driver to userspace */ 499 1.3 riastrad ret = drm_dev_register(&vgem_device->drm, 0); 500 1.1 riastrad if (ret) 501 1.3 riastrad goto out_fini; 502 1.1 riastrad 503 1.1 riastrad return 0; 504 1.1 riastrad 505 1.3 riastrad out_fini: 506 1.3 riastrad drm_dev_fini(&vgem_device->drm); 507 1.3 riastrad out_unregister: 508 1.3 riastrad platform_device_unregister(vgem_device->platform); 509 1.3 riastrad out_free: 510 1.3 riastrad kfree(vgem_device); 511 1.1 riastrad return ret; 512 1.1 riastrad } 513 1.1 riastrad 514 1.1 riastrad static void __exit vgem_exit(void) 515 1.1 riastrad { 516 1.3 riastrad drm_dev_unregister(&vgem_device->drm); 517 1.3 riastrad drm_dev_put(&vgem_device->drm); 518 1.1 riastrad } 519 1.1 riastrad 520 1.1 riastrad module_init(vgem_init); 521 1.1 riastrad module_exit(vgem_exit); 522 1.1 riastrad 523 1.1 riastrad MODULE_AUTHOR("Red Hat, Inc."); 524 1.3 riastrad MODULE_AUTHOR("Intel Corporation"); 525 1.1 riastrad MODULE_DESCRIPTION(DRIVER_DESC); 526 1.1 riastrad MODULE_LICENSE("GPL and additional rights"); 527