Skip to content

Commit 4302a87

Browse files
committed
Merge tag 'dt-fixes-for-3.14' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux
Pull devicetree fixes from Rob Herring: "Fix booting on PPC boards. Changes to of_match_node matching caused the serial port on some PPC boards to stop working. Reverted the change and reimplement to split matching between new style compatible only matching and fallback to old matching algorithm" * tag 'dt-fixes-for-3.14' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux: of: search the best compatible match first in __of_match_node() Revert "OF: base: match each node compatible against all given matches first"
2 parents 946dd68 + 06b29e7 commit 4302a87

File tree

1 file changed

+54
-34
lines changed

1 file changed

+54
-34
lines changed

drivers/of/base.c

Lines changed: 54 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -730,46 +730,64 @@ struct device_node *of_find_node_with_property(struct device_node *from,
730730
}
731731
EXPORT_SYMBOL(of_find_node_with_property);
732732

733-
static
734-
const struct of_device_id *__of_match_node(const struct of_device_id *matches,
735-
const struct device_node *node)
733+
static const struct of_device_id *
734+
of_match_compatible(const struct of_device_id *matches,
735+
const struct device_node *node)
736736
{
737737
const char *cp;
738738
int cplen, l;
739-
740-
if (!matches)
741-
return NULL;
739+
const struct of_device_id *m;
742740

743741
cp = __of_get_property(node, "compatible", &cplen);
744-
do {
745-
const struct of_device_id *m = matches;
746-
747-
/* Check against matches with current compatible string */
742+
while (cp && (cplen > 0)) {
743+
m = matches;
748744
while (m->name[0] || m->type[0] || m->compatible[0]) {
749-
int match = 1;
750-
if (m->name[0])
751-
match &= node->name
752-
&& !strcmp(m->name, node->name);
753-
if (m->type[0])
754-
match &= node->type
755-
&& !strcmp(m->type, node->type);
756-
if (m->compatible[0])
757-
match &= cp
758-
&& !of_compat_cmp(m->compatible, cp,
759-
strlen(m->compatible));
760-
if (match)
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
761751
return m;
762-
m++;
763752
}
764753

765-
/* Get node's next compatible string */
766-
if (cp) {
767-
l = strlen(cp) + 1;
768-
cp += l;
769-
cplen -= l;
770-
}
771-
} while (cp && (cplen > 0));
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+
763+
static
764+
const struct of_device_id *__of_match_node(const struct of_device_id *matches,
765+
const struct device_node *node)
766+
{
767+
const struct of_device_id *m;
772768

769+
if (!matches)
770+
return NULL;
771+
772+
m = of_match_compatible(matches, node);
773+
if (m)
774+
return m;
775+
776+
while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
777+
int match = 1;
778+
if (matches->name[0])
779+
match &= node->name
780+
&& !strcmp(matches->name, node->name);
781+
if (matches->type[0])
782+
match &= node->type
783+
&& !strcmp(matches->type, node->type);
784+
if (matches->compatible[0])
785+
match &= __of_device_is_compatible(node,
786+
matches->compatible);
787+
if (match)
788+
return matches;
789+
matches++;
790+
}
773791
return NULL;
774792
}
775793

@@ -778,10 +796,12 @@ const struct of_device_id *__of_match_node(const struct of_device_id *matches,
778796
* @matches: array of of device match structures to search in
779797
* @node: the of device structure to match against
780798
*
781-
* Low level utility function used by device matching. Matching order
782-
* is to compare each of the node's compatibles with all given matches
783-
* first. This implies node's compatible is sorted from specific to
784-
* generic while matches can be in any order.
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.
785805
*/
786806
const struct of_device_id *of_match_node(const struct of_device_id *matches,
787807
const struct device_node *node)

0 commit comments

Comments
 (0)