xref: /linux/include/linux/dma-fence-unwrap.h (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
164a8f92fSChristian König /* SPDX-License-Identifier: GPL-2.0-only */
264a8f92fSChristian König /*
364a8f92fSChristian König  * Copyright (C) 2022 Advanced Micro Devices, Inc.
464a8f92fSChristian König  * Authors:
564a8f92fSChristian König  *	Christian König <christian.koenig@amd.com>
664a8f92fSChristian König  */
764a8f92fSChristian König 
864a8f92fSChristian König #ifndef __LINUX_DMA_FENCE_UNWRAP_H
964a8f92fSChristian König #define __LINUX_DMA_FENCE_UNWRAP_H
1064a8f92fSChristian König 
1101357a5aSChristian König struct dma_fence;
1264a8f92fSChristian König 
1364a8f92fSChristian König /**
1464a8f92fSChristian König  * struct dma_fence_unwrap - cursor into the container structure
1564a8f92fSChristian König  *
1664a8f92fSChristian König  * Should be used with dma_fence_unwrap_for_each() iterator macro.
1764a8f92fSChristian König  */
1864a8f92fSChristian König struct dma_fence_unwrap {
1964a8f92fSChristian König 	/**
2064a8f92fSChristian König 	 * @chain: potential dma_fence_chain, but can be other fence as well
2164a8f92fSChristian König 	 */
2264a8f92fSChristian König 	struct dma_fence *chain;
2364a8f92fSChristian König 	/**
2464a8f92fSChristian König 	 * @array: potential dma_fence_array, but can be other fence as well
2564a8f92fSChristian König 	 */
2664a8f92fSChristian König 	struct dma_fence *array;
2764a8f92fSChristian König 	/**
2864a8f92fSChristian König 	 * @index: last returned index if @array is really a dma_fence_array
2964a8f92fSChristian König 	 */
3064a8f92fSChristian König 	unsigned int index;
3164a8f92fSChristian König };
3264a8f92fSChristian König 
3301357a5aSChristian König struct dma_fence *dma_fence_unwrap_first(struct dma_fence *head,
3401357a5aSChristian König 					 struct dma_fence_unwrap *cursor);
3501357a5aSChristian König struct dma_fence *dma_fence_unwrap_next(struct dma_fence_unwrap *cursor);
3664a8f92fSChristian König 
3764a8f92fSChristian König /**
3864a8f92fSChristian König  * dma_fence_unwrap_for_each - iterate over all fences in containers
3964a8f92fSChristian König  * @fence: current fence
4064a8f92fSChristian König  * @cursor: current position inside the containers
4164a8f92fSChristian König  * @head: starting point for the iterator
4264a8f92fSChristian König  *
4364a8f92fSChristian König  * Unwrap dma_fence_chain and dma_fence_array containers and deep dive into all
4464a8f92fSChristian König  * potential fences in them. If @head is just a normal fence only that one is
4564a8f92fSChristian König  * returned.
4664a8f92fSChristian König  */
4764a8f92fSChristian König #define dma_fence_unwrap_for_each(fence, cursor, head)			\
4864a8f92fSChristian König 	for (fence = dma_fence_unwrap_first(head, cursor); fence;	\
49*4fa05a67SChristian König 	     fence = dma_fence_unwrap_next(cursor))
5064a8f92fSChristian König 
51245a4a7bSChristian König struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences,
52245a4a7bSChristian König 					   struct dma_fence **fences,
53245a4a7bSChristian König 					   struct dma_fence_unwrap *cursors);
54245a4a7bSChristian König 
55245a4a7bSChristian König /**
56245a4a7bSChristian König  * dma_fence_unwrap_merge - unwrap and merge fences
57245a4a7bSChristian König  *
58245a4a7bSChristian König  * All fences given as parameters are unwrapped and merged back together as flat
59245a4a7bSChristian König  * dma_fence_array. Useful if multiple containers need to be merged together.
60245a4a7bSChristian König  *
61245a4a7bSChristian König  * Implemented as a macro to allocate the necessary arrays on the stack and
62245a4a7bSChristian König  * account the stack frame size to the caller.
63245a4a7bSChristian König  *
64245a4a7bSChristian König  * Returns NULL on memory allocation failure, a dma_fence object representing
65245a4a7bSChristian König  * all the given fences otherwise.
66245a4a7bSChristian König  */
67245a4a7bSChristian König #define dma_fence_unwrap_merge(...)					\
68245a4a7bSChristian König 	({								\
69245a4a7bSChristian König 		struct dma_fence *__f[] = { __VA_ARGS__ };		\
70245a4a7bSChristian König 		struct dma_fence_unwrap __c[ARRAY_SIZE(__f)];		\
71245a4a7bSChristian König 									\
72245a4a7bSChristian König 		__dma_fence_unwrap_merge(ARRAY_SIZE(__f), __f, __c);	\
73245a4a7bSChristian König 	})
74245a4a7bSChristian König 
7564a8f92fSChristian König #endif
76