diff options
| author | Stephen Rothwell <sfr@canb.auug.org.au> | 2007-04-24 03:57:33 -0400 |
|---|---|---|
| committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2007-07-19 23:39:06 -0400 |
| commit | 1ef4d4242d9c494c49ae1ae66dc938fce0272816 (patch) | |
| tree | 74c64ec940b306b5d1e7bb93a980041ad670468d /drivers/of | |
| parent | d1cd355a5e44dfe993efc0c0458ca9f99a28a9a3 (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>
Diffstat (limited to 'drivers/of')
| -rw-r--r-- | drivers/of/base.c | 115 |
1 files changed, 115 insertions, 0 deletions
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 | ||
| 23 | struct 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 | } |
| 160 | EXPORT_SYMBOL(of_get_next_child); | 162 | EXPORT_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 | */ | ||
| 171 | struct 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 | } | ||
| 184 | EXPORT_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 | */ | ||
| 197 | struct 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 | } | ||
| 212 | EXPORT_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 | */ | ||
| 226 | struct 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 | } | ||
| 241 | EXPORT_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 | */ | ||
| 257 | struct 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 | } | ||
| 275 | EXPORT_SYMBOL(of_find_compatible_node); | ||
