[PATCH] of: give priority to the compatible match in __of_match_node()
Stephen N Chivers
schivers at csc.com.au
Thu Feb 13 07:42:19 EST 2014
Kevin Hao <haokexin at gmail.com> wrote on 02/12/2014 10:38:04 PM:
> From: Kevin Hao <haokexin at gmail.com>
> To: devicetree at vger.kernel.org, linuxppc-dev at lists.ozlabs.org
> Cc: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>, Stephen
> N Chivers <schivers at csc.com.au>, Chris Proctor
> <cproctor at csc.com.au>, Arnd Bergmann <arnd at arndb.de>, Scott Wood
> <scottwood at freescale.com>, Grant Likely <grant.likely at linaro.org>,
> Rob Herring <robh+dt at kernel.org>
> Date: 02/12/2014 10:38 PM
> Subject: [PATCH] of: give priority to the compatible match in
> __of_match_node()
>
> When the device node do have a compatible property, we definitely
> prefer the compatible match besides the type and name. Only if
> there is no such a match, we then consider the candidate which
> doesn't have compatible entry but do match the type or name with
> the device node.
>
> This is based on a patch from Sebastian Hesselbarth.
> http://patchwork.ozlabs.org/patch/319434/
>
> I did some code refactoring and also fixed a bug in the original patch.
>
> Cc: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>
> Signed-off-by: Kevin Hao <haokexin at gmail.com>
Tested-by: Stephen Chivers <schivers at csc.com>
Patch works for both orderings. Platform boots without problems and
I get the normal serial console.
> ---
> drivers/of/base.c | 55 ++++++++++++++++++++++++++++++++++++
> +------------------
> 1 file changed, 37 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index ff85450d5683..9d655df458bd 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -730,32 +730,45 @@ out:
> }
> EXPORT_SYMBOL(of_find_node_with_property);
>
> +static int of_match_type_or_name(const struct device_node *node,
> + const struct of_device_id *m)
> +{
> + int match = 1;
> +
> + if (m->name[0])
> + match &= node->name && !strcmp(m->name, node->name);
> +
> + if (m->type[0])
> + match &= node->type && !strcmp(m->type, node->type);
> +
> + return match;
> +}
> +
> static
> const struct of_device_id *__of_match_node(const struct
> of_device_id *matches,
> const struct device_node *node)
> {
> const char *cp;
> int cplen, l;
> + const struct of_device_id *m;
> + int match;
>
> if (!matches)
> return NULL;
>
> cp = __of_get_property(node, "compatible", &cplen);
> - do {
> - const struct of_device_id *m = matches;
> + while (cp && (cplen > 0)) {
> + m = matches;
>
> /* Check against matches with current compatible string */
> while (m->name[0] || m->type[0] || m->compatible[0]) {
> - int match = 1;
> - if (m->name[0])
> - match &= node->name
> - && !strcmp(m->name, node->name);
> - if (m->type[0])
> - match &= node->type
> - && !strcmp(m->type, node->type);
> - if (m->compatible[0])
> - match &= cp
> - && !of_compat_cmp(m->compatible, cp,
> + if (!m->compatible[0]) {
> + m++;
> + continue;
> + }
> +
> + match = of_match_type_or_name(node, m);
> + match &= cp && !of_compat_cmp(m->compatible, cp,
> strlen(m->compatible));
> if (match)
> return m;
> @@ -763,12 +776,18 @@ const struct of_device_id *__of_match_node
> (const struct of_device_id *matches,
> }
>
> /* Get node's next compatible string */
> - if (cp) {
> - l = strlen(cp) + 1;
> - cp += l;
> - cplen -= l;
> - }
> - } while (cp && (cplen > 0));
> + l = strlen(cp) + 1;
> + cp += l;
> + cplen -= l;
> + }
> +
> + m = matches;
> + /* Check against matches without compatible string */
> + while (m->name[0] || m->type[0] || m->compatible[0]) {
> + if (!m->compatible[0] && of_match_type_or_name(node, m))
> + return m;
> + m++;
> + }
>
> return NULL;
> }
> --
> 1.8.5.3
>
More information about the Linuxppc-dev
mailing list