aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Hao <haokexin@gmail.com>2014-02-14 00:22:46 -0500
committerRob Herring <robh@kernel.org>2014-02-15 19:51:17 -0500
commit06b29e76a74b2373e6f8b5a7938b3630b9ae98b2 (patch)
treea9ad65687400206ef0b07f08af5237c977be7009
parent4e8ca6ee3a5d0e0f4c0cb32e43dc3d69e79e5a76 (diff)
of: search the best compatible match first in __of_match_node()
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@gmail.com> Signed-off-by: Kevin Hao <haokexin@gmail.com> Tested-by: Stephen Chivers <schivers@csc.com> Signed-off-by: Rob Herring <robh@kernel.org>
-rw-r--r--drivers/of/base.c43
1 files changed, 42 insertions, 1 deletions
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:
730} 730}
731EXPORT_SYMBOL(of_find_node_with_property); 731EXPORT_SYMBOL(of_find_node_with_property);
732 732
733static const struct of_device_id *
734of_match_compatible(const struct of_device_id *matches,
735 const struct device_node *node)
736{
737 const char *cp;
738 int cplen, l;
739 const struct of_device_id *m;
740
741 cp = __of_get_property(node, "compatible", &cplen);
742 while (cp && (cplen > 0)) {
743 m = matches;
744 while (m->name[0] || m->type[0] || m->compatible[0]) {
745 /* Only match for the entries without type and name */
746 if (m->name[0] || m->type[0] ||
747 of_compat_cmp(m->compatible, cp,
748 strlen(m->compatible)))
749 m++;
750 else
751 return m;
752 }
753
754 /* Get node's next compatible string */
755 l = strlen(cp) + 1;
756 cp += l;
757 cplen -= l;
758 }
759
760 return NULL;
761}
762
733static 763static
734const struct of_device_id *__of_match_node(const struct of_device_id *matches, 764const struct of_device_id *__of_match_node(const struct of_device_id *matches,
735 const struct device_node *node) 765 const struct device_node *node)
736{ 766{
767 const struct of_device_id *m;
768
737 if (!matches) 769 if (!matches)
738 return NULL; 770 return NULL;
739 771
772 m = of_match_compatible(matches, node);
773 if (m)
774 return m;
775
740 while (matches->name[0] || matches->type[0] || matches->compatible[0]) { 776 while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
741 int match = 1; 777 int match = 1;
742 if (matches->name[0]) 778 if (matches->name[0])
@@ -760,7 +796,12 @@ const struct of_device_id *__of_match_node(const struct of_device_id *matches,
760 * @matches: array of of device match structures to search in 796 * @matches: array of of device match structures to search in
761 * @node: the of device structure to match against 797 * @node: the of device structure to match against
762 * 798 *
763 * Low level utility function used by device matching. 799 * Low level utility function used by device matching. We have two ways
800 * of matching:
801 * - Try to find the best compatible match by comparing each compatible
802 * string of device node with all the given matches respectively.
803 * - If the above method failed, then try to match the compatible by using
804 * __of_device_is_compatible() besides the match in type and name.
764 */ 805 */
765const struct of_device_id *of_match_node(const struct of_device_id *matches, 806const struct of_device_id *of_match_node(const struct of_device_id *matches,
766 const struct device_node *node) 807 const struct device_node *node)