| .. | .. |
|---|
| 30 | 30 | * software renderer and the X server for efficient buffer sharing. |
|---|
| 31 | 31 | */ |
|---|
| 32 | 32 | |
|---|
| 33 | | -#include <linux/module.h> |
|---|
| 34 | | -#include <linux/ramfs.h> |
|---|
| 35 | | -#include <linux/shmem_fs.h> |
|---|
| 36 | 33 | #include <linux/dma-buf.h> |
|---|
| 34 | +#include <linux/module.h> |
|---|
| 35 | +#include <linux/platform_device.h> |
|---|
| 36 | +#include <linux/shmem_fs.h> |
|---|
| 37 | +#include <linux/vmalloc.h> |
|---|
| 38 | + |
|---|
| 39 | +#include <drm/drm_drv.h> |
|---|
| 40 | +#include <drm/drm_file.h> |
|---|
| 41 | +#include <drm/drm_ioctl.h> |
|---|
| 42 | +#include <drm/drm_managed.h> |
|---|
| 43 | +#include <drm/drm_prime.h> |
|---|
| 44 | + |
|---|
| 37 | 45 | #include "vgem_drv.h" |
|---|
| 38 | 46 | |
|---|
| 39 | 47 | #define DRIVER_NAME "vgem" |
|---|
| .. | .. |
|---|
| 189 | 197 | return ERR_CAST(obj); |
|---|
| 190 | 198 | |
|---|
| 191 | 199 | ret = drm_gem_handle_create(file, &obj->base, handle); |
|---|
| 192 | | - drm_gem_object_put_unlocked(&obj->base); |
|---|
| 193 | | - if (ret) |
|---|
| 200 | + if (ret) { |
|---|
| 201 | + drm_gem_object_put(&obj->base); |
|---|
| 194 | 202 | return ERR_PTR(ret); |
|---|
| 203 | + } |
|---|
| 195 | 204 | |
|---|
| 196 | 205 | return &obj->base; |
|---|
| 197 | 206 | } |
|---|
| .. | .. |
|---|
| 214 | 223 | args->size = gem_object->size; |
|---|
| 215 | 224 | args->pitch = pitch; |
|---|
| 216 | 225 | |
|---|
| 217 | | - DRM_DEBUG_DRIVER("Created object of size %lld\n", size); |
|---|
| 226 | + drm_gem_object_put(gem_object); |
|---|
| 227 | + |
|---|
| 228 | + DRM_DEBUG("Created object of size %llu\n", args->size); |
|---|
| 218 | 229 | |
|---|
| 219 | 230 | return 0; |
|---|
| 220 | 231 | } |
|---|
| 221 | 232 | |
|---|
| 222 | 233 | static struct drm_ioctl_desc vgem_ioctls[] = { |
|---|
| 223 | | - DRM_IOCTL_DEF_DRV(VGEM_FENCE_ATTACH, vgem_fence_attach_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), |
|---|
| 224 | | - DRM_IOCTL_DEF_DRV(VGEM_FENCE_SIGNAL, vgem_fence_signal_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), |
|---|
| 234 | + DRM_IOCTL_DEF_DRV(VGEM_FENCE_ATTACH, vgem_fence_attach_ioctl, DRM_RENDER_ALLOW), |
|---|
| 235 | + DRM_IOCTL_DEF_DRV(VGEM_FENCE_SIGNAL, vgem_fence_signal_ioctl, DRM_RENDER_ALLOW), |
|---|
| 225 | 236 | }; |
|---|
| 226 | 237 | |
|---|
| 227 | 238 | static int vgem_mmap(struct file *filp, struct vm_area_struct *vma) |
|---|
| .. | .. |
|---|
| 310 | 321 | { |
|---|
| 311 | 322 | struct drm_vgem_gem_object *bo = to_vgem_bo(obj); |
|---|
| 312 | 323 | |
|---|
| 313 | | - return drm_prime_pages_to_sg(bo->pages, bo->base.size >> PAGE_SHIFT); |
|---|
| 324 | + return drm_prime_pages_to_sg(obj->dev, bo->pages, bo->base.size >> PAGE_SHIFT); |
|---|
| 314 | 325 | } |
|---|
| 315 | 326 | |
|---|
| 316 | 327 | static struct drm_gem_object* vgem_prime_import(struct drm_device *dev, |
|---|
| .. | .. |
|---|
| 390 | 401 | return 0; |
|---|
| 391 | 402 | } |
|---|
| 392 | 403 | |
|---|
| 393 | | -static void vgem_release(struct drm_device *dev) |
|---|
| 394 | | -{ |
|---|
| 395 | | - struct vgem_device *vgem = container_of(dev, typeof(*vgem), drm); |
|---|
| 396 | | - |
|---|
| 397 | | - platform_device_unregister(vgem->platform); |
|---|
| 398 | | - drm_dev_fini(&vgem->drm); |
|---|
| 399 | | - |
|---|
| 400 | | - kfree(vgem); |
|---|
| 401 | | -} |
|---|
| 402 | | - |
|---|
| 403 | 404 | static struct drm_driver vgem_driver = { |
|---|
| 404 | | - .driver_features = DRIVER_GEM | DRIVER_PRIME, |
|---|
| 405 | | - .release = vgem_release, |
|---|
| 405 | + .driver_features = DRIVER_GEM | DRIVER_RENDER, |
|---|
| 406 | 406 | .open = vgem_open, |
|---|
| 407 | 407 | .postclose = vgem_postclose, |
|---|
| 408 | 408 | .gem_free_object_unlocked = vgem_gem_free_object, |
|---|
| .. | .. |
|---|
| 418 | 418 | .gem_prime_pin = vgem_prime_pin, |
|---|
| 419 | 419 | .gem_prime_unpin = vgem_prime_unpin, |
|---|
| 420 | 420 | .gem_prime_import = vgem_prime_import, |
|---|
| 421 | | - .gem_prime_export = drm_gem_prime_export, |
|---|
| 422 | 421 | .gem_prime_import_sg_table = vgem_prime_import_sg_table, |
|---|
| 423 | 422 | .gem_prime_get_sg_table = vgem_prime_get_sg_table, |
|---|
| 424 | 423 | .gem_prime_vmap = vgem_prime_vmap, |
|---|
| .. | .. |
|---|
| 435 | 434 | static int __init vgem_init(void) |
|---|
| 436 | 435 | { |
|---|
| 437 | 436 | int ret; |
|---|
| 437 | + struct platform_device *pdev; |
|---|
| 438 | 438 | |
|---|
| 439 | | - vgem_device = kzalloc(sizeof(*vgem_device), GFP_KERNEL); |
|---|
| 440 | | - if (!vgem_device) |
|---|
| 441 | | - return -ENOMEM; |
|---|
| 439 | + pdev = platform_device_register_simple("vgem", -1, NULL, 0); |
|---|
| 440 | + if (IS_ERR(pdev)) |
|---|
| 441 | + return PTR_ERR(pdev); |
|---|
| 442 | 442 | |
|---|
| 443 | | - vgem_device->platform = |
|---|
| 444 | | - platform_device_register_simple("vgem", -1, NULL, 0); |
|---|
| 445 | | - if (IS_ERR(vgem_device->platform)) { |
|---|
| 446 | | - ret = PTR_ERR(vgem_device->platform); |
|---|
| 447 | | - goto out_free; |
|---|
| 443 | + if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL)) { |
|---|
| 444 | + ret = -ENOMEM; |
|---|
| 445 | + goto out_unregister; |
|---|
| 448 | 446 | } |
|---|
| 449 | 447 | |
|---|
| 450 | | - dma_coerce_mask_and_coherent(&vgem_device->platform->dev, |
|---|
| 448 | + dma_coerce_mask_and_coherent(&pdev->dev, |
|---|
| 451 | 449 | DMA_BIT_MASK(64)); |
|---|
| 452 | | - ret = drm_dev_init(&vgem_device->drm, &vgem_driver, |
|---|
| 453 | | - &vgem_device->platform->dev); |
|---|
| 454 | | - if (ret) |
|---|
| 455 | | - goto out_unregister; |
|---|
| 450 | + |
|---|
| 451 | + vgem_device = devm_drm_dev_alloc(&pdev->dev, &vgem_driver, |
|---|
| 452 | + struct vgem_device, drm); |
|---|
| 453 | + if (IS_ERR(vgem_device)) { |
|---|
| 454 | + ret = PTR_ERR(vgem_device); |
|---|
| 455 | + goto out_devres; |
|---|
| 456 | + } |
|---|
| 457 | + vgem_device->platform = pdev; |
|---|
| 456 | 458 | |
|---|
| 457 | 459 | /* Final step: expose the device/driver to userspace */ |
|---|
| 458 | | - ret = drm_dev_register(&vgem_device->drm, 0); |
|---|
| 460 | + ret = drm_dev_register(&vgem_device->drm, 0); |
|---|
| 459 | 461 | if (ret) |
|---|
| 460 | | - goto out_fini; |
|---|
| 462 | + goto out_devres; |
|---|
| 461 | 463 | |
|---|
| 462 | 464 | return 0; |
|---|
| 463 | 465 | |
|---|
| 464 | | -out_fini: |
|---|
| 465 | | - drm_dev_fini(&vgem_device->drm); |
|---|
| 466 | +out_devres: |
|---|
| 467 | + devres_release_group(&pdev->dev, NULL); |
|---|
| 466 | 468 | out_unregister: |
|---|
| 467 | | - platform_device_unregister(vgem_device->platform); |
|---|
| 468 | | -out_free: |
|---|
| 469 | | - kfree(vgem_device); |
|---|
| 469 | + platform_device_unregister(pdev); |
|---|
| 470 | 470 | return ret; |
|---|
| 471 | 471 | } |
|---|
| 472 | 472 | |
|---|
| 473 | 473 | static void __exit vgem_exit(void) |
|---|
| 474 | 474 | { |
|---|
| 475 | + struct platform_device *pdev = vgem_device->platform; |
|---|
| 476 | + |
|---|
| 475 | 477 | drm_dev_unregister(&vgem_device->drm); |
|---|
| 476 | | - drm_dev_unref(&vgem_device->drm); |
|---|
| 478 | + devres_release_group(&pdev->dev, NULL); |
|---|
| 479 | + platform_device_unregister(pdev); |
|---|
| 477 | 480 | } |
|---|
| 478 | 481 | |
|---|
| 479 | 482 | module_init(vgem_init); |
|---|