summaryrefslogtreecommitdiff
path: root/drivers/of
diff options
context:
space:
mode:
authorChen-Yu Tsai <wenst@chromium.org>2024-11-06 17:33:29 +0800
committerWolfram Sang <wsa+renesas@sang-engineering.com>2024-11-27 12:04:01 +0100
commit1fcc67e3a354865775355eafec1fb061a755c971 (patch)
tree79d6df1b04a3b367ca0b1f518f49643565a2db32 /drivers/of
parent81de291d86b704de1809cfb06672902d003cf3a3 (diff)
of: base: Add for_each_child_of_node_with_prefix()
There are cases where drivers would go through child device nodes and operate on only the ones whose node name starts with a given prefix. Provide a helper for these users. This will mainly be used in a subsequent patch that implements a hardware component prober for I2C busses. Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: Rob Herring (Arm) <robh@kernel.org> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Diffstat (limited to 'drivers/of')
-rw-r--r--drivers/of/base.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index a8b0c42bdc8e..4cba021c89d3 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -644,6 +644,41 @@ struct device_node *of_get_next_child(const struct device_node *node,
}
EXPORT_SYMBOL(of_get_next_child);
+/**
+ * of_get_next_child_with_prefix - Find the next child node with prefix
+ * @node: parent node
+ * @prev: previous child of the parent node, or NULL to get first
+ *
+ * This function is like of_get_next_child(), except that it automatically
+ * skips any nodes whose name doesn't have the given prefix.
+ *
+ * Return: A node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_get_next_child_with_prefix(const struct device_node *node,
+ struct device_node *prev,
+ const char *prefix)
+{
+ struct device_node *next;
+ unsigned long flags;
+
+ if (!node)
+ return NULL;
+
+ raw_spin_lock_irqsave(&devtree_lock, flags);
+ next = prev ? prev->sibling : node->child;
+ for (; next; next = next->sibling) {
+ if (!of_node_name_prefix(next, prefix))
+ continue;
+ if (of_node_get(next))
+ break;
+ }
+ of_node_put(prev);
+ raw_spin_unlock_irqrestore(&devtree_lock, flags);
+ return next;
+}
+EXPORT_SYMBOL(of_get_next_child_with_prefix);
+
static struct device_node *of_get_next_status_child(const struct device_node *node,
struct device_node *prev,
bool (*checker)(const struct device_node *))