aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/of/base.c')
-rw-r--r--drivers/of/base.c53
1 files changed, 31 insertions, 22 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 3823edf2d012..1f61a908a767 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -32,8 +32,8 @@
32 32
33LIST_HEAD(aliases_lookup); 33LIST_HEAD(aliases_lookup);
34 34
35struct device_node *of_allnodes; 35struct device_node *of_root;
36EXPORT_SYMBOL(of_allnodes); 36EXPORT_SYMBOL(of_root);
37struct device_node *of_chosen; 37struct device_node *of_chosen;
38struct device_node *of_aliases; 38struct device_node *of_aliases;
39struct device_node *of_stdout; 39struct device_node *of_stdout;
@@ -48,7 +48,7 @@ struct kset *of_kset;
48 */ 48 */
49DEFINE_MUTEX(of_mutex); 49DEFINE_MUTEX(of_mutex);
50 50
51/* use when traversing tree through the allnext, child, sibling, 51/* use when traversing tree through the child, sibling,
52 * or parent members of struct device_node. 52 * or parent members of struct device_node.
53 */ 53 */
54DEFINE_RAW_SPINLOCK(devtree_lock); 54DEFINE_RAW_SPINLOCK(devtree_lock);
@@ -204,7 +204,7 @@ static int __init of_init(void)
204 mutex_unlock(&of_mutex); 204 mutex_unlock(&of_mutex);
205 205
206 /* Symlink in /proc as required by userspace ABI */ 206 /* Symlink in /proc as required by userspace ABI */
207 if (of_allnodes) 207 if (of_root)
208 proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base"); 208 proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base");
209 209
210 return 0; 210 return 0;
@@ -245,6 +245,23 @@ struct property *of_find_property(const struct device_node *np,
245} 245}
246EXPORT_SYMBOL(of_find_property); 246EXPORT_SYMBOL(of_find_property);
247 247
248struct device_node *__of_find_all_nodes(struct device_node *prev)
249{
250 struct device_node *np;
251 if (!prev) {
252 np = of_root;
253 } else if (prev->child) {
254 np = prev->child;
255 } else {
256 /* Walk back up looking for a sibling, or the end of the structure */
257 np = prev;
258 while (np->parent && !np->sibling)
259 np = np->parent;
260 np = np->sibling; /* Might be null at the end of the tree */
261 }
262 return np;
263}
264
248/** 265/**
249 * of_find_all_nodes - Get next node in global list 266 * of_find_all_nodes - Get next node in global list
250 * @prev: Previous node or NULL to start iteration 267 * @prev: Previous node or NULL to start iteration
@@ -259,10 +276,8 @@ struct device_node *of_find_all_nodes(struct device_node *prev)
259 unsigned long flags; 276 unsigned long flags;
260 277
261 raw_spin_lock_irqsave(&devtree_lock, flags); 278 raw_spin_lock_irqsave(&devtree_lock, flags);
262 np = prev ? prev->allnext : of_allnodes; 279 np = __of_find_all_nodes(prev);
263 for (; np != NULL; np = np->allnext) 280 of_node_get(np);
264 if (of_node_get(np))
265 break;
266 of_node_put(prev); 281 of_node_put(prev);
267 raw_spin_unlock_irqrestore(&devtree_lock, flags); 282 raw_spin_unlock_irqrestore(&devtree_lock, flags);
268 return np; 283 return np;
@@ -736,7 +751,7 @@ struct device_node *of_find_node_by_path(const char *path)
736 unsigned long flags; 751 unsigned long flags;
737 752
738 if (strcmp(path, "/") == 0) 753 if (strcmp(path, "/") == 0)
739 return of_node_get(of_allnodes); 754 return of_node_get(of_root);
740 755
741 /* The path could begin with an alias */ 756 /* The path could begin with an alias */
742 if (*path != '/') { 757 if (*path != '/') {
@@ -761,7 +776,7 @@ struct device_node *of_find_node_by_path(const char *path)
761 /* Step down the tree matching path components */ 776 /* Step down the tree matching path components */
762 raw_spin_lock_irqsave(&devtree_lock, flags); 777 raw_spin_lock_irqsave(&devtree_lock, flags);
763 if (!np) 778 if (!np)
764 np = of_node_get(of_allnodes); 779 np = of_node_get(of_root);
765 while (np && *path == '/') { 780 while (np && *path == '/') {
766 path++; /* Increment past '/' delimiter */ 781 path++; /* Increment past '/' delimiter */
767 np = __of_find_node_by_path(np, path); 782 np = __of_find_node_by_path(np, path);
@@ -790,8 +805,7 @@ struct device_node *of_find_node_by_name(struct device_node *from,
790 unsigned long flags; 805 unsigned long flags;
791 806
792 raw_spin_lock_irqsave(&devtree_lock, flags); 807 raw_spin_lock_irqsave(&devtree_lock, flags);
793 np = from ? from->allnext : of_allnodes; 808 for_each_of_allnodes_from(from, np)
794 for (; np; np = np->allnext)
795 if (np->name && (of_node_cmp(np->name, name) == 0) 809 if (np->name && (of_node_cmp(np->name, name) == 0)
796 && of_node_get(np)) 810 && of_node_get(np))
797 break; 811 break;
@@ -820,8 +834,7 @@ struct device_node *of_find_node_by_type(struct device_node *from,
820 unsigned long flags; 834 unsigned long flags;
821 835
822 raw_spin_lock_irqsave(&devtree_lock, flags); 836 raw_spin_lock_irqsave(&devtree_lock, flags);
823 np = from ? from->allnext : of_allnodes; 837 for_each_of_allnodes_from(from, np)
824 for (; np; np = np->allnext)
825 if (np->type && (of_node_cmp(np->type, type) == 0) 838 if (np->type && (of_node_cmp(np->type, type) == 0)
826 && of_node_get(np)) 839 && of_node_get(np))
827 break; 840 break;
@@ -852,12 +865,10 @@ struct device_node *of_find_compatible_node(struct device_node *from,
852 unsigned long flags; 865 unsigned long flags;
853 866
854 raw_spin_lock_irqsave(&devtree_lock, flags); 867 raw_spin_lock_irqsave(&devtree_lock, flags);
855 np = from ? from->allnext : of_allnodes; 868 for_each_of_allnodes_from(from, np)
856 for (; np; np = np->allnext) {
857 if (__of_device_is_compatible(np, compatible, type, NULL) && 869 if (__of_device_is_compatible(np, compatible, type, NULL) &&
858 of_node_get(np)) 870 of_node_get(np))
859 break; 871 break;
860 }
861 of_node_put(from); 872 of_node_put(from);
862 raw_spin_unlock_irqrestore(&devtree_lock, flags); 873 raw_spin_unlock_irqrestore(&devtree_lock, flags);
863 return np; 874 return np;
@@ -884,8 +895,7 @@ struct device_node *of_find_node_with_property(struct device_node *from,
884 unsigned long flags; 895 unsigned long flags;
885 896
886 raw_spin_lock_irqsave(&devtree_lock, flags); 897 raw_spin_lock_irqsave(&devtree_lock, flags);
887 np = from ? from->allnext : of_allnodes; 898 for_each_of_allnodes_from(from, np) {
888 for (; np; np = np->allnext) {
889 for (pp = np->properties; pp; pp = pp->next) { 899 for (pp = np->properties; pp; pp = pp->next) {
890 if (of_prop_cmp(pp->name, prop_name) == 0) { 900 if (of_prop_cmp(pp->name, prop_name) == 0) {
891 of_node_get(np); 901 of_node_get(np);
@@ -967,8 +977,7 @@ struct device_node *of_find_matching_node_and_match(struct device_node *from,
967 *match = NULL; 977 *match = NULL;
968 978
969 raw_spin_lock_irqsave(&devtree_lock, flags); 979 raw_spin_lock_irqsave(&devtree_lock, flags);
970 np = from ? from->allnext : of_allnodes; 980 for_each_of_allnodes_from(from, np) {
971 for (; np; np = np->allnext) {
972 m = __of_match_node(matches, np); 981 m = __of_match_node(matches, np);
973 if (m && of_node_get(np)) { 982 if (m && of_node_get(np)) {
974 if (match) 983 if (match)
@@ -1025,7 +1034,7 @@ struct device_node *of_find_node_by_phandle(phandle handle)
1025 return NULL; 1034 return NULL;
1026 1035
1027 raw_spin_lock_irqsave(&devtree_lock, flags); 1036 raw_spin_lock_irqsave(&devtree_lock, flags);
1028 for (np = of_allnodes; np; np = np->allnext) 1037 for_each_of_allnodes(np)
1029 if (np->phandle == handle) 1038 if (np->phandle == handle)
1030 break; 1039 break;
1031 of_node_get(np); 1040 of_node_get(np);