.. | .. |
---|
1 | 1 | // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note |
---|
2 | 2 | /* |
---|
3 | 3 | * |
---|
4 | | - * (C) COPYRIGHT 2011-2021 ARM Limited. All rights reserved. |
---|
| 4 | + * (C) COPYRIGHT 2011-2022 ARM Limited. All rights reserved. |
---|
5 | 5 | * |
---|
6 | 6 | * This program is free software and is provided to you under the terms of the |
---|
7 | 7 | * GNU General Public License version 2 as published by the Free Software |
---|
.. | .. |
---|
59 | 59 | return fence; |
---|
60 | 60 | } |
---|
61 | 61 | |
---|
62 | | -bool |
---|
63 | | -kbase_fence_free_callbacks(struct kbase_jd_atom *katom) |
---|
64 | | -{ |
---|
65 | | - struct kbase_fence_cb *cb, *tmp; |
---|
66 | | - bool res = false; |
---|
67 | | - |
---|
68 | | - lockdep_assert_held(&katom->kctx->jctx.lock); |
---|
69 | | - |
---|
70 | | - /* Clean up and free callbacks. */ |
---|
71 | | - list_for_each_entry_safe(cb, tmp, &katom->dma_fence.callbacks, node) { |
---|
72 | | - bool ret; |
---|
73 | | - |
---|
74 | | - /* Cancel callbacks that hasn't been called yet. */ |
---|
75 | | - ret = dma_fence_remove_callback(cb->fence, &cb->fence_cb); |
---|
76 | | - if (ret) { |
---|
77 | | - int ret; |
---|
78 | | - |
---|
79 | | - /* Fence had not signaled, clean up after |
---|
80 | | - * canceling. |
---|
81 | | - */ |
---|
82 | | - ret = atomic_dec_return(&katom->dma_fence.dep_count); |
---|
83 | | - |
---|
84 | | - if (unlikely(ret == 0)) |
---|
85 | | - res = true; |
---|
86 | | - } |
---|
87 | | - |
---|
88 | | - /* |
---|
89 | | - * Release the reference taken in |
---|
90 | | - * kbase_fence_add_callback(). |
---|
91 | | - */ |
---|
92 | | - dma_fence_put(cb->fence); |
---|
93 | | - list_del(&cb->node); |
---|
94 | | - kfree(cb); |
---|
95 | | - } |
---|
96 | | - |
---|
97 | | - return res; |
---|
98 | | -} |
---|
99 | | - |
---|
100 | | -#if (KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE) |
---|
101 | | -int |
---|
102 | | -kbase_fence_add_callback(struct kbase_jd_atom *katom, |
---|
103 | | - struct fence *fence, |
---|
104 | | - fence_func_t callback) |
---|
105 | | -#else |
---|
106 | | -int |
---|
107 | | -kbase_fence_add_callback(struct kbase_jd_atom *katom, |
---|
108 | | - struct dma_fence *fence, |
---|
109 | | - dma_fence_func_t callback) |
---|
110 | | -#endif |
---|
111 | | -{ |
---|
112 | | - int err = 0; |
---|
113 | | - struct kbase_fence_cb *kbase_fence_cb; |
---|
114 | | - |
---|
115 | | - if (!fence) |
---|
116 | | - return -EINVAL; |
---|
117 | | - |
---|
118 | | - kbase_fence_cb = kmalloc(sizeof(*kbase_fence_cb), GFP_KERNEL); |
---|
119 | | - if (!kbase_fence_cb) |
---|
120 | | - return -ENOMEM; |
---|
121 | | - |
---|
122 | | - kbase_fence_cb->fence = fence; |
---|
123 | | - kbase_fence_cb->katom = katom; |
---|
124 | | - INIT_LIST_HEAD(&kbase_fence_cb->node); |
---|
125 | | - atomic_inc(&katom->dma_fence.dep_count); |
---|
126 | | - |
---|
127 | | - err = dma_fence_add_callback(fence, &kbase_fence_cb->fence_cb, |
---|
128 | | - callback); |
---|
129 | | - if (err == -ENOENT) { |
---|
130 | | - /* Fence signaled, get the completion result */ |
---|
131 | | - err = dma_fence_get_status(fence); |
---|
132 | | - |
---|
133 | | - /* remap success completion to err code */ |
---|
134 | | - if (err == 1) |
---|
135 | | - err = 0; |
---|
136 | | - |
---|
137 | | - kfree(kbase_fence_cb); |
---|
138 | | - atomic_dec(&katom->dma_fence.dep_count); |
---|
139 | | - } else if (err) { |
---|
140 | | - kfree(kbase_fence_cb); |
---|
141 | | - atomic_dec(&katom->dma_fence.dep_count); |
---|
142 | | - } else { |
---|
143 | | - /* |
---|
144 | | - * Get reference to fence that will be kept until callback gets |
---|
145 | | - * cleaned up in kbase_fence_free_callbacks(). |
---|
146 | | - */ |
---|
147 | | - dma_fence_get(fence); |
---|
148 | | - /* Add callback to katom's list of callbacks */ |
---|
149 | | - list_add(&kbase_fence_cb->node, &katom->dma_fence.callbacks); |
---|
150 | | - } |
---|
151 | | - |
---|
152 | | - return err; |
---|
153 | | -} |
---|