diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index c6a214f1e991..ab83dfcabb41 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |||
@@ -25,6 +25,7 @@ | |||
25 | * Jerome Glisse <glisse@freedesktop.org> | 25 | * Jerome Glisse <glisse@freedesktop.org> |
26 | */ | 26 | */ |
27 | #include <linux/pagemap.h> | 27 | #include <linux/pagemap.h> |
28 | #include <linux/sync_file.h> | ||
28 | #include <drm/drmP.h> | 29 | #include <drm/drmP.h> |
29 | #include <drm/amdgpu_drm.h> | 30 | #include <drm/amdgpu_drm.h> |
30 | #include <drm/drm_syncobj.h> | 31 | #include <drm/drm_syncobj.h> |
@@ -1330,6 +1331,66 @@ static struct dma_fence *amdgpu_cs_get_fence(struct amdgpu_device *adev, | |||
1330 | return fence; | 1331 | return fence; |
1331 | } | 1332 | } |
1332 | 1333 | ||
1334 | int amdgpu_cs_fence_to_handle_ioctl(struct drm_device *dev, void *data, | ||
1335 | struct drm_file *filp) | ||
1336 | { | ||
1337 | struct amdgpu_device *adev = dev->dev_private; | ||
1338 | struct amdgpu_fpriv *fpriv = filp->driver_priv; | ||
1339 | union drm_amdgpu_fence_to_handle *info = data; | ||
1340 | struct dma_fence *fence; | ||
1341 | struct drm_syncobj *syncobj; | ||
1342 | struct sync_file *sync_file; | ||
1343 | int fd, r; | ||
1344 | |||
1345 | if (amdgpu_kms_vram_lost(adev, fpriv)) | ||
1346 | return -ENODEV; | ||
1347 | |||
1348 | fence = amdgpu_cs_get_fence(adev, filp, &info->in.fence); | ||
1349 | if (IS_ERR(fence)) | ||
1350 | return PTR_ERR(fence); | ||
1351 | |||
1352 | switch (info->in.what) { | ||
1353 | case AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ: | ||
1354 | r = drm_syncobj_create(&syncobj, 0, fence); | ||
1355 | dma_fence_put(fence); | ||
1356 | if (r) | ||
1357 | return r; | ||
1358 | r = drm_syncobj_get_handle(filp, syncobj, &info->out.handle); | ||
1359 | drm_syncobj_put(syncobj); | ||
1360 | return r; | ||
1361 | |||
1362 | case AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ_FD: | ||
1363 | r = drm_syncobj_create(&syncobj, 0, fence); | ||
1364 | dma_fence_put(fence); | ||
1365 | if (r) | ||
1366 | return r; | ||
1367 | r = drm_syncobj_get_fd(syncobj, (int*)&info->out.handle); | ||
1368 | drm_syncobj_put(syncobj); | ||
1369 | return r; | ||
1370 | |||
1371 | case AMDGPU_FENCE_TO_HANDLE_GET_SYNC_FILE_FD: | ||
1372 | fd = get_unused_fd_flags(O_CLOEXEC); | ||
1373 | if (fd < 0) { | ||
1374 | dma_fence_put(fence); | ||
1375 | return fd; | ||
1376 | } | ||
1377 | |||
1378 | sync_file = sync_file_create(fence); | ||
1379 | dma_fence_put(fence); | ||
1380 | if (!sync_file) { | ||
1381 | put_unused_fd(fd); | ||
1382 | return -ENOMEM; | ||
1383 | } | ||
1384 | |||
1385 | fd_install(fd, sync_file->file); | ||
1386 | info->out.handle = fd; | ||
1387 | return 0; | ||
1388 | |||
1389 | default: | ||
1390 | return -EINVAL; | ||
1391 | } | ||
1392 | } | ||
1393 | |||
1333 | /** | 1394 | /** |
1334 | * amdgpu_cs_wait_all_fence - wait on all fences to signal | 1395 | * amdgpu_cs_wait_all_fence - wait on all fences to signal |
1335 | * | 1396 | * |