aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2007-04-24 03:57:33 -0400
committerStephen Rothwell <sfr@canb.auug.org.au>2007-07-19 23:39:06 -0400
commit1ef4d4242d9c494c49ae1ae66dc938fce0272816 (patch)
tree74c64ec940b306b5d1e7bb93a980041ad670468d
parentd1cd355a5e44dfe993efc0c0458ca9f99a28a9a3 (diff)
Consolidate of_find_node_by routines
This consolidates the routines of_find_node_by_path, of_find_node_by_name, of_find_node_by_type and of_find_compatible_device. Again, the comparison of strings are done differently by Sparc and PowerPC and also these add read_locks around the iterations. Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au> Acked-by: Paul Mackerras <paulus@samba.org> Acked-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/powerpc/kernel/prom.c115
-rw-r--r--arch/sparc/kernel/prom.c61
-rw-r--r--arch/sparc64/kernel/prom.c61
-rw-r--r--drivers/of/base.c115
-rw-r--r--include/asm-powerpc/prom.h1
-rw-r--r--include/asm-sparc/prom.h1
-rw-r--r--include/asm-sparc64/prom.h1
7 files changed, 121 insertions, 234 deletions
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 5fa221ce8714..bdcd23d8d8b9 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -78,7 +78,7 @@ static struct boot_param_header *initial_boot_params __initdata;
78struct boot_param_header *initial_boot_params; 78struct boot_param_header *initial_boot_params;
79#endif 79#endif
80 80
81static struct device_node *allnodes = NULL; 81extern struct device_node *allnodes; /* temporary while merging */
82 82
83extern rwlock_t devtree_lock; /* temporary while merging */ 83extern rwlock_t devtree_lock; /* temporary while merging */
84 84
@@ -1084,119 +1084,6 @@ EXPORT_SYMBOL(machine_is_compatible);
1084 *******/ 1084 *******/
1085 1085
1086/** 1086/**
1087 * of_find_node_by_name - Find a node by its "name" property
1088 * @from: The node to start searching from or NULL, the node
1089 * you pass will not be searched, only the next one
1090 * will; typically, you pass what the previous call
1091 * returned. of_node_put() will be called on it
1092 * @name: The name string to match against
1093 *
1094 * Returns a node pointer with refcount incremented, use
1095 * of_node_put() on it when done.
1096 */
1097struct device_node *of_find_node_by_name(struct device_node *from,
1098 const char *name)
1099{
1100 struct device_node *np;
1101
1102 read_lock(&devtree_lock);
1103 np = from ? from->allnext : allnodes;
1104 for (; np != NULL; np = np->allnext)
1105 if (np->name != NULL && strcasecmp(np->name, name) == 0
1106 && of_node_get(np))
1107 break;
1108 of_node_put(from);
1109 read_unlock(&devtree_lock);
1110 return np;
1111}
1112EXPORT_SYMBOL(of_find_node_by_name);
1113
1114/**
1115 * of_find_node_by_type - Find a node by its "device_type" property
1116 * @from: The node to start searching from, or NULL to start searching
1117 * the entire device tree. The node you pass will not be
1118 * searched, only the next one will; typically, you pass
1119 * what the previous call returned. of_node_put() will be
1120 * called on from for you.
1121 * @type: The type string to match against
1122 *
1123 * Returns a node pointer with refcount incremented, use
1124 * of_node_put() on it when done.
1125 */
1126struct device_node *of_find_node_by_type(struct device_node *from,
1127 const char *type)
1128{
1129 struct device_node *np;
1130
1131 read_lock(&devtree_lock);
1132 np = from ? from->allnext : allnodes;
1133 for (; np != 0; np = np->allnext)
1134 if (np->type != 0 && strcasecmp(np->type, type) == 0
1135 && of_node_get(np))
1136 break;
1137 of_node_put(from);
1138 read_unlock(&devtree_lock);
1139 return np;
1140}
1141EXPORT_SYMBOL(of_find_node_by_type);
1142
1143/**
1144 * of_find_compatible_node - Find a node based on type and one of the
1145 * tokens in its "compatible" property
1146 * @from: The node to start searching from or NULL, the node
1147 * you pass will not be searched, only the next one
1148 * will; typically, you pass what the previous call
1149 * returned. of_node_put() will be called on it
1150 * @type: The type string to match "device_type" or NULL to ignore
1151 * @compatible: The string to match to one of the tokens in the device
1152 * "compatible" list.
1153 *
1154 * Returns a node pointer with refcount incremented, use
1155 * of_node_put() on it when done.
1156 */
1157struct device_node *of_find_compatible_node(struct device_node *from,
1158 const char *type, const char *compatible)
1159{
1160 struct device_node *np;
1161
1162 read_lock(&devtree_lock);
1163 np = from ? from->allnext : allnodes;
1164 for (; np != 0; np = np->allnext) {
1165 if (type != NULL
1166 && !(np->type != 0 && strcasecmp(np->type, type) == 0))
1167 continue;
1168 if (of_device_is_compatible(np, compatible) && of_node_get(np))
1169 break;
1170 }
1171 of_node_put(from);
1172 read_unlock(&devtree_lock);
1173 return np;
1174}
1175EXPORT_SYMBOL(of_find_compatible_node);
1176
1177/**
1178 * of_find_node_by_path - Find a node matching a full OF path
1179 * @path: The full path to match
1180 *
1181 * Returns a node pointer with refcount incremented, use
1182 * of_node_put() on it when done.
1183 */
1184struct device_node *of_find_node_by_path(const char *path)
1185{
1186 struct device_node *np = allnodes;
1187
1188 read_lock(&devtree_lock);
1189 for (; np != 0; np = np->allnext) {
1190 if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0
1191 && of_node_get(np))
1192 break;
1193 }
1194 read_unlock(&devtree_lock);
1195 return np;
1196}
1197EXPORT_SYMBOL(of_find_node_by_path);
1198
1199/**
1200 * of_find_node_by_phandle - Find a node given a phandle 1087 * of_find_node_by_phandle - Find a node given a phandle
1201 * @handle: phandle of the node to find 1088 * @handle: phandle of the node to find
1202 * 1089 *
diff --git a/arch/sparc/kernel/prom.c b/arch/sparc/kernel/prom.c
index 3f8ccfad2e01..012f98346bcd 100644
--- a/arch/sparc/kernel/prom.c
+++ b/arch/sparc/kernel/prom.c
@@ -25,23 +25,10 @@
25#include <asm/prom.h> 25#include <asm/prom.h>
26#include <asm/oplib.h> 26#include <asm/oplib.h>
27 27
28static struct device_node *allnodes; 28extern struct device_node *allnodes; /* temporary while merging */
29 29
30extern rwlock_t devtree_lock; /* temporary while merging */ 30extern rwlock_t devtree_lock; /* temporary while merging */
31 31
32struct device_node *of_find_node_by_path(const char *path)
33{
34 struct device_node *np = allnodes;
35
36 for (; np != 0; np = np->allnext) {
37 if (np->full_name != 0 && strcmp(np->full_name, path) == 0)
38 break;
39 }
40
41 return np;
42}
43EXPORT_SYMBOL(of_find_node_by_path);
44
45struct device_node *of_find_node_by_phandle(phandle handle) 32struct device_node *of_find_node_by_phandle(phandle handle)
46{ 33{
47 struct device_node *np; 34 struct device_node *np;
@@ -54,52 +41,6 @@ struct device_node *of_find_node_by_phandle(phandle handle)
54} 41}
55EXPORT_SYMBOL(of_find_node_by_phandle); 42EXPORT_SYMBOL(of_find_node_by_phandle);
56 43
57struct device_node *of_find_node_by_name(struct device_node *from,
58 const char *name)
59{
60 struct device_node *np;
61
62 np = from ? from->allnext : allnodes;
63 for (; np != NULL; np = np->allnext)
64 if (np->name != NULL && strcmp(np->name, name) == 0)
65 break;
66
67 return np;
68}
69EXPORT_SYMBOL(of_find_node_by_name);
70
71struct device_node *of_find_node_by_type(struct device_node *from,
72 const char *type)
73{
74 struct device_node *np;
75
76 np = from ? from->allnext : allnodes;
77 for (; np != 0; np = np->allnext)
78 if (np->type != 0 && strcmp(np->type, type) == 0)
79 break;
80
81 return np;
82}
83EXPORT_SYMBOL(of_find_node_by_type);
84
85struct device_node *of_find_compatible_node(struct device_node *from,
86 const char *type, const char *compatible)
87{
88 struct device_node *np;
89
90 np = from ? from->allnext : allnodes;
91 for (; np != 0; np = np->allnext) {
92 if (type != NULL
93 && !(np->type != 0 && strcmp(np->type, type) == 0))
94 continue;
95 if (of_device_is_compatible(np, compatible))
96 break;
97 }
98
99 return np;
100}
101EXPORT_SYMBOL(of_find_compatible_node);
102
103int of_getintprop_default(struct device_node *np, const char *name, int def) 44int of_getintprop_default(struct device_node *np, const char *name, int def)
104{ 45{
105 struct property *prop; 46 struct property *prop;
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
index ee96ef61bc99..2b2017ce2267 100644
--- a/arch/sparc64/kernel/prom.c
+++ b/arch/sparc64/kernel/prom.c
@@ -30,23 +30,10 @@
30#include <asm/upa.h> 30#include <asm/upa.h>
31#include <asm/smp.h> 31#include <asm/smp.h>
32 32
33static struct device_node *allnodes; 33extern struct device_node *allnodes; /* temporary while merging */
34 34
35extern rwlock_t devtree_lock; /* temporary while merging */ 35extern rwlock_t devtree_lock; /* temporary while merging */
36 36
37struct device_node *of_find_node_by_path(const char *path)
38{
39 struct device_node *np = allnodes;
40
41 for (; np != 0; np = np->allnext) {
42 if (np->full_name != 0 && strcmp(np->full_name, path) == 0)
43 break;
44 }
45
46 return np;
47}
48EXPORT_SYMBOL(of_find_node_by_path);
49
50struct device_node *of_find_node_by_phandle(phandle handle) 37struct device_node *of_find_node_by_phandle(phandle handle)
51{ 38{
52 struct device_node *np; 39 struct device_node *np;
@@ -59,52 +46,6 @@ struct device_node *of_find_node_by_phandle(phandle handle)
59} 46}
60EXPORT_SYMBOL(of_find_node_by_phandle); 47EXPORT_SYMBOL(of_find_node_by_phandle);
61 48
62struct device_node *of_find_node_by_name(struct device_node *from,
63 const char *name)
64{
65 struct device_node *np;
66
67 np = from ? from->allnext : allnodes;
68 for (; np != NULL; np = np->allnext)
69 if (np->name != NULL && strcmp(np->name, name) == 0)
70 break;
71
72 return np;
73}
74EXPORT_SYMBOL(of_find_node_by_name);
75
76struct device_node *of_find_node_by_type(struct device_node *from,
77 const char *type)
78{
79 struct device_node *np;
80
81 np = from ? from->allnext : allnodes;
82 for (; np != 0; np = np->allnext)
83 if (np->type != 0 && strcmp(np->type, type) == 0)
84 break;
85
86 return np;
87}
88EXPORT_SYMBOL(of_find_node_by_type);
89
90struct device_node *of_find_compatible_node(struct device_node *from,
91 const char *type, const char *compatible)
92{
93 struct device_node *np;
94
95 np = from ? from->allnext : allnodes;
96 for (; np != 0; np = np->allnext) {
97 if (type != NULL
98 && !(np->type != 0 && strcmp(np->type, type) == 0))
99 continue;
100 if (of_device_is_compatible(np, compatible))
101 break;
102 }
103
104 return np;
105}
106EXPORT_SYMBOL(of_find_compatible_node);
107
108int of_getintprop_default(struct device_node *np, const char *name, int def) 49int of_getintprop_default(struct device_node *np, const char *name, int def)
109{ 50{
110 struct property *prop; 51 struct property *prop;
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 6b6dfcc56522..9377f3bc410a 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -20,6 +20,8 @@
20#include <linux/of.h> 20#include <linux/of.h>
21#include <linux/spinlock.h> 21#include <linux/spinlock.h>
22 22
23struct device_node *allnodes;
24
23/* use when traversing tree through the allnext, child, sibling, 25/* use when traversing tree through the allnext, child, sibling,
24 * or parent members of struct device_node. 26 * or parent members of struct device_node.
25 */ 27 */
@@ -158,3 +160,116 @@ struct device_node *of_get_next_child(const struct device_node *node,
158 return next; 160 return next;
159} 161}
160EXPORT_SYMBOL(of_get_next_child); 162EXPORT_SYMBOL(of_get_next_child);
163
164/**
165 * of_find_node_by_path - Find a node matching a full OF path
166 * @path: The full path to match
167 *
168 * Returns a node pointer with refcount incremented, use
169 * of_node_put() on it when done.
170 */
171struct device_node *of_find_node_by_path(const char *path)
172{
173 struct device_node *np = allnodes;
174
175 read_lock(&devtree_lock);
176 for (; np; np = np->allnext) {
177 if (np->full_name && (of_node_cmp(np->full_name, path) == 0)
178 && of_node_get(np))
179 break;
180 }
181 read_unlock(&devtree_lock);
182 return np;
183}
184EXPORT_SYMBOL(of_find_node_by_path);
185
186/**
187 * of_find_node_by_name - Find a node by its "name" property
188 * @from: The node to start searching from or NULL, the node
189 * you pass will not be searched, only the next one
190 * will; typically, you pass what the previous call
191 * returned. of_node_put() will be called on it
192 * @name: The name string to match against
193 *
194 * Returns a node pointer with refcount incremented, use
195 * of_node_put() on it when done.
196 */
197struct device_node *of_find_node_by_name(struct device_node *from,
198 const char *name)
199{
200 struct device_node *np;
201
202 read_lock(&devtree_lock);
203 np = from ? from->allnext : allnodes;
204 for (; np; np = np->allnext)
205 if (np->name && (of_node_cmp(np->name, name) == 0)
206 && of_node_get(np))
207 break;
208 of_node_put(from);
209 read_unlock(&devtree_lock);
210 return np;
211}
212EXPORT_SYMBOL(of_find_node_by_name);
213
214/**
215 * of_find_node_by_type - Find a node by its "device_type" property
216 * @from: The node to start searching from, or NULL to start searching
217 * the entire device tree. The node you pass will not be
218 * searched, only the next one will; typically, you pass
219 * what the previous call returned. of_node_put() will be
220 * called on from for you.
221 * @type: The type string to match against
222 *
223 * Returns a node pointer with refcount incremented, use
224 * of_node_put() on it when done.
225 */
226struct device_node *of_find_node_by_type(struct device_node *from,
227 const char *type)
228{
229 struct device_node *np;
230
231 read_lock(&devtree_lock);
232 np = from ? from->allnext : allnodes;
233 for (; np; np = np->allnext)
234 if (np->type && (of_node_cmp(np->type, type) == 0)
235 && of_node_get(np))
236 break;
237 of_node_put(from);
238 read_unlock(&devtree_lock);
239 return np;
240}
241EXPORT_SYMBOL(of_find_node_by_type);
242
243/**
244 * of_find_compatible_node - Find a node based on type and one of the
245 * tokens in its "compatible" property
246 * @from: The node to start searching from or NULL, the node
247 * you pass will not be searched, only the next one
248 * will; typically, you pass what the previous call
249 * returned. of_node_put() will be called on it
250 * @type: The type string to match "device_type" or NULL to ignore
251 * @compatible: The string to match to one of the tokens in the device
252 * "compatible" list.
253 *
254 * Returns a node pointer with refcount incremented, use
255 * of_node_put() on it when done.
256 */
257struct device_node *of_find_compatible_node(struct device_node *from,
258 const char *type, const char *compatible)
259{
260 struct device_node *np;
261
262 read_lock(&devtree_lock);
263 np = from ? from->allnext : allnodes;
264 for (; np; np = np->allnext) {
265 if (type
266 && !(np->type && (of_node_cmp(np->type, type) == 0)))
267 continue;
268 if (of_device_is_compatible(np, compatible) && of_node_get(np))
269 break;
270 }
271 of_node_put(from);
272 read_unlock(&devtree_lock);
273 return np;
274}
275EXPORT_SYMBOL(of_find_compatible_node);
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
index 75b1144ca580..6e391c9894ce 100644
--- a/include/asm-powerpc/prom.h
+++ b/include/asm-powerpc/prom.h
@@ -26,6 +26,7 @@
26 26
27#define of_compat_cmp(s1, s2, l) strncasecmp((s1), (s2), (l)) 27#define of_compat_cmp(s1, s2, l) strncasecmp((s1), (s2), (l))
28#define of_prop_cmp(s1, s2) strcmp((s1), (s2)) 28#define of_prop_cmp(s1, s2) strcmp((s1), (s2))
29#define of_node_cmp(s1, s2) strcasecmp((s1), (s2))
29 30
30/* Definitions used by the flattened device tree */ 31/* Definitions used by the flattened device tree */
31#define OF_DT_HEADER 0xd00dfeed /* marker */ 32#define OF_DT_HEADER 0xd00dfeed /* marker */
diff --git a/include/asm-sparc/prom.h b/include/asm-sparc/prom.h
index c7d54958a90e..db9feb75bd86 100644
--- a/include/asm-sparc/prom.h
+++ b/include/asm-sparc/prom.h
@@ -25,6 +25,7 @@
25 25
26#define of_compat_cmp(s1, s2, l) strncmp((s1), (s2), (l)) 26#define of_compat_cmp(s1, s2, l) strncmp((s1), (s2), (l))
27#define of_prop_cmp(s1, s2) strcasecmp((s1), (s2)) 27#define of_prop_cmp(s1, s2) strcasecmp((s1), (s2))
28#define of_node_cmp(s1, s2) strcmp((s1), (s2))
28 29
29typedef u32 phandle; 30typedef u32 phandle;
30typedef u32 ihandle; 31typedef u32 ihandle;
diff --git a/include/asm-sparc64/prom.h b/include/asm-sparc64/prom.h
index e83896f3c141..2b9e0d795faf 100644
--- a/include/asm-sparc64/prom.h
+++ b/include/asm-sparc64/prom.h
@@ -25,6 +25,7 @@
25 25
26#define of_compat_cmp(s1, s2, l) strncmp((s1), (s2), (l)) 26#define of_compat_cmp(s1, s2, l) strncmp((s1), (s2), (l))
27#define of_prop_cmp(s1, s2) strcasecmp((s1), (s2)) 27#define of_prop_cmp(s1, s2) strcasecmp((s1), (s2))
28#define of_node_cmp(s1, s2) strcmp((s1), (s2))
28 29
29typedef u32 phandle; 30typedef u32 phandle;
30typedef u32 ihandle; 31typedef u32 ihandle;