diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-21 13:30:03 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-21 13:30:03 -0400 |
commit | f8974cb71310a05632aada76be6a27576d61e609 (patch) | |
tree | c0b6f59333796c95aa2de9a2eb755e9b68599b71 /drivers/of | |
parent | c207f3a43194e108dda43dc9a1ce507335cff6b9 (diff) | |
parent | 0f22dd395fc473cee252b9af50249b8e0f32fde7 (diff) |
Merge tag 'dt-for-linus' of git://git.secretlab.ca/git/linux-2.6
Pull core device tree changes for Linux v3.4 from Grant Likely:
"This branch contains a minor documentation addition, a utility
function for parsing string properties needed by some of the new ARM
platforms, disables dynamic DT code that isn't used anywhere but on a
few PPC machines, and exports DT node compatible data to userspace via
UEVENT properties. Nothing earth shattering here."
* tag 'dt-for-linus' of git://git.secretlab.ca/git/linux-2.6:
of: Only compile OF_DYNAMIC on PowerPC pseries and iseries
arm/dts: OMAP3: Add omap3evm and am335xevm support
drivercore: Output common devicetree information in uevent
of: Add of_property_match_string() to find index into a string list
Diffstat (limited to 'drivers/of')
-rw-r--r-- | drivers/of/Kconfig | 5 | ||||
-rw-r--r-- | drivers/of/base.c | 40 | ||||
-rw-r--r-- | drivers/of/device.c | 30 | ||||
-rw-r--r-- | drivers/of/selftest.c | 29 |
4 files changed, 86 insertions, 18 deletions
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index 268163dd71c7..6ea51dcbc728 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig | |||
@@ -35,9 +35,10 @@ config OF_EARLY_FLATTREE | |||
35 | config OF_PROMTREE | 35 | config OF_PROMTREE |
36 | bool | 36 | bool |
37 | 37 | ||
38 | # Hardly any platforms need this. It is safe to select, but only do so if you | ||
39 | # need it. | ||
38 | config OF_DYNAMIC | 40 | config OF_DYNAMIC |
39 | def_bool y | 41 | bool |
40 | depends on PPC_OF | ||
41 | 42 | ||
42 | config OF_ADDRESS | 43 | config OF_ADDRESS |
43 | def_bool y | 44 | def_bool y |
diff --git a/drivers/of/base.c b/drivers/of/base.c index 133908a6fd8d..580644986945 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
@@ -88,7 +88,7 @@ int of_n_size_cells(struct device_node *np) | |||
88 | } | 88 | } |
89 | EXPORT_SYMBOL(of_n_size_cells); | 89 | EXPORT_SYMBOL(of_n_size_cells); |
90 | 90 | ||
91 | #if !defined(CONFIG_SPARC) /* SPARC doesn't do ref counting (yet) */ | 91 | #if defined(CONFIG_OF_DYNAMIC) |
92 | /** | 92 | /** |
93 | * of_node_get - Increment refcount of a node | 93 | * of_node_get - Increment refcount of a node |
94 | * @node: Node to inc refcount, NULL is supported to | 94 | * @node: Node to inc refcount, NULL is supported to |
@@ -161,7 +161,7 @@ void of_node_put(struct device_node *node) | |||
161 | kref_put(&node->kref, of_node_release); | 161 | kref_put(&node->kref, of_node_release); |
162 | } | 162 | } |
163 | EXPORT_SYMBOL(of_node_put); | 163 | EXPORT_SYMBOL(of_node_put); |
164 | #endif /* !CONFIG_SPARC */ | 164 | #endif /* CONFIG_OF_DYNAMIC */ |
165 | 165 | ||
166 | struct property *of_find_property(const struct device_node *np, | 166 | struct property *of_find_property(const struct device_node *np, |
167 | const char *name, | 167 | const char *name, |
@@ -761,6 +761,42 @@ int of_property_read_string_index(struct device_node *np, const char *propname, | |||
761 | } | 761 | } |
762 | EXPORT_SYMBOL_GPL(of_property_read_string_index); | 762 | EXPORT_SYMBOL_GPL(of_property_read_string_index); |
763 | 763 | ||
764 | /** | ||
765 | * of_property_match_string() - Find string in a list and return index | ||
766 | * @np: pointer to node containing string list property | ||
767 | * @propname: string list property name | ||
768 | * @string: pointer to string to search for in string list | ||
769 | * | ||
770 | * This function searches a string list property and returns the index | ||
771 | * of a specific string value. | ||
772 | */ | ||
773 | int of_property_match_string(struct device_node *np, const char *propname, | ||
774 | const char *string) | ||
775 | { | ||
776 | struct property *prop = of_find_property(np, propname, NULL); | ||
777 | size_t l; | ||
778 | int i; | ||
779 | const char *p, *end; | ||
780 | |||
781 | if (!prop) | ||
782 | return -EINVAL; | ||
783 | if (!prop->value) | ||
784 | return -ENODATA; | ||
785 | |||
786 | p = prop->value; | ||
787 | end = p + prop->length; | ||
788 | |||
789 | for (i = 0; p < end; i++, p += l) { | ||
790 | l = strlen(p) + 1; | ||
791 | if (p + l > end) | ||
792 | return -EILSEQ; | ||
793 | pr_debug("comparing %s with %s\n", string, p); | ||
794 | if (strcmp(string, p) == 0) | ||
795 | return i; /* Found it; return index */ | ||
796 | } | ||
797 | return -ENODATA; | ||
798 | } | ||
799 | EXPORT_SYMBOL_GPL(of_property_match_string); | ||
764 | 800 | ||
765 | /** | 801 | /** |
766 | * of_property_count_strings - Find and return the number of strings from a | 802 | * of_property_count_strings - Find and return the number of strings from a |
diff --git a/drivers/of/device.c b/drivers/of/device.c index 62b4b32ac887..4c74e4fc5a51 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c | |||
@@ -128,39 +128,41 @@ ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len) | |||
128 | /** | 128 | /** |
129 | * of_device_uevent - Display OF related uevent information | 129 | * of_device_uevent - Display OF related uevent information |
130 | */ | 130 | */ |
131 | int of_device_uevent(struct device *dev, struct kobj_uevent_env *env) | 131 | void of_device_uevent(struct device *dev, struct kobj_uevent_env *env) |
132 | { | 132 | { |
133 | const char *compat; | 133 | const char *compat; |
134 | int seen = 0, cplen, sl; | 134 | int seen = 0, cplen, sl; |
135 | 135 | ||
136 | if ((!dev) || (!dev->of_node)) | 136 | if ((!dev) || (!dev->of_node)) |
137 | return -ENODEV; | 137 | return; |
138 | |||
139 | if (add_uevent_var(env, "OF_NAME=%s", dev->of_node->name)) | ||
140 | return -ENOMEM; | ||
141 | 138 | ||
142 | if (add_uevent_var(env, "OF_TYPE=%s", dev->of_node->type)) | 139 | add_uevent_var(env, "OF_NAME=%s", dev->of_node->name); |
143 | return -ENOMEM; | 140 | add_uevent_var(env, "OF_FULLNAME=%s", dev->of_node->full_name); |
141 | if (dev->of_node->type && strcmp("<NULL>", dev->of_node->type) != 0) | ||
142 | add_uevent_var(env, "OF_TYPE=%s", dev->of_node->type); | ||
144 | 143 | ||
145 | /* Since the compatible field can contain pretty much anything | 144 | /* Since the compatible field can contain pretty much anything |
146 | * it's not really legal to split it out with commas. We split it | 145 | * it's not really legal to split it out with commas. We split it |
147 | * up using a number of environment variables instead. */ | 146 | * up using a number of environment variables instead. */ |
148 | |||
149 | compat = of_get_property(dev->of_node, "compatible", &cplen); | 147 | compat = of_get_property(dev->of_node, "compatible", &cplen); |
150 | while (compat && *compat && cplen > 0) { | 148 | while (compat && *compat && cplen > 0) { |
151 | if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat)) | 149 | add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat); |
152 | return -ENOMEM; | ||
153 | |||
154 | sl = strlen(compat) + 1; | 150 | sl = strlen(compat) + 1; |
155 | compat += sl; | 151 | compat += sl; |
156 | cplen -= sl; | 152 | cplen -= sl; |
157 | seen++; | 153 | seen++; |
158 | } | 154 | } |
155 | add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen); | ||
156 | } | ||
159 | 157 | ||
160 | if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen)) | 158 | int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env) |
161 | return -ENOMEM; | 159 | { |
160 | int sl; | ||
161 | |||
162 | if ((!dev) || (!dev->of_node)) | ||
163 | return -ENODEV; | ||
162 | 164 | ||
163 | /* modalias is trickier, we add it in 2 steps */ | 165 | /* Devicetree modalias is tricky, we add it in 2 steps */ |
164 | if (add_uevent_var(env, "MODALIAS=")) | 166 | if (add_uevent_var(env, "MODALIAS=")) |
165 | return -ENOMEM; | 167 | return -ENOMEM; |
166 | 168 | ||
diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c index 9d2b4803a9d6..f24ffd7088d2 100644 --- a/drivers/of/selftest.c +++ b/drivers/of/selftest.c | |||
@@ -120,6 +120,34 @@ static void __init of_selftest_parse_phandle_with_args(void) | |||
120 | pr_info("end - %s\n", passed_all ? "PASS" : "FAIL"); | 120 | pr_info("end - %s\n", passed_all ? "PASS" : "FAIL"); |
121 | } | 121 | } |
122 | 122 | ||
123 | static void __init of_selftest_property_match_string(void) | ||
124 | { | ||
125 | struct device_node *np; | ||
126 | int rc; | ||
127 | |||
128 | pr_info("start\n"); | ||
129 | np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); | ||
130 | if (!np) { | ||
131 | pr_err("No testcase data in device tree\n"); | ||
132 | return; | ||
133 | } | ||
134 | |||
135 | rc = of_property_match_string(np, "phandle-list-names", "first"); | ||
136 | selftest(rc == 0, "first expected:0 got:%i\n", rc); | ||
137 | rc = of_property_match_string(np, "phandle-list-names", "second"); | ||
138 | selftest(rc == 1, "second expected:0 got:%i\n", rc); | ||
139 | rc = of_property_match_string(np, "phandle-list-names", "third"); | ||
140 | selftest(rc == 2, "third expected:0 got:%i\n", rc); | ||
141 | rc = of_property_match_string(np, "phandle-list-names", "fourth"); | ||
142 | selftest(rc == -ENODATA, "unmatched string; rc=%i", rc); | ||
143 | rc = of_property_match_string(np, "missing-property", "blah"); | ||
144 | selftest(rc == -EINVAL, "missing property; rc=%i", rc); | ||
145 | rc = of_property_match_string(np, "empty-property", "blah"); | ||
146 | selftest(rc == -ENODATA, "empty property; rc=%i", rc); | ||
147 | rc = of_property_match_string(np, "unterminated-string", "blah"); | ||
148 | selftest(rc == -EILSEQ, "unterminated string; rc=%i", rc); | ||
149 | } | ||
150 | |||
123 | static int __init of_selftest(void) | 151 | static int __init of_selftest(void) |
124 | { | 152 | { |
125 | struct device_node *np; | 153 | struct device_node *np; |
@@ -133,6 +161,7 @@ static int __init of_selftest(void) | |||
133 | 161 | ||
134 | pr_info("start of selftest - you will see error messages\n"); | 162 | pr_info("start of selftest - you will see error messages\n"); |
135 | of_selftest_parse_phandle_with_args(); | 163 | of_selftest_parse_phandle_with_args(); |
164 | of_selftest_property_match_string(); | ||
136 | pr_info("end of selftest - %s\n", selftest_passed ? "PASS" : "FAIL"); | 165 | pr_info("end of selftest - %s\n", selftest_passed ? "PASS" : "FAIL"); |
137 | return 0; | 166 | return 0; |
138 | } | 167 | } |