2 * Copyright (c) 2019 Jonathan Gray <jsg@openbsd.org>
3 * Copyright (c) 2020 François Tigeot <ftigeot@wolfpond.org>
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 #ifndef _LINUX_DMA_FENCE_H_
26 #define _LINUX_DMA_FENCE_H_
28 #include <linux/err.h>
29 #include <linux/wait.h>
30 #include <linux/list.h>
31 #include <linux/bitops.h>
32 #include <linux/kref.h>
33 #include <linux/sched.h>
34 #include <linux/printk.h>
35 #include <linux/rcupdate.h>
37 #define DMA_FENCE_TRACE(fence, fmt, args...) do {} while(0)
44 const struct dma_fence_ops *ops;
46 struct list_head cb_list;
54 enum dma_fence_flag_bits {
55 DMA_FENCE_FLAG_SIGNALED_BIT,
56 DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT,
57 DMA_FENCE_FLAG_USER_BITS, /* must always be last member */
60 typedef void (*dma_fence_func_t)(struct dma_fence *fence,
61 struct dma_fence_cb *cb);
64 struct list_head node;
65 dma_fence_func_t func;
68 struct dma_fence_ops {
69 const char * (*get_driver_name)(struct dma_fence *fence);
70 const char * (*get_timeline_name)(struct dma_fence *fence);
71 bool (*enable_signaling)(struct dma_fence *fence);
72 bool (*signaled)(struct dma_fence *fence);
73 signed long (*wait)(struct dma_fence *fence,
74 bool intr, signed long timeout);
75 void (*release)(struct dma_fence *fence);
77 int (*fill_driver_data)(struct dma_fence *fence, void *data, int size);
78 void (*fence_value_str)(struct dma_fence *fence, char *str, int size);
79 void (*timeline_value_str)(struct dma_fence *fence,
83 void dma_fence_init(struct dma_fence *fence, const struct dma_fence_ops *ops,
84 spinlock_t *lock, u64 context, unsigned seqno);
86 void dma_fence_release(struct kref *kref);
88 static inline struct dma_fence *
89 dma_fence_get(struct dma_fence *fence)
92 kref_get(&fence->refcount);
96 static inline struct dma_fence *
97 dma_fence_get_rcu(struct dma_fence *fence)
100 kref_get(&fence->refcount);
105 dma_fence_put(struct dma_fence *fence)
108 kref_put(&fence->refcount, dma_fence_release);
111 int dma_fence_signal(struct dma_fence *fence);
112 int dma_fence_signal_locked(struct dma_fence *fence);
115 dma_fence_is_signaled(struct dma_fence *fence)
117 if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
120 if (fence->ops->signaled && fence->ops->signaled(fence)) {
121 dma_fence_signal(fence);
128 void dma_fence_enable_sw_signaling(struct dma_fence *fence);
130 signed long dma_fence_default_wait(struct dma_fence *fence,
131 bool intr, signed long timeout);
132 signed long dma_fence_wait_timeout(struct dma_fence *,
133 bool intr, signed long timeout);
135 static inline signed long
136 dma_fence_wait(struct dma_fence *fence, bool intr)
138 return dma_fence_wait_timeout(fence, intr, MAX_SCHEDULE_TIMEOUT);
141 int dma_fence_add_callback(struct dma_fence *fence,
142 struct dma_fence_cb *cb,
143 dma_fence_func_t func);
145 bool dma_fence_remove_callback(struct dma_fence *fence,
146 struct dma_fence_cb *cb);
148 u64 dma_fence_context_alloc(unsigned num);
151 dma_fence_is_later(struct dma_fence *a, struct dma_fence *b)
153 return (a->seqno > b->seqno);
157 dma_fence_set_error(struct dma_fence *fence, int error)
159 fence->error = error;
162 #endif /* _LINUX_DMA_FENCE_H_ */