summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/msm_fence.c
diff options
context:
space:
mode:
authorRob Clark <robdclark@gmail.com>2016-03-16 01:26:28 +0300
committerRob Clark <robdclark@gmail.com>2016-05-08 17:22:15 +0300
commitb6295f9a38fc3f7d59ec0caa45aa803461c6cea5 (patch)
tree81f8e68dfaf8d900d86cd971e293d6a824a178d0 /drivers/gpu/drm/msm/msm_fence.c
parentba00c3f2f0c84456ffe9d548823ff4fb8e4e7ed4 (diff)
downloadlinux-b6295f9a38fc3f7d59ec0caa45aa803461c6cea5.tar.xz
drm/msm: 'struct fence' conversion
Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/msm/msm_fence.c')
-rw-r--r--drivers/gpu/drm/msm/msm_fence.c71
1 files changed, 69 insertions, 2 deletions
diff --git a/drivers/gpu/drm/msm/msm_fence.c b/drivers/gpu/drm/msm/msm_fence.c
index 088610ca80ca..a9b9b1c95a2e 100644
--- a/drivers/gpu/drm/msm/msm_fence.c
+++ b/drivers/gpu/drm/msm/msm_fence.c
@@ -32,7 +32,9 @@ msm_fence_context_alloc(struct drm_device *dev, const char *name)
fctx->dev = dev;
fctx->name = name;
+ fctx->context = fence_context_alloc(1);
init_waitqueue_head(&fctx->event);
+ spin_lock_init(&fctx->spinlock);
return fctx;
}
@@ -47,6 +49,7 @@ static inline bool fence_completed(struct msm_fence_context *fctx, uint32_t fenc
return (int32_t)(fctx->completed_fence - fence) >= 0;
}
+/* legacy path for WAIT_FENCE ioctl: */
int msm_wait_fence(struct msm_fence_context *fctx, uint32_t fence,
ktime_t *timeout, bool interruptible)
{
@@ -88,9 +91,73 @@ int msm_wait_fence(struct msm_fence_context *fctx, uint32_t fence,
/* called from workqueue */
void msm_update_fence(struct msm_fence_context *fctx, uint32_t fence)
{
- mutex_lock(&fctx->dev->struct_mutex);
+ spin_lock(&fctx->spinlock);
fctx->completed_fence = max(fence, fctx->completed_fence);
- mutex_unlock(&fctx->dev->struct_mutex);
+ spin_unlock(&fctx->spinlock);
wake_up_all(&fctx->event);
}
+
+struct msm_fence {
+ struct msm_fence_context *fctx;
+ struct fence base;
+};
+
+static inline struct msm_fence *to_msm_fence(struct fence *fence)
+{
+ return container_of(fence, struct msm_fence, base);
+}
+
+static const char *msm_fence_get_driver_name(struct fence *fence)
+{
+ return "msm";
+}
+
+static const char *msm_fence_get_timeline_name(struct fence *fence)
+{
+ struct msm_fence *f = to_msm_fence(fence);
+ return f->fctx->name;
+}
+
+static bool msm_fence_enable_signaling(struct fence *fence)
+{
+ return true;
+}
+
+static bool msm_fence_signaled(struct fence *fence)
+{
+ struct msm_fence *f = to_msm_fence(fence);
+ return fence_completed(f->fctx, f->base.seqno);
+}
+
+static void msm_fence_release(struct fence *fence)
+{
+ struct msm_fence *f = to_msm_fence(fence);
+ kfree_rcu(f, base.rcu);
+}
+
+static const struct fence_ops msm_fence_ops = {
+ .get_driver_name = msm_fence_get_driver_name,
+ .get_timeline_name = msm_fence_get_timeline_name,
+ .enable_signaling = msm_fence_enable_signaling,
+ .signaled = msm_fence_signaled,
+ .wait = fence_default_wait,
+ .release = msm_fence_release,
+};
+
+struct fence *
+msm_fence_alloc(struct msm_fence_context *fctx)
+{
+ struct msm_fence *f;
+
+ f = kzalloc(sizeof(*f), GFP_KERNEL);
+ if (!f)
+ return ERR_PTR(-ENOMEM);
+
+ f->fctx = fctx;
+
+ fence_init(&f->base, &msm_fence_ops, &fctx->spinlock,
+ fctx->context, ++fctx->last_fence);
+
+ return &f->base;
+}