Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 36156f92 authored by Johan Hovold's avatar Johan Hovold Committed by Rob Herring
Browse files

of: add helper to lookup compatible child node



Add of_get_compatible_child() helper that can be used to lookup
compatible child nodes.

Several drivers currently use of_find_compatible_node() to lookup child
nodes while failing to notice that the of_find_ functions search the
entire tree depth-first (from a given start node) and therefore can
match unrelated nodes. The fact that these functions also drop a
reference to the node they start searching from (e.g. the parent node)
is typically also overlooked, something which can lead to use-after-free
bugs.

Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
Signed-off-by: default avatarRob Herring <robh@kernel.org>
parent 5b394b2d
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -719,6 +719,31 @@ struct device_node *of_get_next_available_child(const struct device_node *node,
}
EXPORT_SYMBOL(of_get_next_available_child);

/**
 * of_get_compatible_child - Find compatible child node
 * @parent:	parent node
 * @compatible:	compatible string
 *
 * Lookup child node whose compatible property contains the given compatible
 * string.
 *
 * Returns a node pointer with refcount incremented, use of_node_put() on it
 * when done; or NULL if not found.
 */
struct device_node *of_get_compatible_child(const struct device_node *parent,
				const char *compatible)
{
	struct device_node *child;

	for_each_child_of_node(parent, child) {
		if (of_device_is_compatible(child, compatible))
			break;
	}

	return child;
}
EXPORT_SYMBOL(of_get_compatible_child);

/**
 *	of_get_child_by_name - Find the child node by name for a given parent
 *	@node:	parent node
+8 −0
Original line number Diff line number Diff line
@@ -290,6 +290,8 @@ extern struct device_node *of_get_next_child(const struct device_node *node,
extern struct device_node *of_get_next_available_child(
	const struct device_node *node, struct device_node *prev);

extern struct device_node *of_get_compatible_child(const struct device_node *parent,
					const char *compatible);
extern struct device_node *of_get_child_by_name(const struct device_node *node,
					const char *name);

@@ -632,6 +634,12 @@ static inline bool of_have_populated_dt(void)
	return false;
}

static inline struct device_node *of_get_compatible_child(const struct device_node *parent,
					const char *compatible)
{
	return NULL;
}

static inline struct device_node *of_get_child_by_name(
					const struct device_node *node,
					const char *name)