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