diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c
index e8fe9dc..86129ef 100644
--- a/drivers/dma/of-dma.c
+++ b/drivers/dma/of-dma.c
@@ -19,7 +19,29 @@
 #include <linux/of_dma.h>
 
 static LIST_HEAD(of_dma_list);
+static LIST_HEAD(of_dma_router_list);
 static DEFINE_MUTEX(of_dma_lock);
+static DEFINE_MUTEX(of_dma_router_lock);
+
+/**
+ * of_dma_get_router_data - Get a DMA router in DT DMA routers list
+ * @phandle:	phandle to the dma router
+ *
+ * Finds a DMA router using matching phandle and returns the router
+ * specific data. Should be called from dma-controller xlate callback.
+ */
+void *of_dma_get_router_data(phandle router)
+{
+	struct of_dma_router *ofrouter;
+
+	list_for_each_entry(ofrouter, &of_dma_router_list, of_dma_routers) {
+		if (ofrouter->of_node->phandle == router)
+			return ofrouter->of_router_data;
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL(of_dma_get_router_data);
 
 /**
  * of_dma_find_controller - Get a DMA controller in DT DMA helpers list
@@ -45,6 +67,39 @@ static struct of_dma *of_dma_find_controller(struct of_phandle_args *dma_spec)
 }
 
 /**
+ * of_dma_router_register - Register a DMA router to DT DMA helpers
+ * @np:			device node of DMA controller
+ * @data		pointer to controller specific data to be used by
+ *			dma-controller
+ *
+ * Returns 0 on success or appropriate errno value on error.
+ *
+ * Allocated memory should be freed with appropriate of_dma_router_free()
+ * call.
+ */
+int of_dma_router_register(struct device_node *np, void *data)
+{
+	struct of_dma_router *ofrouter;
+
+	if (!np || !data)
+		return -EINVAL;
+
+	ofrouter = kzalloc(sizeof(*ofrouter), GFP_KERNEL);
+	if (!ofrouter)
+		return -ENOMEM;
+
+	ofrouter->of_node = np;
+	ofrouter->of_router_data = data;
+
+	mutex_lock(&of_dma_router_lock);
+	list_add_tail(&ofrouter->of_dma_routers, &of_dma_router_list);
+	mutex_unlock(&of_dma_router_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL(of_dma_router_register);
+
+/**
  * of_dma_controller_register - Register a DMA controller to DT DMA helpers
  * @np:			device node of DMA controller
  * @of_dma_xlate:	translation function which converts a phandle
@@ -87,10 +142,10 @@ int of_dma_controller_register(struct device_node *np,
 EXPORT_SYMBOL_GPL(of_dma_controller_register);
 
 /**
- * of_dma_controller_free - Remove a DMA controller from DT DMA helpers list
+ * of_dma_router_free - Remove a DMA router from DT DMA routers list
  * @np:		device node of DMA controller
  *
- * Memory allocated by of_dma_controller_register() is freed here.
+ * Memory allocated by of_dma_router_register() is freed here.
  */
 void of_dma_controller_free(struct device_node *np)
 {
@@ -110,6 +165,29 @@ void of_dma_controller_free(struct device_node *np)
 EXPORT_SYMBOL_GPL(of_dma_controller_free);
 
 /**
+ * of_dma_controller_free - Remove a DMA controller from DT DMA helpers list
+ * @np:		device node of DMA controller
+ *
+ * Memory allocated by of_dma_router_register() is freed here.
+ */
+void of_dma_router_free(struct device_node *np)
+{
+	struct of_dma_router *ofrouter;
+
+	mutex_lock(&of_dma_router_lock);
+
+	list_for_each_entry(ofrouter, &of_dma_router_list, of_dma_routers)
+		if (ofrouter->of_node == np) {
+			list_del(&ofrouter->of_dma_routers);
+			kfree(ofrouter);
+			break;
+		}
+
+	mutex_unlock(&of_dma_router_lock);
+}
+EXPORT_SYMBOL_GPL(of_dma_router_free);
+
+/**
  * of_dma_match_channel - Check if a DMA specifier matches name
  * @np:		device node to look for DMA channels
  * @name:	channel name to be matched
diff --git a/include/linux/of_dma.h b/include/linux/of_dma.h
index ae36298..50962a0 100644
--- a/include/linux/of_dma.h
+++ b/include/linux/of_dma.h
@@ -26,6 +26,12 @@ struct of_dma {
 	void			*of_dma_data;
 };
 
+struct of_dma_router {
+	struct list_head	of_dma_routers;
+	struct device_node	*of_node;
+	void			*of_router_data;
+};
+
 struct of_dma_filter_info {
 	dma_cap_mask_t	dma_cap;
 	dma_filter_fn	filter_fn;
@@ -41,6 +47,9 @@ extern struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
 						     const char *name);
 extern struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec,
 		struct of_dma *ofdma);
+extern void *of_dma_get_router_data(phandle router);
+extern int of_dma_router_register(struct device_node *np, void *data);
+extern void of_dma_router_free(struct device_node *np);
 #else
 static inline int of_dma_controller_register(struct device_node *np,
 		struct dma_chan *(*of_dma_xlate)
@@ -66,6 +75,19 @@ static inline struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_s
 	return NULL;
 }
 
+static inline void *of_dma_get_router_data(phandle router)
+{
+	return NULL;
+}
+
+static inline int of_dma_router_register(struct device_node *np, void *data)
+{
+	return NULL;
+}
+
+static void of_dma_router_free(struct device_node *np)
+{
+}
 #endif
 
 #endif /* __LINUX_OF_DMA_H */
