forked from Mirrors/opensbi
		
	lib: utils/fdt: Add fdt_parse_phandle_with_args() API
The libfdt project does not have a generic API to parse phandle with args from a DT node so we add fdt_parse_phandle_with_args() for this purpose. This new API will be useful to FDT based drivers. Signed-off-by: Anup Patel <anup.patel@wdc.com> Reviewed-by: Atish Patra <atish.patra@wdc.com>
This commit is contained in:
		@@ -72,6 +72,53 @@ int fdt_find_match(void *fdt, int startoff,
 | 
			
		||||
	return SBI_ENODEV;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int fdt_parse_phandle_with_args(void *fdt, int nodeoff,
 | 
			
		||||
				const char *prop, const char *cells_prop,
 | 
			
		||||
				int index, struct fdt_phandle_args *out_args)
 | 
			
		||||
{
 | 
			
		||||
	u32 i, pcells;
 | 
			
		||||
	int len, pnodeoff;
 | 
			
		||||
	const fdt32_t *list, *list_end, *val;
 | 
			
		||||
 | 
			
		||||
	if (!fdt || (nodeoff < 0) || !prop || !cells_prop || !out_args)
 | 
			
		||||
		return SBI_EINVAL;
 | 
			
		||||
 | 
			
		||||
	list = fdt_getprop(fdt, nodeoff, prop, &len);
 | 
			
		||||
	if (!list)
 | 
			
		||||
		return SBI_ENOENT;
 | 
			
		||||
	list_end = list + (len / sizeof(*list));
 | 
			
		||||
 | 
			
		||||
	while (list < list_end) {
 | 
			
		||||
		pnodeoff = fdt_node_offset_by_phandle(fdt,
 | 
			
		||||
						fdt32_to_cpu(*list));
 | 
			
		||||
		if (pnodeoff < 0)
 | 
			
		||||
			return pnodeoff;
 | 
			
		||||
		list++;
 | 
			
		||||
 | 
			
		||||
		val = fdt_getprop(fdt, pnodeoff, cells_prop, &len);
 | 
			
		||||
		if (!val)
 | 
			
		||||
			return SBI_ENOENT;
 | 
			
		||||
		pcells = fdt32_to_cpu(*val);
 | 
			
		||||
		if (FDT_MAX_PHANDLE_ARGS < pcells)
 | 
			
		||||
			return SBI_EINVAL;
 | 
			
		||||
		if (list + pcells > list_end)
 | 
			
		||||
			return SBI_ENOENT;
 | 
			
		||||
 | 
			
		||||
		if (index > 0) {
 | 
			
		||||
			list += pcells;
 | 
			
		||||
			index--;
 | 
			
		||||
		} else {
 | 
			
		||||
			out_args->node_offset = pnodeoff;
 | 
			
		||||
			out_args->args_count = pcells;
 | 
			
		||||
			for (i = 0; i < pcells; i++)
 | 
			
		||||
				out_args->args[i] = fdt32_to_cpu(list[i]);
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return SBI_ENOENT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int fdt_translate_address(void *fdt, uint64_t reg, int parent,
 | 
			
		||||
				 unsigned long *addr)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user