aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/boot/dts/testcases/tests-interrupts.dtsi41
-rw-r--r--arch/arm/boot/dts/testcases/tests.dtsi1
-rw-r--r--drivers/of/selftest.c91
3 files changed, 127 insertions, 6 deletions
diff --git a/arch/arm/boot/dts/testcases/tests-interrupts.dtsi b/arch/arm/boot/dts/testcases/tests-interrupts.dtsi
new file mode 100644
index 000000000000..6ecda716e9d4
--- /dev/null
+++ b/arch/arm/boot/dts/testcases/tests-interrupts.dtsi
@@ -0,0 +1,41 @@
1
2/ {
3 testcase-data {
4 interrupts {
5 #address-cells = <0>;
6 test_intc0: intc0 {
7 interrupt-controller;
8 #interrupt-cells = <1>;
9 };
10
11 test_intc1: intc1 {
12 interrupt-controller;
13 #interrupt-cells = <3>;
14 };
15
16 test_intc2: intc2 {
17 interrupt-controller;
18 #interrupt-cells = <2>;
19 };
20
21 test_intmap0: intmap0 {
22 #interrupt-cells = <1>;
23 #address-cells = <0>;
24 interrupt-map = <1 &test_intc0 9>,
25 <2 &test_intc1 10 11 12>,
26 <3 &test_intc2 13 14>,
27 <4 &test_intc2 15 16>;
28 };
29
30 interrupts0 {
31 interrupt-parent = <&test_intc0>;
32 interrupts = <1>, <2>, <3>, <4>;
33 };
34
35 interrupts1 {
36 interrupt-parent = <&test_intmap0>;
37 interrupts = <1>, <2>, <3>, <4>;
38 };
39 };
40 };
41};
diff --git a/arch/arm/boot/dts/testcases/tests.dtsi b/arch/arm/boot/dts/testcases/tests.dtsi
index a7c5067622e8..3f123ecc9dd7 100644
--- a/arch/arm/boot/dts/testcases/tests.dtsi
+++ b/arch/arm/boot/dts/testcases/tests.dtsi
@@ -1 +1,2 @@
1/include/ "tests-phandle.dtsi" 1/include/ "tests-phandle.dtsi"
2/include/ "tests-interrupts.dtsi"
diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c
index 0eb5c38b4e07..9c80f0b7556b 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
17static bool selftest_passed = true; 18static 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,78 @@ 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
162static 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
157static int __init of_selftest(void) 234static int __init of_selftest(void)
158{ 235{
159 struct device_node *np; 236 struct device_node *np;
@@ -168,7 +245,9 @@ static int __init of_selftest(void)
168 pr_info("start of selftest - you will see error messages\n"); 245 pr_info("start of selftest - you will see error messages\n");
169 of_selftest_parse_phandle_with_args(); 246 of_selftest_parse_phandle_with_args();
170 of_selftest_property_match_string(); 247 of_selftest_property_match_string();
171 pr_info("end of selftest - %s\n", selftest_passed ? "PASS" : "FAIL"); 248 of_selftest_parse_interrupts();
249 pr_info("end of selftest - %i passed, %i failed\n",
250 selftest_results.passed, selftest_results.failed);
172 return 0; 251 return 0;
173} 252}
174late_initcall(of_selftest); 253late_initcall(of_selftest);