of/flattree: Add of_flat_dt_match() helper function
This patch adds of_flat_dt_match() which tests a node for compatibility with a list of values and converts the relevant powerpc platform code to use it. This approach simplifies the board support code a bit. Signed-off-by: Grant Likely <grant.likely@secretlab.ca> Reviewed-by: Stephen Neuendorffer <stephen.neuendorffer@xilinx.com>
This commit is contained in:
		
					parent
					
						
							
								73930a85cf
							
						
					
				
			
			
				commit
				
					
						a4f740cf33
					
				
			
		
					 11 changed files with 89 additions and 78 deletions
				
			
		| 
						 | 
				
			
			@ -50,7 +50,7 @@ machine_device_initcall(ppc40x_simple, ppc40x_device_probe);
 | 
			
		|||
 * Again, if your board needs to do things differently then create a
 | 
			
		||||
 * board.c file for it rather than adding it to this list.
 | 
			
		||||
 */
 | 
			
		||||
static char *board[] __initdata = {
 | 
			
		||||
static const char *board[] __initdata = {
 | 
			
		||||
	"amcc,acadia",
 | 
			
		||||
	"amcc,haleakala",
 | 
			
		||||
	"amcc,kilauea",
 | 
			
		||||
| 
						 | 
				
			
			@ -60,14 +60,9 @@ static char *board[] __initdata = {
 | 
			
		|||
 | 
			
		||||
static int __init ppc40x_probe(void)
 | 
			
		||||
{
 | 
			
		||||
	unsigned long root = of_get_flat_dt_root();
 | 
			
		||||
	int i = 0;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_SIZE(board); i++) {
 | 
			
		||||
		if (of_flat_dt_is_compatible(root, board[i])) {
 | 
			
		||||
			ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
 | 
			
		||||
			return 1;
 | 
			
		||||
		}
 | 
			
		||||
	if (of_flat_dt_match(of_get_flat_dt_root(), board)) {
 | 
			
		||||
		ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,7 +26,7 @@
 | 
			
		|||
/*
 | 
			
		||||
 * list of supported boards
 | 
			
		||||
 */
 | 
			
		||||
static char *board[] __initdata = {
 | 
			
		||||
static const char *board[] __initdata = {
 | 
			
		||||
	"prt,prtlvt",
 | 
			
		||||
	NULL
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -36,16 +36,7 @@ static char *board[] __initdata = {
 | 
			
		|||
 */
 | 
			
		||||
static int __init mpc5121_generic_probe(void)
 | 
			
		||||
{
 | 
			
		||||
	unsigned long node = of_get_flat_dt_root();
 | 
			
		||||
	int i = 0;
 | 
			
		||||
 | 
			
		||||
	while (board[i]) {
 | 
			
		||||
		if (of_flat_dt_is_compatible(node, board[i]))
 | 
			
		||||
			break;
 | 
			
		||||
		i++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return board[i] != NULL;
 | 
			
		||||
	return of_flat_dt_match(of_get_flat_dt_root(), board);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
define_machine(mpc5121_generic) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -172,20 +172,18 @@ static void __init lite5200_setup_arch(void)
 | 
			
		|||
	mpc52xx_setup_pci();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char *board[] __initdata = {
 | 
			
		||||
	"fsl,lite5200",
 | 
			
		||||
	"fsl,lite5200b",
 | 
			
		||||
	NULL,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Called very early, MMU is off, device-tree isn't unflattened
 | 
			
		||||
 */
 | 
			
		||||
static int __init lite5200_probe(void)
 | 
			
		||||
{
 | 
			
		||||
	unsigned long node = of_get_flat_dt_root();
 | 
			
		||||
	const char *model = of_get_flat_dt_prop(node, "model", NULL);
 | 
			
		||||
 | 
			
		||||
	if (!of_flat_dt_is_compatible(node, "fsl,lite5200") &&
 | 
			
		||||
	    !of_flat_dt_is_compatible(node, "fsl,lite5200b"))
 | 
			
		||||
		return 0;
 | 
			
		||||
	pr_debug("%s board found\n", model ? model : "unknown");
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
	return of_flat_dt_match(of_get_flat_dt_root(), board);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
define_machine(lite5200) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -239,7 +239,7 @@ static void __init media5200_setup_arch(void)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
/* list of the supported boards */
 | 
			
		||||
static char *board[] __initdata = {
 | 
			
		||||
static const char *board[] __initdata = {
 | 
			
		||||
	"fsl,media5200",
 | 
			
		||||
	NULL
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -249,16 +249,7 @@ static char *board[] __initdata = {
 | 
			
		|||
 */
 | 
			
		||||
static int __init media5200_probe(void)
 | 
			
		||||
{
 | 
			
		||||
	unsigned long node = of_get_flat_dt_root();
 | 
			
		||||
	int i = 0;
 | 
			
		||||
 | 
			
		||||
	while (board[i]) {
 | 
			
		||||
		if (of_flat_dt_is_compatible(node, board[i]))
 | 
			
		||||
			break;
 | 
			
		||||
		i++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (board[i] != NULL);
 | 
			
		||||
	return of_flat_dt_match(of_get_flat_dt_root(), board);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
define_machine(media5200_platform) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,7 +49,7 @@ static void __init mpc5200_simple_setup_arch(void)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
/* list of the supported boards */
 | 
			
		||||
static char *board[] __initdata = {
 | 
			
		||||
static const char *board[] __initdata = {
 | 
			
		||||
	"intercontrol,digsy-mtc",
 | 
			
		||||
	"manroland,mucmc52",
 | 
			
		||||
	"manroland,uc101",
 | 
			
		||||
| 
						 | 
				
			
			@ -66,16 +66,7 @@ static char *board[] __initdata = {
 | 
			
		|||
 */
 | 
			
		||||
static int __init mpc5200_simple_probe(void)
 | 
			
		||||
{
 | 
			
		||||
	unsigned long node = of_get_flat_dt_root();
 | 
			
		||||
	int i = 0;
 | 
			
		||||
 | 
			
		||||
	while (board[i]) {
 | 
			
		||||
		if (of_flat_dt_is_compatible(node, board[i]))
 | 
			
		||||
			break;
 | 
			
		||||
		i++;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return (board[i] != NULL);
 | 
			
		||||
	return of_flat_dt_match(of_get_flat_dt_root(), board);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
define_machine(mpc5200_simple_platform) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,16 +57,19 @@ static void __init mpc830x_rdb_init_IRQ(void)
 | 
			
		|||
	ipic_set_default_priority();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct const char *board[] __initdata = {
 | 
			
		||||
	"MPC8308RDB",
 | 
			
		||||
	"fsl,mpc8308rdb",
 | 
			
		||||
	"denx,mpc8308_p1m",
 | 
			
		||||
	NULL
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Called very early, MMU is off, device-tree isn't unflattened
 | 
			
		||||
 */
 | 
			
		||||
static int __init mpc830x_rdb_probe(void)
 | 
			
		||||
{
 | 
			
		||||
	unsigned long root = of_get_flat_dt_root();
 | 
			
		||||
 | 
			
		||||
	return of_flat_dt_is_compatible(root, "MPC8308RDB") ||
 | 
			
		||||
	       of_flat_dt_is_compatible(root, "fsl,mpc8308rdb") ||
 | 
			
		||||
	       of_flat_dt_is_compatible(root, "denx,mpc8308_p1m");
 | 
			
		||||
	return of_flat_dt_match(of_get_flat_dt_root(), board);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct of_device_id __initdata of_bus_ids[] = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,15 +60,18 @@ static void __init mpc831x_rdb_init_IRQ(void)
 | 
			
		|||
	ipic_set_default_priority();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct const char *board[] __initdata = {
 | 
			
		||||
	"MPC8313ERDB",
 | 
			
		||||
	"fsl,mpc8315erdb",
 | 
			
		||||
	NULL
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Called very early, MMU is off, device-tree isn't unflattened
 | 
			
		||||
 */
 | 
			
		||||
static int __init mpc831x_rdb_probe(void)
 | 
			
		||||
{
 | 
			
		||||
	unsigned long root = of_get_flat_dt_root();
 | 
			
		||||
 | 
			
		||||
	return of_flat_dt_is_compatible(root, "MPC8313ERDB") ||
 | 
			
		||||
	       of_flat_dt_is_compatible(root, "fsl,mpc8315erdb");
 | 
			
		||||
	return of_flat_dt_match(of_get_flat_dt_root(), board);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct of_device_id __initdata of_bus_ids[] = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -101,17 +101,20 @@ static void __init mpc837x_rdb_init_IRQ(void)
 | 
			
		|||
	ipic_set_default_priority();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char *board[] __initdata = {
 | 
			
		||||
	"fsl,mpc8377rdb",
 | 
			
		||||
	"fsl,mpc8378rdb",
 | 
			
		||||
	"fsl,mpc8379rdb",
 | 
			
		||||
	"fsl,mpc8377wlan",
 | 
			
		||||
	NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Called very early, MMU is off, device-tree isn't unflattened
 | 
			
		||||
 */
 | 
			
		||||
static int __init mpc837x_rdb_probe(void)
 | 
			
		||||
{
 | 
			
		||||
	unsigned long root = of_get_flat_dt_root();
 | 
			
		||||
 | 
			
		||||
	return of_flat_dt_is_compatible(root, "fsl,mpc8377rdb") ||
 | 
			
		||||
	       of_flat_dt_is_compatible(root, "fsl,mpc8378rdb") ||
 | 
			
		||||
	       of_flat_dt_is_compatible(root, "fsl,mpc8379rdb") ||
 | 
			
		||||
	       of_flat_dt_is_compatible(root, "fsl,mpc8377wlan");
 | 
			
		||||
	return of_flat_dt_match(of_get_flat_dt_root(), board);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
define_machine(mpc837x_rdb) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -186,21 +186,21 @@ static int __init declare_of_platform_devices(void)
 | 
			
		|||
}
 | 
			
		||||
machine_device_initcall(tqm85xx, declare_of_platform_devices);
 | 
			
		||||
 | 
			
		||||
static const char *board[] __initdata = {
 | 
			
		||||
	"tqc,tqm8540",
 | 
			
		||||
	"tqc,tqm8541",
 | 
			
		||||
	"tqc,tqm8548",
 | 
			
		||||
	"tqc,tqm8555",
 | 
			
		||||
	"tqc,tqm8560",
 | 
			
		||||
	NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Called very early, device-tree isn't unflattened
 | 
			
		||||
 */
 | 
			
		||||
static int __init tqm85xx_probe(void)
 | 
			
		||||
{
 | 
			
		||||
	unsigned long root = of_get_flat_dt_root();
 | 
			
		||||
 | 
			
		||||
	if ((of_flat_dt_is_compatible(root, "tqc,tqm8540")) ||
 | 
			
		||||
	    (of_flat_dt_is_compatible(root, "tqc,tqm8541")) ||
 | 
			
		||||
	    (of_flat_dt_is_compatible(root, "tqc,tqm8548")) ||
 | 
			
		||||
	    (of_flat_dt_is_compatible(root, "tqc,tqm8555")) ||
 | 
			
		||||
	    (of_flat_dt_is_compatible(root, "tqc,tqm8560")))
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
	return of_flat_dt_match(of_get_flat_dt_root(), board);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
define_machine(tqm85xx) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -78,19 +78,23 @@ void *of_fdt_get_property(struct boot_param_header *blob,
 | 
			
		|||
 * @blob: A device tree blob
 | 
			
		||||
 * @node: node to test
 | 
			
		||||
 * @compat: compatible string to compare with compatible list.
 | 
			
		||||
 *
 | 
			
		||||
 * On match, returns a non-zero value with smaller values returned for more
 | 
			
		||||
 * specific compatible values.
 | 
			
		||||
 */
 | 
			
		||||
int of_fdt_is_compatible(struct boot_param_header *blob,
 | 
			
		||||
		      unsigned long node, const char *compat)
 | 
			
		||||
{
 | 
			
		||||
	const char *cp;
 | 
			
		||||
	unsigned long cplen, l;
 | 
			
		||||
	unsigned long cplen, l, score = 0;
 | 
			
		||||
 | 
			
		||||
	cp = of_fdt_get_property(blob, node, "compatible", &cplen);
 | 
			
		||||
	if (cp == NULL)
 | 
			
		||||
		return 0;
 | 
			
		||||
	while (cplen > 0) {
 | 
			
		||||
		score++;
 | 
			
		||||
		if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
 | 
			
		||||
			return 1;
 | 
			
		||||
			return score;
 | 
			
		||||
		l = strlen(cp) + 1;
 | 
			
		||||
		cp += l;
 | 
			
		||||
		cplen -= l;
 | 
			
		||||
| 
						 | 
				
			
			@ -99,6 +103,27 @@ int of_fdt_is_compatible(struct boot_param_header *blob,
 | 
			
		|||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * of_fdt_match - Return true if node matches a list of compatible values
 | 
			
		||||
 */
 | 
			
		||||
int of_fdt_match(struct boot_param_header *blob, unsigned long node,
 | 
			
		||||
                 const char **compat)
 | 
			
		||||
{
 | 
			
		||||
	unsigned int tmp, score = 0;
 | 
			
		||||
 | 
			
		||||
	if (!compat)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	while (*compat) {
 | 
			
		||||
		tmp = of_fdt_is_compatible(blob, node, *compat);
 | 
			
		||||
		if (tmp && (score == 0 || (tmp < score)))
 | 
			
		||||
			score = tmp;
 | 
			
		||||
		compat++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return score;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size,
 | 
			
		||||
				       unsigned long align)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -511,6 +536,14 @@ int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
 | 
			
		|||
	return of_fdt_is_compatible(initial_boot_params, node, compat);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * of_flat_dt_match - Return true if node matches a list of compatible values
 | 
			
		||||
 */
 | 
			
		||||
int __init of_flat_dt_match(unsigned long node, const char **compat)
 | 
			
		||||
{
 | 
			
		||||
	return of_fdt_match(initial_boot_params, node, compat);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_BLK_DEV_INITRD
 | 
			
		||||
/**
 | 
			
		||||
 * early_init_dt_check_for_initrd - Decode initrd location from flat tree
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -68,6 +68,8 @@ extern void *of_fdt_get_property(struct boot_param_header *blob,
 | 
			
		|||
extern int of_fdt_is_compatible(struct boot_param_header *blob,
 | 
			
		||||
				unsigned long node,
 | 
			
		||||
				const char *compat);
 | 
			
		||||
extern int of_fdt_match(struct boot_param_header *blob, unsigned long node,
 | 
			
		||||
			const char **compat);
 | 
			
		||||
extern void of_fdt_unflatten_tree(unsigned long *blob,
 | 
			
		||||
			       struct device_node **mynodes);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -84,6 +86,7 @@ extern int of_scan_flat_dt(int (*it)(unsigned long node, const char *uname,
 | 
			
		|||
extern void *of_get_flat_dt_prop(unsigned long node, const char *name,
 | 
			
		||||
				 unsigned long *size);
 | 
			
		||||
extern int of_flat_dt_is_compatible(unsigned long node, const char *name);
 | 
			
		||||
extern int of_flat_dt_match(unsigned long node, const char **matches);
 | 
			
		||||
extern unsigned long of_get_flat_dt_root(void);
 | 
			
		||||
 | 
			
		||||
extern int early_init_dt_scan_chosen(unsigned long node, const char *uname,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue