cma: Add support for associating regions by name

Currently, the devicetree lookup code assumes that all
CMA regions are present at a fixed address and uses the
fixed address for associating CMA regions to devices.
This presents a problem for dynamically assigning regions.
Device names get mangled/changed between flattened and
populated devicetree so relying on that is unworkable.
Add a separate name binding to allow lookup later between
devices.

Change-Id: Iaacd9888ea708d7293f1120e2b8c473c5c601f3d
Signed-off-by: Laura Abbott <lauraa@codeaurora.org>
This commit is contained in:
Laura Abbott
2013-03-06 12:43:34 -08:00
parent 51f4635bdf
commit 52c4dce95e
3 changed files with 37 additions and 7 deletions
+6 -1
View File
@@ -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
+29 -4
View File
@@ -58,6 +58,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;
@@ -77,6 +78,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
@@ -196,6 +211,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))
@@ -208,9 +224,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;
}
@@ -251,7 +269,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
@@ -274,7 +293,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;
@@ -326,6 +345,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;
@@ -366,6 +386,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);
@@ -373,7 +394,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;
+2 -2
View File
@@ -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;