aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of/base.c
diff options
context:
space:
mode:
authorSebastian Hesselbarth <sebastian.hesselbarth@gmail.com>2013-12-03 08:52:00 -0500
committerRob Herring <rob.herring@calxeda.com>2013-12-04 14:12:43 -0500
commit105353145eafb3ea919f5cdeb652a9d8f270228e (patch)
treeda068ad9e86d3183abec81e5bf1582280e28b99c /drivers/of/base.c
parent3ab72f9156bbcd0b7490e2475448693e90f10299 (diff)
OF: base: match each node compatible against all given matches first
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 modifies of_match_node to match each of the node's compatible strings against all given matches 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. Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Tested-by: Meelis Roos <mroos@linux.ee> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Diffstat (limited to 'drivers/of/base.c')
-rw-r--r--drivers/of/base.c53
1 files changed, 37 insertions, 16 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index f807d0edabf3..8d007d8b8c78 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -731,24 +731,42 @@ static
731const struct of_device_id *__of_match_node(const struct of_device_id *matches, 731const struct of_device_id *__of_match_node(const struct of_device_id *matches,
732 const struct device_node *node) 732 const struct device_node *node)
733{ 733{
734 const char *cp;
735 int cplen, l;
736
734 if (!matches) 737 if (!matches)
735 return NULL; 738 return NULL;
736 739
737 while (matches->name[0] || matches->type[0] || matches->compatible[0]) { 740 cp = __of_get_property(node, "compatible", &cplen);
738 int match = 1; 741 do {
739 if (matches->name[0]) 742 const struct of_device_id *m = matches;
740 match &= node->name 743
741 && !strcmp(matches->name, node->name); 744 /* Check against matches with current compatible string */
742 if (matches->type[0]) 745 while (m->name[0] || m->type[0] || m->compatible[0]) {
743 match &= node->type 746 int match = 1;
744 && !strcmp(matches->type, node->type); 747 if (m->name[0])
745 if (matches->compatible[0]) 748 match &= node->name
746 match &= __of_device_is_compatible(node, 749 && !strcmp(m->name, node->name);
747 matches->compatible); 750 if (m->type[0])
748 if (match) 751 match &= node->type
749 return matches; 752 && !strcmp(m->type, node->type);
750 matches++; 753 if (m->compatible[0])
751 } 754 match &= cp
755 && !of_compat_cmp(m->compatible, cp,
756 strlen(m->compatible));
757 if (match)
758 return m;
759 m++;
760 }
761
762 /* Get node's next compatible string */
763 if (cp) {
764 l = strlen(cp) + 1;
765 cp += l;
766 cplen -= l;
767 }
768 } while (cp && (cplen > 0));
769
752 return NULL; 770 return NULL;
753} 771}
754 772
@@ -757,7 +775,10 @@ const struct of_device_id *__of_match_node(const struct of_device_id *matches,
757 * @matches: array of of device match structures to search in 775 * @matches: array of of device match structures to search in
758 * @node: the of device structure to match against 776 * @node: the of device structure to match against
759 * 777 *
760 * Low level utility function used by device matching. 778 * Low level utility function used by device matching. Matching order
779 * is to compare each of the node's compatibles with all given matches
780 * first. This implies node's compatible is sorted from specific to
781 * generic while matches can be in any order.
761 */ 782 */
762const struct of_device_id *of_match_node(const struct of_device_id *matches, 783const struct of_device_id *of_match_node(const struct of_device_id *matches,
763 const struct device_node *node) 784 const struct device_node *node)