1151497Sru/* SPDX-License-Identifier: GPL-2.0-only */ 2104862Sru/* 3151497Sru * Copyright (C) 2022 Advanced Micro Devices, Inc. 4104862Sru * Authors: 5151497Sru * Christian K��nig <christian.koenig@amd.com> 6151497Sru */ 7104862Sru 8104862Sru#ifndef __LINUX_DMA_FENCE_UNWRAP_H 9104862Sru#define __LINUX_DMA_FENCE_UNWRAP_H 10104862Sru 11104862Srustruct dma_fence; 12104862Sru 13104862Sru/** 14104862Sru * struct dma_fence_unwrap - cursor into the container structure 15104862Sru * 16104862Sru * Should be used with dma_fence_unwrap_for_each() iterator macro. 17104862Sru */ 18104862Srustruct dma_fence_unwrap { 19151497Sru /** 20114402Sru * @chain: potential dma_fence_chain, but can be other fence as well 21104862Sru */ 22104862Sru struct dma_fence *chain; 23104862Sru /** 24104862Sru * @array: potential dma_fence_array, but can be other fence as well 25104862Sru */ 26104862Sru struct dma_fence *array; 27104862Sru /** 28104862Sru * @index: last returned index if @array is really a dma_fence_array 29104862Sru */ 30104862Sru unsigned int index; 31151497Sru}; 32104862Sru 33151497Srustruct dma_fence *dma_fence_unwrap_first(struct dma_fence *head, 34151497Sru struct dma_fence_unwrap *cursor); 35104862Srustruct dma_fence *dma_fence_unwrap_next(struct dma_fence_unwrap *cursor); 36104862Sru 37104862Sru/** 38104862Sru * dma_fence_unwrap_for_each - iterate over all fences in containers 39104862Sru * @fence: current fence 40104862Sru * @cursor: current position inside the containers 41104862Sru * @head: starting point for the iterator 42104862Sru * 43104862Sru * Unwrap dma_fence_chain and dma_fence_array containers and deep dive into all 44104862Sru * potential fences in them. If @head is just a normal fence only that one is 45104862Sru * returned. 46104862Sru */ 47151497Sru#define dma_fence_unwrap_for_each(fence, cursor, head) \ 48104862Sru for (fence = dma_fence_unwrap_first(head, cursor); fence; \ 49104862Sru fence = dma_fence_unwrap_next(cursor)) 50104862Sru 51104862Srustruct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences, 52104862Sru struct dma_fence **fences, 53104862Sru struct dma_fence_unwrap *cursors); 54104862Sru 55104862Sru/** 56104862Sru * dma_fence_unwrap_merge - unwrap and merge fences 57104862Sru * 58104862Sru * All fences given as parameters are unwrapped and merged back together as flat 59104862Sru * dma_fence_array. Useful if multiple containers need to be merged together. 60104862Sru * 61104862Sru * Implemented as a macro to allocate the necessary arrays on the stack and 62104862Sru * account the stack frame size to the caller. 63104862Sru * 64104862Sru * Returns NULL on memory allocation failure, a dma_fence object representing 65104862Sru * all the given fences otherwise. 66104862Sru */ 67104862Sru#define dma_fence_unwrap_merge(...) \ 68104862Sru ({ \ 69104862Sru struct dma_fence *__f[] = { __VA_ARGS__ }; \ 70104862Sru struct dma_fence_unwrap __c[ARRAY_SIZE(__f)]; \ 71104862Sru \ 72104862Sru __dma_fence_unwrap_merge(ARRAY_SIZE(__f), __f, __c); \ 73104862Sru }) 74151497Sru 75151497Sru#endif 76104862Sru