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; |