diff options
| author | Stefano Babic <sbabic@denx.de> | 2012-12-08 12:02:45 +0100 | 
|---|---|---|
| committer | Stefano Babic <sbabic@denx.de> | 2012-12-08 12:02:45 +0100 | 
| commit | 05a860c228fe6c8f2e7aced8cc8ef88bc1038363 (patch) | |
| tree | 764536da9202b9de387a0d957829f64dfba818b7 /common/image.c | |
| parent | 393ff47ba3123208f7c4f08d63f114300a41d0c4 (diff) | |
| parent | fd4d564b3c80b111f18c93adb14233a6a7ddb0e9 (diff) | |
| download | olio-uboot-2014.01-05a860c228fe6c8f2e7aced8cc8ef88bc1038363.tar.xz olio-uboot-2014.01-05a860c228fe6c8f2e7aced8cc8ef88bc1038363.zip | |
Merge branch 'master' of git://git.denx.de/u-boot into master
Conflicts:
	drivers/power/power_fsl.c
	include/configs/mx35pdk.h
	include/configs/mx53loco.h
	include/configs/woodburn_common.h
	board/woodburn/woodburn.c
These boards still use the old old PMIC framework, so they
do not merge properly after the power framework was merged into
mainline.
Fix all conflicts and update woodburn to use Power Framework.
Signed-off-by: Stefano Babic <sbabic@denx.de>
Diffstat (limited to 'common/image.c')
| -rw-r--r-- | common/image.c | 127 | 
1 files changed, 127 insertions, 0 deletions
| diff --git a/common/image.c b/common/image.c index df642e656..e93b6e89c 100644 --- a/common/image.c +++ b/common/image.c @@ -3049,6 +3049,133 @@ int fit_check_format(const void *fit)  	return 1;  } + +/** + * fit_conf_find_compat + * @fit: pointer to the FIT format image header + * @fdt: pointer to the device tree to compare against + * + * fit_conf_find_compat() attempts to find the configuration whose fdt is the + * most compatible with the passed in device tree. + * + * Example: + * + * / o image-tree + *   |-o images + *   | |-o fdt@1 + *   | |-o fdt@2 + *   | + *   |-o configurations + *     |-o config@1 + *     | |-fdt = fdt@1 + *     | + *     |-o config@2 + *       |-fdt = fdt@2 + * + * / o U-Boot fdt + *   |-compatible = "foo,bar", "bim,bam" + * + * / o kernel fdt1 + *   |-compatible = "foo,bar", + * + * / o kernel fdt2 + *   |-compatible = "bim,bam", "baz,biz" + * + * Configuration 1 would be picked because the first string in U-Boot's + * compatible list, "foo,bar", matches a compatible string in the root of fdt1. + * "bim,bam" in fdt2 matches the second string which isn't as good as fdt1. + * + * returns: + *     offset to the configuration to use if one was found + *     -1 otherwise + */ +int fit_conf_find_compat(const void *fit, const void *fdt) +{ +	int ndepth = 0; +	int noffset, confs_noffset, images_noffset; +	const void *fdt_compat; +	int fdt_compat_len; +	int best_match_offset = 0; +	int best_match_pos = 0; + +	confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH); +	images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); +	if (confs_noffset < 0 || images_noffset < 0) { +		debug("Can't find configurations or images nodes.\n"); +		return -1; +	} + +	fdt_compat = fdt_getprop(fdt, 0, "compatible", &fdt_compat_len); +	if (!fdt_compat) { +		debug("Fdt for comparison has no \"compatible\" property.\n"); +		return -1; +	} + +	/* +	 * Loop over the configurations in the FIT image. +	 */ +	for (noffset = fdt_next_node(fit, confs_noffset, &ndepth); +			(noffset >= 0) && (ndepth > 0); +			noffset = fdt_next_node(fit, noffset, &ndepth)) { +		const void *kfdt; +		const char *kfdt_name; +		int kfdt_noffset; +		const char *cur_fdt_compat; +		int len; +		size_t size; +		int i; + +		if (ndepth > 1) +			continue; + +		kfdt_name = fdt_getprop(fit, noffset, "fdt", &len); +		if (!kfdt_name) { +			debug("No fdt property found.\n"); +			continue; +		} +		kfdt_noffset = fdt_subnode_offset(fit, images_noffset, +						  kfdt_name); +		if (kfdt_noffset < 0) { +			debug("No image node named \"%s\" found.\n", +			      kfdt_name); +			continue; +		} +		/* +		 * Get a pointer to this configuration's fdt. +		 */ +		if (fit_image_get_data(fit, kfdt_noffset, &kfdt, &size)) { +			debug("Failed to get fdt \"%s\".\n", kfdt_name); +			continue; +		} + +		len = fdt_compat_len; +		cur_fdt_compat = fdt_compat; +		/* +		 * Look for a match for each U-Boot compatibility string in +		 * turn in this configuration's fdt. +		 */ +		for (i = 0; len > 0 && +		     (!best_match_offset || best_match_pos > i); i++) { +			int cur_len = strlen(cur_fdt_compat) + 1; + +			if (!fdt_node_check_compatible(kfdt, 0, +						       cur_fdt_compat)) { +				best_match_offset = noffset; +				best_match_pos = i; +				break; +			} +			len -= cur_len; +			cur_fdt_compat += cur_len; +		} +	} +	if (!best_match_offset) { +		debug("No match found.\n"); +		return -1; +	} + +	return best_match_offset; +} +  /**   * fit_conf_get_node - get node offset for configuration of a given unit name   * @fit: pointer to the FIT format image header |