.. | .. |
---|
| 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 * |
---|