1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2016 Google, Inc 4 * Written by Simon Glass <sjg@chromium.org> 5 */ 6 7 #include <common.h> 8 #include <errno.h> 9 #include <image.h> 10 #include <linux/libfdt.h> 11 12 ulong fdt_getprop_u32(const void *fdt, int node, const char *prop) 13 { 14 const u32 *cell; 15 int len; 16 17 cell = fdt_getprop(fdt, node, prop, &len); 18 if (!cell || len != sizeof(*cell)) 19 return FDT_ERROR; 20 21 return fdt32_to_cpu(*cell); 22 } 23 24 /* 25 * Iterate over all /configurations subnodes and call a platform specific 26 * function to find the matching configuration. 27 * Returns the node offset or a negative error number. 28 */ 29 int fit_find_config_node(const void *fdt) 30 { 31 const char *name; 32 int conf, node, len; 33 const char *dflt_conf_name; 34 const char *dflt_conf_desc = NULL; 35 int dflt_conf_node = -ENOENT; 36 37 conf = fdt_path_offset(fdt, FIT_CONFS_PATH); 38 if (conf < 0) { 39 debug("%s: Cannot find /configurations node: %d\n", __func__, 40 conf); 41 return -EINVAL; 42 } 43 44 dflt_conf_name = fdt_getprop(fdt, conf, "default", &len); 45 46 for (node = fdt_first_subnode(fdt, conf); 47 node >= 0; 48 node = fdt_next_subnode(fdt, node)) { 49 name = fdt_getprop(fdt, node, "description", &len); 50 if (!name) { 51 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 52 printf("%s: Missing FDT description in DTB\n", 53 __func__); 54 #endif 55 return -EINVAL; 56 } 57 58 if (dflt_conf_name) { 59 const char *node_name = fdt_get_name(fdt, node, NULL); 60 if (strcmp(dflt_conf_name, node_name) == 0) { 61 dflt_conf_node = node; 62 dflt_conf_desc = name; 63 } 64 } 65 66 if (board_fit_config_name_match(name)) 67 continue; 68 69 debug("Selecting config '%s'", name); 70 71 return node; 72 } 73 74 if (dflt_conf_node != -ENOENT) { 75 debug("Selecting default config '%s'\n", dflt_conf_desc); 76 return dflt_conf_node; 77 } 78 79 return -ENOENT; 80 } 81