Lines Matching +full:reserved +full:- +full:memory
1 // SPDX-License-Identifier: GPL-2.0+
3 * Device tree based initialization code for reserved memory.
5 * Copyright (c) 2013, 2015 The Linux Foundation. All Rights Reserved.
12 #define pr_fmt(fmt) "OF: reserved mem: " fmt
46 return -ENOMEM; in early_init_dt_alloc_reserved_memory_arch()
62 * alloc_reserved_mem_array() - allocate memory for the reserved_mem
65 * This function is used to allocate memory for the reserved_mem
66 * array according to the total number of reserved memory regions
79 pr_err("Failed to allocate memory for reserved_mem array with err: %d", -EOVERFLOW); in alloc_reserved_mem_array()
85 pr_err("Failed to allocate memory for reserved_mem array with err: %d", -ENOMEM); in alloc_reserved_mem_array()
93 pr_err("Failed to allocate memory for reserved_mem array with err: %d", -EOVERFLOW); in alloc_reserved_mem_array()
97 memset_size = alloc_size - copy_size; in alloc_reserved_mem_array()
107 * fdt_reserved_mem_save_node() - save fdt node for second pass initialization
119 rmem->fdt_node = node; in fdt_reserved_mem_save_node()
120 rmem->name = uname; in fdt_reserved_mem_save_node()
121 rmem->base = base; in fdt_reserved_mem_save_node()
122 rmem->size = size; in fdt_reserved_mem_save_node()
136 * If the memory is already reserved (by another region), we in early_init_dt_reserve_memory()
138 * if the region isn't memory as it won't be mapped. in early_init_dt_reserve_memory()
140 if (memblock_overlaps_region(&memblock.memory, base, size) && in early_init_dt_reserve_memory()
142 return -EBUSY; in early_init_dt_reserve_memory()
150 * __reserved_mem_reserve_reg() - reserve all memory described in 'reg' property
163 return -ENOENT; in __reserved_mem_reserve_reg()
166 pr_err("Reserved memory: invalid reg property in '%s', skipping node.\n", in __reserved_mem_reserve_reg()
168 return -EINVAL; in __reserved_mem_reserve_reg()
171 nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL; in __reserved_mem_reserve_reg()
179 pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n", in __reserved_mem_reserve_reg()
182 pr_err("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n", in __reserved_mem_reserve_reg()
185 len -= t_len; in __reserved_mem_reserve_reg()
191 * __reserved_mem_check_root() - check if #size-cells, #address-cells provided
192 * in /reserved-memory matches the values supported by the current implementation,
199 prop = of_get_flat_dt_prop(node, "#size-cells", NULL); in __reserved_mem_check_root()
201 return -EINVAL; in __reserved_mem_check_root()
203 prop = of_get_flat_dt_prop(node, "#address-cells", NULL); in __reserved_mem_check_root()
205 return -EINVAL; in __reserved_mem_check_root()
209 return -EINVAL; in __reserved_mem_check_root()
216 * fdt_scan_reserved_mem_reg_nodes() - Store info for the "reg" defined
217 * reserved memory regions.
220 * information for the reserved memory regions that are defined using
237 node = fdt_path_offset(fdt, "/reserved-memory"); in fdt_scan_reserved_mem_reg_nodes()
239 pr_info("Reserved memory: No reserved-memory node in the DT\n"); in fdt_scan_reserved_mem_reg_nodes()
247 pr_err("Reserved memory: unsupported node format, ignoring\n"); in fdt_scan_reserved_mem_reg_nodes()
262 pr_err("Reserved memory: invalid reg property in '%s', skipping node.\n", in fdt_scan_reserved_mem_reg_nodes()
269 __func__, len / t_len - 1, uname); in fdt_scan_reserved_mem_reg_nodes()
278 /* check for overlapping reserved regions */ in fdt_scan_reserved_mem_reg_nodes()
285 * fdt_scan_reserved_mem() - scan a single FDT node for reserved memory
294 node = fdt_path_offset(fdt, "/reserved-memory"); in fdt_scan_reserved_mem()
296 return -ENODEV; in fdt_scan_reserved_mem()
299 pr_err("Reserved memory: unsupported node format, ignoring\n"); in fdt_scan_reserved_mem()
300 return -EINVAL; in fdt_scan_reserved_mem()
316 * Save the nodes for the dynamically-placed regions in fdt_scan_reserved_mem()
318 * after all the statically-placed regions are reserved in fdt_scan_reserved_mem()
319 * or marked as no-map. This is done to avoid dynamically in fdt_scan_reserved_mem()
320 * allocating from one of the statically-placed regions. in fdt_scan_reserved_mem()
322 if (err == -ENOENT && of_get_flat_dt_prop(child, "size", NULL)) { in fdt_scan_reserved_mem()
342 * __reserved_mem_alloc_in_range() - allocate reserved memory described with
343 * 'alloc-ranges'. Choose bottom-up/top-down depending on nearby existing
344 * reserved regions to keep the reserved memory contiguous if possible.
357 /* Skip regions that were not reserved yet */ in __reserved_mem_alloc_in_range()
358 if (rmem->size == 0) in __reserved_mem_alloc_in_range()
362 * If range starts next to an existing reservation, use bottom-up: in __reserved_mem_alloc_in_range()
364 * --RRRR------ in __reserved_mem_alloc_in_range()
366 if (start >= rmem->base && start <= (rmem->base + rmem->size)) in __reserved_mem_alloc_in_range()
370 * If range ends next to an existing reservation, use top-down: in __reserved_mem_alloc_in_range()
372 * -------RRRR----- in __reserved_mem_alloc_in_range()
374 if (end >= rmem->base && end <= (rmem->base + rmem->size)) in __reserved_mem_alloc_in_range()
378 /* Change setting only if either bottom-up or top-down was selected */ in __reserved_mem_alloc_in_range()
393 * __reserved_mem_alloc_size() - allocate reserved memory described by
394 * 'size', 'alignment' and 'alloc-ranges' properties.
408 return -EINVAL; in __reserved_mem_alloc_size()
412 return -EINVAL; in __reserved_mem_alloc_size()
421 return -EINVAL; in __reserved_mem_alloc_size()
426 nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL; in __reserved_mem_alloc_size()
430 && of_flat_dt_is_compatible(node, "shared-dma-pool") in __reserved_mem_alloc_size()
435 prop = of_get_flat_dt_prop(node, "alloc-ranges", &len); in __reserved_mem_alloc_size()
439 pr_err("invalid alloc-ranges property in '%s', skipping node.\n", in __reserved_mem_alloc_size()
441 return -EINVAL; in __reserved_mem_alloc_size()
453 pr_debug("allocated memory for '%s' node: base %pa, size %lu MiB\n", in __reserved_mem_alloc_size()
458 len -= t_len; in __reserved_mem_alloc_size()
465 pr_debug("allocated memory for '%s' node: base %pa, size %lu MiB\n", in __reserved_mem_alloc_size()
470 pr_err("failed to allocate memory for node '%s': size %lu MiB\n", in __reserved_mem_alloc_size()
472 return -ENOMEM; in __reserved_mem_alloc_size()
484 * __reserved_mem_init_node() - call region specific reserved memory init code
490 int ret = -ENOENT; in __reserved_mem_init_node()
493 reservedmem_of_init_fn initfn = i->data; in __reserved_mem_init_node()
494 const char *compat = i->compatible; in __reserved_mem_init_node()
496 if (!of_flat_dt_is_compatible(rmem->fdt_node, compat)) in __reserved_mem_init_node()
502 rmem->name, compat); in __reserved_mem_init_node()
513 if (ra->base < rb->base) in __rmem_cmp()
514 return -1; in __rmem_cmp()
516 if (ra->base > rb->base) in __rmem_cmp()
524 if (ra->size < rb->size) in __rmem_cmp()
525 return -1; in __rmem_cmp()
526 if (ra->size > rb->size) in __rmem_cmp()
529 if (ra->fdt_node < rb->fdt_node) in __rmem_cmp()
530 return -1; in __rmem_cmp()
531 if (ra->fdt_node > rb->fdt_node) in __rmem_cmp()
546 for (i = 0; i < reserved_mem_count - 1; i++) { in __rmem_check_for_overlap()
552 if (this->base + this->size > next->base) { in __rmem_check_for_overlap()
555 this_end = this->base + this->size; in __rmem_check_for_overlap()
556 next_end = next->base + next->size; in __rmem_check_for_overlap()
557 pr_err("OVERLAP DETECTED!\n%s (%pa--%pa) overlaps with %s (%pa--%pa)\n", in __rmem_check_for_overlap()
558 this->name, &this->base, &this_end, in __rmem_check_for_overlap()
559 next->name, &next->base, &next_end); in __rmem_check_for_overlap()
565 * fdt_init_reserved_mem_node() - Initialize a reserved memory region
566 * @rmem: reserved_mem struct of the memory region to be initialized.
569 * function for a reserved memory region.
573 unsigned long node = rmem->fdt_node; in fdt_init_reserved_mem_node()
577 nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL; in fdt_init_reserved_mem_node()
580 if (err != 0 && err != -ENOENT) { in fdt_init_reserved_mem_node()
581 pr_info("node %s compatible matching fail\n", rmem->name); in fdt_init_reserved_mem_node()
583 memblock_clear_nomap(rmem->base, rmem->size); in fdt_init_reserved_mem_node()
585 memblock_phys_free(rmem->base, rmem->size); in fdt_init_reserved_mem_node()
587 phys_addr_t end = rmem->base + rmem->size - 1; in fdt_init_reserved_mem_node()
592 &rmem->base, &end, (unsigned long)(rmem->size / SZ_1K), in fdt_init_reserved_mem_node()
594 reusable ? "reusable" : "non-reusable", in fdt_init_reserved_mem_node()
595 rmem->name ? rmem->name : "unknown"); in fdt_init_reserved_mem_node()
609 * of_reserved_mem_device_init_by_idx() - assign reserved memory region to
612 * @np: Pointer to the device_node with 'reserved-memory' property
615 * This function assigns respective DMA-mapping operations based on reserved
616 * memory region specified by 'memory-region' property in @np node to the @dev
617 * device. When driver needs to use more than one reserved memory region, it
632 return -EINVAL; in of_reserved_mem_device_init_by_idx()
634 target = of_parse_phandle(np, "memory-region", idx); in of_reserved_mem_device_init_by_idx()
636 return -ENODEV; in of_reserved_mem_device_init_by_idx()
646 if (!rmem || !rmem->ops || !rmem->ops->device_init) in of_reserved_mem_device_init_by_idx()
647 return -EINVAL; in of_reserved_mem_device_init_by_idx()
651 return -ENOMEM; in of_reserved_mem_device_init_by_idx()
653 ret = rmem->ops->device_init(rmem, dev); in of_reserved_mem_device_init_by_idx()
655 rd->dev = dev; in of_reserved_mem_device_init_by_idx()
656 rd->rmem = rmem; in of_reserved_mem_device_init_by_idx()
659 list_add(&rd->list, &of_rmem_assigned_device_list); in of_reserved_mem_device_init_by_idx()
662 dev_info(dev, "assigned reserved memory node %s\n", rmem->name); in of_reserved_mem_device_init_by_idx()
672 * of_reserved_mem_device_init_by_name() - assign named reserved memory region
675 * @np: pointer to the device node with 'memory-region' property
676 * @name: name of the selected memory region
678 * Returns: 0 on success or a negative error-code on failure.
684 int idx = of_property_match_string(np, "memory-region-names", name); in of_reserved_mem_device_init_by_name()
691 * of_reserved_mem_device_release() - release reserved memory device structures
694 * This function releases structures allocated for memory region handling for
704 if (rd->dev == dev) in of_reserved_mem_device_release()
705 list_move_tail(&rd->list, &release_list); in of_reserved_mem_device_release()
710 if (rd->rmem && rd->rmem->ops && rd->rmem->ops->device_release) in of_reserved_mem_device_release()
711 rd->rmem->ops->device_release(rd->rmem, dev); in of_reserved_mem_device_release()
719 * of_reserved_mem_lookup() - acquire reserved_mem from a device node
720 * @np: node pointer of the desired reserved-memory region
732 if (!np->full_name) in of_reserved_mem_lookup()
735 name = kbasename(np->full_name); in of_reserved_mem_lookup()