Lines Matching +full:a +full:- +full:child +full:- +full:node +full:- +full:property

1 // SPDX-License-Identifier: GPL-2.0+
28 #include <linux/dma-map-ops.h>
48 return -ENOMEM; in early_init_dt_alloc_reserved_memory_arch()
64 * alloc_reserved_mem_array() - allocate memory for the reserved_mem
81 pr_err("Failed to allocate memory for reserved_mem array with err: %d", -EOVERFLOW); in alloc_reserved_mem_array()
87 pr_err("Failed to allocate memory for reserved_mem array with err: %d", -ENOMEM); in alloc_reserved_mem_array()
95 pr_err("Failed to allocate memory for reserved_mem array with err: %d", -EOVERFLOW); in alloc_reserved_mem_array()
99 memset_size = alloc_size - copy_size; in alloc_reserved_mem_array()
109 * fdt_reserved_mem_save_node() - save fdt node for second pass initialization
111 static void __init fdt_reserved_mem_save_node(unsigned long node, const char *uname, in fdt_reserved_mem_save_node() argument
121 rmem->fdt_node = node; in fdt_reserved_mem_save_node()
122 rmem->name = uname; in fdt_reserved_mem_save_node()
123 rmem->base = base; in fdt_reserved_mem_save_node()
124 rmem->size = size; in fdt_reserved_mem_save_node()
144 return -EBUSY; in early_init_dt_reserve_memory()
152 * __reserved_mem_reserve_reg() - reserve all memory described in 'reg' property
154 static int __init __reserved_mem_reserve_reg(unsigned long node, in __reserved_mem_reserve_reg() argument
163 prop = of_get_flat_dt_prop(node, "reg", &len); in __reserved_mem_reserve_reg()
165 return -ENOENT; in __reserved_mem_reserve_reg()
168 pr_err("Reserved memory: invalid reg property in '%s', skipping node.\n", in __reserved_mem_reserve_reg()
170 return -EINVAL; in __reserved_mem_reserve_reg()
173 nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL; in __reserved_mem_reserve_reg()
181 if (of_flat_dt_is_compatible(node, "shared-dma-pool") && in __reserved_mem_reserve_reg()
182 of_get_flat_dt_prop(node, "reusable", NULL)) in __reserved_mem_reserve_reg()
184 pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n", in __reserved_mem_reserve_reg()
187 pr_err("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n", in __reserved_mem_reserve_reg()
191 len -= t_len; in __reserved_mem_reserve_reg()
197 * __reserved_mem_check_root() - check if #size-cells, #address-cells provided
198 * in /reserved-memory matches the values supported by the current implementation,
199 * also check if ranges property has been provided
201 static int __init __reserved_mem_check_root(unsigned long node) in __reserved_mem_check_root() argument
205 prop = of_get_flat_dt_prop(node, "#size-cells", NULL); in __reserved_mem_check_root()
207 return -EINVAL; in __reserved_mem_check_root()
209 prop = of_get_flat_dt_prop(node, "#address-cells", NULL); in __reserved_mem_check_root()
211 return -EINVAL; in __reserved_mem_check_root()
213 prop = of_get_flat_dt_prop(node, "ranges", NULL); in __reserved_mem_check_root()
215 return -EINVAL; in __reserved_mem_check_root()
222 * fdt_scan_reserved_mem_reg_nodes() - Store info for the "reg" defined
227 * the "reg" property. The region node number, name, base address, and
237 int node, child; in fdt_scan_reserved_mem_reg_nodes() local
243 node = fdt_path_offset(fdt, "/reserved-memory"); in fdt_scan_reserved_mem_reg_nodes()
244 if (node < 0) { in fdt_scan_reserved_mem_reg_nodes()
245 pr_info("Reserved memory: No reserved-memory node in the DT\n"); in fdt_scan_reserved_mem_reg_nodes()
249 /* Attempt dynamic allocation of a new reserved_mem array */ in fdt_scan_reserved_mem_reg_nodes()
252 if (__reserved_mem_check_root(node)) { in fdt_scan_reserved_mem_reg_nodes()
253 pr_err("Reserved memory: unsupported node format, ignoring\n"); in fdt_scan_reserved_mem_reg_nodes()
257 fdt_for_each_subnode(child, fdt, node) { in fdt_scan_reserved_mem_reg_nodes()
260 prop = of_get_flat_dt_prop(child, "reg", &len); in fdt_scan_reserved_mem_reg_nodes()
263 if (!of_fdt_device_is_available(fdt, child)) in fdt_scan_reserved_mem_reg_nodes()
266 uname = fdt_get_name(fdt, child, NULL); in fdt_scan_reserved_mem_reg_nodes()
268 pr_err("Reserved memory: invalid reg property in '%s', skipping node.\n", in fdt_scan_reserved_mem_reg_nodes()
274 pr_warn("%s() ignores %d regions in node '%s'\n", in fdt_scan_reserved_mem_reg_nodes()
275 __func__, len / t_len - 1, uname); in fdt_scan_reserved_mem_reg_nodes()
281 fdt_reserved_mem_save_node(child, uname, base, size); in fdt_scan_reserved_mem_reg_nodes()
288 static int __init __reserved_mem_alloc_size(unsigned long node, const char *uname);
291 * fdt_scan_reserved_mem() - scan a single FDT node for reserved memory
295 int node, child; in fdt_scan_reserved_mem() local
300 node = fdt_path_offset(fdt, "/reserved-memory"); in fdt_scan_reserved_mem()
301 if (node < 0) in fdt_scan_reserved_mem()
302 return -ENODEV; in fdt_scan_reserved_mem()
304 if (__reserved_mem_check_root(node) != 0) { in fdt_scan_reserved_mem()
305 pr_err("Reserved memory: unsupported node format, ignoring\n"); in fdt_scan_reserved_mem()
306 return -EINVAL; in fdt_scan_reserved_mem()
309 fdt_for_each_subnode(child, fdt, node) { in fdt_scan_reserved_mem()
313 if (!of_fdt_device_is_available(fdt, child)) in fdt_scan_reserved_mem()
316 uname = fdt_get_name(fdt, child, NULL); in fdt_scan_reserved_mem()
318 err = __reserved_mem_reserve_reg(child, uname); in fdt_scan_reserved_mem()
322 * Save the nodes for the dynamically-placed regions in fdt_scan_reserved_mem()
324 * after all the statically-placed regions are reserved in fdt_scan_reserved_mem()
325 * or marked as no-map. This is done to avoid dynamically in fdt_scan_reserved_mem()
326 * allocating from one of the statically-placed regions. in fdt_scan_reserved_mem()
328 if (err == -ENOENT && of_get_flat_dt_prop(child, "size", NULL)) { in fdt_scan_reserved_mem()
329 dynamic_nodes[dynamic_nodes_cnt] = child; in fdt_scan_reserved_mem()
337 child = dynamic_nodes[i]; in fdt_scan_reserved_mem()
338 uname = fdt_get_name(fdt, child, NULL); in fdt_scan_reserved_mem()
339 err = __reserved_mem_alloc_size(child, uname); in fdt_scan_reserved_mem()
348 * __reserved_mem_alloc_in_range() - allocate reserved memory described with
349 * 'alloc-ranges'. Choose bottom-up/top-down depending on nearby existing
364 if (rmem->size == 0) in __reserved_mem_alloc_in_range()
368 * If range starts next to an existing reservation, use bottom-up: in __reserved_mem_alloc_in_range()
370 * --RRRR------ in __reserved_mem_alloc_in_range()
372 if (start >= rmem->base && start <= (rmem->base + rmem->size)) in __reserved_mem_alloc_in_range()
376 * If range ends next to an existing reservation, use top-down: in __reserved_mem_alloc_in_range()
378 * -------RRRR----- in __reserved_mem_alloc_in_range()
380 if (end >= rmem->base && end <= (rmem->base + rmem->size)) in __reserved_mem_alloc_in_range()
384 /* Change setting only if either bottom-up or top-down was selected */ in __reserved_mem_alloc_in_range()
399 * __reserved_mem_alloc_size() - allocate reserved memory described by
400 * 'size', 'alignment' and 'alloc-ranges' properties.
402 static int __init __reserved_mem_alloc_size(unsigned long node, const char *uname) in __reserved_mem_alloc_size() argument
412 prop = of_get_flat_dt_prop(node, "size", &len); in __reserved_mem_alloc_size()
414 return -EINVAL; in __reserved_mem_alloc_size()
417 pr_err("invalid size property in '%s' node.\n", uname); in __reserved_mem_alloc_size()
418 return -EINVAL; in __reserved_mem_alloc_size()
422 prop = of_get_flat_dt_prop(node, "alignment", &len); in __reserved_mem_alloc_size()
425 pr_err("invalid alignment property in '%s' node.\n", in __reserved_mem_alloc_size()
427 return -EINVAL; in __reserved_mem_alloc_size()
432 nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL; in __reserved_mem_alloc_size()
436 && of_flat_dt_is_compatible(node, "shared-dma-pool") in __reserved_mem_alloc_size()
437 && of_get_flat_dt_prop(node, "reusable", NULL) in __reserved_mem_alloc_size()
441 prop = of_get_flat_dt_prop(node, "alloc-ranges", &len); in __reserved_mem_alloc_size()
445 pr_err("invalid alloc-ranges property in '%s', skipping node.\n", in __reserved_mem_alloc_size()
447 return -EINVAL; in __reserved_mem_alloc_size()
459 pr_debug("allocated memory for '%s' node: base %pa, size %lu MiB\n", in __reserved_mem_alloc_size()
464 len -= t_len; in __reserved_mem_alloc_size()
471 pr_debug("allocated memory for '%s' node: base %pa, size %lu MiB\n", in __reserved_mem_alloc_size()
476 pr_err("failed to allocate memory for node '%s': size %lu MiB\n", in __reserved_mem_alloc_size()
478 return -ENOMEM; in __reserved_mem_alloc_size()
481 if (of_flat_dt_is_compatible(node, "shared-dma-pool") && in __reserved_mem_alloc_size()
482 of_get_flat_dt_prop(node, "reusable", NULL)) in __reserved_mem_alloc_size()
485 fdt_reserved_mem_save_node(node, uname, base, size); in __reserved_mem_alloc_size()
493 * __reserved_mem_init_node() - call region specific reserved memory init code
499 int ret = -ENOENT; in __reserved_mem_init_node()
502 reservedmem_of_init_fn initfn = i->data; in __reserved_mem_init_node()
503 const char *compat = i->compatible; in __reserved_mem_init_node()
505 if (!of_flat_dt_is_compatible(rmem->fdt_node, compat)) in __reserved_mem_init_node()
510 pr_info("initialized node %s, compatible id %s\n", in __reserved_mem_init_node()
511 rmem->name, compat); in __reserved_mem_init_node()
518 static int __init __rmem_cmp(const void *a, const void *b) in __rmem_cmp() argument
520 const struct reserved_mem *ra = a, *rb = b; in __rmem_cmp()
522 if (ra->base < rb->base) in __rmem_cmp()
523 return -1; in __rmem_cmp()
525 if (ra->base > rb->base) in __rmem_cmp()
533 if (ra->size < rb->size) in __rmem_cmp()
534 return -1; in __rmem_cmp()
535 if (ra->size > rb->size) in __rmem_cmp()
538 if (ra->fdt_node < rb->fdt_node) in __rmem_cmp()
539 return -1; in __rmem_cmp()
540 if (ra->fdt_node > rb->fdt_node) in __rmem_cmp()
555 for (i = 0; i < reserved_mem_count - 1; i++) { in __rmem_check_for_overlap()
561 if (this->base + this->size > next->base) { in __rmem_check_for_overlap()
564 this_end = this->base + this->size; in __rmem_check_for_overlap()
565 next_end = next->base + next->size; in __rmem_check_for_overlap()
566 pr_err("OVERLAP DETECTED!\n%s (%pa--%pa) overlaps with %s (%pa--%pa)\n", in __rmem_check_for_overlap()
567 this->name, &this->base, &this_end, in __rmem_check_for_overlap()
568 next->name, &next->base, &next_end); in __rmem_check_for_overlap()
574 * fdt_init_reserved_mem_node() - Initialize a reserved memory region
578 * function for a reserved memory region.
582 unsigned long node = rmem->fdt_node; in fdt_init_reserved_mem_node() local
586 nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL; in fdt_init_reserved_mem_node()
589 if (err != 0 && err != -ENOENT) { in fdt_init_reserved_mem_node()
590 pr_info("node %s compatible matching fail\n", rmem->name); in fdt_init_reserved_mem_node()
592 memblock_clear_nomap(rmem->base, rmem->size); in fdt_init_reserved_mem_node()
594 memblock_phys_free(rmem->base, rmem->size); in fdt_init_reserved_mem_node()
596 phys_addr_t end = rmem->base + rmem->size - 1; in fdt_init_reserved_mem_node()
598 (of_get_flat_dt_prop(node, "reusable", NULL)) != NULL; in fdt_init_reserved_mem_node()
601 &rmem->base, &end, (unsigned long)(rmem->size / SZ_1K), in fdt_init_reserved_mem_node()
603 reusable ? "reusable" : "non-reusable", in fdt_init_reserved_mem_node()
604 rmem->name ? rmem->name : "unknown"); in fdt_init_reserved_mem_node()
618 * of_reserved_mem_device_init_by_idx() - assign reserved memory region to
621 * @np: Pointer to the device_node with 'reserved-memory' property
624 * This function assigns respective DMA-mapping operations based on reserved
625 * memory region specified by 'memory-region' property in @np node to the @dev
627 * should allocate child devices and initialize regions by name for each of
628 * child device.
641 return -EINVAL; in of_reserved_mem_device_init_by_idx()
643 target = of_parse_phandle(np, "memory-region", idx); in of_reserved_mem_device_init_by_idx()
645 return -ENODEV; in of_reserved_mem_device_init_by_idx()
655 if (!rmem || !rmem->ops || !rmem->ops->device_init) in of_reserved_mem_device_init_by_idx()
656 return -EINVAL; in of_reserved_mem_device_init_by_idx()
660 return -ENOMEM; in of_reserved_mem_device_init_by_idx()
662 ret = rmem->ops->device_init(rmem, dev); in of_reserved_mem_device_init_by_idx()
664 rd->dev = dev; in of_reserved_mem_device_init_by_idx()
665 rd->rmem = rmem; in of_reserved_mem_device_init_by_idx()
668 list_add(&rd->list, &of_rmem_assigned_device_list); in of_reserved_mem_device_init_by_idx()
671 dev_info(dev, "assigned reserved memory node %s\n", rmem->name); in of_reserved_mem_device_init_by_idx()
681 * of_reserved_mem_device_init_by_name() - assign named reserved memory region
684 * @np: pointer to the device node with 'memory-region' property
687 * Returns: 0 on success or a negative error-code on failure.
693 int idx = of_property_match_string(np, "memory-region-names", name); in of_reserved_mem_device_init_by_name()
700 * of_reserved_mem_device_release() - release reserved memory device structures
713 if (rd->dev == dev) in of_reserved_mem_device_release()
714 list_move_tail(&rd->list, &release_list); in of_reserved_mem_device_release()
719 if (rd->rmem && rd->rmem->ops && rd->rmem->ops->device_release) in of_reserved_mem_device_release()
720 rd->rmem->ops->device_release(rd->rmem, dev); in of_reserved_mem_device_release()
728 * of_reserved_mem_lookup() - acquire reserved_mem from a device node
729 * @np: node pointer of the desired reserved-memory region
731 * This function allows drivers to acquire a reference to the reserved_mem
732 * struct based on a device node handle.
734 * Returns a reserved_mem reference, or NULL on error.
741 if (!np->full_name) in of_reserved_mem_lookup()
744 name = kbasename(np->full_name); in of_reserved_mem_lookup()
754 * of_reserved_mem_region_to_resource() - Get a reserved memory region as a resource
755 * @np: node containing 'memory-region' property
756 * @idx: index of 'memory-region' property to lookup
757 * @res: Pointer to a struct resource to fill in with reserved region
759 * This function allows drivers to lookup a node's 'memory-region' property
760 * entries by index and return a struct resource for the entry.
762 * Returns 0 on success with @res filled in. Returns -ENODEV if 'memory-region'
763 * is missing or unavailable, -EINVAL for any other error.
771 return -EINVAL; in of_reserved_mem_region_to_resource()
773 struct device_node __free(device_node) *target = of_parse_phandle(np, "memory-region", idx); in of_reserved_mem_region_to_resource()
775 return -ENODEV; in of_reserved_mem_region_to_resource()
779 return -EINVAL; in of_reserved_mem_region_to_resource()
781 resource_set_range(res, rmem->base, rmem->size); in of_reserved_mem_region_to_resource()
782 res->flags = IORESOURCE_MEM; in of_reserved_mem_region_to_resource()
783 res->name = rmem->name; in of_reserved_mem_region_to_resource()
789 * of_reserved_mem_region_to_resource_byname() - Get a reserved memory region as a resource
790 * @np: node containing 'memory-region' property
791 * @name: name of 'memory-region' property entry to lookup
792 * @res: Pointer to a struct resource to fill in with reserved region
794 * This function allows drivers to lookup a node's 'memory-region' property
795 * entries by name and return a struct resource for the entry.
797 * Returns 0 on success with @res filled in, or a negative error-code on
807 return -EINVAL; in of_reserved_mem_region_to_resource_byname()
809 idx = of_property_match_string(np, "memory-region-names", name); in of_reserved_mem_region_to_resource_byname()
818 * of_reserved_mem_region_count() - Return the number of 'memory-region' entries
819 * @np: node containing 'memory-region' property
821 * This function allows drivers to retrieve the number of entries for a node's
822 * 'memory-region' property.
824 * Returns the number of entries on success, or negative error code on a
825 * malformed property.
829 return of_count_phandle_with_args(np, "memory-region", NULL); in of_reserved_mem_region_count()