From patchwork Wed Feb 12 11:38:04 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Hao X-Patchwork-Id: 319624 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from ozlabs.org (localhost [IPv6:::1]) by ozlabs.org (Postfix) with ESMTP id ECFE62C03A0 for ; Wed, 12 Feb 2014 22:39:13 +1100 (EST) Received: from mail-pd0-x22c.google.com (mail-pd0-x22c.google.com [IPv6:2607:f8b0:400e:c02::22c]) (using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id ADE8C2C00B3 for ; Wed, 12 Feb 2014 22:38:46 +1100 (EST) Received: by mail-pd0-f172.google.com with SMTP id p10so8885770pdj.31 for ; Wed, 12 Feb 2014 03:38:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=od4f4/XSVAPjSq2a/MVXowssayx7Gcfq8pQPt5TZhIQ=; b=l3AAiJ7MDqUolZYmxUY6lgq6s22PRomrmSYv1g6ZzLs3m6lE9umQqFgmj3EJV5Si5z dDMQ+s110pWmpH/XOp5PGEUhvt6Wvi+UA2180D5OSQMuBlZfFFSxkHYOxpkQ+ZiebXF3 2lFff3INicY84SZYoX3qrnfAhMQXE+I+lWYOODv4DdriHrGQk9HWEsIRwQF3KMwZELoa F30wgwsFQCtEyQAYb5ecCnwFZTMlliJG1ncn+0/AvYIl4pxtwcESK9VDrUfctO9DylE9 RZ2F78ZEHqO29ybkrCdnmGbfwl9IFJyfXQjBQMANT0wACkgC74C7YXxe5r0EhekJfDJi wATw== X-Received: by 10.66.176.143 with SMTP id ci15mr38752129pac.35.1392205123016; Wed, 12 Feb 2014 03:38:43 -0800 (PST) Received: from pek-khao-d1.corp.ad.wrs.com ([1.202.252.122]) by mx.google.com with ESMTPSA id qq5sm62727678pbb.24.2014.02.12.03.38.31 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 12 Feb 2014 03:38:42 -0800 (PST) From: Kevin Hao To: devicetree@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH] of: give priority to the compatible match in __of_match_node() Date: Wed, 12 Feb 2014 19:38:04 +0800 Message-Id: <1392205084-2351-1-git-send-email-haokexin@gmail.com> X-Mailer: git-send-email 1.8.5.3 Cc: Chris Proctor , Arnd Bergmann , Stephen N Chivers , Grant Likely , Rob Herring , Scott Wood , Sebastian Hesselbarth X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" 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 Signed-off-by: Kevin Hao Tested-by: Stephen Chivers Tested-by: Stephen Chivers --- 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; }