diff options
Diffstat (limited to 'drivers/gpu/drm/drm_syncobj.c')
-rw-r--r-- | drivers/gpu/drm/drm_syncobj.c | 102 |
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 | ||
59 | struct drm_syncobj_stub_fence { | ||
60 | struct dma_fence base; | ||
61 | spinlock_t lock; | ||
62 | }; | ||
63 | |||
64 | static const char *drm_syncobj_stub_fence_get_name(struct dma_fence *fence) | ||
65 | { | ||
66 | return "syncobjstub"; | ||
67 | } | ||
68 | |||
69 | static bool drm_syncobj_stub_fence_enable_signaling(struct dma_fence *fence) | ||
70 | { | ||
71 | return !dma_fence_is_signaled(fence); | ||
72 | } | ||
73 | |||
74 | static void drm_syncobj_stub_fence_release(struct dma_fence *f) | ||
75 | { | ||
76 | kfree(f); | ||
77 | } | ||
78 | static 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 | */ | ||
131 | void drm_syncobj_add_callback(struct drm_syncobj *syncobj, | 150 | void 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 | } |
139 | EXPORT_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 | */ | ||
146 | void drm_syncobj_remove_callback(struct drm_syncobj *syncobj, | 159 | void 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 | } |
153 | EXPORT_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 | */ |
162 | void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, | 175 | void 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 | } |
188 | EXPORT_SYMBOL(drm_syncobj_replace_fence); | 202 | EXPORT_SYMBOL(drm_syncobj_replace_fence); |
189 | 203 | ||
190 | struct drm_syncobj_null_fence { | ||
191 | struct dma_fence base; | ||
192 | spinlock_t lock; | ||
193 | }; | ||
194 | |||
195 | static const char *drm_syncobj_null_fence_get_name(struct dma_fence *fence) | ||
196 | { | ||
197 | return "syncobjnull"; | ||
198 | } | ||
199 | |||
200 | static 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 | |||
206 | static 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 | |||
213 | static int drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj) | 204 | static 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 | */ |
245 | int drm_syncobj_find_fence(struct drm_file *file_private, | 237 | int 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 | } |
278 | EXPORT_SYMBOL(drm_syncobj_free); | 270 | EXPORT_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; |