Line data Source code
1 : /* SPDX-License-Identifier: GPL-2.0-only */ 2 : /* 3 : * fence-chain: chain fences together in a timeline 4 : * 5 : * Copyright (C) 2022 Advanced Micro Devices, Inc. 6 : * Authors: 7 : * Christian König <christian.koenig@amd.com> 8 : */ 9 : 10 : #ifndef __LINUX_DMA_FENCE_UNWRAP_H 11 : #define __LINUX_DMA_FENCE_UNWRAP_H 12 : 13 : #include <linux/dma-fence-chain.h> 14 : #include <linux/dma-fence-array.h> 15 : 16 : /** 17 : * struct dma_fence_unwrap - cursor into the container structure 18 : * 19 : * Should be used with dma_fence_unwrap_for_each() iterator macro. 20 : */ 21 : struct dma_fence_unwrap { 22 : /** 23 : * @chain: potential dma_fence_chain, but can be other fence as well 24 : */ 25 : struct dma_fence *chain; 26 : /** 27 : * @array: potential dma_fence_array, but can be other fence as well 28 : */ 29 : struct dma_fence *array; 30 : /** 31 : * @index: last returned index if @array is really a dma_fence_array 32 : */ 33 : unsigned int index; 34 : }; 35 : 36 : /* Internal helper to start new array iteration, don't use directly */ 37 : static inline struct dma_fence * 38 0 : __dma_fence_unwrap_array(struct dma_fence_unwrap * cursor) 39 : { 40 0 : cursor->array = dma_fence_chain_contained(cursor->chain); 41 0 : cursor->index = 0; 42 0 : return dma_fence_array_first(cursor->array); 43 : } 44 : 45 : /** 46 : * dma_fence_unwrap_first - return the first fence from fence containers 47 : * @head: the entrypoint into the containers 48 : * @cursor: current position inside the containers 49 : * 50 : * Unwraps potential dma_fence_chain/dma_fence_array containers and return the 51 : * first fence. 52 : */ 53 : static inline struct dma_fence * 54 0 : dma_fence_unwrap_first(struct dma_fence *head, struct dma_fence_unwrap *cursor) 55 : { 56 0 : cursor->chain = dma_fence_get(head); 57 0 : return __dma_fence_unwrap_array(cursor); 58 : } 59 : 60 : /** 61 : * dma_fence_unwrap_next - return the next fence from a fence containers 62 : * @cursor: current position inside the containers 63 : * 64 : * Continue unwrapping the dma_fence_chain/dma_fence_array containers and return 65 : * the next fence from them. 66 : */ 67 : static inline struct dma_fence * 68 0 : dma_fence_unwrap_next(struct dma_fence_unwrap *cursor) 69 : { 70 : struct dma_fence *tmp; 71 : 72 0 : ++cursor->index; 73 0 : tmp = dma_fence_array_next(cursor->array, cursor->index); 74 0 : if (tmp) 75 : return tmp; 76 : 77 0 : cursor->chain = dma_fence_chain_walk(cursor->chain); 78 0 : return __dma_fence_unwrap_array(cursor); 79 : } 80 : 81 : /** 82 : * dma_fence_unwrap_for_each - iterate over all fences in containers 83 : * @fence: current fence 84 : * @cursor: current position inside the containers 85 : * @head: starting point for the iterator 86 : * 87 : * Unwrap dma_fence_chain and dma_fence_array containers and deep dive into all 88 : * potential fences in them. If @head is just a normal fence only that one is 89 : * returned. 90 : */ 91 : #define dma_fence_unwrap_for_each(fence, cursor, head) \ 92 : for (fence = dma_fence_unwrap_first(head, cursor); fence; \ 93 : fence = dma_fence_unwrap_next(cursor)) 94 : 95 : #endif