From patchwork Fri Feb 14 05:22:46 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Hao X-Patchwork-Id: 320286 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 6068D2C055F for ; Fri, 14 Feb 2014 16:26:50 +1100 (EST) Received: from mail-pd0-x233.google.com (mail-pd0-x233.google.com [IPv6:2607:f8b0:400e:c02::233]) (using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 5BBCF2C03E0 for ; Fri, 14 Feb 2014 16:25:17 +1100 (EST) Received: by mail-pd0-f179.google.com with SMTP id fp1so11117534pdb.38 for ; Thu, 13 Feb 2014 21:25:14 -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:in-reply-to:references; bh=hY02H2Bv9ny0i/NvfOD73iOKdgbIr/GgjTzk38ge0/k=; b=ORC+iIz3gNR7x5LaLwqkkWXmBOghV74o5azGFMThYTwjVXqelJ5c7JiRS4V1I6eygL kW1BDIGKMkWg/ZyQbU+HbDKiCJ2gWwUWWqUIQ23eg4c41IiObs0OKo4M3Ly747YdAmHP tg9hNa8GIJHDpJFeM5KuFegFY1mac9R7Mq3hCHqOYVimUVtHVWZOa6SrIWbPrQ2HVWQV kssU3qOAFGRM9+lsia2+zJOX1XHsFjjh3x9/cA7PMkLHEsipcJKEHBaSkF1i479sM+Tk 6G9D60iXekC0RQgAkVSjEr+PXmiGs+P9JHq3cv8saqTH15dE6aY63VjY4vUzwqz9mv8b yXRw== X-Received: by 10.66.182.199 with SMTP id eg7mr6556104pac.135.1392355514793; Thu, 13 Feb 2014 21:25:14 -0800 (PST) Received: from pek-khao-d1.corp.ad.wrs.com ([1.202.252.122]) by mx.google.com with ESMTPSA id sq7sm12738976pbc.19.2014.02.13.21.25.06 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 13 Feb 2014 21:25:14 -0800 (PST) From: Kevin Hao To: devicetree@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH 2/2] of: search the best compatible match first in __of_match_node() Date: Fri, 14 Feb 2014 13:22:46 +0800 Message-Id: <1392355366-1445-3-git-send-email-haokexin@gmail.com> X-Mailer: git-send-email 1.8.5.3 In-Reply-To: <1392355366-1445-1-git-send-email-haokexin@gmail.com> References: <1392355366-1445-1-git-send-email-haokexin@gmail.com> Cc: Grant Likely , Stephen N Chivers , Rob Herring , Kevin Hao , 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" 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 Signed-off-by: Kevin Hao Tested-by: Stephen Chivers --- 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)