mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	of: introduce for_each_matching_node_and_match()
The following pattern of code is tempting:
    for_each_matching_node(np, table) {
        match = of_match_node(table, np);
However, this results in iterating over table twice; the second time
inside of_match_node(). The implementation of for_each_matching_node()
already found the match, so this is redundant. Invent new function
of_find_matching_node_and_match() and macro
for_each_matching_node_and_match() to remove the double iteration,
thus transforming the above code to:
    for_each_matching_node_and_match(np, table, &match)
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
			
			
This commit is contained in:
		
							parent
							
								
									be193249b4
								
							
						
					
					
						commit
						50c8af4cf9
					
				
					 2 changed files with 26 additions and 7 deletions
				
			
		| 
						 | 
				
			
			@ -594,27 +594,35 @@ const struct of_device_id *of_match_node(const struct of_device_id *matches,
 | 
			
		|||
EXPORT_SYMBOL(of_match_node);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *	of_find_matching_node - Find a node based on an of_device_id match
 | 
			
		||||
 *				table.
 | 
			
		||||
 *	of_find_matching_node_and_match - Find a node based on an of_device_id
 | 
			
		||||
 *					  match table.
 | 
			
		||||
 *	@from:		The node to start searching from or NULL, the node
 | 
			
		||||
 *			you pass will not be searched, only the next one
 | 
			
		||||
 *			will; typically, you pass what the previous call
 | 
			
		||||
 *			returned. of_node_put() will be called on it
 | 
			
		||||
 *	@matches:	array of of device match structures to search in
 | 
			
		||||
 *	@match		Updated to point at the matches entry which matched
 | 
			
		||||
 *
 | 
			
		||||
 *	Returns a node pointer with refcount incremented, use
 | 
			
		||||
 *	of_node_put() on it when done.
 | 
			
		||||
 */
 | 
			
		||||
struct device_node *of_find_matching_node(struct device_node *from,
 | 
			
		||||
					  const struct of_device_id *matches)
 | 
			
		||||
struct device_node *of_find_matching_node_and_match(struct device_node *from,
 | 
			
		||||
					const struct of_device_id *matches,
 | 
			
		||||
					const struct of_device_id **match)
 | 
			
		||||
{
 | 
			
		||||
	struct device_node *np;
 | 
			
		||||
 | 
			
		||||
	if (match)
 | 
			
		||||
		*match = NULL;
 | 
			
		||||
 | 
			
		||||
	read_lock(&devtree_lock);
 | 
			
		||||
	np = from ? from->allnext : allnodes;
 | 
			
		||||
	for (; np; np = np->allnext) {
 | 
			
		||||
		if (of_match_node(matches, np) && of_node_get(np))
 | 
			
		||||
		if (of_match_node(matches, np) && of_node_get(np)) {
 | 
			
		||||
			if (match)
 | 
			
		||||
				*match = matches;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	of_node_put(from);
 | 
			
		||||
	read_unlock(&devtree_lock);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -179,11 +179,22 @@ extern struct device_node *of_find_compatible_node(struct device_node *from,
 | 
			
		|||
#define for_each_compatible_node(dn, type, compatible) \
 | 
			
		||||
	for (dn = of_find_compatible_node(NULL, type, compatible); dn; \
 | 
			
		||||
	     dn = of_find_compatible_node(dn, type, compatible))
 | 
			
		||||
extern struct device_node *of_find_matching_node(struct device_node *from,
 | 
			
		||||
	const struct of_device_id *matches);
 | 
			
		||||
extern struct device_node *of_find_matching_node_and_match(
 | 
			
		||||
	struct device_node *from,
 | 
			
		||||
	const struct of_device_id *matches,
 | 
			
		||||
	const struct of_device_id **match);
 | 
			
		||||
static inline struct device_node *of_find_matching_node(
 | 
			
		||||
	struct device_node *from,
 | 
			
		||||
	const struct of_device_id *matches)
 | 
			
		||||
{
 | 
			
		||||
	return of_find_matching_node_and_match(from, matches, NULL);
 | 
			
		||||
}
 | 
			
		||||
#define for_each_matching_node(dn, matches) \
 | 
			
		||||
	for (dn = of_find_matching_node(NULL, matches); dn; \
 | 
			
		||||
	     dn = of_find_matching_node(dn, matches))
 | 
			
		||||
#define for_each_matching_node_and_match(dn, matches, match) \
 | 
			
		||||
	for (dn = of_find_matching_node_and_match(NULL, matches, match); \
 | 
			
		||||
	     dn; dn = of_find_matching_node_and_match(dn, matches, match))
 | 
			
		||||
extern struct device_node *of_find_node_by_path(const char *path);
 | 
			
		||||
extern struct device_node *of_find_node_by_phandle(phandle handle);
 | 
			
		||||
extern struct device_node *of_get_parent(const struct device_node *node);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue