aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_syncobj.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_syncobj.c')
-rw-r--r--drivers/gpu/drm/drm_syncobj.c93
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}
263EXPORT_SYMBOL(drm_syncobj_free); 263EXPORT_SYMBOL(drm_syncobj_free);
264 264
265static 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 */
271int 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}
299EXPORT_SYMBOL(drm_syncobj_create);
300
301/**
302 * drm_syncobj_get_handle - get a handle from a syncobj
303 */
304int 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}
327EXPORT_SYMBOL(drm_syncobj_get_handle);
328
329static 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
303static int drm_syncobj_destroy(struct drm_file *file_private, 344static 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
348static int drm_syncobj_handle_to_fd(struct drm_file *file_private, 389int 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;
373out_put_fd: 408}
374 put_unused_fd(fd); 409EXPORT_SYMBOL(drm_syncobj_get_fd);
410
411static 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
420int drm_syncobj_import_sync_file_fence(struct drm_file *file_private, 466static 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
441int drm_syncobj_export_sync_file(struct drm_file *file_private, 487static 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
529int 575int
@@ -799,7 +845,8 @@ static int drm_syncobj_array_wait(struct drm_device *dev,
799} 845}
800 846
801static int drm_syncobj_array_find(struct drm_file *file_private, 847static 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;