for_each_matching_node(np, matches)
892 #define for_each_matching_node(dn, matches)
893 for (dn = of_find_matching_node(NULL, matches); dn;
894 dn = of_find_matching_node(dn, matches))
for (np = of_find_matching_node(NULL, matches); np; np = of_find_matching_node(np, matches))
of_find_matching_node
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);
}
/**
-
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_and_match(struct device_node *from,
const struct of_device_id *matches,
const struct of_device_id **match)
{
struct device_node *np;
const struct of_device_id *m;
unsigned long flags;if (match)
*match = NULL;raw_spin_lock_irqsave(&devtree_lock, flags);
for_each_of_allnodes_from(from, np) {// 从from开始遍历设备树节点,此循环会遍历所有设备树节点,但是一旦当前结点找到了匹配的matches,那就直接退出循环了
m = __of_match_node(matches, np);
if (m && of_node_get(np)) {
if (match)
*match = m;
break;
}
}
of_node_put(from);
raw_spin_unlock_irqrestore(&devtree_lock, flags);
return np;
}
EXPORT_SYMBOL(of_find_matching_node_and_match);
// 就是从from开始遍历设备树节点
#define for_each_of_allnodes_from(from, dn)
for (dn = __of_find_all_nodes(from); dn; dn = __of_find_all_nodes(dn))
大概看了一下逻辑,就是遍历设备树节点
struct device_node *__of_find_all_nodes(struct device_node *prev)
{
struct device_node np;
if (!prev) {
np = of_root; //第一个自然是根结点
} else if (prev->child) {
np = prev->child;//有子节点优先返回子节点
} else {
/ Walk back up looking for a sibling, or the end of the structure /
np = prev;
while (np->parent && !np->sibling)
np = np->parent;
np = np->sibling; / Might be null at the end of the tree */ //返回兄弟结点
}
return np;
}
of_root哪里来的?
drivers/of/pdt.c:234: of_root = of_pdt_create_node(root_node, NULL);
他日有缘再细分析
// 传入一个node设备树节点,让它与给定的一组的matches匹配,返回其中最合适的matches
static const struct of_device_id *__of_match_node(const struct of_device_id *matches,
const struct device_node *node)
{
const struct of_device_id *best_match = NULL;
int score, best_score = 0;
if (!matches)
return NULL;
// 遍历matches,返回与节点node最匹配的那个matches
for (; matches->name[0] || matches->type[0] || matches->compatible[0]; matches++) {
score = __of_device_is_compatible(node, matches->compatible,
matches->type, matches->name);
if (score > best_score) {
best_match = matches;
best_score = score;
}
}
return best_match;
}