diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2013-02-08 04:23:33 -0500 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2013-02-08 04:23:33 -0500 |
commit | d2f4ec1026fecbef9b72cc899a626516ef3f265f (patch) | |
tree | 3b9ed2b015cc714151fba71244f3dbba300cc3ac /drivers/of | |
parent | 12514aa0e6c6ca4e03b8a4da557b7d3ee0d91f5d (diff) | |
parent | eb7ccb8184ab36b61fb596bd8d573e22e04d6266 (diff) |
Merge branch 'robherring/for-next' from git://sources.calxeda.com/kernel/linux.git
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/of')
-rw-r--r-- | drivers/of/base.c | 95 |
1 files changed, 73 insertions, 22 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c index d1bb50719ed7..8b9fa83dc77b 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
@@ -147,16 +147,14 @@ void of_node_put(struct device_node *node) | |||
147 | EXPORT_SYMBOL(of_node_put); | 147 | EXPORT_SYMBOL(of_node_put); |
148 | #endif /* CONFIG_OF_DYNAMIC */ | 148 | #endif /* CONFIG_OF_DYNAMIC */ |
149 | 149 | ||
150 | struct property *of_find_property(const struct device_node *np, | 150 | static struct property *__of_find_property(const struct device_node *np, |
151 | const char *name, | 151 | const char *name, int *lenp) |
152 | int *lenp) | ||
153 | { | 152 | { |
154 | struct property *pp; | 153 | struct property *pp; |
155 | 154 | ||
156 | if (!np) | 155 | if (!np) |
157 | return NULL; | 156 | return NULL; |
158 | 157 | ||
159 | read_lock(&devtree_lock); | ||
160 | for (pp = np->properties; pp; pp = pp->next) { | 158 | for (pp = np->properties; pp; pp = pp->next) { |
161 | if (of_prop_cmp(pp->name, name) == 0) { | 159 | if (of_prop_cmp(pp->name, name) == 0) { |
162 | if (lenp) | 160 | if (lenp) |
@@ -164,6 +162,18 @@ struct property *of_find_property(const struct device_node *np, | |||
164 | break; | 162 | break; |
165 | } | 163 | } |
166 | } | 164 | } |
165 | |||
166 | return pp; | ||
167 | } | ||
168 | |||
169 | struct property *of_find_property(const struct device_node *np, | ||
170 | const char *name, | ||
171 | int *lenp) | ||
172 | { | ||
173 | struct property *pp; | ||
174 | |||
175 | read_lock(&devtree_lock); | ||
176 | pp = __of_find_property(np, name, lenp); | ||
167 | read_unlock(&devtree_lock); | 177 | read_unlock(&devtree_lock); |
168 | 178 | ||
169 | return pp; | 179 | return pp; |
@@ -197,8 +207,20 @@ EXPORT_SYMBOL(of_find_all_nodes); | |||
197 | * Find a property with a given name for a given node | 207 | * Find a property with a given name for a given node |
198 | * and return the value. | 208 | * and return the value. |
199 | */ | 209 | */ |
210 | static const void *__of_get_property(const struct device_node *np, | ||
211 | const char *name, int *lenp) | ||
212 | { | ||
213 | struct property *pp = __of_find_property(np, name, lenp); | ||
214 | |||
215 | return pp ? pp->value : NULL; | ||
216 | } | ||
217 | |||
218 | /* | ||
219 | * Find a property with a given name for a given node | ||
220 | * and return the value. | ||
221 | */ | ||
200 | const void *of_get_property(const struct device_node *np, const char *name, | 222 | const void *of_get_property(const struct device_node *np, const char *name, |
201 | int *lenp) | 223 | int *lenp) |
202 | { | 224 | { |
203 | struct property *pp = of_find_property(np, name, lenp); | 225 | struct property *pp = of_find_property(np, name, lenp); |
204 | 226 | ||
@@ -209,13 +231,13 @@ EXPORT_SYMBOL(of_get_property); | |||
209 | /** Checks if the given "compat" string matches one of the strings in | 231 | /** Checks if the given "compat" string matches one of the strings in |
210 | * the device's "compatible" property | 232 | * the device's "compatible" property |
211 | */ | 233 | */ |
212 | int of_device_is_compatible(const struct device_node *device, | 234 | static int __of_device_is_compatible(const struct device_node *device, |
213 | const char *compat) | 235 | const char *compat) |
214 | { | 236 | { |
215 | const char* cp; | 237 | const char* cp; |
216 | int cplen, l; | 238 | int cplen, l; |
217 | 239 | ||
218 | cp = of_get_property(device, "compatible", &cplen); | 240 | cp = __of_get_property(device, "compatible", &cplen); |
219 | if (cp == NULL) | 241 | if (cp == NULL) |
220 | return 0; | 242 | return 0; |
221 | while (cplen > 0) { | 243 | while (cplen > 0) { |
@@ -228,6 +250,20 @@ int of_device_is_compatible(const struct device_node *device, | |||
228 | 250 | ||
229 | return 0; | 251 | return 0; |
230 | } | 252 | } |
253 | |||
254 | /** Checks if the given "compat" string matches one of the strings in | ||
255 | * the device's "compatible" property | ||
256 | */ | ||
257 | int of_device_is_compatible(const struct device_node *device, | ||
258 | const char *compat) | ||
259 | { | ||
260 | int res; | ||
261 | |||
262 | read_lock(&devtree_lock); | ||
263 | res = __of_device_is_compatible(device, compat); | ||
264 | read_unlock(&devtree_lock); | ||
265 | return res; | ||
266 | } | ||
231 | EXPORT_SYMBOL(of_device_is_compatible); | 267 | EXPORT_SYMBOL(of_device_is_compatible); |
232 | 268 | ||
233 | /** | 269 | /** |
@@ -501,7 +537,8 @@ struct device_node *of_find_compatible_node(struct device_node *from, | |||
501 | if (type | 537 | if (type |
502 | && !(np->type && (of_node_cmp(np->type, type) == 0))) | 538 | && !(np->type && (of_node_cmp(np->type, type) == 0))) |
503 | continue; | 539 | continue; |
504 | if (of_device_is_compatible(np, compatible) && of_node_get(np)) | 540 | if (__of_device_is_compatible(np, compatible) && |
541 | of_node_get(np)) | ||
505 | break; | 542 | break; |
506 | } | 543 | } |
507 | of_node_put(from); | 544 | of_node_put(from); |
@@ -545,15 +582,9 @@ out: | |||
545 | } | 582 | } |
546 | EXPORT_SYMBOL(of_find_node_with_property); | 583 | EXPORT_SYMBOL(of_find_node_with_property); |
547 | 584 | ||
548 | /** | 585 | static |
549 | * of_match_node - Tell if an device_node has a matching of_match structure | 586 | const struct of_device_id *__of_match_node(const struct of_device_id *matches, |
550 | * @matches: array of of device match structures to search in | 587 | const struct device_node *node) |
551 | * @node: the of device structure to match against | ||
552 | * | ||
553 | * Low level utility function used by device matching. | ||
554 | */ | ||
555 | const struct of_device_id *of_match_node(const struct of_device_id *matches, | ||
556 | const struct device_node *node) | ||
557 | { | 588 | { |
558 | if (!matches) | 589 | if (!matches) |
559 | return NULL; | 590 | return NULL; |
@@ -567,14 +598,32 @@ const struct of_device_id *of_match_node(const struct of_device_id *matches, | |||
567 | match &= node->type | 598 | match &= node->type |
568 | && !strcmp(matches->type, node->type); | 599 | && !strcmp(matches->type, node->type); |
569 | if (matches->compatible[0]) | 600 | if (matches->compatible[0]) |
570 | match &= of_device_is_compatible(node, | 601 | match &= __of_device_is_compatible(node, |
571 | matches->compatible); | 602 | matches->compatible); |
572 | if (match) | 603 | if (match) |
573 | return matches; | 604 | return matches; |
574 | matches++; | 605 | matches++; |
575 | } | 606 | } |
576 | return NULL; | 607 | return NULL; |
577 | } | 608 | } |
609 | |||
610 | /** | ||
611 | * of_match_node - Tell if an device_node has a matching of_match structure | ||
612 | * @matches: array of of device match structures to search in | ||
613 | * @node: the of device structure to match against | ||
614 | * | ||
615 | * Low level utility function used by device matching. | ||
616 | */ | ||
617 | const struct of_device_id *of_match_node(const struct of_device_id *matches, | ||
618 | const struct device_node *node) | ||
619 | { | ||
620 | const struct of_device_id *match; | ||
621 | |||
622 | read_lock(&devtree_lock); | ||
623 | match = __of_match_node(matches, node); | ||
624 | read_unlock(&devtree_lock); | ||
625 | return match; | ||
626 | } | ||
578 | EXPORT_SYMBOL(of_match_node); | 627 | EXPORT_SYMBOL(of_match_node); |
579 | 628 | ||
580 | /** | 629 | /** |
@@ -595,6 +644,7 @@ struct device_node *of_find_matching_node_and_match(struct device_node *from, | |||
595 | const struct of_device_id **match) | 644 | const struct of_device_id **match) |
596 | { | 645 | { |
597 | struct device_node *np; | 646 | struct device_node *np; |
647 | const struct of_device_id *m; | ||
598 | 648 | ||
599 | if (match) | 649 | if (match) |
600 | *match = NULL; | 650 | *match = NULL; |
@@ -602,9 +652,10 @@ struct device_node *of_find_matching_node_and_match(struct device_node *from, | |||
602 | read_lock(&devtree_lock); | 652 | read_lock(&devtree_lock); |
603 | np = from ? from->allnext : of_allnodes; | 653 | np = from ? from->allnext : of_allnodes; |
604 | for (; np; np = np->allnext) { | 654 | for (; np; np = np->allnext) { |
605 | if (of_match_node(matches, np) && of_node_get(np)) { | 655 | m = __of_match_node(matches, np); |
656 | if (m && of_node_get(np)) { | ||
606 | if (match) | 657 | if (match) |
607 | *match = matches; | 658 | *match = m; |
608 | break; | 659 | break; |
609 | } | 660 | } |
610 | } | 661 | } |