diff options
Diffstat (limited to 'drivers/gpu/drm/drm_syncobj.c')
| -rw-r--r-- | drivers/gpu/drm/drm_syncobj.c | 93 |
1 files changed, 70 insertions, 23 deletions
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 0422b8c2c2e7..f776fc1cc543 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c | |||
| @@ -262,8 +262,14 @@ void drm_syncobj_free(struct kref *kref) | |||
| 262 | } | 262 | } |
| 263 | EXPORT_SYMBOL(drm_syncobj_free); | 263 | EXPORT_SYMBOL(drm_syncobj_free); |
| 264 | 264 | ||
| 265 | static int drm_syncobj_create(struct drm_file *file_private, | 265 | /** |
| 266 | u32 *handle, uint32_t flags) | 266 | * drm_syncobj_create - create a new syncobj |
| 267 | * @out_syncobj: returned syncobj | ||
| 268 | * @flags: DRM_SYNCOBJ_* flags | ||
| 269 | * @fence: if non-NULL, the syncobj will represent this fence | ||
| 270 | */ | ||
| 271 | int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags, | ||
| 272 | struct dma_fence *fence) | ||
| 267 | { | 273 | { |
| 268 | int ret; | 274 | int ret; |
| 269 | struct drm_syncobj *syncobj; | 275 | struct drm_syncobj *syncobj; |
| @@ -284,6 +290,25 @@ static int drm_syncobj_create(struct drm_file *file_private, | |||
| 284 | } | 290 | } |
| 285 | } | 291 | } |
| 286 | 292 | ||
| 293 | if (fence) | ||
| 294 | drm_syncobj_replace_fence(syncobj, fence); | ||
| 295 | |||
| 296 | *out_syncobj = syncobj; | ||
| 297 | return 0; | ||
| 298 | } | ||
| 299 | EXPORT_SYMBOL(drm_syncobj_create); | ||
| 300 | |||
| 301 | /** | ||
| 302 | * drm_syncobj_get_handle - get a handle from a syncobj | ||
| 303 | */ | ||
| 304 | int drm_syncobj_get_handle(struct drm_file *file_private, | ||
| 305 | struct drm_syncobj *syncobj, u32 *handle) | ||
| 306 | { | ||
| 307 | int ret; | ||
| 308 | |||
| 309 | /* take a reference to put in the idr */ | ||
| 310 | drm_syncobj_get(syncobj); | ||
| 311 | |||
| 287 | idr_preload(GFP_KERNEL); | 312 | idr_preload(GFP_KERNEL); |
| 288 | spin_lock(&file_private->syncobj_table_lock); | 313 | spin_lock(&file_private->syncobj_table_lock); |
| 289 | ret = idr_alloc(&file_private->syncobj_idr, syncobj, 1, 0, GFP_NOWAIT); | 314 | ret = idr_alloc(&file_private->syncobj_idr, syncobj, 1, 0, GFP_NOWAIT); |
| @@ -299,6 +324,22 @@ static int drm_syncobj_create(struct drm_file *file_private, | |||
| 299 | *handle = ret; | 324 | *handle = ret; |
| 300 | return 0; | 325 | return 0; |
| 301 | } | 326 | } |
| 327 | EXPORT_SYMBOL(drm_syncobj_get_handle); | ||
| 328 | |||
| 329 | static int drm_syncobj_create_as_handle(struct drm_file *file_private, | ||
| 330 | u32 *handle, uint32_t flags) | ||
| 331 | { | ||
| 332 | int ret; | ||
| 333 | struct drm_syncobj *syncobj; | ||
| 334 | |||
| 335 | ret = drm_syncobj_create(&syncobj, flags, NULL); | ||
| 336 | if (ret) | ||
| 337 | return ret; | ||
| 338 | |||
| 339 | ret = drm_syncobj_get_handle(file_private, syncobj, handle); | ||
| 340 | drm_syncobj_put(syncobj); | ||
| 341 | return ret; | ||
| 342 | } | ||
| 302 | 343 | ||
| 303 | static int drm_syncobj_destroy(struct drm_file *file_private, | 344 | static int drm_syncobj_destroy(struct drm_file *file_private, |
| 304 | u32 handle) | 345 | u32 handle) |
| @@ -345,33 +386,38 @@ static int drm_syncobj_alloc_file(struct drm_syncobj *syncobj) | |||
| 345 | return 0; | 386 | return 0; |
| 346 | } | 387 | } |
| 347 | 388 | ||
| 348 | static int drm_syncobj_handle_to_fd(struct drm_file *file_private, | 389 | int drm_syncobj_get_fd(struct drm_syncobj *syncobj, int *p_fd) |
| 349 | u32 handle, int *p_fd) | ||
| 350 | { | 390 | { |
| 351 | struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle); | ||
| 352 | int ret; | 391 | int ret; |
| 353 | int fd; | 392 | int fd; |
| 354 | 393 | ||
| 355 | if (!syncobj) | ||
| 356 | return -EINVAL; | ||
| 357 | |||
| 358 | fd = get_unused_fd_flags(O_CLOEXEC); | 394 | fd = get_unused_fd_flags(O_CLOEXEC); |
| 359 | if (fd < 0) { | 395 | if (fd < 0) |
| 360 | drm_syncobj_put(syncobj); | ||
| 361 | return fd; | 396 | return fd; |
| 362 | } | ||
| 363 | 397 | ||
| 364 | if (!syncobj->file) { | 398 | if (!syncobj->file) { |
| 365 | ret = drm_syncobj_alloc_file(syncobj); | 399 | ret = drm_syncobj_alloc_file(syncobj); |
| 366 | if (ret) | 400 | if (ret) { |
| 367 | goto out_put_fd; | 401 | put_unused_fd(fd); |
| 402 | return ret; | ||
| 403 | } | ||
| 368 | } | 404 | } |
| 369 | fd_install(fd, syncobj->file); | 405 | fd_install(fd, syncobj->file); |
| 370 | drm_syncobj_put(syncobj); | ||
| 371 | *p_fd = fd; | 406 | *p_fd = fd; |
| 372 | return 0; | 407 | return 0; |
| 373 | out_put_fd: | 408 | } |
| 374 | put_unused_fd(fd); | 409 | EXPORT_SYMBOL(drm_syncobj_get_fd); |
| 410 | |||
| 411 | static int drm_syncobj_handle_to_fd(struct drm_file *file_private, | ||
| 412 | u32 handle, int *p_fd) | ||
| 413 | { | ||
| 414 | struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle); | ||
| 415 | int ret; | ||
| 416 | |||
| 417 | if (!syncobj) | ||
| 418 | return -EINVAL; | ||
| 419 | |||
| 420 | ret = drm_syncobj_get_fd(syncobj, p_fd); | ||
| 375 | drm_syncobj_put(syncobj); | 421 | drm_syncobj_put(syncobj); |
| 376 | return ret; | 422 | return ret; |
| 377 | } | 423 | } |
| @@ -417,8 +463,8 @@ static int drm_syncobj_fd_to_handle(struct drm_file *file_private, | |||
| 417 | return 0; | 463 | return 0; |
| 418 | } | 464 | } |
| 419 | 465 | ||
| 420 | int drm_syncobj_import_sync_file_fence(struct drm_file *file_private, | 466 | static int drm_syncobj_import_sync_file_fence(struct drm_file *file_private, |
| 421 | int fd, int handle) | 467 | int fd, int handle) |
| 422 | { | 468 | { |
| 423 | struct dma_fence *fence = sync_file_get_fence(fd); | 469 | struct dma_fence *fence = sync_file_get_fence(fd); |
| 424 | struct drm_syncobj *syncobj; | 470 | struct drm_syncobj *syncobj; |
| @@ -438,8 +484,8 @@ int drm_syncobj_import_sync_file_fence(struct drm_file *file_private, | |||
| 438 | return 0; | 484 | return 0; |
| 439 | } | 485 | } |
| 440 | 486 | ||
| 441 | int drm_syncobj_export_sync_file(struct drm_file *file_private, | 487 | static int drm_syncobj_export_sync_file(struct drm_file *file_private, |
| 442 | int handle, int *p_fd) | 488 | int handle, int *p_fd) |
| 443 | { | 489 | { |
| 444 | int ret; | 490 | int ret; |
| 445 | struct dma_fence *fence; | 491 | struct dma_fence *fence; |
| @@ -522,8 +568,8 @@ drm_syncobj_create_ioctl(struct drm_device *dev, void *data, | |||
| 522 | if (args->flags & ~DRM_SYNCOBJ_CREATE_SIGNALED) | 568 | if (args->flags & ~DRM_SYNCOBJ_CREATE_SIGNALED) |
| 523 | return -EINVAL; | 569 | return -EINVAL; |
| 524 | 570 | ||
| 525 | return drm_syncobj_create(file_private, | 571 | return drm_syncobj_create_as_handle(file_private, |
| 526 | &args->handle, args->flags); | 572 | &args->handle, args->flags); |
| 527 | } | 573 | } |
| 528 | 574 | ||
| 529 | int | 575 | int |
| @@ -799,7 +845,8 @@ static int drm_syncobj_array_wait(struct drm_device *dev, | |||
| 799 | } | 845 | } |
| 800 | 846 | ||
| 801 | static int drm_syncobj_array_find(struct drm_file *file_private, | 847 | static int drm_syncobj_array_find(struct drm_file *file_private, |
| 802 | void *user_handles, uint32_t count_handles, | 848 | void __user *user_handles, |
| 849 | uint32_t count_handles, | ||
| 803 | struct drm_syncobj ***syncobjs_out) | 850 | struct drm_syncobj ***syncobjs_out) |
| 804 | { | 851 | { |
| 805 | uint32_t i, *handles; | 852 | uint32_t i, *handles; |
