xref: /OK3568_Linux_fs/kernel/drivers/rknpu/rknpu_fence.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) Rockchip Electronics Co.Ltd
4  * Author: Felix Zeng <felix.zeng@rock-chips.com>
5  */
6 
7 #include <linux/slab.h>
8 #include <linux/file.h>
9 #include <linux/dma-fence.h>
10 #include <linux/sync_file.h>
11 
12 #include "rknpu_drv.h"
13 #include "rknpu_job.h"
14 
15 #include "rknpu_fence.h"
16 
rknpu_fence_get_name(struct dma_fence * fence)17 static const char *rknpu_fence_get_name(struct dma_fence *fence)
18 {
19 	return DRIVER_NAME;
20 }
21 
22 static const struct dma_fence_ops rknpu_fence_ops = {
23 	.get_driver_name = rknpu_fence_get_name,
24 	.get_timeline_name = rknpu_fence_get_name,
25 };
26 
rknpu_fence_context_alloc(struct rknpu_device * rknpu_dev)27 int rknpu_fence_context_alloc(struct rknpu_device *rknpu_dev)
28 {
29 	struct rknpu_fence_context *fence_ctx = NULL;
30 
31 	fence_ctx =
32 		devm_kzalloc(rknpu_dev->dev, sizeof(*fence_ctx), GFP_KERNEL);
33 	if (!fence_ctx)
34 		return -ENOMEM;
35 
36 	fence_ctx->context = dma_fence_context_alloc(1);
37 	spin_lock_init(&fence_ctx->spinlock);
38 
39 	rknpu_dev->fence_ctx = fence_ctx;
40 
41 	return 0;
42 }
43 
rknpu_fence_alloc(struct rknpu_job * job)44 int rknpu_fence_alloc(struct rknpu_job *job)
45 {
46 	struct rknpu_fence_context *fence_ctx = job->rknpu_dev->fence_ctx;
47 	struct dma_fence *fence = NULL;
48 
49 	fence = kzalloc(sizeof(*fence), GFP_KERNEL);
50 	if (!fence)
51 		return -ENOMEM;
52 
53 	dma_fence_init(fence, &rknpu_fence_ops, &fence_ctx->spinlock,
54 		       fence_ctx->context, ++fence_ctx->seqno);
55 
56 	job->fence = fence;
57 
58 	return 0;
59 }
60 
rknpu_fence_get_fd(struct rknpu_job * job)61 int rknpu_fence_get_fd(struct rknpu_job *job)
62 {
63 	struct sync_file *sync_file = NULL;
64 	int fence_fd = -1;
65 
66 	if (!job->fence)
67 		return -EINVAL;
68 
69 	fence_fd = get_unused_fd_flags(O_CLOEXEC);
70 	if (fence_fd < 0)
71 		return fence_fd;
72 
73 	sync_file = sync_file_create(job->fence);
74 	if (!sync_file)
75 		return -ENOMEM;
76 
77 	fd_install(fence_fd, sync_file->file);
78 
79 	return fence_fd;
80 }
81