diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/bootm.c | 69 |
1 files changed, 43 insertions, 26 deletions
diff --git a/common/bootm.c b/common/bootm.c index 8167c3a603..169000cccb 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -320,25 +320,24 @@ static int bootm_open_oftree_uimage(struct image_data *data, size_t *size, } /* - * bootm_load_devicetree() - load devicetree + * bootm_get_devicetree() - get devicetree * * @data: image data context - * @load_address: The address where the devicetree should be loaded to * - * This loads the devicetree to a RAM location. load_address must be a valid - * address. The resulting devicetree will be found at data->oftree. + * This gets the fixed devicetree from the various image sources or the internal + * devicetree. It returns a pointer to the allocated devicetree which must be + * freed after use. * - * Return: 0 on success, negative error code otherwise + * Return: pointer to the fixed devicetree or a ERR_PTR() on failure. */ -int bootm_load_devicetree(struct image_data *data, unsigned long load_address) +void *bootm_get_devicetree(struct image_data *data) { enum filetype type; - int fdt_size; struct fdt_header *oftree; int ret; if (!IS_ENABLED(CONFIG_OFTREE)) - return 0; + return ERR_PTR(-ENOSYS); if (IS_ENABLED(CONFIG_FITIMAGE) && data->os_fit && fit_has_image(data->os_fit, data->fit_config, "fdt")) { @@ -348,7 +347,7 @@ int bootm_load_devicetree(struct image_data *data, unsigned long load_address) ret = fit_open_image(data->os_fit, data->fit_config, "fdt", &of_tree, &of_size); if (ret) - return ret; + return ERR_PTR(ret); data->of_root_node = of_unflatten_dtb(of_tree); } else if (data->oftree_file) { @@ -359,7 +358,7 @@ int bootm_load_devicetree(struct image_data *data, unsigned long load_address) if ((int)type < 0) { printf("could not open %s: %s\n", data->oftree_file, strerror(-type)); - return (int)type; + return ERR_PTR((int)type); } switch (type) { @@ -372,11 +371,11 @@ int bootm_load_devicetree(struct image_data *data, unsigned long load_address) FILESIZE_MAX); break; default: - return -EINVAL; + return ERR_PTR(-EINVAL); } if (ret) - return ret; + return ERR_PTR(ret); data->of_root_node = of_unflatten_dtb(oftree); @@ -385,13 +384,13 @@ int bootm_load_devicetree(struct image_data *data, unsigned long load_address) if (IS_ERR(data->of_root_node)) { data->of_root_node = NULL; pr_err("unable to unflatten devicetree\n"); - return -EINVAL; + return ERR_PTR(-EINVAL); } } else { data->of_root_node = of_get_root_node(); if (!data->of_root_node) - return 0; + return NULL; if (bootm_verbose(data) > 1 && data->of_root_node) printf("using internal devicetree\n"); @@ -405,24 +404,42 @@ int bootm_load_devicetree(struct image_data *data, unsigned long load_address) oftree = of_get_fixed_tree(data->of_root_node); if (!oftree) - return -EINVAL; + return ERR_PTR(-EINVAL); - fdt_size = be32_to_cpu(oftree->totalsize); + fdt_add_reserve_map(oftree); - data->oftree_res = request_sdram_region("oftree", load_address, - fdt_size); - if (!data->oftree_res) { - free(oftree); - return -ENOMEM; - } + return oftree; +} - memcpy((void *)data->oftree_res->start, oftree, fdt_size); +/* + * bootm_load_devicetree() - load devicetree + * + * @data: image data context + * @fdt: The flat device tree to load + * @load_address: The address where the devicetree should be loaded to + * + * This loads the devicetree to a RAM location. load_address must be a valid + * address which is requested with request_sdram_region. The associated region + * is released automatically in the bootm error path. + * + * Return: 0 on success, negative error code otherwise + */ +int bootm_load_devicetree(struct image_data *data, void *fdt, + unsigned long load_address) +{ + int fdt_size; - free(oftree); + if (!IS_ENABLED(CONFIG_OFTREE)) + return -ENOSYS; - oftree = (void *)data->oftree_res->start; + fdt_size = be32_to_cpu(((struct fdt_header *)fdt)->totalsize); - fdt_add_reserve_map(oftree); + data->oftree_res = request_sdram_region("oftree", load_address, + fdt_size); + if (!data->oftree_res) + return -ENOMEM; + + memcpy((void *)data->oftree_res->start, fdt, fdt_size); of_print_cmdline(data->of_root_node); if (bootm_verbose(data) > 1) |