diff options
Diffstat (limited to 'drivers/of/selftest.c')
-rw-r--r-- | drivers/of/selftest.c | 161 |
1 files changed, 155 insertions, 6 deletions
diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c index 0eb5c38b4e07..e21012bde639 100644 --- a/drivers/of/selftest.c +++ b/drivers/of/selftest.c | |||
@@ -9,18 +9,24 @@ | |||
9 | #include <linux/errno.h> | 9 | #include <linux/errno.h> |
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/of.h> | 11 | #include <linux/of.h> |
12 | #include <linux/of_irq.h> | ||
12 | #include <linux/list.h> | 13 | #include <linux/list.h> |
13 | #include <linux/mutex.h> | 14 | #include <linux/mutex.h> |
14 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
15 | #include <linux/device.h> | 16 | #include <linux/device.h> |
16 | 17 | ||
17 | static bool selftest_passed = true; | 18 | static struct selftest_results { |
19 | int passed; | ||
20 | int failed; | ||
21 | } selftest_results; | ||
22 | |||
18 | #define selftest(result, fmt, ...) { \ | 23 | #define selftest(result, fmt, ...) { \ |
19 | if (!(result)) { \ | 24 | if (!(result)) { \ |
20 | pr_err("FAIL %s:%i " fmt, __FILE__, __LINE__, ##__VA_ARGS__); \ | 25 | selftest_results.failed++; \ |
21 | selftest_passed = false; \ | 26 | pr_err("FAIL %s():%i " fmt, __func__, __LINE__, ##__VA_ARGS__); \ |
22 | } else { \ | 27 | } else { \ |
23 | pr_info("pass %s:%i\n", __FILE__, __LINE__); \ | 28 | selftest_results.passed++; \ |
29 | pr_debug("pass %s():%i\n", __func__, __LINE__); \ | ||
24 | } \ | 30 | } \ |
25 | } | 31 | } |
26 | 32 | ||
@@ -131,7 +137,6 @@ static void __init of_selftest_property_match_string(void) | |||
131 | struct device_node *np; | 137 | struct device_node *np; |
132 | int rc; | 138 | int rc; |
133 | 139 | ||
134 | pr_info("start\n"); | ||
135 | np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); | 140 | np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); |
136 | if (!np) { | 141 | if (!np) { |
137 | pr_err("No testcase data in device tree\n"); | 142 | pr_err("No testcase data in device tree\n"); |
@@ -154,6 +159,147 @@ static void __init of_selftest_property_match_string(void) | |||
154 | selftest(rc == -EILSEQ, "unterminated string; rc=%i", rc); | 159 | selftest(rc == -EILSEQ, "unterminated string; rc=%i", rc); |
155 | } | 160 | } |
156 | 161 | ||
162 | static void __init of_selftest_parse_interrupts(void) | ||
163 | { | ||
164 | struct device_node *np; | ||
165 | struct of_phandle_args args; | ||
166 | int i, rc; | ||
167 | |||
168 | np = of_find_node_by_path("/testcase-data/interrupts/interrupts0"); | ||
169 | if (!np) { | ||
170 | pr_err("missing testcase data\n"); | ||
171 | return; | ||
172 | } | ||
173 | |||
174 | for (i = 0; i < 4; i++) { | ||
175 | bool passed = true; | ||
176 | args.args_count = 0; | ||
177 | rc = of_irq_parse_one(np, i, &args); | ||
178 | |||
179 | passed &= !rc; | ||
180 | passed &= (args.args_count == 1); | ||
181 | passed &= (args.args[0] == (i + 1)); | ||
182 | |||
183 | selftest(passed, "index %i - data error on node %s rc=%i\n", | ||
184 | i, args.np->full_name, rc); | ||
185 | } | ||
186 | of_node_put(np); | ||
187 | |||
188 | np = of_find_node_by_path("/testcase-data/interrupts/interrupts1"); | ||
189 | if (!np) { | ||
190 | pr_err("missing testcase data\n"); | ||
191 | return; | ||
192 | } | ||
193 | |||
194 | for (i = 0; i < 4; i++) { | ||
195 | bool passed = true; | ||
196 | args.args_count = 0; | ||
197 | rc = of_irq_parse_one(np, i, &args); | ||
198 | |||
199 | /* Test the values from tests-phandle.dtsi */ | ||
200 | switch (i) { | ||
201 | case 0: | ||
202 | passed &= !rc; | ||
203 | passed &= (args.args_count == 1); | ||
204 | passed &= (args.args[0] == 9); | ||
205 | break; | ||
206 | case 1: | ||
207 | passed &= !rc; | ||
208 | passed &= (args.args_count == 3); | ||
209 | passed &= (args.args[0] == 10); | ||
210 | passed &= (args.args[1] == 11); | ||
211 | passed &= (args.args[2] == 12); | ||
212 | break; | ||
213 | case 2: | ||
214 | passed &= !rc; | ||
215 | passed &= (args.args_count == 2); | ||
216 | passed &= (args.args[0] == 13); | ||
217 | passed &= (args.args[1] == 14); | ||
218 | break; | ||
219 | case 3: | ||
220 | passed &= !rc; | ||
221 | passed &= (args.args_count == 2); | ||
222 | passed &= (args.args[0] == 15); | ||
223 | passed &= (args.args[1] == 16); | ||
224 | break; | ||
225 | default: | ||
226 | passed = false; | ||
227 | } | ||
228 | selftest(passed, "index %i - data error on node %s rc=%i\n", | ||
229 | i, args.np->full_name, rc); | ||
230 | } | ||
231 | of_node_put(np); | ||
232 | } | ||
233 | |||
234 | static void __init of_selftest_parse_interrupts_extended(void) | ||
235 | { | ||
236 | struct device_node *np; | ||
237 | struct of_phandle_args args; | ||
238 | int i, rc; | ||
239 | |||
240 | np = of_find_node_by_path("/testcase-data/interrupts/interrupts-extended0"); | ||
241 | if (!np) { | ||
242 | pr_err("missing testcase data\n"); | ||
243 | return; | ||
244 | } | ||
245 | |||
246 | for (i = 0; i < 7; i++) { | ||
247 | bool passed = true; | ||
248 | rc = of_irq_parse_one(np, i, &args); | ||
249 | |||
250 | /* Test the values from tests-phandle.dtsi */ | ||
251 | switch (i) { | ||
252 | case 0: | ||
253 | passed &= !rc; | ||
254 | passed &= (args.args_count == 1); | ||
255 | passed &= (args.args[0] == 1); | ||
256 | break; | ||
257 | case 1: | ||
258 | passed &= !rc; | ||
259 | passed &= (args.args_count == 3); | ||
260 | passed &= (args.args[0] == 2); | ||
261 | passed &= (args.args[1] == 3); | ||
262 | passed &= (args.args[2] == 4); | ||
263 | break; | ||
264 | case 2: | ||
265 | passed &= !rc; | ||
266 | passed &= (args.args_count == 2); | ||
267 | passed &= (args.args[0] == 5); | ||
268 | passed &= (args.args[1] == 6); | ||
269 | break; | ||
270 | case 3: | ||
271 | passed &= !rc; | ||
272 | passed &= (args.args_count == 1); | ||
273 | passed &= (args.args[0] == 9); | ||
274 | break; | ||
275 | case 4: | ||
276 | passed &= !rc; | ||
277 | passed &= (args.args_count == 3); | ||
278 | passed &= (args.args[0] == 10); | ||
279 | passed &= (args.args[1] == 11); | ||
280 | passed &= (args.args[2] == 12); | ||
281 | break; | ||
282 | case 5: | ||
283 | passed &= !rc; | ||
284 | passed &= (args.args_count == 2); | ||
285 | passed &= (args.args[0] == 13); | ||
286 | passed &= (args.args[1] == 14); | ||
287 | break; | ||
288 | case 6: | ||
289 | passed &= !rc; | ||
290 | passed &= (args.args_count == 1); | ||
291 | passed &= (args.args[0] == 15); | ||
292 | break; | ||
293 | default: | ||
294 | passed = false; | ||
295 | } | ||
296 | |||
297 | selftest(passed, "index %i - data error on node %s rc=%i\n", | ||
298 | i, args.np->full_name, rc); | ||
299 | } | ||
300 | of_node_put(np); | ||
301 | } | ||
302 | |||
157 | static int __init of_selftest(void) | 303 | static int __init of_selftest(void) |
158 | { | 304 | { |
159 | struct device_node *np; | 305 | struct device_node *np; |
@@ -168,7 +314,10 @@ static int __init of_selftest(void) | |||
168 | pr_info("start of selftest - you will see error messages\n"); | 314 | pr_info("start of selftest - you will see error messages\n"); |
169 | of_selftest_parse_phandle_with_args(); | 315 | of_selftest_parse_phandle_with_args(); |
170 | of_selftest_property_match_string(); | 316 | of_selftest_property_match_string(); |
171 | pr_info("end of selftest - %s\n", selftest_passed ? "PASS" : "FAIL"); | 317 | of_selftest_parse_interrupts(); |
318 | of_selftest_parse_interrupts_extended(); | ||
319 | pr_info("end of selftest - %i passed, %i failed\n", | ||
320 | selftest_results.passed, selftest_results.failed); | ||
172 | return 0; | 321 | return 0; |
173 | } | 322 | } |
174 | late_initcall(of_selftest); | 323 | late_initcall(of_selftest); |