diff --git a/Documentation/devicetree/bindings/memory.txt b/Documentation/devicetree/bindings/memory.txt index 21299d1525c4bf06941fa636d09acb7cc1891d7e..3ee245ee8efa2e3d136df1ca1679592c905671c3 100644 --- a/Documentation/devicetree/bindings/memory.txt +++ b/Documentation/devicetree/bindings/memory.txt @@ -37,6 +37,7 @@ wit the following convention: (linux,contiguous-region); (linux,default-contiguous-region); (linux,reserve-region); + (linux,memory-limit); label = (unique_name); }; @@ -52,6 +53,11 @@ linux,default-contiguous-region: property indicating that the region linux,reserve-region: property indicating that the contiguous memory will not be given back to the system allocator. The memory be always be available for contiguous use. +linux,memory-limit: property specifying an upper bound on the physical address + of the region if the region is placed dynamically. If no limit + is specificed, the region may be placed anywhere in the physical + address space. 0 may be used to specify lowmem (i.e. the region + will be placed in the direct mapped lowmem region) 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 diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c index caf870b3c852108401b6c7aceaa54a6b54a23dfe..022c1718b70839341c4987de4c7aa88f19525398 100644 --- a/drivers/base/dma-contiguous.c +++ b/drivers/base/dma-contiguous.c @@ -222,6 +222,7 @@ int __init cma_fdt_scan(unsigned long node, const char *uname, bool in_system; unsigned long size_cells = dt_root_size_cells; unsigned long addr_cells = dt_root_addr_cells; + phys_addr_t limit = MEMBLOCK_ALLOC_ANYWHERE; if (!of_get_flat_dt_prop(node, "linux,contiguous-region", NULL)) return 0; @@ -245,9 +246,13 @@ int __init cma_fdt_scan(unsigned long node, const char *uname, in_system = of_get_flat_dt_prop(node, "linux,reserve-region", NULL) ? 0 : 1; - 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, MEMBLOCK_ALLOC_ANYWHERE, name, + prop = of_get_flat_dt_prop(node, "linux,memory-limit", NULL); + if (prop) + limit = be32_to_cpu(prop[0]); + + pr_info("Found %s, memory base %lx, size %ld MiB, limit %pa\n", uname, + (unsigned long)base, (unsigned long)size / SZ_1M, &limit); + dma_contiguous_reserve_area(size, &base, limit, name, in_system); return 0;