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;