Skip to content

Commit

Permalink
of: Create unlocked version of for_each_child_of_node()
Browse files Browse the repository at this point in the history
When iterating over nodes, sometimes it needs to be done when the DT
lock is already held. This patch makes an unlocked version of the
for_each_child_of_node() macro.

Signed-off-by: Grant Likely <grant.likely@linaro.org>
  • Loading branch information
Grant Likely committed May 23, 2014
1 parent 11d200e commit 0d0e02d
Showing 1 changed file with 17 additions and 5 deletions.
22 changes: 17 additions & 5 deletions drivers/of/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,22 @@ struct device_node *of_get_next_parent(struct device_node *node)
}
EXPORT_SYMBOL(of_get_next_parent);

static struct device_node *__of_get_next_child(const struct device_node *node,
struct device_node *prev)
{
struct device_node *next;

next = prev ? prev->sibling : node->child;
for (; next; next = next->sibling)
if (of_node_get(next))
break;
of_node_put(prev);
return next;
}
#define __for_each_child_of_node(parent, child) \
for (child = __of_get_next_child(parent, NULL); child != NULL; \
child = __of_get_next_child(parent, child))

/**
* of_get_next_child - Iterate a node childs
* @node: parent node
Expand All @@ -710,11 +726,7 @@ struct device_node *of_get_next_child(const struct device_node *node,
unsigned long flags;

raw_spin_lock_irqsave(&devtree_lock, flags);
next = prev ? prev->sibling : node->child;
for (; next; next = next->sibling)
if (of_node_get(next))
break;
of_node_put(prev);
next = __of_get_next_child(node, prev);
raw_spin_unlock_irqrestore(&devtree_lock, flags);
return next;
}
Expand Down

0 comments on commit 0d0e02d

Please sign in to comment.