diff --git a/drivers/of/base.c b/drivers/of/base.c index ba195fbce4c637ac85edbffbb73ccbdf39c1f6b0..10b51106c854f20fc1b73bf80d9b5c37d23d8545 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -730,13 +730,49 @@ struct device_node *of_find_node_with_property(struct device_node *from, } 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)