aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_syncobj.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_syncobj.c')
-rw-r--r--drivers/gpu/drm/drm_syncobj.c102
1 files changed, 47 insertions, 55 deletions
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index adb3cb27d31e..497729202bfe 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -56,6 +56,33 @@
56#include "drm_internal.h" 56#include "drm_internal.h"
57#include <drm/drm_syncobj.h> 57#include <drm/drm_syncobj.h>
58 58
59struct drm_syncobj_stub_fence {
60 struct dma_fence base;
61 spinlock_t lock;
62};
63
64static const char *drm_syncobj_stub_fence_get_name(struct dma_fence *fence)
65{
66 return "syncobjstub";
67}
68
69static bool drm_syncobj_stub_fence_enable_signaling(struct dma_fence *fence)
70{
71 return !dma_fence_is_signaled(fence);
72}
73
74static void drm_syncobj_stub_fence_release(struct dma_fence *f)
75{
76 kfree(f);
77}
78static const struct dma_fence_ops drm_syncobj_stub_fence_ops = {
79 .get_driver_name = drm_syncobj_stub_fence_get_name,
80 .get_timeline_name = drm_syncobj_stub_fence_get_name,
81 .enable_signaling = drm_syncobj_stub_fence_enable_signaling,
82 .release = drm_syncobj_stub_fence_release,
83};
84
85
59/** 86/**
60 * drm_syncobj_find - lookup and reference a sync object. 87 * drm_syncobj_find - lookup and reference a sync object.
61 * @file_private: drm file private pointer 88 * @file_private: drm file private pointer
@@ -120,14 +147,6 @@ static int drm_syncobj_fence_get_or_add_callback(struct drm_syncobj *syncobj,
120 return ret; 147 return ret;
121} 148}
122 149
123/**
124 * drm_syncobj_add_callback - adds a callback to syncobj::cb_list
125 * @syncobj: Sync object to which to add the callback
126 * @cb: Callback to add
127 * @func: Func to use when initializing the drm_syncobj_cb struct
128 *
129 * This adds a callback to be called next time the fence is replaced
130 */
131void drm_syncobj_add_callback(struct drm_syncobj *syncobj, 150void drm_syncobj_add_callback(struct drm_syncobj *syncobj,
132 struct drm_syncobj_cb *cb, 151 struct drm_syncobj_cb *cb,
133 drm_syncobj_func_t func) 152 drm_syncobj_func_t func)
@@ -136,13 +155,7 @@ void drm_syncobj_add_callback(struct drm_syncobj *syncobj,
136 drm_syncobj_add_callback_locked(syncobj, cb, func); 155 drm_syncobj_add_callback_locked(syncobj, cb, func);
137 spin_unlock(&syncobj->lock); 156 spin_unlock(&syncobj->lock);
138} 157}
139EXPORT_SYMBOL(drm_syncobj_add_callback);
140 158
141/**
142 * drm_syncobj_add_callback - removes a callback to syncobj::cb_list
143 * @syncobj: Sync object from which to remove the callback
144 * @cb: Callback to remove
145 */
146void drm_syncobj_remove_callback(struct drm_syncobj *syncobj, 159void drm_syncobj_remove_callback(struct drm_syncobj *syncobj,
147 struct drm_syncobj_cb *cb) 160 struct drm_syncobj_cb *cb)
148{ 161{
@@ -150,16 +163,17 @@ void drm_syncobj_remove_callback(struct drm_syncobj *syncobj,
150 list_del_init(&cb->node); 163 list_del_init(&cb->node);
151 spin_unlock(&syncobj->lock); 164 spin_unlock(&syncobj->lock);
152} 165}
153EXPORT_SYMBOL(drm_syncobj_remove_callback);
154 166
155/** 167/**
156 * drm_syncobj_replace_fence - replace fence in a sync object. 168 * drm_syncobj_replace_fence - replace fence in a sync object.
157 * @syncobj: Sync object to replace fence in 169 * @syncobj: Sync object to replace fence in
170 * @point: timeline point
158 * @fence: fence to install in sync file. 171 * @fence: fence to install in sync file.
159 * 172 *
160 * This replaces the fence on a sync object. 173 * This replaces the fence on a sync object, or a timeline point fence.
161 */ 174 */
162void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, 175void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
176 u64 point,
163 struct dma_fence *fence) 177 struct dma_fence *fence)
164{ 178{
165 struct dma_fence *old_fence; 179 struct dma_fence *old_fence;
@@ -187,42 +201,19 @@ void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
187} 201}
188EXPORT_SYMBOL(drm_syncobj_replace_fence); 202EXPORT_SYMBOL(drm_syncobj_replace_fence);
189 203
190struct drm_syncobj_null_fence {
191 struct dma_fence base;
192 spinlock_t lock;
193};
194
195static const char *drm_syncobj_null_fence_get_name(struct dma_fence *fence)
196{
197 return "syncobjnull";
198}
199
200static bool drm_syncobj_null_fence_enable_signaling(struct dma_fence *fence)
201{
202 dma_fence_enable_sw_signaling(fence);
203 return !dma_fence_is_signaled(fence);
204}
205
206static const struct dma_fence_ops drm_syncobj_null_fence_ops = {
207 .get_driver_name = drm_syncobj_null_fence_get_name,
208 .get_timeline_name = drm_syncobj_null_fence_get_name,
209 .enable_signaling = drm_syncobj_null_fence_enable_signaling,
210 .release = NULL,
211};
212
213static int drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj) 204static int drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj)
214{ 205{
215 struct drm_syncobj_null_fence *fence; 206 struct drm_syncobj_stub_fence *fence;
216 fence = kzalloc(sizeof(*fence), GFP_KERNEL); 207 fence = kzalloc(sizeof(*fence), GFP_KERNEL);
217 if (fence == NULL) 208 if (fence == NULL)
218 return -ENOMEM; 209 return -ENOMEM;
219 210
220 spin_lock_init(&fence->lock); 211 spin_lock_init(&fence->lock);
221 dma_fence_init(&fence->base, &drm_syncobj_null_fence_ops, 212 dma_fence_init(&fence->base, &drm_syncobj_stub_fence_ops,
222 &fence->lock, 0, 0); 213 &fence->lock, 0, 0);
223 dma_fence_signal(&fence->base); 214 dma_fence_signal(&fence->base);
224 215
225 drm_syncobj_replace_fence(syncobj, &fence->base); 216 drm_syncobj_replace_fence(syncobj, 0, &fence->base);
226 217
227 dma_fence_put(&fence->base); 218 dma_fence_put(&fence->base);
228 219
@@ -233,6 +224,7 @@ static int drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj)
233 * drm_syncobj_find_fence - lookup and reference the fence in a sync object 224 * drm_syncobj_find_fence - lookup and reference the fence in a sync object
234 * @file_private: drm file private pointer 225 * @file_private: drm file private pointer
235 * @handle: sync object handle to lookup. 226 * @handle: sync object handle to lookup.
227 * @point: timeline point
236 * @fence: out parameter for the fence 228 * @fence: out parameter for the fence
237 * 229 *
238 * This is just a convenience function that combines drm_syncobj_find() and 230 * This is just a convenience function that combines drm_syncobj_find() and
@@ -243,7 +235,7 @@ static int drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj)
243 * dma_fence_put(). 235 * dma_fence_put().
244 */ 236 */
245int drm_syncobj_find_fence(struct drm_file *file_private, 237int drm_syncobj_find_fence(struct drm_file *file_private,
246 u32 handle, 238 u32 handle, u64 point,
247 struct dma_fence **fence) 239 struct dma_fence **fence)
248{ 240{
249 struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle); 241 struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle);
@@ -272,7 +264,7 @@ void drm_syncobj_free(struct kref *kref)
272 struct drm_syncobj *syncobj = container_of(kref, 264 struct drm_syncobj *syncobj = container_of(kref,
273 struct drm_syncobj, 265 struct drm_syncobj,
274 refcount); 266 refcount);
275 drm_syncobj_replace_fence(syncobj, NULL); 267 drm_syncobj_replace_fence(syncobj, 0, NULL);
276 kfree(syncobj); 268 kfree(syncobj);
277} 269}
278EXPORT_SYMBOL(drm_syncobj_free); 270EXPORT_SYMBOL(drm_syncobj_free);
@@ -312,7 +304,7 @@ int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags,
312 } 304 }
313 305
314 if (fence) 306 if (fence)
315 drm_syncobj_replace_fence(syncobj, fence); 307 drm_syncobj_replace_fence(syncobj, 0, fence);
316 308
317 *out_syncobj = syncobj; 309 *out_syncobj = syncobj;
318 return 0; 310 return 0;
@@ -497,7 +489,7 @@ static int drm_syncobj_import_sync_file_fence(struct drm_file *file_private,
497 return -ENOENT; 489 return -ENOENT;
498 } 490 }
499 491
500 drm_syncobj_replace_fence(syncobj, fence); 492 drm_syncobj_replace_fence(syncobj, 0, fence);
501 dma_fence_put(fence); 493 dma_fence_put(fence);
502 drm_syncobj_put(syncobj); 494 drm_syncobj_put(syncobj);
503 return 0; 495 return 0;
@@ -514,7 +506,7 @@ static int drm_syncobj_export_sync_file(struct drm_file *file_private,
514 if (fd < 0) 506 if (fd < 0)
515 return fd; 507 return fd;
516 508
517 ret = drm_syncobj_find_fence(file_private, handle, &fence); 509 ret = drm_syncobj_find_fence(file_private, handle, 0, &fence);
518 if (ret) 510 if (ret)
519 goto err_put_fd; 511 goto err_put_fd;
520 512
@@ -581,7 +573,7 @@ drm_syncobj_create_ioctl(struct drm_device *dev, void *data,
581 struct drm_syncobj_create *args = data; 573 struct drm_syncobj_create *args = data;
582 574
583 if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) 575 if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
584 return -ENODEV; 576 return -EOPNOTSUPP;
585 577
586 /* no valid flags yet */ 578 /* no valid flags yet */
587 if (args->flags & ~DRM_SYNCOBJ_CREATE_SIGNALED) 579 if (args->flags & ~DRM_SYNCOBJ_CREATE_SIGNALED)
@@ -598,7 +590,7 @@ drm_syncobj_destroy_ioctl(struct drm_device *dev, void *data,
598 struct drm_syncobj_destroy *args = data; 590 struct drm_syncobj_destroy *args = data;
599 591
600 if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) 592 if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
601 return -ENODEV; 593 return -EOPNOTSUPP;
602 594
603 /* make sure padding is empty */ 595 /* make sure padding is empty */
604 if (args->pad) 596 if (args->pad)
@@ -613,7 +605,7 @@ drm_syncobj_handle_to_fd_ioctl(struct drm_device *dev, void *data,
613 struct drm_syncobj_handle *args = data; 605 struct drm_syncobj_handle *args = data;
614 606
615 if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) 607 if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
616 return -ENODEV; 608 return -EOPNOTSUPP;
617 609
618 if (args->pad) 610 if (args->pad)
619 return -EINVAL; 611 return -EINVAL;
@@ -637,7 +629,7 @@ drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, void *data,
637 struct drm_syncobj_handle *args = data; 629 struct drm_syncobj_handle *args = data;
638 630
639 if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) 631 if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
640 return -ENODEV; 632 return -EOPNOTSUPP;
641 633
642 if (args->pad) 634 if (args->pad)
643 return -EINVAL; 635 return -EINVAL;
@@ -929,7 +921,7 @@ drm_syncobj_wait_ioctl(struct drm_device *dev, void *data,
929 int ret = 0; 921 int ret = 0;
930 922
931 if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) 923 if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
932 return -ENODEV; 924 return -EOPNOTSUPP;
933 925
934 if (args->flags & ~(DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL | 926 if (args->flags & ~(DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL |
935 DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT)) 927 DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT))
@@ -963,7 +955,7 @@ drm_syncobj_reset_ioctl(struct drm_device *dev, void *data,
963 int ret; 955 int ret;
964 956
965 if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) 957 if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
966 return -ENODEV; 958 return -EOPNOTSUPP;
967 959
968 if (args->pad != 0) 960 if (args->pad != 0)
969 return -EINVAL; 961 return -EINVAL;
@@ -979,7 +971,7 @@ drm_syncobj_reset_ioctl(struct drm_device *dev, void *data,
979 return ret; 971 return ret;
980 972
981 for (i = 0; i < args->count_handles; i++) 973 for (i = 0; i < args->count_handles; i++)
982 drm_syncobj_replace_fence(syncobjs[i], NULL); 974 drm_syncobj_replace_fence(syncobjs[i], 0, NULL);
983 975
984 drm_syncobj_array_free(syncobjs, args->count_handles); 976 drm_syncobj_array_free(syncobjs, args->count_handles);
985 977
@@ -996,7 +988,7 @@ drm_syncobj_signal_ioctl(struct drm_device *dev, void *data,
996 int ret; 988 int ret;
997 989
998 if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) 990 if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
999 return -ENODEV; 991 return -EOPNOTSUPP;
1000 992
1001 if (args->pad != 0) 993 if (args->pad != 0)
1002 return -EINVAL; 994 return -EINVAL;