Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
selftest.c
Go to the documentation of this file.
1 /*
2  * Self tests for device tree subsystem
3  */
4 
5 #define pr_fmt(fmt) "### %s(): " fmt, __func__
6 
7 #include <linux/clk.h>
8 #include <linux/err.h>
9 #include <linux/errno.h>
10 #include <linux/module.h>
11 #include <linux/of.h>
12 #include <linux/list.h>
13 #include <linux/mutex.h>
14 #include <linux/slab.h>
15 #include <linux/device.h>
16 
17 static bool selftest_passed = true;
18 #define selftest(result, fmt, ...) { \
19  selftest_passed &= (result); \
20  if (!(result)) \
21  pr_err("FAIL %s:%i " fmt, __FILE__, __LINE__, ##__VA_ARGS__); \
22 }
23 
24 static void __init of_selftest_parse_phandle_with_args(void)
25 {
26  struct device_node *np;
27  struct of_phandle_args args;
28  int rc, i;
29  bool passed_all = true;
30 
31  pr_info("start\n");
32  np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
33  if (!np) {
34  pr_err("missing testcase data\n");
35  return;
36  }
37 
38  for (i = 0; i < 7; i++) {
39  bool passed = true;
40  rc = of_parse_phandle_with_args(np, "phandle-list",
41  "#phandle-cells", i, &args);
42 
43  /* Test the values from tests-phandle.dtsi */
44  switch (i) {
45  case 0:
46  passed &= !rc;
47  passed &= (args.args_count == 1);
48  passed &= (args.args[0] == (i + 1));
49  break;
50  case 1:
51  passed &= !rc;
52  passed &= (args.args_count == 2);
53  passed &= (args.args[0] == (i + 1));
54  passed &= (args.args[1] == 0);
55  break;
56  case 2:
57  passed &= (rc == -ENOENT);
58  break;
59  case 3:
60  passed &= !rc;
61  passed &= (args.args_count == 3);
62  passed &= (args.args[0] == (i + 1));
63  passed &= (args.args[1] == 4);
64  passed &= (args.args[2] == 3);
65  break;
66  case 4:
67  passed &= !rc;
68  passed &= (args.args_count == 2);
69  passed &= (args.args[0] == (i + 1));
70  passed &= (args.args[1] == 100);
71  break;
72  case 5:
73  passed &= !rc;
74  passed &= (args.args_count == 0);
75  break;
76  case 6:
77  passed &= !rc;
78  passed &= (args.args_count == 1);
79  passed &= (args.args[0] == (i + 1));
80  break;
81  case 7:
82  passed &= (rc == -EINVAL);
83  break;
84  default:
85  passed = false;
86  }
87 
88  if (!passed) {
89  int j;
90  pr_err("index %i - data error on node %s rc=%i regs=[",
91  i, args.np->full_name, rc);
92  for (j = 0; j < args.args_count; j++)
93  printk(" %i", args.args[j]);
94  printk(" ]\n");
95 
96  passed_all = false;
97  }
98  }
99 
100  /* Check for missing list property */
101  rc = of_parse_phandle_with_args(np, "phandle-list-missing",
102  "#phandle-cells", 0, &args);
103  passed_all &= (rc == -EINVAL);
104 
105  /* Check for missing cells property */
106  rc = of_parse_phandle_with_args(np, "phandle-list",
107  "#phandle-cells-missing", 0, &args);
108  passed_all &= (rc == -EINVAL);
109 
110  /* Check for bad phandle in list */
111  rc = of_parse_phandle_with_args(np, "phandle-list-bad-phandle",
112  "#phandle-cells", 0, &args);
113  passed_all &= (rc == -EINVAL);
114 
115  /* Check for incorrectly formed argument list */
116  rc = of_parse_phandle_with_args(np, "phandle-list-bad-args",
117  "#phandle-cells", 1, &args);
118  passed_all &= (rc == -EINVAL);
119 
120  pr_info("end - %s\n", passed_all ? "PASS" : "FAIL");
121 }
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 
151 static int __init of_selftest(void)
152 {
153  struct device_node *np;
154 
155  np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
156  if (!np) {
157  pr_info("No testcase data in device tree; not running tests\n");
158  return 0;
159  }
160  of_node_put(np);
161 
162  pr_info("start of selftest - you will see error messages\n");
163  of_selftest_parse_phandle_with_args();
164  of_selftest_property_match_string();
165  pr_info("end of selftest - %s\n", selftest_passed ? "PASS" : "FAIL");
166  return 0;
167 }
168 late_initcall(of_selftest);