lkml.org 
[lkml]   [2018]   [Aug]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 1/9] of: add helper to lookup compatible child node
    Date
    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 and therefore can match unrelated (non-child)
    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: Johan Hovold <johan@kernel.org>
    ---
    drivers/of/base.c | 25 +++++++++++++++++++++++++
    include/linux/of.h | 8 ++++++++
    2 files changed, 33 insertions(+)

    diff --git a/drivers/of/base.c b/drivers/of/base.c
    index 466e3c8582f0..bc420d2aa5f5 100644
    --- a/drivers/of/base.c
    +++ b/drivers/of/base.c
    @@ -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
    diff --git a/include/linux/of.h b/include/linux/of.h
    index 4d25e4f952d9..c22982fc1bff 100644
    --- a/include/linux/of.h
    +++ b/include/linux/of.h
    @@ -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 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)
    --
    2.18.0
    \
     
     \ /
      Last update: 2018-08-22 12:57    [W:3.351 / U:0.296 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site