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 | |
| 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')
| -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 | } |
