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