/** * dma_contiguous_reserve() - reserve area(s) for contiguous memory handling * @limit: End address of the reserved memory (optional, 0 for any). * * This function reserves memory from early allocator. It should be * called by arch specific code once the early allocator (memblock or bootmem) * has been activated and all other subsystems have already allocated/reserved * memory. */ void __init dma_contiguous_reserve(phys_addr_t limit) { phys_addr_t selected_size = 0; pr_debug("%s(limit %08lx)\n", __func__, (unsigned long)limit); if (size_cmdline != -1) { selected_size = size_cmdline; } else { #ifdef CONFIG_CMA_SIZE_SEL_MBYTES selected_size = size_bytes; #elif defined(CONFIG_CMA_SIZE_SEL_PERCENTAGE) selected_size = cma_early_percent_memory(); #elif defined(CONFIG_CMA_SIZE_SEL_MIN) selected_size = min(size_bytes, cma_early_percent_memory()); #elif defined(CONFIG_CMA_SIZE_SEL_MAX) selected_size = max(size_bytes, cma_early_percent_memory()); #endif } if (selected_size && !dma_contiguous_default_area) { pr_debug("%s: reserving %ld MiB for global area\n", __func__, (unsigned long)selected_size / SZ_1M); __dma_contiguous_reserve_area(selected_size, 0, limit, &dma_contiguous_default_area); } };
int __init cma_reserve_mem_fdt_scan(unsigned long node, const char *uname, int depth, void *data) { static int found; phys_addr_t base, size; int len; int sec_prot = 0; int dynamic_prot = 0; const __be32 *prop; unsigned long size_cells = dt_root_size_cells; unsigned long addr_cells = dt_root_addr_cells; char *status; char *cma_name = NULL; if (!found && depth == 1 && strcmp(uname, "reserved-memory") == 0) { prop = of_get_flat_dt_prop(node, "#size-cells", NULL); if (prop) size_cells = be32_to_cpup(prop); prop = of_get_flat_dt_prop(node, "#address-cells", NULL); if (prop) addr_cells = be32_to_cpup(prop); found = 1; /* scan next node */ return 0; } else if (!found) { /* scan next node */ return 0; } else if (found && depth < 2) { /* scanning of /reserved-memory has been finished */ return 1; } status = (char *)of_get_flat_dt_prop(node, "status", NULL); /* * Yes, we actually want strncmp here to check for a prefix * ok vs. okay */ if (status && (strncmp(status, "ok", 2) != 0)) return 0; if (!of_get_flat_dt_prop(node, "hisi,cma-mem", NULL)) return 0; if (of_get_flat_dt_prop(node, "hisi,sec-mem", NULL)) sec_prot = 1; if (of_get_flat_dt_prop(node, "hisi,cma-dynamic", NULL)) dynamic_prot = 1; prop = (const __be32 *)of_get_flat_dt_prop(node, "reg", &len); if (!prop&&(depth != 2)) return 0; cma_name = (char *)of_get_flat_dt_prop(node, "hisi,cma-name", NULL); base = (phys_addr_t)dt_mem_next_cell(addr_cells, &prop); size = (phys_addr_t)dt_mem_next_cell(size_cells, &prop); pr_err("size is %lu base 0x%lu cma_name %s\n", (unsigned long)size / SZ_1M, (unsigned long)base, cma_name); __dma_contiguous_reserve_area(size, base, SZ_4M, cma_name, NULL,sec_prot,dynamic_prot); return 0; }
int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base, phys_addr_t limit, struct cma **res_cma) { return __dma_contiguous_reserve_area(size, base, limit, res_cma); }