| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2012 Russell King |
|---|
| 3 | | - * |
|---|
| 4 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 5 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 6 | | - * published by the Free Software Foundation. |
|---|
| 7 | 4 | */ |
|---|
| 5 | + |
|---|
| 8 | 6 | #include <linux/dma-buf.h> |
|---|
| 9 | 7 | #include <linux/dma-mapping.h> |
|---|
| 8 | +#include <linux/mman.h> |
|---|
| 10 | 9 | #include <linux/shmem_fs.h> |
|---|
| 10 | + |
|---|
| 11 | +#include <drm/armada_drm.h> |
|---|
| 12 | +#include <drm/drm_prime.h> |
|---|
| 13 | + |
|---|
| 11 | 14 | #include "armada_drm.h" |
|---|
| 12 | 15 | #include "armada_gem.h" |
|---|
| 13 | | -#include <drm/armada_drm.h> |
|---|
| 14 | 16 | #include "armada_ioctlP.h" |
|---|
| 15 | 17 | |
|---|
| 16 | 18 | static vm_fault_t armada_gem_vm_fault(struct vm_fault *vmf) |
|---|
| .. | .. |
|---|
| 37 | 39 | void armada_gem_free_object(struct drm_gem_object *obj) |
|---|
| 38 | 40 | { |
|---|
| 39 | 41 | struct armada_gem_object *dobj = drm_to_armada_gem(obj); |
|---|
| 40 | | - struct armada_private *priv = obj->dev->dev_private; |
|---|
| 42 | + struct armada_private *priv = drm_to_armada_dev(obj->dev); |
|---|
| 41 | 43 | |
|---|
| 42 | 44 | DRM_DEBUG_DRIVER("release obj %p\n", dobj); |
|---|
| 43 | 45 | |
|---|
| .. | .. |
|---|
| 75 | 77 | int |
|---|
| 76 | 78 | armada_gem_linear_back(struct drm_device *dev, struct armada_gem_object *obj) |
|---|
| 77 | 79 | { |
|---|
| 78 | | - struct armada_private *priv = dev->dev_private; |
|---|
| 80 | + struct armada_private *priv = drm_to_armada_dev(dev); |
|---|
| 79 | 81 | size_t size = obj->obj.size; |
|---|
| 80 | 82 | |
|---|
| 81 | 83 | if (obj->page || obj->linear) |
|---|
| .. | .. |
|---|
| 254 | 256 | /* drop reference from allocate - handle holds it now */ |
|---|
| 255 | 257 | DRM_DEBUG_DRIVER("obj %p size %zu handle %#x\n", dobj, size, handle); |
|---|
| 256 | 258 | err: |
|---|
| 257 | | - drm_gem_object_put_unlocked(&dobj->obj); |
|---|
| 259 | + drm_gem_object_put(&dobj->obj); |
|---|
| 258 | 260 | return ret; |
|---|
| 259 | 261 | } |
|---|
| 260 | 262 | |
|---|
| .. | .. |
|---|
| 286 | 288 | /* drop reference from allocate - handle holds it now */ |
|---|
| 287 | 289 | DRM_DEBUG_DRIVER("obj %p size %zu handle %#x\n", dobj, size, handle); |
|---|
| 288 | 290 | err: |
|---|
| 289 | | - drm_gem_object_put_unlocked(&dobj->obj); |
|---|
| 291 | + drm_gem_object_put(&dobj->obj); |
|---|
| 290 | 292 | return ret; |
|---|
| 291 | 293 | } |
|---|
| 292 | 294 | |
|---|
| .. | .. |
|---|
| 303 | 305 | return -ENOENT; |
|---|
| 304 | 306 | |
|---|
| 305 | 307 | if (!dobj->obj.filp) { |
|---|
| 306 | | - drm_gem_object_put_unlocked(&dobj->obj); |
|---|
| 308 | + drm_gem_object_put(&dobj->obj); |
|---|
| 307 | 309 | return -EINVAL; |
|---|
| 308 | 310 | } |
|---|
| 309 | 311 | |
|---|
| 310 | 312 | addr = vm_mmap(dobj->obj.filp, 0, args->size, PROT_READ | PROT_WRITE, |
|---|
| 311 | 313 | MAP_SHARED, args->offset); |
|---|
| 312 | | - drm_gem_object_put_unlocked(&dobj->obj); |
|---|
| 314 | + drm_gem_object_put(&dobj->obj); |
|---|
| 313 | 315 | if (IS_ERR_VALUE(addr)) |
|---|
| 314 | 316 | return addr; |
|---|
| 315 | 317 | |
|---|
| .. | .. |
|---|
| 334 | 336 | |
|---|
| 335 | 337 | ptr = (char __user *)(uintptr_t)args->ptr; |
|---|
| 336 | 338 | |
|---|
| 337 | | - if (!access_ok(VERIFY_READ, ptr, args->size)) |
|---|
| 339 | + if (!access_ok(ptr, args->size)) |
|---|
| 338 | 340 | return -EFAULT; |
|---|
| 339 | 341 | |
|---|
| 340 | 342 | ret = fault_in_pages_readable(ptr, args->size); |
|---|
| .. | .. |
|---|
| 364 | 366 | } |
|---|
| 365 | 367 | |
|---|
| 366 | 368 | unref: |
|---|
| 367 | | - drm_gem_object_put_unlocked(&dobj->obj); |
|---|
| 369 | + drm_gem_object_put(&dobj->obj); |
|---|
| 368 | 370 | return ret; |
|---|
| 369 | 371 | } |
|---|
| 370 | 372 | |
|---|
| .. | .. |
|---|
| 377 | 379 | struct armada_gem_object *dobj = drm_to_armada_gem(obj); |
|---|
| 378 | 380 | struct scatterlist *sg; |
|---|
| 379 | 381 | struct sg_table *sgt; |
|---|
| 380 | | - int i, num; |
|---|
| 382 | + int i; |
|---|
| 381 | 383 | |
|---|
| 382 | 384 | sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); |
|---|
| 383 | 385 | if (!sgt) |
|---|
| .. | .. |
|---|
| 393 | 395 | |
|---|
| 394 | 396 | mapping = dobj->obj.filp->f_mapping; |
|---|
| 395 | 397 | |
|---|
| 396 | | - for_each_sg(sgt->sgl, sg, count, i) { |
|---|
| 398 | + for_each_sgtable_sg(sgt, sg, i) { |
|---|
| 397 | 399 | struct page *page; |
|---|
| 398 | 400 | |
|---|
| 399 | 401 | page = shmem_read_mapping_page(mapping, i); |
|---|
| 400 | | - if (IS_ERR(page)) { |
|---|
| 401 | | - num = i; |
|---|
| 402 | + if (IS_ERR(page)) |
|---|
| 402 | 403 | goto release; |
|---|
| 403 | | - } |
|---|
| 404 | 404 | |
|---|
| 405 | 405 | sg_set_page(sg, page, PAGE_SIZE, 0); |
|---|
| 406 | 406 | } |
|---|
| 407 | 407 | |
|---|
| 408 | | - if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0) { |
|---|
| 409 | | - num = sgt->nents; |
|---|
| 408 | + if (dma_map_sgtable(attach->dev, sgt, dir, 0)) |
|---|
| 410 | 409 | goto release; |
|---|
| 411 | | - } |
|---|
| 412 | 410 | } else if (dobj->page) { |
|---|
| 413 | 411 | /* Single contiguous page */ |
|---|
| 414 | 412 | if (sg_alloc_table(sgt, 1, GFP_KERNEL)) |
|---|
| .. | .. |
|---|
| 416 | 414 | |
|---|
| 417 | 415 | sg_set_page(sgt->sgl, dobj->page, dobj->obj.size, 0); |
|---|
| 418 | 416 | |
|---|
| 419 | | - if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0) |
|---|
| 417 | + if (dma_map_sgtable(attach->dev, sgt, dir, 0)) |
|---|
| 420 | 418 | goto free_table; |
|---|
| 421 | 419 | } else if (dobj->linear) { |
|---|
| 422 | 420 | /* Single contiguous physical region - no struct page */ |
|---|
| .. | .. |
|---|
| 430 | 428 | return sgt; |
|---|
| 431 | 429 | |
|---|
| 432 | 430 | release: |
|---|
| 433 | | - for_each_sg(sgt->sgl, sg, num, i) |
|---|
| 434 | | - put_page(sg_page(sg)); |
|---|
| 431 | + for_each_sgtable_sg(sgt, sg, i) |
|---|
| 432 | + if (sg_page(sg)) |
|---|
| 433 | + put_page(sg_page(sg)); |
|---|
| 435 | 434 | free_table: |
|---|
| 436 | 435 | sg_free_table(sgt); |
|---|
| 437 | 436 | free_sgt: |
|---|
| .. | .. |
|---|
| 447 | 446 | int i; |
|---|
| 448 | 447 | |
|---|
| 449 | 448 | if (!dobj->linear) |
|---|
| 450 | | - dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir); |
|---|
| 449 | + dma_unmap_sgtable(attach->dev, sgt, dir, 0); |
|---|
| 451 | 450 | |
|---|
| 452 | 451 | if (dobj->obj.filp) { |
|---|
| 453 | 452 | struct scatterlist *sg; |
|---|
| 454 | | - for_each_sg(sgt->sgl, sg, sgt->nents, i) |
|---|
| 453 | + |
|---|
| 454 | + for_each_sgtable_sg(sgt, sg, i) |
|---|
| 455 | 455 | put_page(sg_page(sg)); |
|---|
| 456 | 456 | } |
|---|
| 457 | 457 | |
|---|
| 458 | 458 | sg_free_table(sgt); |
|---|
| 459 | 459 | kfree(sgt); |
|---|
| 460 | | -} |
|---|
| 461 | | - |
|---|
| 462 | | -static void *armada_gem_dmabuf_no_kmap(struct dma_buf *buf, unsigned long n) |
|---|
| 463 | | -{ |
|---|
| 464 | | - return NULL; |
|---|
| 465 | | -} |
|---|
| 466 | | - |
|---|
| 467 | | -static void |
|---|
| 468 | | -armada_gem_dmabuf_no_kunmap(struct dma_buf *buf, unsigned long n, void *addr) |
|---|
| 469 | | -{ |
|---|
| 470 | 460 | } |
|---|
| 471 | 461 | |
|---|
| 472 | 462 | static int |
|---|
| .. | .. |
|---|
| 479 | 469 | .map_dma_buf = armada_gem_prime_map_dma_buf, |
|---|
| 480 | 470 | .unmap_dma_buf = armada_gem_prime_unmap_dma_buf, |
|---|
| 481 | 471 | .release = drm_gem_dmabuf_release, |
|---|
| 482 | | - .map = armada_gem_dmabuf_no_kmap, |
|---|
| 483 | | - .unmap = armada_gem_dmabuf_no_kunmap, |
|---|
| 484 | 472 | .mmap = armada_gem_dmabuf_mmap, |
|---|
| 485 | 473 | }; |
|---|
| 486 | 474 | |
|---|
| 487 | 475 | struct dma_buf * |
|---|
| 488 | | -armada_gem_prime_export(struct drm_device *dev, struct drm_gem_object *obj, |
|---|
| 489 | | - int flags) |
|---|
| 476 | +armada_gem_prime_export(struct drm_gem_object *obj, int flags) |
|---|
| 490 | 477 | { |
|---|
| 491 | 478 | DEFINE_DMA_BUF_EXPORT_INFO(exp_info); |
|---|
| 492 | 479 | |
|---|
| .. | .. |
|---|
| 495 | 482 | exp_info.flags = O_RDWR; |
|---|
| 496 | 483 | exp_info.priv = obj; |
|---|
| 497 | 484 | |
|---|
| 498 | | - return drm_gem_dmabuf_export(dev, &exp_info); |
|---|
| 485 | + return drm_gem_dmabuf_export(obj->dev, &exp_info); |
|---|
| 499 | 486 | } |
|---|
| 500 | 487 | |
|---|
| 501 | 488 | struct drm_gem_object * |
|---|