summaryrefslogtreecommitdiff
path: root/gxp-dma-fence.c
blob: 900ea233072a2798c4cc152592d0ab507861e585 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// SPDX-License-Identifier: GPL-2.0
/*
 * GXP support for DMA fence.
 *
 * Copyright (C) 2023 Google LLC
 */

#include <linux/slab.h>

#include <gcip/gcip-dma-fence.h>

#include "gxp-dma-fence.h"
#include "gxp-internal.h"
#include "gxp-vd.h"
#include "gxp.h"

static const char *gxp_get_driver_name(struct dma_fence *fence)
{
	return GXP_NAME;
}

static void gxp_dma_fence_release(struct dma_fence *fence)
{
	struct gxp_dma_fence *gxp_fence = to_gxp_fence(fence);

	gcip_dma_fence_exit(&gxp_fence->gfence);
	kfree(gxp_fence);
}

static const struct dma_fence_ops gxp_dma_fence_ops = {
	.get_driver_name = gxp_get_driver_name,
	.get_timeline_name = gcip_dma_fence_get_timeline_name,
	.wait = dma_fence_default_wait,
	.enable_signaling = gcip_dma_fence_always_true,
	.release = gxp_dma_fence_release,
};

int gxp_dma_fence_create(struct gxp_dev *gxp, struct gxp_virtual_device *vd,
			 struct gxp_create_sync_fence_data *datap)
{
	struct gcip_dma_fence_data data = {
		.timeline_name = datap->timeline_name,
		.ops = &gxp_dma_fence_ops,
		.seqno = datap->seqno,
	};
	struct gxp_dma_fence *gxp_fence =
		kzalloc(sizeof(*gxp_fence), GFP_KERNEL);
	int ret;

	if (!gxp_fence)
		return -ENOMEM;

	/* TODO(b/264855736): add VD association support */

	ret = gcip_dma_fence_init(gxp->gfence_mgr, &gxp_fence->gfence, &data);
	if (!ret)
		datap->fence = data.fence;
	/*
	 * We don't need to kfree(gxp_fence) on error because that's called in
	 * gxp_dma_fence_release.
	 */

	return ret;
}