summaryrefslogtreecommitdiffstats
path: root/drivers/dma-buf
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@canonical.com>2014-07-01 12:57:20 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-07-08 12:50:59 -0700
commit606b23ad609c71cfb37eeb972ea4c901034edd3c (patch)
tree2c6493abc82330a61911937409ace22d78fd3893 /drivers/dma-buf
parente941759c74a44d6ac2eed21bb0a38b21fe4559e2 (diff)
downloadlinux-stable-606b23ad609c71cfb37eeb972ea4c901034edd3c.tar.gz
linux-stable-606b23ad609c71cfb37eeb972ea4c901034edd3c.tar.bz2
linux-stable-606b23ad609c71cfb37eeb972ea4c901034edd3c.zip
seqno-fence: Hardware dma-buf implementation of fencing (v6)
This type of fence can be used with hardware synchronization for simple hardware that can block execution until the condition (dma_buf[offset] - value) >= 0 has been met when WAIT_GEQUAL is used, or (dma_buf[offset] != 0) has been met when WAIT_NONZERO is set. A software fallback still has to be provided in case the fence is used with a device that doesn't support this mechanism. It is useful to expose this for graphics cards that have an op to support this. Some cards like i915 can export those, but don't have an option to wait, so they need the software fallback. I extended the original patch by Rob Clark. v1: Original v2: Renamed from bikeshed to seqno, moved into dma-fence.c since not much was left of the file. Lots of documentation added. v3: Use fence_ops instead of custom callbacks. Moved to own file to avoid circular dependency between dma-buf.h and fence.h v4: Add spinlock pointer to seqno_fence_init v5: Add condition member to allow wait for != 0. Fix small style errors pointed out by checkpatch. v6: Move to a separate file. Fix up api changes in fences. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com> Acked-by: Sumit Semwal <sumit.semwal@linaro.org> Acked-by: Daniel Vetter <daniel@ffwll.ch> Reviewed-by: Rob Clark <robdclark@gmail.com> #v4 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/dma-buf')
-rw-r--r--drivers/dma-buf/Makefile2
-rw-r--r--drivers/dma-buf/seqno-fence.c73
2 files changed, 74 insertions, 1 deletions
diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile
index d7825bfe630e..57a675f90cd0 100644
--- a/drivers/dma-buf/Makefile
+++ b/drivers/dma-buf/Makefile
@@ -1 +1 @@
-obj-y := dma-buf.o fence.o reservation.o
+obj-y := dma-buf.o fence.o reservation.o seqno-fence.o
diff --git a/drivers/dma-buf/seqno-fence.c b/drivers/dma-buf/seqno-fence.c
new file mode 100644
index 000000000000..7d12a39a4b57
--- /dev/null
+++ b/drivers/dma-buf/seqno-fence.c
@@ -0,0 +1,73 @@
+/*
+ * seqno-fence, using a dma-buf to synchronize fencing
+ *
+ * Copyright (C) 2012 Texas Instruments
+ * Copyright (C) 2012-2014 Canonical Ltd
+ * Authors:
+ * Rob Clark <robdclark@gmail.com>
+ * Maarten Lankhorst <maarten.lankhorst@canonical.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/slab.h>
+#include <linux/export.h>
+#include <linux/seqno-fence.h>
+
+static const char *seqno_fence_get_driver_name(struct fence *fence)
+{
+ struct seqno_fence *seqno_fence = to_seqno_fence(fence);
+ return seqno_fence->ops->get_driver_name(fence);
+}
+
+static const char *seqno_fence_get_timeline_name(struct fence *fence)
+{
+ struct seqno_fence *seqno_fence = to_seqno_fence(fence);
+ return seqno_fence->ops->get_timeline_name(fence);
+}
+
+static bool seqno_enable_signaling(struct fence *fence)
+{
+ struct seqno_fence *seqno_fence = to_seqno_fence(fence);
+ return seqno_fence->ops->enable_signaling(fence);
+}
+
+static bool seqno_signaled(struct fence *fence)
+{
+ struct seqno_fence *seqno_fence = to_seqno_fence(fence);
+ return seqno_fence->ops->signaled && seqno_fence->ops->signaled(fence);
+}
+
+static void seqno_release(struct fence *fence)
+{
+ struct seqno_fence *f = to_seqno_fence(fence);
+
+ dma_buf_put(f->sync_buf);
+ if (f->ops->release)
+ f->ops->release(fence);
+ else
+ fence_free(&f->base);
+}
+
+static signed long seqno_wait(struct fence *fence, bool intr, signed long timeout)
+{
+ struct seqno_fence *f = to_seqno_fence(fence);
+ return f->ops->wait(fence, intr, timeout);
+}
+
+const struct fence_ops seqno_fence_ops = {
+ .get_driver_name = seqno_fence_get_driver_name,
+ .get_timeline_name = seqno_fence_get_timeline_name,
+ .enable_signaling = seqno_enable_signaling,
+ .signaled = seqno_signaled,
+ .wait = seqno_wait,
+ .release = seqno_release,
+};
+EXPORT_SYMBOL(seqno_fence_ops);