]>
Commit | Line | Data |
---|---|---|
97e873e5 SR |
1 | /* |
2 | * Procedures for creating, accessing and interpreting the device tree. | |
3 | * | |
4 | * Paul Mackerras August 1996. | |
5 | * Copyright (C) 1996-2005 Paul Mackerras. | |
6 | * | |
7 | * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner. | |
8 | * {engebret|bergner}@us.ibm.com | |
9 | * | |
10 | * Adapted for sparc and sparc64 by David S. Miller davem@davemloft.net | |
11 | * | |
12 | * Reconsolidated from arch/x/kernel/prom.c by Stephen Rothwell. | |
13 | * | |
14 | * This program is free software; you can redistribute it and/or | |
15 | * modify it under the terms of the GNU General Public License | |
16 | * as published by the Free Software Foundation; either version | |
17 | * 2 of the License, or (at your option) any later version. | |
18 | */ | |
19 | #include <linux/module.h> | |
20 | #include <linux/of.h> | |
581b605a SR |
21 | #include <linux/spinlock.h> |
22 | ||
23 | /* use when traversing tree through the allnext, child, sibling, | |
24 | * or parent members of struct device_node. | |
25 | */ | |
26 | DEFINE_RWLOCK(devtree_lock); | |
97e873e5 SR |
27 | |
28 | int of_n_addr_cells(struct device_node *np) | |
29 | { | |
30 | const int *ip; | |
31 | ||
32 | do { | |
33 | if (np->parent) | |
34 | np = np->parent; | |
35 | ip = of_get_property(np, "#address-cells", NULL); | |
36 | if (ip) | |
37 | return *ip; | |
38 | } while (np->parent); | |
39 | /* No #address-cells property for the root node */ | |
40 | return OF_ROOT_NODE_ADDR_CELLS_DEFAULT; | |
41 | } | |
42 | EXPORT_SYMBOL(of_n_addr_cells); | |
43 | ||
44 | int of_n_size_cells(struct device_node *np) | |
45 | { | |
46 | const int *ip; | |
47 | ||
48 | do { | |
49 | if (np->parent) | |
50 | np = np->parent; | |
51 | ip = of_get_property(np, "#size-cells", NULL); | |
52 | if (ip) | |
53 | return *ip; | |
54 | } while (np->parent); | |
55 | /* No #size-cells property for the root node */ | |
56 | return OF_ROOT_NODE_SIZE_CELLS_DEFAULT; | |
57 | } | |
58 | EXPORT_SYMBOL(of_n_size_cells); | |
59 | ||
581b605a SR |
60 | struct property *of_find_property(const struct device_node *np, |
61 | const char *name, | |
62 | int *lenp) | |
63 | { | |
64 | struct property *pp; | |
65 | ||
66 | read_lock(&devtree_lock); | |
67 | for (pp = np->properties; pp != 0; pp = pp->next) { | |
68 | if (of_prop_cmp(pp->name, name) == 0) { | |
69 | if (lenp != 0) | |
70 | *lenp = pp->length; | |
71 | break; | |
72 | } | |
73 | } | |
74 | read_unlock(&devtree_lock); | |
75 | ||
76 | return pp; | |
77 | } | |
78 | EXPORT_SYMBOL(of_find_property); | |
79 | ||
97e873e5 SR |
80 | /* |
81 | * Find a property with a given name for a given node | |
82 | * and return the value. | |
83 | */ | |
84 | const void *of_get_property(const struct device_node *np, const char *name, | |
85 | int *lenp) | |
86 | { | |
87 | struct property *pp = of_find_property(np, name, lenp); | |
88 | ||
89 | return pp ? pp->value : NULL; | |
90 | } | |
91 | EXPORT_SYMBOL(of_get_property); | |
0081cbc3 SR |
92 | |
93 | /** Checks if the given "compat" string matches one of the strings in | |
94 | * the device's "compatible" property | |
95 | */ | |
96 | int of_device_is_compatible(const struct device_node *device, | |
97 | const char *compat) | |
98 | { | |
99 | const char* cp; | |
100 | int cplen, l; | |
101 | ||
102 | cp = of_get_property(device, "compatible", &cplen); | |
103 | if (cp == NULL) | |
104 | return 0; | |
105 | while (cplen > 0) { | |
106 | if (of_compat_cmp(cp, compat, strlen(compat)) == 0) | |
107 | return 1; | |
108 | l = strlen(cp) + 1; | |
109 | cp += l; | |
110 | cplen -= l; | |
111 | } | |
112 | ||
113 | return 0; | |
114 | } | |
115 | EXPORT_SYMBOL(of_device_is_compatible); |