diff --git a/Documentation/devicetree/bindings/memory.txt b/Documentation/devicetree/bindings/memory.txt
index 74e0476ed717345bc53dedf83e4bbcee1b95fd88..e98ee0588f3c9ecffe829139ed95bfd042ed545a 100644
--- a/Documentation/devicetree/bindings/memory.txt
+++ b/Documentation/devicetree/bindings/memory.txt
@@ -36,6 +36,7 @@ wit the following convention:
 	reg = <(baseaddr) (size)>;
 	(linux,contiguous-region);
 	(linux,default-contiguous-region);
+        label = (unique_name);
 };
 
 name:		an name given to the defined region.
@@ -47,7 +48,11 @@ linux,contiguous-region: property indicating that the defined memory
 linux,default-contiguous-region: property indicating that the region
 		is the default region for all contiguous memory
 		allocations, Linux specific (optional)
-
+label:		an internal name used for automatically associating the
+		cma region with a given device. The label is optional;
+		if the label is not given the client is responsible for
+		calling the appropriate functions to associate the region
+		with a device.
 
 * Device nodes
 
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index 24b1c7ff8859e9a6a002d5006ea1cf2514a54147..81372444caea3d5b868130fcdb39eca3b02c2c40 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -55,6 +55,7 @@ static struct cma_area {
 	phys_addr_t base;
 	unsigned long size;
 	struct cma *cma;
+	const char *name;
 } cma_areas[MAX_CMA_AREAS];
 static unsigned cma_area_count;
 
@@ -74,6 +75,20 @@ static struct cma *cma_get_area(phys_addr_t base)
 	return NULL;
 }
 
+static struct cma *cma_get_area_by_name(const char *name)
+{
+	int i;
+	if (!name)
+		return NULL;
+
+	for (i = 0; i < cma_area_count; i++)
+		if (cma_areas[i].name && strcmp(cma_areas[i].name, name) == 0)
+			return cma_areas[i].cma;
+	return NULL;
+}
+
+
+
 #ifdef CONFIG_CMA_SIZE_MBYTES
 #define CMA_SIZE_MBYTES CONFIG_CMA_SIZE_MBYTES
 #else
@@ -193,6 +208,7 @@ int __init cma_fdt_scan(unsigned long node, const char *uname,
 	phys_addr_t base, size;
 	unsigned long len;
 	__be32 *prop;
+	char *name;
 
 	if (strncmp(uname, "region@", 7) != 0 || depth != 2 ||
 	    !of_get_flat_dt_prop(node, "linux,contiguous-region", NULL))
@@ -205,9 +221,11 @@ int __init cma_fdt_scan(unsigned long node, const char *uname,
 	base = be32_to_cpu(prop[0]);
 	size = be32_to_cpu(prop[1]);
 
+	name = of_get_flat_dt_prop(node, "label", NULL);
+
 	pr_info("Found %s, memory base %lx, size %ld MiB\n", uname,
 		(unsigned long)base, (unsigned long)size / SZ_1M);
-	dma_contiguous_reserve_area(size, &base, 0);
+	dma_contiguous_reserve_area(size, &base, 0, name);
 
 	return 0;
 }
@@ -248,7 +266,8 @@ void __init dma_contiguous_reserve(phys_addr_t limit)
 		pr_debug("%s: reserving %ld MiB for global area\n", __func__,
 			 (unsigned long)sel_size / SZ_1M);
 
-		if (dma_contiguous_reserve_area(sel_size, &base, limit) == 0)
+		if (dma_contiguous_reserve_area(sel_size, &base, limit, NULL)
+		    == 0)
 			dma_contiguous_def_base = base;
 	}
 #ifdef CONFIG_OF
@@ -271,7 +290,7 @@ void __init dma_contiguous_reserve(phys_addr_t limit)
  * devices.
  */
 int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t *res_base,
-				       phys_addr_t limit)
+				       phys_addr_t limit, const char *name)
 {
 	phys_addr_t base = *res_base;
 	phys_addr_t alignment;
@@ -323,6 +342,7 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t *res_base,
 	 */
 	cma_areas[cma_area_count].base = base;
 	cma_areas[cma_area_count].size = size;
+	cma_areas[cma_area_count].name = name;
 	cma_area_count++;
 	*res_base = base;
 
@@ -363,6 +383,7 @@ static void cma_assign_device_from_dt(struct device *dev)
 {
 	struct device_node *node;
 	struct cma *cma;
+	const char *name;
 	u32 value;
 
 	node = of_parse_phandle(dev->of_node, "linux,contiguous-region", 0);
@@ -370,7 +391,11 @@ static void cma_assign_device_from_dt(struct device *dev)
 		return;
 	if (of_property_read_u32(node, "reg", &value) && !value)
 		return;
-	cma = cma_get_area(value);
+
+	if (of_property_read_string(node, "label", &name))
+		return;
+
+	cma = cma_get_area_by_name(name);
 	if (!cma)
 		return;
 
diff --git a/include/linux/dma-contiguous.h b/include/linux/dma-contiguous.h
index 285b593f47b98d20a5748f86e69d72f919a050b8..8a1b3a1b41bddad77ac52325aaf317e96015b67f 100644
--- a/include/linux/dma-contiguous.h
+++ b/include/linux/dma-contiguous.h
@@ -70,7 +70,7 @@ extern struct cma *dma_contiguous_def_area;
 void dma_contiguous_reserve(phys_addr_t addr_limit);
 
 int dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t *res_base,
-				  phys_addr_t limit);
+				  phys_addr_t limit, const char *name);
 
 int dma_contiguous_add_device(struct device *dev, phys_addr_t base);
 
@@ -91,7 +91,7 @@ static inline int dma_declare_contiguous(struct device *dev, phys_addr_t size,
 					 phys_addr_t base, phys_addr_t limit)
 {
 	int ret;
-	ret = dma_contiguous_reserve_area(size, &base, limit);
+	ret = dma_contiguous_reserve_area(size, &base, limit, NULL);
 	if (ret == 0)
 		ret = dma_contiguous_add_device(dev, base);
 	return ret;