list_add_tail(&cb->node, &syncobj->cb_list);
}
-static int drm_syncobj_fence_get_or_add_callback(struct drm_syncobj *syncobj,
- struct dma_fence **fence,
- struct drm_syncobj_cb *cb,
- drm_syncobj_func_t func)
+static void drm_syncobj_fence_get_or_add_callback(struct drm_syncobj *syncobj,
+ struct dma_fence **fence,
+ struct drm_syncobj_cb *cb,
+ drm_syncobj_func_t func)
{
- int ret;
+ u64 pt_value = 0;
- *fence = drm_syncobj_fence_get(syncobj);
- if (*fence)
- return 1;
+ WARN_ON(*fence);
+
+ if (syncobj->type == DRM_SYNCOBJ_TYPE_BINARY) {
+ /*BINARY syncobj always wait on last pt */
+ pt_value = syncobj->signal_point;
- spin_lock(&syncobj->lock);
- /* We've already tried once to get a fence and failed. Now that we
- * have the lock, try one more time just to be sure we don't add a
- * callback when a fence has already been set.
- */
- if (syncobj->fence) {
- *fence = dma_fence_get(rcu_dereference_protected(syncobj->fence,
- lockdep_is_held(&syncobj->lock)));
- ret = 1;
- } else {
- *fence = NULL;
- drm_syncobj_add_callback_locked(syncobj, cb, func);
- ret = 0;
+ if (pt_value == 0)
+ pt_value += DRM_SYNCOBJ_BINARY_POINT;
}
- spin_unlock(&syncobj->lock);
- return ret;
+ mutex_lock(&syncobj->cb_mutex);
+ spin_lock(&syncobj->pt_lock);
+ *fence = drm_syncobj_find_signal_pt_for_point(syncobj, pt_value);
+ spin_unlock(&syncobj->pt_lock);
+ if (!*fence)
+ drm_syncobj_add_callback_locked(syncobj, cb, func);
+ mutex_unlock(&syncobj->cb_mutex);
}
void drm_syncobj_add_callback(struct drm_syncobj *syncobj,