diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile
index 57a675f..fb03696 100644
--- a/drivers/dma-buf/Makefile
+++ b/drivers/dma-buf/Makefile
@@ -1 +1 @@
-obj-y := dma-buf.o fence.o reservation.o seqno-fence.o
+obj-y := dma-buf.o fence.o fence_debug.o reservation.o seqno-fence.o
diff --git a/drivers/dma-buf/fence.c b/drivers/dma-buf/fence.c
index 0a07fcb..09faf2e 100644
--- a/drivers/dma-buf/fence.c
+++ b/drivers/dma-buf/fence.c
@@ -84,6 +84,8 @@ struct fence_timeline *fence_timeline_create(unsigned num, int size,
 	INIT_LIST_HEAD(&timeline->active_list_head);
 	spin_lock_init(&timeline->lock);
 
+	fence_timeline_debug_add(timeline);
+
 	return timeline;
 }
 EXPORT_SYMBOL(fence_timeline_create);
@@ -100,6 +102,8 @@ static void fence_timeline_free(struct kref *kref)
 	struct fence_timeline *timeline =
 		container_of(kref, struct fence_timeline, kref);
 
+	fence_timeline_debug_remove(timeline);
+
 	kfree(timeline);
 }
 
diff --git a/drivers/dma-buf/fence_debug.c b/drivers/dma-buf/fence_debug.c
new file mode 100644
index 0000000..c7529c6
--- /dev/null
+++ b/drivers/dma-buf/fence_debug.c
@@ -0,0 +1,128 @@
+/*
+ * drivers/dma-buf/fence_debug.c
+ *
+ * Copyright (C) 2012 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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/seq_file.h>
+#include <linux/fence.h>
+
+#ifdef CONFIG_DEBUG_FS
+
+static LIST_HEAD(fence_timeline_list_head);
+static DEFINE_SPINLOCK(fence_timeline_list_lock);
+
+void fence_timeline_debug_add(struct fence_timeline *obj)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&fence_timeline_list_lock, flags);
+	list_add_tail(&obj->fence_timeline_list, &fence_timeline_list_head);
+	spin_unlock_irqrestore(&fence_timeline_list_lock, flags);
+}
+EXPORT_SYMBOL(fence_timeline_debug_add);
+
+void fence_timeline_debug_remove(struct fence_timeline *obj)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&fence_timeline_list_lock, flags);
+	list_del(&obj->fence_timeline_list);
+	spin_unlock_irqrestore(&fence_timeline_list_lock, flags);
+}
+EXPORT_SYMBOL(fence_timeline_debug_remove);
+
+const char *fence_status_str(int status)
+{
+	if (status == 0)
+		return "signaled";
+
+	if (status > 0)
+		return "active";
+
+	return "error";
+}
+EXPORT_SYMBOL(fence_status_str);
+
+void fence_print(struct seq_file *s, struct fence *fence, bool show)
+{
+	int status = 1;
+	struct fence_timeline *parent = fence_parent(fence);
+
+	if (fence_is_signaled_locked(fence))
+		status = fence->status;
+
+	seq_printf(s, "  %s%sfence %s",
+		   show ? parent->name : "",
+		   show ? "_" : "",
+		   fence_status_str(status));
+
+	if (status <= 0) {
+		struct timespec64 ts64 =
+			ktime_to_timespec64(fence->timestamp);
+
+		seq_printf(s, "@%lld.%09ld", (s64)ts64.tv_sec, ts64.tv_nsec);
+	}
+
+	if (fence->ops->timeline_value_str &&
+	    fence->ops->fence_value_str) {
+		char value[64];
+
+		fence->ops->fence_value_str(fence, value, sizeof(value));
+		seq_printf(s, ": %s", value);
+		if (show) {
+			fence->ops->timeline_value_str(fence, value,
+						       sizeof(value));
+			seq_printf(s, " / %s", value);
+		}
+	}
+
+	seq_puts(s, "\n");
+}
+EXPORT_SYMBOL(fence_print);
+
+void fence_timeline_print(struct seq_file *s, struct fence_timeline *obj)
+{
+	struct list_head *pos;
+	unsigned long flags;
+
+	seq_printf(s, "%s %s: %u\n", obj->name, obj->drv_name, obj->value);
+
+	spin_lock_irqsave(&obj->lock, flags);
+	list_for_each(pos, &obj->child_list_head) {
+		struct fence *fence =
+			container_of(pos, struct fence, child_list);
+		fence_print(s, fence, false);
+	}
+	spin_unlock_irqrestore(&obj->lock, flags);
+}
+EXPORT_SYMBOL(fence_timeline_print);
+
+void fence_timeline_print_all(struct seq_file* s)
+{
+	unsigned long flags;
+	struct list_head *pos;
+
+	spin_lock_irqsave(&fence_timeline_list_lock, flags);
+	list_for_each(pos, &fence_timeline_list_head) {
+		struct fence_timeline *obj =
+			container_of(pos, struct fence_timeline,
+				     fence_timeline_list);
+
+		fence_timeline_print(s, obj);
+		seq_puts(s, "\n");
+	}
+	spin_unlock_irqrestore(&fence_timeline_list_lock, flags);
+}
+EXPORT_SYMBOL(fence_timeline_print_all);
+#endif
diff --git a/drivers/staging/android/sync.h b/drivers/staging/android/sync.h
index 256315c..8e6827b 100644
--- a/drivers/staging/android/sync.h
+++ b/drivers/staging/android/sync.h
@@ -184,15 +184,11 @@ int sync_fence_wait(struct sync_fence *fence, long timeout);
 
 #ifdef CONFIG_DEBUG_FS
 
-void sync_timeline_debug_add(struct fence_timeline *obj);
-void sync_timeline_debug_remove(struct fence_timeline *obj);
 void sync_fence_debug_add(struct sync_fence *fence);
 void sync_fence_debug_remove(struct sync_fence *fence);
 void sync_dump(void);
 
 #else
-# define sync_timeline_debug_add(obj)
-# define sync_timeline_debug_remove(obj)
 # define sync_fence_debug_add(fence)
 # define sync_fence_debug_remove(fence)
 # define sync_dump()
diff --git a/drivers/staging/android/sync_debug.c b/drivers/staging/android/sync_debug.c
index 13d225f..8e2ca57 100644
--- a/drivers/staging/android/sync_debug.c
+++ b/drivers/staging/android/sync_debug.c
@@ -33,29 +33,9 @@
 
 static struct dentry *dbgfs;
 
-static LIST_HEAD(sync_timeline_list_head);
-static DEFINE_SPINLOCK(sync_timeline_list_lock);
 static LIST_HEAD(sync_fence_list_head);
 static DEFINE_SPINLOCK(sync_fence_list_lock);
 
-void sync_timeline_debug_add(struct fence_timeline *obj)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&sync_timeline_list_lock, flags);
-	list_add_tail(&obj->fence_timeline_list, &sync_timeline_list_head);
-	spin_unlock_irqrestore(&sync_timeline_list_lock, flags);
-}
-
-void sync_timeline_debug_remove(struct fence_timeline *obj)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&sync_timeline_list_lock, flags);
-	list_del(&obj->fence_timeline_list);
-	spin_unlock_irqrestore(&sync_timeline_list_lock, flags);
-}
-
 void sync_fence_debug_add(struct sync_fence *sync_fence)
 {
 	unsigned long flags;
@@ -74,76 +54,6 @@ void sync_fence_debug_remove(struct sync_fence *sync_fence)
 	spin_unlock_irqrestore(&sync_fence_list_lock, flags);
 }
 
-static const char *sync_status_str(int status)
-{
-	if (status == 0)
-		return "signaled";
-
-	if (status > 0)
-		return "active";
-
-	return "error";
-}
-
-static void sync_print_fence(struct seq_file *s, struct fence *fence, bool show)
-{
-	int status = 1;
-	struct fence_timeline *parent = fence_parent(fence);
-
-	if (fence_is_signaled_locked(fence))
-		status = fence->status;
-
-	seq_printf(s, "  %s%sfence %s",
-		   show ? parent->name : "",
-		   show ? "_" : "",
-		   sync_status_str(status));
-
-	if (status <= 0) {
-		struct timespec64 ts64 =
-			ktime_to_timespec64(fence->timestamp);
-
-		seq_printf(s, "@%lld.%09ld", (s64)ts64.tv_sec, ts64.tv_nsec);
-	}
-
-	if ((!fence || fence->ops->timeline_value_str) &&
-		fence->ops->fence_value_str) {
-		char value[64];
-		bool success;
-
-		fence->ops->fence_value_str(fence, value, sizeof(value));
-		success = strlen(value);
-
-		if (success)
-			seq_printf(s, ": %s", value);
-
-		if (success && fence) {
-			fence->ops->timeline_value_str(fence, value,
-						       sizeof(value));
-
-			if (strlen(value))
-				seq_printf(s, " / %s", value);
-		}
-	}
-
-	seq_puts(s, "\n");
-}
-
-static void sync_print_obj(struct seq_file *s, struct fence_timeline *obj)
-{
-	struct list_head *pos;
-	unsigned long flags;
-
-	seq_printf(s, "%s %s: %d\n", obj->name, obj->drv_name, obj->value);
-
-	spin_lock_irqsave(&obj->lock, flags);
-	list_for_each(pos, &obj->child_list_head) {
-		struct fence *fence =
-			container_of(pos, struct fence, child_list);
-		sync_print_fence(s, fence, false);
-	}
-	spin_unlock_irqrestore(&obj->lock, flags);
-}
-
 static void sync_print_sync_fence(struct seq_file *s,
 				  struct sync_fence *sync_fence)
 {
@@ -152,10 +62,10 @@ static void sync_print_sync_fence(struct seq_file *s,
 	int i;
 
 	seq_printf(s, "[%p] %s: %s\n", sync_fence, sync_fence->name,
-		   sync_status_str(atomic_read(&sync_fence->status)));
+		   fence_status_str(atomic_read(&sync_fence->status)));
 
 	for (i = 0; i < sync_fence->num_fences; ++i) {
-		sync_print_fence(s, sync_fence->cbs[i].fence, true);
+		fence_print(s, sync_fence->cbs[i].fence, true);
 	}
 
 	spin_lock_irqsave(&sync_fence->wq.lock, flags);
@@ -179,16 +89,7 @@ static int sync_debugfs_show(struct seq_file *s, void *unused)
 
 	seq_puts(s, "objs:\n--------------\n");
 
-	spin_lock_irqsave(&sync_timeline_list_lock, flags);
-	list_for_each(pos, &sync_timeline_list_head) {
-		struct fence_timeline *obj =
-			container_of(pos, struct fence_timeline,
-				     fence_timeline_list);
-
-		sync_print_obj(s, obj);
-		seq_puts(s, "\n");
-	}
-	spin_unlock_irqrestore(&sync_timeline_list_lock, flags);
+	fence_timeline_print_all(s);
 
 	seq_puts(s, "fences:\n--------------\n");
 
diff --git a/include/linux/fence.h b/include/linux/fence.h
index adece43..32a26ab 100644
--- a/include/linux/fence.h
+++ b/include/linux/fence.h
@@ -407,6 +407,24 @@ static inline signed long fence_wait(struct fence *fence, bool intr)
 
 unsigned fence_context_alloc(unsigned num);
 
+#ifdef CONFIG_DEBUG_FS
+
+void fence_timeline_debug_add(struct fence_timeline *obj);
+void fence_timeline_debug_remove(struct fence_timeline *obj);
+const char *fence_status_str(int status);
+void fence_print(struct seq_file *s, struct fence *fence, bool show);
+void fence_timeline_print(struct seq_file *s, struct fence_timeline *obj);
+void fence_timeline_print_all(struct seq_file* s);
+
+#else
+#define fence_timeline_debug_add(obj)
+#define fence_timeline_debug_remove(obj)
+#define fence_status_str(status)
+#define fence_print(s, fence, show)
+#define fence_timeline_print(s, obj)
+#define fence_timeline_print_all(s)
+#endif
+
 #define FENCE_TRACE(f, fmt, args...) \
 	do {								\
 		struct fence *__ff = (f);				\
