diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl
index 7514dbf..36252ac 100644
--- a/Documentation/DocBook/device-drivers.tmpl
+++ b/Documentation/DocBook/device-drivers.tmpl
@@ -126,6 +126,8 @@ X!Edrivers/base/interface.c
      </sect1>
      <sect1><title>Device Drivers DMA Management</title>
 !Edrivers/base/dma-buf.c
+!Edrivers/base/dma-fence.c
+!Iinclude/linux/dma-fence.h
 !Edrivers/base/dma-coherent.c
 !Edrivers/base/dma-mapping.c
      </sect1>
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 5aa2d70..6e9f217 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -10,7 +10,7 @@ obj-$(CONFIG_CMA) += dma-contiguous.o
 obj-y			+= power/
 obj-$(CONFIG_HAS_DMA)	+= dma-mapping.o
 obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o
-obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf.o
+obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf.o dma-fence.o
 obj-$(CONFIG_ISA)	+= isa.o
 obj-$(CONFIG_FW_LOADER)	+= firmware_class.o
 obj-$(CONFIG_NUMA)	+= node.o
diff --git a/drivers/base/dma-fence.c b/drivers/base/dma-fence.c
new file mode 100644
index 0000000..93448e4
--- /dev/null
+++ b/drivers/base/dma-fence.c
@@ -0,0 +1,268 @@
+/*
+ * Fence mechanism for dma-buf to allow for asynchronous dma access
+ *
+ * Copyright (C) 2012 Texas Instruments
+ * Author: Rob Clark <rob.clark@linaro.org>
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/export.h>
+#include <linux/dma-fence.h>
+
+/**
+ * dma_fence_signal - signal completion of a fence
+ * @fence: the fence to signal
+ *
+ * All registered callbacks will be called directly (synchronously) and
+ * all blocked waters will be awoken. This should be always be called on
+ * software only fences, or alternatively be called after
+ * dma_fence_ops::enable_signaling is called.
+ */
+int dma_fence_signal(struct dma_fence *fence)
+{
+	unsigned long flags;
+	int ret = -EINVAL;
+
+	if (WARN_ON(!fence))
+		return -EINVAL;
+
+	spin_lock_irqsave(&fence->event_queue.lock, flags);
+	if (!fence->signaled) {
+		fence->signaled = true;
+		__wake_up_locked_key(&fence->event_queue, TASK_NORMAL,
+				     &fence->event_queue);
+		ret = 0;
+	} else
+		WARN(1, "Already signaled");
+	spin_unlock_irqrestore(&fence->event_queue.lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(dma_fence_signal);
+
+static void release_fence(struct kref *kref)
+{
+	struct dma_fence *fence =
+			container_of(kref, struct dma_fence, refcount);
+
+	BUG_ON(waitqueue_active(&fence->event_queue));
+
+	if (fence->ops->release)
+		fence->ops->release(fence);
+
+	kfree(fence);
+}
+
+/**
+ * dma_fence_put - decreases refcount of the fence
+ * @fence:	[in]	fence to reduce refcount of
+ */
+void dma_fence_put(struct dma_fence *fence)
+{
+	if (WARN_ON(!fence))
+		return;
+	kref_put(&fence->refcount, release_fence);
+}
+EXPORT_SYMBOL_GPL(dma_fence_put);
+
+/**
+ * dma_fence_get - increases refcount of the fence
+ * @fence:	[in]	fence to increase refcount of
+ */
+void dma_fence_get(struct dma_fence *fence)
+{
+	if (WARN_ON(!fence))
+		return;
+	kref_get(&fence->refcount);
+}
+EXPORT_SYMBOL_GPL(dma_fence_get);
+
+static int check_signaling(struct dma_fence *fence)
+{
+	bool enable_signaling = false, signaled;
+	unsigned long flags;
+
+	spin_lock_irqsave(&fence->event_queue.lock, flags);
+	signaled = fence->signaled;
+	if (!signaled && !fence->needs_sw_signal)
+		enable_signaling = fence->needs_sw_signal = true;
+	spin_unlock_irqrestore(&fence->event_queue.lock, flags);
+
+	if (enable_signaling) {
+		int ret;
+
+		/* At this point, if enable_signaling returns any error
+		 * a wakeup has to be performanced regardless.
+		 * -ENOENT signals fence was already signaled. Any other error
+		 * inidicates a catastrophic hardware error.
+		 *
+		 * If any hardware error occurs, nothing can be done against
+		 * it, so it's treated like the fence was already signaled.
+		 * No synchronization can be performed, so we have to assume
+		 * the fence was already signaled.
+		 */
+		ret = fence->ops->enable_signaling(fence);
+		if (ret) {
+			signaled = true;
+			dma_fence_signal(fence);
+		}
+	}
+
+	if (!signaled)
+		return 0;
+	else
+		return -ENOENT;
+}
+
+static int
+__dma_fence_wake_func(wait_queue_t *wait, unsigned mode, int flags, void *key)
+{
+	struct dma_fence_cb *cb =
+			container_of(wait, struct dma_fence_cb, base);
+
+	__remove_wait_queue(key, wait);
+	return cb->func(cb, wait->private);
+}
+
+/**
+ * dma_fence_add_callback - add a callback to be called when the fence
+ * is signaled
+ *
+ * @fence:	[in]	the fence to wait on
+ * @cb:		[in]	the callback to register
+ * @func:	[in]	the function to call
+ * @priv:	[in]	the argument to pass to function
+ *
+ * cb will be initialized by dma_fence_add_callback, no initialization
+ * by the caller is required. Any number of callbacks can be registered
+ * to a fence, but a callback can only be registered to one fence at a time.
+ *
+ * Note that the callback can be called from an atomic context.  If
+ * fence is already signaled, this function will return -ENOENT (and
+ * *not* call the callback)
+ */
+int dma_fence_add_callback(struct dma_fence *fence, struct dma_fence_cb *cb,
+			   dma_fence_func_t func, void *priv)
+{
+	unsigned long flags;
+	int ret;
+
+	if (WARN_ON(!fence || !func))
+		return -EINVAL;
+
+	ret = check_signaling(fence);
+
+	spin_lock_irqsave(&fence->event_queue.lock, flags);
+	if (!ret && fence->signaled)
+		ret = -ENOENT;
+
+	if (!ret) {
+		cb->base.flags = 0;
+		cb->base.func = __dma_fence_wake_func;
+		cb->base.private = priv;
+		cb->fence = fence;
+		cb->func = func;
+		__add_wait_queue(&fence->event_queue, &cb->base);
+	}
+	spin_unlock_irqrestore(&fence->event_queue.lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(dma_fence_add_callback);
+
+/**
+ * dma_fence_wait - wait for a fence to be signaled
+ *
+ * @fence:	[in]	The fence to wait on
+ * @intr:	[in]	if true, do an interruptible wait
+ * @timeout:	[in]	absolute time for timeout, in jiffies.
+ *
+ * Returns 0 on success, -EBUSY if a timeout occured,
+ * -ERESTARTSYS if the wait was interrupted by a signal.
+ */
+int dma_fence_wait(struct dma_fence *fence, bool intr, unsigned long timeout)
+{
+	unsigned long cur;
+	int ret;
+
+	if (WARN_ON(!fence))
+		return -EINVAL;
+
+	cur = jiffies;
+	if (time_after_eq(cur, timeout))
+		return -EBUSY;
+
+	timeout -= cur;
+
+	ret = check_signaling(fence);
+	if (ret == -ENOENT)
+		return 0;
+	else if (ret)
+		return ret;
+
+	if (intr)
+		ret = wait_event_interruptible_timeout(fence->event_queue,
+						       fence->signaled,
+						       timeout);
+	else
+		ret = wait_event_timeout(fence->event_queue,
+				fence->signaled, timeout);
+
+	if (ret > 0)
+		return 0;
+	else if (!ret)
+		return -EBUSY;
+	else
+		return ret;
+}
+EXPORT_SYMBOL_GPL(dma_fence_wait);
+
+static int sw_enable_signaling(struct dma_fence *fence)
+{
+	/* dma_fence_create sets needs_sw_signal,
+	 * so this should never be called
+	 */
+	WARN_ON_ONCE(1);
+	return 0;
+}
+
+static const struct dma_fence_ops sw_fence_ops = {
+	.enable_signaling = sw_enable_signaling,
+};
+
+/**
+ * dma_fence_create - create a simple sw-only fence
+ * @priv:	[in]	the value to use for the priv member
+ *
+ * This fence only supports signaling from/to CPU.  Other implementations
+ * of dma-fence can be used to support hardware to hardware signaling, if
+ * supported by the hardware, and use the dma_fence_helper_* functions for
+ * compatibility with other devices that only support sw signaling.
+ */
+struct dma_fence *dma_fence_create(void *priv)
+{
+	struct dma_fence *fence;
+
+	fence = kmalloc(sizeof(struct dma_fence), GFP_KERNEL);
+	if (!fence)
+		return NULL;
+
+	__dma_fence_init(fence, &sw_fence_ops, priv);
+	fence->needs_sw_signal = true;
+
+	return fence;
+}
+EXPORT_SYMBOL_GPL(dma_fence_create);
diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h
new file mode 100644
index 0000000..e0ceddd
--- /dev/null
+++ b/include/linux/dma-fence.h
@@ -0,0 +1,124 @@
+/*
+ * Fence mechanism for dma-buf to allow for asynchronous dma access
+ *
+ * Copyright (C) 2012 Texas Instruments
+ * Author: Rob Clark <rob.clark@linaro.org>
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __DMA_FENCE_H__
+#define __DMA_FENCE_H__
+
+#include <linux/err.h>
+#include <linux/list.h>
+#include <linux/wait.h>
+#include <linux/list.h>
+#include <linux/dma-buf.h>
+
+struct dma_fence;
+struct dma_fence_ops;
+struct dma_fence_cb;
+
+/**
+ * struct dma_fence - software synchronization primitive
+ * @refcount: refcount for this fence
+ * @ops: dma_fence_ops associated with this fence
+ * @priv: fence specific private data
+ * @event_queue: event queue used for signaling fence
+ * @signaled: whether this fence has been completed yet
+ * @needs_sw_signal: whether dma_fence_ops::enable_signaling
+ *                   has been called yet
+ *
+ * Read Documentation/dma-buf-synchronization.txt for usage.
+ */
+struct dma_fence {
+	struct kref refcount;
+	const struct dma_fence_ops *ops;
+	wait_queue_head_t event_queue;
+	void *priv;
+	bool signaled:1;
+	bool needs_sw_signal:1;
+};
+
+typedef int (*dma_fence_func_t)(struct dma_fence_cb *cb, void *priv);
+
+/**
+ * struct dma_fence_cb - callback for dma_fence_add_callback
+ * @base: wait_queue_t added to event_queue
+ * @func: dma_fence_func_t to call
+ * @fence: fence this dma_fence_cb was used on
+ *
+ * This struct will be initialized by dma_fence_add_callback, additional
+ * data can be passed along by embedding dma_fence_cb in another struct.
+ */
+struct dma_fence_cb {
+	wait_queue_t base;
+	dma_fence_func_t func;
+	struct dma_fence *fence;
+};
+
+/**
+ * struct dma_fence_ops - operations implemented for dma-fence
+ * @enable_signaling: enable software signaling of fence
+ * @release: [optional] called on destruction of fence
+ *
+ * Notes on enable_signaling:
+ * For fence implementations that have the capability for hw->hw
+ * signaling, they can implement this op to enable the necessary
+ * irqs, or insert commands into cmdstream, etc.  This is called
+ * in the first wait() or add_callback() path to let the fence
+ * implementation know that there is another driver waiting on
+ * the signal (ie. hw->sw case).
+ *
+ * A return value of -ENOENT will indicate that the fence has
+ * already passed. Any other errors will be treated as -ENOENT,
+ * and can happen because of hardware failure.
+ */
+
+struct dma_fence_ops {
+	int (*enable_signaling)(struct dma_fence *fence);
+	void (*release)(struct dma_fence *fence);
+};
+
+struct dma_fence *dma_fence_create(void *priv);
+
+/**
+ * __dma_fence_init - Initialize a custom dma_fence.
+ * @fence:	[in]	The fence to initialize
+ * @ops:	[in]	The dma_fence_ops for operations on this fence.
+ * @priv:	[in]	The value to use for the priv member.
+ */
+static inline void
+__dma_fence_init(struct dma_fence *fence,
+		 const struct dma_fence_ops *ops, void *priv)
+{
+	WARN_ON(!ops || !ops->enable_signaling);
+
+	kref_init(&fence->refcount);
+	fence->ops = ops;
+	fence->priv = priv;
+	fence->needs_sw_signal = false;
+	fence->signaled = false;
+	init_waitqueue_head(&fence->event_queue);
+}
+
+void dma_fence_get(struct dma_fence *fence);
+void dma_fence_put(struct dma_fence *fence);
+
+int dma_fence_signal(struct dma_fence *fence);
+int dma_fence_wait(struct dma_fence *fence, bool intr, unsigned long timeout);
+int dma_fence_add_callback(struct dma_fence *fence, struct dma_fence_cb *cb,
+			   dma_fence_func_t func, void *priv);
+
+#endif /* __DMA_FENCE_H__ */
