[PATCH 2/2] of: search the best compatible match first in __of_match_node()

Rob Herring robherring2 at gmail.com
Sat Feb 15 02:53:40 EST 2014


On Thu, Feb 13, 2014 at 11:22 PM, Kevin Hao <haokexin at gmail.com> wrote:
> Currently, of_match_node compares each given match against all node's
> compatible strings with of_device_is_compatible.
>
> To achieve multiple compatible strings per node with ordering from
> specific to generic, this requires given matches to be ordered from
> specific to generic. For most of the drivers this is not true and also
> an alphabetical ordering is more sane there.
>
> Therefore, this patch introduces a function to match each of the node's
> compatible strings against all given compatible matches without type and
> name first, before checking the next compatible string. This implies
> that node's compatibles are ordered from specific to generic while
> given matches can be in any order. If we fail to find such a match
> entry, then fall-back to the old method in order to keep compatibility.
>
> Cc: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>
> Signed-off-by: Kevin Hao <haokexin at gmail.com>

Looks good to me. I'll put this in next for a few days. I'd really
like to see some acks and tested-by's before sending to Linus.

We could be a bit more strict here and fallback to the old matching if
the match table has any entries with name or type. I don't think that
should be necessary though.

Rob

> ---
>  drivers/of/base.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 42 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index ba195fbce4c6..10b51106c854 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -730,13 +730,49 @@ out:
>  }
>  EXPORT_SYMBOL(of_find_node_with_property);
>
> +static const struct of_device_id *
> +of_match_compatible(const struct of_device_id *matches,
> +                       const struct device_node *node)
> +{
> +       const char *cp;
> +       int cplen, l;
> +       const struct of_device_id *m;
> +
> +       cp = __of_get_property(node, "compatible", &cplen);
> +       while (cp && (cplen > 0)) {
> +               m = matches;
> +               while (m->name[0] || m->type[0] || m->compatible[0]) {
> +                       /* Only match for the entries without type and name */
> +                       if (m->name[0] || m->type[0] ||
> +                               of_compat_cmp(m->compatible, cp,
> +                                        strlen(m->compatible)))
> +                               m++;
> +                       else
> +                               return m;
> +               }
> +
> +               /* Get node's next compatible string */
> +               l = strlen(cp) + 1;
> +               cp += l;
> +               cplen -= l;
> +       }
> +
> +       return NULL;
> +}
> +
>  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 *m;
> +
>         if (!matches)
>                 return NULL;
>
> +       m = of_match_compatible(matches, node);
> +       if (m)
> +               return m;
> +
>         while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
>                 int match = 1;
>                 if (matches->name[0])
> @@ -760,7 +796,12 @@ const struct of_device_id *__of_match_node(const struct of_device_id *matches,
>   *     @matches:       array of of device match structures to search in
>   *     @node:          the of device structure to match against
>   *
> - *     Low level utility function used by device matching.
> + *     Low level utility function used by device matching. We have two ways
> + *     of matching:
> + *     - Try to find the best compatible match by comparing each compatible
> + *       string of device node with all the given matches respectively.
> + *     - If the above method failed, then try to match the compatible by using
> + *       __of_device_is_compatible() besides the match in type and name.
>   */
>  const struct of_device_id *of_match_node(const struct of_device_id *matches,
>                                          const struct device_node *node)
> --
> 1.8.5.3
>


More information about the Linuxppc-dev mailing list