summaryrefslogtreecommitdiffstats
path: root/drivers/of/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/of/base.c')
-rw-r--r--drivers/of/base.c56
1 files changed, 40 insertions, 16 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index f807d0edabf3..ff85450d5683 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -415,6 +415,9 @@ static int __of_device_is_available(const struct device_node *device)
const char *status;
int statlen;
+ if (!device)
+ return 0;
+
status = __of_get_property(device, "status", &statlen);
if (status == NULL)
return 1;
@@ -731,24 +734,42 @@ 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;
+
if (!matches)
return NULL;
- while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
- int match = 1;
- if (matches->name[0])
- match &= node->name
- && !strcmp(matches->name, node->name);
- if (matches->type[0])
- match &= node->type
- && !strcmp(matches->type, node->type);
- if (matches->compatible[0])
- match &= __of_device_is_compatible(node,
- matches->compatible);
- if (match)
- return matches;
- matches++;
- }
+ cp = __of_get_property(node, "compatible", &cplen);
+ do {
+ const struct of_device_id *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,
+ strlen(m->compatible));
+ if (match)
+ return m;
+ m++;
+ }
+
+ /* Get node's next compatible string */
+ if (cp) {
+ l = strlen(cp) + 1;
+ cp += l;
+ cplen -= l;
+ }
+ } while (cp && (cplen > 0));
+
return NULL;
}
@@ -757,7 +778,10 @@ 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. Matching order
+ * is to compare each of the node's compatibles with all given matches
+ * first. This implies node's compatible is sorted from specific to
+ * generic while matches can be in any order.
*/
const struct of_device_id *of_match_node(const struct of_device_id *matches,
const struct device_node *node)