Merge remote-tracking branch 'stable/linux-3.0.y' into develop-3.0-jb
[firefly-linux-kernel-4.4.55.git] / include / linux / sync.h
1 /*
2  * include/linux/sync.h
3  *
4  * Copyright (C) 2012 Google, Inc.
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9  * GNU General Public License for more details.
10  *
11  */
12
13 #ifndef _LINUX_SYNC_H
14 #define _LINUX_SYNC_H
15
16 #include <linux/types.h>
17 #ifdef __KERNEL__
18
19 #include <linux/ktime.h>
20 #include <linux/list.h>
21 #include <linux/spinlock.h>
22 #include <linux/wait.h>
23
24 struct sync_timeline;
25 struct sync_pt;
26 struct sync_fence;
27
28 /**
29  * struct sync_timeline_ops - sync object implementation ops
30  * @driver_name:        name of the implentation
31  * @dup:                duplicate a sync_pt
32  * @has_signaled:       returns:
33  *                        1 if pt has signaled
34  *                        0 if pt has not signaled
35  *                       <0 on error
36  * @compare:            returns:
37  *                        1 if b will signal before a
38  *                        0 if a and b will signal at the same time
39  *                       -1 if a will signabl before b
40  * @free_pt:            called before sync_pt is freed
41  * @release_obj:        called before sync_timeline is freed
42  * @print_obj:          print aditional debug information about sync_timeline.
43  *                        should not print a newline
44  * @print_pt:           print aditional debug information about sync_pt.
45  *                        should not print a newline
46  * @fill_driver_data:   write implmentation specific driver data to data.
47  *                        should return an error if there is not enough room
48  *                        as specified by size.  This information is returned
49  *                        to userspace by SYNC_IOC_FENCE_INFO.
50  */
51 struct sync_timeline_ops {
52         const char *driver_name;
53
54         /* required */
55         struct sync_pt *(*dup)(struct sync_pt *pt);
56
57         /* required */
58         int (*has_signaled)(struct sync_pt *pt);
59
60         /* required */
61         int (*compare)(struct sync_pt *a, struct sync_pt *b);
62
63         /* optional */
64         void (*free_pt)(struct sync_pt *sync_pt);
65
66         /* optional */
67         void (*release_obj)(struct sync_timeline *sync_timeline);
68
69         /* optional */
70         void (*print_obj)(struct seq_file *s,
71                           struct sync_timeline *sync_timeline);
72
73         /* optional */
74         void (*print_pt)(struct seq_file *s, struct sync_pt *sync_pt);
75
76         /* optional */
77         int (*fill_driver_data)(struct sync_pt *syncpt, void *data, int size);
78 };
79
80 /**
81  * struct sync_timeline - sync object
82  * @ops:                ops that define the implementaiton of the sync_timeline
83  * @name:               name of the sync_timeline. Useful for debugging
84  * @destoryed:          set when sync_timeline is destroyed
85  * @child_list_head:    list of children sync_pts for this sync_timeline
86  * @child_list_lock:    lock protecting @child_list_head, destroyed, and
87  *                        sync_pt.status
88  * @active_list_head:   list of active (unsignaled/errored) sync_pts
89  * @sync_timeline_list: membership in global sync_timeline_list
90  */
91 struct sync_timeline {
92         const struct sync_timeline_ops  *ops;
93         char                    name[32];
94
95         /* protected by child_list_lock */
96         bool                    destroyed;
97
98         struct list_head        child_list_head;
99         spinlock_t              child_list_lock;
100
101         struct list_head        active_list_head;
102         spinlock_t              active_list_lock;
103
104         struct list_head        sync_timeline_list;
105 };
106
107 /**
108  * struct sync_pt - sync point
109  * @parent:             sync_timeline to which this sync_pt belongs
110  * @child_list:         membership in sync_timeline.child_list_head
111  * @active_list:        membership in sync_timeline.active_list_head
112  * @fence:              sync_fence to which the sync_pt belongs
113  * @pt_list:            membership in sync_fence.pt_list_head
114  * @status:             1: signaled, 0:active, <0: error
115  * @timestamp:          time which sync_pt status transitioned from active to
116  *                        singaled or error.
117  */
118 struct sync_pt {
119         struct sync_timeline            *parent;
120         struct list_head        child_list;
121
122         struct list_head        active_list;
123
124         struct sync_fence       *fence;
125         struct list_head        pt_list;
126
127         /* protected by parent->active_list_lock */
128         int                     status;
129
130         ktime_t                 timestamp;
131 };
132
133 /**
134  * struct sync_fence - sync fence
135  * @file:               file representing this fence
136  * @name:               name of sync_fence.  Useful for debugging
137  * @pt_list_head:       list of sync_pts in ths fence.  immutable once fence
138  *                        is created
139  * @waiter_list_head:   list of asynchronous waiters on this fence
140  * @waiter_list_lock:   lock protecting @waiter_list_head and @status
141  * @status:             1: signaled, 0:active, <0: error
142  *
143  * @wq:                 wait queue for fence signaling
144  * @sync_fence_list:    membership in global fence list
145  */
146 struct sync_fence {
147         struct file             *file;
148         char                    name[32];
149
150         /* this list is immutable once the fence is created */
151         struct list_head        pt_list_head;
152
153         struct list_head        waiter_list_head;
154         spinlock_t              waiter_list_lock; /* also protects status */
155         int                     status;
156
157         wait_queue_head_t       wq;
158
159         struct list_head        sync_fence_list;
160 };
161
162 /**
163  * struct sync_fence_waiter - metadata for asynchronous waiter on a fence
164  * @waiter_list:        membership in sync_fence.waiter_list_head
165  * @callback:           function pointer to call when fence signals
166  * @callback_data:      pointer to pass to @callback
167  */
168 struct sync_fence_waiter {
169         struct list_head        waiter_list;
170
171         void (*callback)(struct sync_fence *fence, void *data);
172         void *callback_data;
173 };
174
175 /*
176  * API for sync_timeline implementers
177  */
178
179 /**
180  * sync_timeline_create() - creates a sync object
181  * @ops:        specifies the implemention ops for the object
182  * @size:       size to allocate for this obj
183  * @name:       sync_timeline name
184  *
185  * Creates a new sync_timeline which will use the implemetation specified by
186  * @ops.  @size bytes will be allocated allowing for implemntation specific
187  * data to be kept after the generic sync_timeline stuct.
188  */
189 struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops,
190                                            int size, const char *name);
191
192 /**
193  * sync_timeline_destory() - destorys a sync object
194  * @obj:        sync_timeline to destroy
195  *
196  * A sync implemntation should call this when the @obj is going away
197  * (i.e. module unload.)  @obj won't actually be freed until all its childern
198  * sync_pts are freed.
199  */
200 void sync_timeline_destroy(struct sync_timeline *obj);
201
202 /**
203  * sync_timeline_signal() - signal a status change on a sync_timeline
204  * @obj:        sync_timeline to signal
205  *
206  * A sync implemntation should call this any time one of it's sync_pts
207  * has signaled or has an error condition.
208  */
209 void sync_timeline_signal(struct sync_timeline *obj);
210
211 /**
212  * sync_pt_create() - creates a sync pt
213  * @parent:     sync_pt's parent sync_timeline
214  * @size:       size to allocate for this pt
215  *
216  * Creates a new sync_pt as a chiled of @parent.  @size bytes will be
217  * allocated allowing for implemntation specific data to be kept after
218  * the generic sync_timeline struct.
219  */
220 struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size);
221
222 /**
223  * sync_pt_free() - frees a sync pt
224  * @pt:         sync_pt to free
225  *
226  * This should only be called on sync_pts which have been created but
227  * not added to a fence.
228  */
229 void sync_pt_free(struct sync_pt *pt);
230
231 /**
232  * sync_fence_create() - creates a sync fence
233  * @name:       name of fence to create
234  * @pt:         sync_pt to add to the fence
235  *
236  * Creates a fence containg @pt.  Once this is called, the fence takes
237  * ownership of @pt.
238  */
239 struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt);
240
241 /*
242  * API for sync_fence consumers
243  */
244
245 /**
246  * sync_fence_merge() - merge two fences
247  * @name:       name of new fence
248  * @a:          fence a
249  * @b:          fence b
250  *
251  * Creates a new fence which contains copies of all the sync_pts in both
252  * @a and @b.  @a and @b remain valid, independent fences.
253  */
254 struct sync_fence *sync_fence_merge(const char *name,
255                                     struct sync_fence *a, struct sync_fence *b);
256
257 /**
258  * sync_fence_fdget() - get a fence from an fd
259  * @fd:         fd referencing a fence
260  *
261  * Ensures @fd references a valid fence, increments the refcount of the backing
262  * file, and returns the fence.
263  */
264 struct sync_fence *sync_fence_fdget(int fd);
265
266 /**
267  * sync_fence_put() - puts a refernnce of a sync fence
268  * @fence:      fence to put
269  *
270  * Puts a reference on @fence.  If this is the last reference, the fence and
271  * all it's sync_pts will be freed
272  */
273 void sync_fence_put(struct sync_fence *fence);
274
275 /**
276  * sync_fence_install() - installs a fence into a file descriptor
277  * @fence:      fence to instal
278  * @fd:         file descriptor in which to install the fence
279  *
280  * Installs @fence into @fd.  @fd's should be acquired through get_unused_fd().
281  */
282 void sync_fence_install(struct sync_fence *fence, int fd);
283
284 /**
285  * sync_fence_wait_async() - registers and async wait on the fence
286  * @fence:              fence to wait on
287  * @callback:           callback
288  * @callback_data       data to pass to the callback
289  *
290  * Returns 1 if @fence has already signaled.
291  *
292  * Registers a callback to be called when @fence signals or has an error
293  */
294 int sync_fence_wait_async(struct sync_fence *fence,
295                           void (*callback)(struct sync_fence *, void *data),
296                           void *callback_data);
297
298 /**
299  * sync_fence_wait() - wait on fence
300  * @fence:      fence to wait on
301  * @tiemout:    timeout in ms
302  *
303  * Wait for @fence to be signaled or have an error.  Waits indefintly
304  * if @timeout = 0
305  */
306 int sync_fence_wait(struct sync_fence *fence, long timeout);
307
308 #endif /* __KERNEL__ */
309
310 /**
311  * struct sync_merge_data - data passed to merge ioctl
312  * @fd2:        file descriptor of second fence
313  * @name:       name of new fence
314  * @fence:      returns the fd of the new fence to userspace
315  */
316 struct sync_merge_data {
317         __s32   fd2; /* fd of second fence */
318         char    name[32]; /* name of new fence */
319         __s32   fence; /* fd on newly created fence */
320 };
321
322 /**
323  * struct sync_pt_info - detailed sync_pt information
324  * @len:                length of sync_pt_info including any driver_data
325  * @obj_name:           name of parent sync_timeline
326  * @driver_name:        name of driver implmenting the parent
327  * @status:             status of the sync_pt 0:active 1:signaled <0:error
328  * @timestamp_ns:       timestamp of status change in nanoseconds
329  * @driver_data:        any driver dependant data
330  */
331 struct sync_pt_info {
332         __u32   len;
333         char    obj_name[32];
334         char    driver_name[32];
335         __s32   status;
336         __u64   timestamp_ns;
337
338         __u8    driver_data[0];
339 };
340
341 /**
342  * struct sync_fence_info_data - data returned from fence info ioctl
343  * @len:        ioctl caller writes the size of the buffer its passing in.
344  *              ioctl returns length of sync_fence_data reutnred to userspace
345  *              including pt_info.
346  * @name:       name of fence
347  * @status:     status of fence. 1: signaled 0:active <0:error
348  * @pt_info:    a sync_pt_info struct for every sync_pt in the fence
349  */
350 struct sync_fence_info_data {
351         __u32   len;
352         char    name[32];
353         __s32   status;
354
355         __u8    pt_info[0];
356 };
357
358 #define SYNC_IOC_MAGIC          '>'
359
360 /**
361  * DOC: SYNC_IOC_WAIT - wait for a fence to signal
362  *
363  * pass timeout in milliseconds.
364  */
365 #define SYNC_IOC_WAIT           _IOW(SYNC_IOC_MAGIC, 0, __u32)
366
367 /**
368  * DOC: SYNC_IOC_MERGE - merge two fences
369  *
370  * Takes a struct sync_merge_data.  Creates a new fence containing copies of
371  * the sync_pts in both the calling fd and sync_merge_data.fd2.  Returns the
372  * new fence's fd in sync_merge_data.fence
373  */
374 #define SYNC_IOC_MERGE          _IOWR(SYNC_IOC_MAGIC, 1, struct sync_merge_data)
375
376 /**
377  * DOC: SYNC_IOC_FENCE_INFO - get detailed information on a fence
378  *
379  * Takes a struct sync_fence_info_data with extra space allocated for pt_info.
380  * Caller should write the size of the buffer into len.  On return, len is
381  * updated to reflect the total size of the sync_fence_info_data including
382  * pt_info.
383  *
384  * pt_info is a buffer containing sync_pt_infos for every sync_pt in the fence.
385  * To itterate over the sync_pt_infos, use the sync_pt_info.len field.
386  */
387 #define SYNC_IOC_FENCE_INFO     _IOWR(SYNC_IOC_MAGIC, 2,\
388         struct sync_fence_info_data)
389
390 #endif /* _LINUX_SYNC_H */