1 // SPDX-License-Identifier: GPL-2.0
2 // Unit tests for property entries API
3 //
4 // Copyright 2019 Google LLC.
5
6 #include <kunit/test.h>
7
8 #include <linux/of.h>
9 #include <linux/property.h>
10 #include <linux/types.h>
11
pe_test_uints(struct kunit * test)12 static void pe_test_uints(struct kunit *test)
13 {
14 static const struct property_entry entries[] = {
15 PROPERTY_ENTRY_U8("prop-u8", 8),
16 PROPERTY_ENTRY_U16("prop-u16", 16),
17 PROPERTY_ENTRY_U32("prop-u32", 32),
18 PROPERTY_ENTRY_U64("prop-u64", 64),
19 { }
20 };
21
22 struct fwnode_handle *node;
23 u8 val_u8, array_u8[2];
24 u16 val_u16, array_u16[2];
25 u32 val_u32, array_u32[2];
26 u64 val_u64, array_u64[2];
27 int error;
28
29 node = fwnode_create_software_node(entries, NULL);
30 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node);
31
32 error = fwnode_property_count_u8(node, "prop-u8");
33 KUNIT_EXPECT_EQ(test, error, 1);
34
35 error = fwnode_property_read_u8(node, "prop-u8", &val_u8);
36 KUNIT_EXPECT_EQ(test, error, 0);
37 KUNIT_EXPECT_EQ(test, val_u8, 8);
38
39 error = fwnode_property_read_u8_array(node, "prop-u8", array_u8, 1);
40 KUNIT_EXPECT_EQ(test, error, 0);
41 KUNIT_EXPECT_EQ(test, array_u8[0], 8);
42
43 error = fwnode_property_read_u8_array(node, "prop-u8", array_u8, 2);
44 KUNIT_EXPECT_NE(test, error, 0);
45
46 error = fwnode_property_read_u8(node, "no-prop-u8", &val_u8);
47 KUNIT_EXPECT_NE(test, error, 0);
48
49 error = fwnode_property_read_u8_array(node, "no-prop-u8", array_u8, 1);
50 KUNIT_EXPECT_NE(test, error, 0);
51
52 error = fwnode_property_read_u16(node, "prop-u16", &val_u16);
53 KUNIT_EXPECT_EQ(test, error, 0);
54 KUNIT_EXPECT_EQ(test, val_u16, 16);
55
56 error = fwnode_property_count_u16(node, "prop-u16");
57 KUNIT_EXPECT_EQ(test, error, 1);
58
59 error = fwnode_property_read_u16_array(node, "prop-u16", array_u16, 1);
60 KUNIT_EXPECT_EQ(test, error, 0);
61 KUNIT_EXPECT_EQ(test, array_u16[0], 16);
62
63 error = fwnode_property_read_u16_array(node, "prop-u16", array_u16, 2);
64 KUNIT_EXPECT_NE(test, error, 0);
65
66 error = fwnode_property_read_u16(node, "no-prop-u16", &val_u16);
67 KUNIT_EXPECT_NE(test, error, 0);
68
69 error = fwnode_property_read_u16_array(node, "no-prop-u16", array_u16, 1);
70 KUNIT_EXPECT_NE(test, error, 0);
71
72 error = fwnode_property_read_u32(node, "prop-u32", &val_u32);
73 KUNIT_EXPECT_EQ(test, error, 0);
74 KUNIT_EXPECT_EQ(test, val_u32, 32);
75
76 error = fwnode_property_count_u32(node, "prop-u32");
77 KUNIT_EXPECT_EQ(test, error, 1);
78
79 error = fwnode_property_read_u32_array(node, "prop-u32", array_u32, 1);
80 KUNIT_EXPECT_EQ(test, error, 0);
81 KUNIT_EXPECT_EQ(test, array_u32[0], 32);
82
83 error = fwnode_property_read_u32_array(node, "prop-u32", array_u32, 2);
84 KUNIT_EXPECT_NE(test, error, 0);
85
86 error = fwnode_property_read_u32(node, "no-prop-u32", &val_u32);
87 KUNIT_EXPECT_NE(test, error, 0);
88
89 error = fwnode_property_read_u32_array(node, "no-prop-u32", array_u32, 1);
90 KUNIT_EXPECT_NE(test, error, 0);
91
92 error = fwnode_property_read_u64(node, "prop-u64", &val_u64);
93 KUNIT_EXPECT_EQ(test, error, 0);
94 KUNIT_EXPECT_EQ(test, val_u64, 64);
95
96 error = fwnode_property_count_u64(node, "prop-u64");
97 KUNIT_EXPECT_EQ(test, error, 1);
98
99 error = fwnode_property_read_u64_array(node, "prop-u64", array_u64, 1);
100 KUNIT_EXPECT_EQ(test, error, 0);
101 KUNIT_EXPECT_EQ(test, array_u64[0], 64);
102
103 error = fwnode_property_read_u64_array(node, "prop-u64", array_u64, 2);
104 KUNIT_EXPECT_NE(test, error, 0);
105
106 error = fwnode_property_read_u64(node, "no-prop-u64", &val_u64);
107 KUNIT_EXPECT_NE(test, error, 0);
108
109 error = fwnode_property_read_u64_array(node, "no-prop-u64", array_u64, 1);
110 KUNIT_EXPECT_NE(test, error, 0);
111
112 /* Count 64-bit values as 16-bit */
113 error = fwnode_property_count_u16(node, "prop-u64");
114 KUNIT_EXPECT_EQ(test, error, 4);
115
116 fwnode_remove_software_node(node);
117 }
118
pe_test_uint_arrays(struct kunit * test)119 static void pe_test_uint_arrays(struct kunit *test)
120 {
121 static const u8 a_u8[10] = { 8, 9 };
122 static const u16 a_u16[10] = { 16, 17 };
123 static const u32 a_u32[10] = { 32, 33 };
124 static const u64 a_u64[10] = { 64, 65 };
125 static const struct property_entry entries[] = {
126 PROPERTY_ENTRY_U8_ARRAY("prop-u8", a_u8),
127 PROPERTY_ENTRY_U16_ARRAY("prop-u16", a_u16),
128 PROPERTY_ENTRY_U32_ARRAY("prop-u32", a_u32),
129 PROPERTY_ENTRY_U64_ARRAY("prop-u64", a_u64),
130 { }
131 };
132
133 struct fwnode_handle *node;
134 u8 val_u8, array_u8[32];
135 u16 val_u16, array_u16[32];
136 u32 val_u32, array_u32[32];
137 u64 val_u64, array_u64[32];
138 int error;
139
140 node = fwnode_create_software_node(entries, NULL);
141 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node);
142
143 error = fwnode_property_read_u8(node, "prop-u8", &val_u8);
144 KUNIT_EXPECT_EQ(test, error, 0);
145 KUNIT_EXPECT_EQ(test, val_u8, 8);
146
147 error = fwnode_property_count_u8(node, "prop-u8");
148 KUNIT_EXPECT_EQ(test, error, 10);
149
150 error = fwnode_property_read_u8_array(node, "prop-u8", array_u8, 1);
151 KUNIT_EXPECT_EQ(test, error, 0);
152 KUNIT_EXPECT_EQ(test, array_u8[0], 8);
153
154 error = fwnode_property_read_u8_array(node, "prop-u8", array_u8, 2);
155 KUNIT_EXPECT_EQ(test, error, 0);
156 KUNIT_EXPECT_EQ(test, array_u8[0], 8);
157 KUNIT_EXPECT_EQ(test, array_u8[1], 9);
158
159 error = fwnode_property_read_u8_array(node, "prop-u8", array_u8, 17);
160 KUNIT_EXPECT_NE(test, error, 0);
161
162 error = fwnode_property_read_u8(node, "no-prop-u8", &val_u8);
163 KUNIT_EXPECT_NE(test, error, 0);
164
165 error = fwnode_property_read_u8_array(node, "no-prop-u8", array_u8, 1);
166 KUNIT_EXPECT_NE(test, error, 0);
167
168 error = fwnode_property_read_u16(node, "prop-u16", &val_u16);
169 KUNIT_EXPECT_EQ(test, error, 0);
170 KUNIT_EXPECT_EQ(test, val_u16, 16);
171
172 error = fwnode_property_count_u16(node, "prop-u16");
173 KUNIT_EXPECT_EQ(test, error, 10);
174
175 error = fwnode_property_read_u16_array(node, "prop-u16", array_u16, 1);
176 KUNIT_EXPECT_EQ(test, error, 0);
177 KUNIT_EXPECT_EQ(test, array_u16[0], 16);
178
179 error = fwnode_property_read_u16_array(node, "prop-u16", array_u16, 2);
180 KUNIT_EXPECT_EQ(test, error, 0);
181 KUNIT_EXPECT_EQ(test, array_u16[0], 16);
182 KUNIT_EXPECT_EQ(test, array_u16[1], 17);
183
184 error = fwnode_property_read_u16_array(node, "prop-u16", array_u16, 17);
185 KUNIT_EXPECT_NE(test, error, 0);
186
187 error = fwnode_property_read_u16(node, "no-prop-u16", &val_u16);
188 KUNIT_EXPECT_NE(test, error, 0);
189
190 error = fwnode_property_read_u16_array(node, "no-prop-u16", array_u16, 1);
191 KUNIT_EXPECT_NE(test, error, 0);
192
193 error = fwnode_property_read_u32(node, "prop-u32", &val_u32);
194 KUNIT_EXPECT_EQ(test, error, 0);
195 KUNIT_EXPECT_EQ(test, val_u32, 32);
196
197 error = fwnode_property_count_u32(node, "prop-u32");
198 KUNIT_EXPECT_EQ(test, error, 10);
199
200 error = fwnode_property_read_u32_array(node, "prop-u32", array_u32, 1);
201 KUNIT_EXPECT_EQ(test, error, 0);
202 KUNIT_EXPECT_EQ(test, array_u32[0], 32);
203
204 error = fwnode_property_read_u32_array(node, "prop-u32", array_u32, 2);
205 KUNIT_EXPECT_EQ(test, error, 0);
206 KUNIT_EXPECT_EQ(test, array_u32[0], 32);
207 KUNIT_EXPECT_EQ(test, array_u32[1], 33);
208
209 error = fwnode_property_read_u32_array(node, "prop-u32", array_u32, 17);
210 KUNIT_EXPECT_NE(test, error, 0);
211
212 error = fwnode_property_read_u32(node, "no-prop-u32", &val_u32);
213 KUNIT_EXPECT_NE(test, error, 0);
214
215 error = fwnode_property_read_u32_array(node, "no-prop-u32", array_u32, 1);
216 KUNIT_EXPECT_NE(test, error, 0);
217
218 error = fwnode_property_read_u64(node, "prop-u64", &val_u64);
219 KUNIT_EXPECT_EQ(test, error, 0);
220 KUNIT_EXPECT_EQ(test, val_u64, 64);
221
222 error = fwnode_property_count_u64(node, "prop-u64");
223 KUNIT_EXPECT_EQ(test, error, 10);
224
225 error = fwnode_property_read_u64_array(node, "prop-u64", array_u64, 1);
226 KUNIT_EXPECT_EQ(test, error, 0);
227 KUNIT_EXPECT_EQ(test, array_u64[0], 64);
228
229 error = fwnode_property_read_u64_array(node, "prop-u64", array_u64, 2);
230 KUNIT_EXPECT_EQ(test, error, 0);
231 KUNIT_EXPECT_EQ(test, array_u64[0], 64);
232 KUNIT_EXPECT_EQ(test, array_u64[1], 65);
233
234 error = fwnode_property_read_u64_array(node, "prop-u64", array_u64, 17);
235 KUNIT_EXPECT_NE(test, error, 0);
236
237 error = fwnode_property_read_u64(node, "no-prop-u64", &val_u64);
238 KUNIT_EXPECT_NE(test, error, 0);
239
240 error = fwnode_property_read_u64_array(node, "no-prop-u64", array_u64, 1);
241 KUNIT_EXPECT_NE(test, error, 0);
242
243 /* Count 64-bit values as 16-bit */
244 error = fwnode_property_count_u16(node, "prop-u64");
245 KUNIT_EXPECT_EQ(test, error, 40);
246
247 /* Other way around */
248 error = fwnode_property_count_u64(node, "prop-u16");
249 KUNIT_EXPECT_EQ(test, error, 2);
250
251 fwnode_remove_software_node(node);
252 }
253
pe_test_strings(struct kunit * test)254 static void pe_test_strings(struct kunit *test)
255 {
256 static const char *strings[] = {
257 "string-a",
258 "string-b",
259 };
260
261 static const struct property_entry entries[] = {
262 PROPERTY_ENTRY_STRING("str", "single"),
263 PROPERTY_ENTRY_STRING("empty", ""),
264 PROPERTY_ENTRY_STRING_ARRAY("strs", strings),
265 { }
266 };
267
268 struct fwnode_handle *node;
269 const char *str;
270 const char *strs[10];
271 int error;
272
273 node = fwnode_create_software_node(entries, NULL);
274 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node);
275
276 error = fwnode_property_read_string(node, "str", &str);
277 KUNIT_EXPECT_EQ(test, error, 0);
278 KUNIT_EXPECT_STREQ(test, str, "single");
279
280 error = fwnode_property_string_array_count(node, "str");
281 KUNIT_EXPECT_EQ(test, error, 1);
282
283 error = fwnode_property_read_string_array(node, "str", strs, 1);
284 KUNIT_EXPECT_EQ(test, error, 1);
285 KUNIT_EXPECT_STREQ(test, strs[0], "single");
286
287 /* asking for more data returns what we have */
288 error = fwnode_property_read_string_array(node, "str", strs, 2);
289 KUNIT_EXPECT_EQ(test, error, 1);
290 KUNIT_EXPECT_STREQ(test, strs[0], "single");
291
292 error = fwnode_property_read_string(node, "no-str", &str);
293 KUNIT_EXPECT_NE(test, error, 0);
294
295 error = fwnode_property_read_string_array(node, "no-str", strs, 1);
296 KUNIT_EXPECT_LT(test, error, 0);
297
298 error = fwnode_property_read_string(node, "empty", &str);
299 KUNIT_EXPECT_EQ(test, error, 0);
300 KUNIT_EXPECT_STREQ(test, str, "");
301
302 error = fwnode_property_string_array_count(node, "strs");
303 KUNIT_EXPECT_EQ(test, error, 2);
304
305 error = fwnode_property_read_string_array(node, "strs", strs, 3);
306 KUNIT_EXPECT_EQ(test, error, 2);
307 KUNIT_EXPECT_STREQ(test, strs[0], "string-a");
308 KUNIT_EXPECT_STREQ(test, strs[1], "string-b");
309
310 error = fwnode_property_read_string_array(node, "strs", strs, 1);
311 KUNIT_EXPECT_EQ(test, error, 1);
312 KUNIT_EXPECT_STREQ(test, strs[0], "string-a");
313
314 /* NULL argument -> returns size */
315 error = fwnode_property_read_string_array(node, "strs", NULL, 0);
316 KUNIT_EXPECT_EQ(test, error, 2);
317
318 /* accessing array as single value */
319 error = fwnode_property_read_string(node, "strs", &str);
320 KUNIT_EXPECT_EQ(test, error, 0);
321 KUNIT_EXPECT_STREQ(test, str, "string-a");
322
323 fwnode_remove_software_node(node);
324 }
325
pe_test_bool(struct kunit * test)326 static void pe_test_bool(struct kunit *test)
327 {
328 static const struct property_entry entries[] = {
329 PROPERTY_ENTRY_BOOL("prop"),
330 { }
331 };
332
333 struct fwnode_handle *node;
334
335 node = fwnode_create_software_node(entries, NULL);
336 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node);
337
338 KUNIT_EXPECT_TRUE(test, fwnode_property_read_bool(node, "prop"));
339 KUNIT_EXPECT_FALSE(test, fwnode_property_read_bool(node, "not-prop"));
340
341 fwnode_remove_software_node(node);
342 }
343
344 /* Verifies that small U8 array is stored inline when property is copied */
pe_test_move_inline_u8(struct kunit * test)345 static void pe_test_move_inline_u8(struct kunit *test)
346 {
347 static const u8 u8_array_small[8] = { 1, 2, 3, 4 };
348 static const u8 u8_array_big[128] = { 5, 6, 7, 8 };
349 static const struct property_entry entries[] = {
350 PROPERTY_ENTRY_U8_ARRAY("small", u8_array_small),
351 PROPERTY_ENTRY_U8_ARRAY("big", u8_array_big),
352 { }
353 };
354
355 struct property_entry *copy;
356 const u8 *data_ptr;
357
358 copy = property_entries_dup(entries);
359 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, copy);
360
361 KUNIT_EXPECT_TRUE(test, copy[0].is_inline);
362 data_ptr = (u8 *)©[0].value;
363 KUNIT_EXPECT_EQ(test, data_ptr[0], 1);
364 KUNIT_EXPECT_EQ(test, data_ptr[1], 2);
365
366 KUNIT_EXPECT_FALSE(test, copy[1].is_inline);
367 data_ptr = copy[1].pointer;
368 KUNIT_EXPECT_EQ(test, data_ptr[0], 5);
369 KUNIT_EXPECT_EQ(test, data_ptr[1], 6);
370
371 property_entries_free(copy);
372 }
373
374 /* Verifies that single string array is stored inline when property is copied */
pe_test_move_inline_str(struct kunit * test)375 static void pe_test_move_inline_str(struct kunit *test)
376 {
377 static char *str_array_small[] = { "a" };
378 static char *str_array_big[] = { "b", "c", "d", "e" };
379 static char *str_array_small_empty[] = { "" };
380 static struct property_entry entries[] = {
381 PROPERTY_ENTRY_STRING_ARRAY("small", str_array_small),
382 PROPERTY_ENTRY_STRING_ARRAY("big", str_array_big),
383 PROPERTY_ENTRY_STRING_ARRAY("small-empty", str_array_small_empty),
384 { }
385 };
386
387 struct property_entry *copy;
388 const char * const *data_ptr;
389
390 copy = property_entries_dup(entries);
391 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, copy);
392
393 KUNIT_EXPECT_TRUE(test, copy[0].is_inline);
394 KUNIT_EXPECT_STREQ(test, copy[0].value.str[0], "a");
395
396 KUNIT_EXPECT_FALSE(test, copy[1].is_inline);
397 data_ptr = copy[1].pointer;
398 KUNIT_EXPECT_STREQ(test, data_ptr[0], "b");
399 KUNIT_EXPECT_STREQ(test, data_ptr[1], "c");
400
401 KUNIT_EXPECT_TRUE(test, copy[2].is_inline);
402 KUNIT_EXPECT_STREQ(test, copy[2].value.str[0], "");
403
404 property_entries_free(copy);
405 }
406
407 /* Handling of reference properties */
pe_test_reference(struct kunit * test)408 static void pe_test_reference(struct kunit *test)
409 {
410 static const struct software_node node1 = { .name = "1" };
411 static const struct software_node node2 = { .name = "2" };
412 static const struct software_node *group[] = { &node1, &node2, NULL };
413
414 static const struct software_node_ref_args refs[] = {
415 SOFTWARE_NODE_REFERENCE(&node1),
416 SOFTWARE_NODE_REFERENCE(&node2, 3, 4),
417 };
418
419 const struct property_entry entries[] = {
420 PROPERTY_ENTRY_REF("ref-1", &node1),
421 PROPERTY_ENTRY_REF("ref-2", &node2, 1, 2),
422 PROPERTY_ENTRY_REF_ARRAY("ref-3", refs),
423 { }
424 };
425
426 struct fwnode_handle *node;
427 struct fwnode_reference_args ref;
428 int error;
429
430 error = software_node_register_node_group(group);
431 KUNIT_ASSERT_EQ(test, error, 0);
432
433 node = fwnode_create_software_node(entries, NULL);
434 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node);
435
436 error = fwnode_property_get_reference_args(node, "ref-1", NULL,
437 0, 0, &ref);
438 KUNIT_ASSERT_EQ(test, error, 0);
439 KUNIT_EXPECT_PTR_EQ(test, to_software_node(ref.fwnode), &node1);
440 KUNIT_EXPECT_EQ(test, ref.nargs, 0U);
441
442 /* wrong index */
443 error = fwnode_property_get_reference_args(node, "ref-1", NULL,
444 0, 1, &ref);
445 KUNIT_EXPECT_NE(test, error, 0);
446
447 error = fwnode_property_get_reference_args(node, "ref-2", NULL,
448 1, 0, &ref);
449 KUNIT_ASSERT_EQ(test, error, 0);
450 KUNIT_EXPECT_PTR_EQ(test, to_software_node(ref.fwnode), &node2);
451 KUNIT_EXPECT_EQ(test, ref.nargs, 1U);
452 KUNIT_EXPECT_EQ(test, ref.args[0], 1LLU);
453
454 /* asking for more args, padded with zero data */
455 error = fwnode_property_get_reference_args(node, "ref-2", NULL,
456 3, 0, &ref);
457 KUNIT_ASSERT_EQ(test, error, 0);
458 KUNIT_EXPECT_PTR_EQ(test, to_software_node(ref.fwnode), &node2);
459 KUNIT_EXPECT_EQ(test, ref.nargs, 3U);
460 KUNIT_EXPECT_EQ(test, ref.args[0], 1LLU);
461 KUNIT_EXPECT_EQ(test, ref.args[1], 2LLU);
462 KUNIT_EXPECT_EQ(test, ref.args[2], 0LLU);
463
464 /* wrong index */
465 error = fwnode_property_get_reference_args(node, "ref-2", NULL,
466 2, 1, &ref);
467 KUNIT_EXPECT_NE(test, error, 0);
468
469 /* array of references */
470 error = fwnode_property_get_reference_args(node, "ref-3", NULL,
471 0, 0, &ref);
472 KUNIT_ASSERT_EQ(test, error, 0);
473 KUNIT_EXPECT_PTR_EQ(test, to_software_node(ref.fwnode), &node1);
474 KUNIT_EXPECT_EQ(test, ref.nargs, 0U);
475
476 /* second reference in the array */
477 error = fwnode_property_get_reference_args(node, "ref-3", NULL,
478 2, 1, &ref);
479 KUNIT_ASSERT_EQ(test, error, 0);
480 KUNIT_EXPECT_PTR_EQ(test, to_software_node(ref.fwnode), &node2);
481 KUNIT_EXPECT_EQ(test, ref.nargs, 2U);
482 KUNIT_EXPECT_EQ(test, ref.args[0], 3LLU);
483 KUNIT_EXPECT_EQ(test, ref.args[1], 4LLU);
484
485 /* wrong index */
486 error = fwnode_property_get_reference_args(node, "ref-1", NULL,
487 0, 2, &ref);
488 KUNIT_EXPECT_NE(test, error, 0);
489
490 fwnode_remove_software_node(node);
491 software_node_unregister_node_group(group);
492 }
493
create_device_node(struct kunit * test,const char * name,const char * full_name,struct device_node * parent)494 static struct fwnode_handle *create_device_node(struct kunit *test,
495 const char *name,
496 const char *full_name,
497 struct device_node *parent)
498 {
499 struct device_node *node;
500
501 node = kunit_kzalloc(test, sizeof(*node), GFP_KERNEL);
502 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node);
503
504 node->name = kunit_kstrdup(test, name, GFP_KERNEL);
505 node->full_name = kunit_kstrdup(test, full_name, GFP_KERNEL);
506
507 if (parent) {
508 node->sibling = parent->child;
509 /* set the node as the first child of the parent */
510 parent->child = node;
511 node->parent = parent;
512 }
513
514 of_node_init(node);
515 return of_fwnode_handle(node);
516 }
517
518 /* Verifies that fwnode_for_each_child_node() can output correct children */
pe_test_child_iteration(struct kunit * test)519 static void pe_test_child_iteration(struct kunit *test)
520 {
521 struct fwnode_handle *of_node, *of_node1;
522 struct fwnode_handle *sw_node, *sw_node1;
523 struct fwnode_handle *child;
524 int error, i, num;
525
526 if (!IS_ENABLED(CONFIG_OF))
527 kunit_skip(test, "requires CONFIG_OF");
528
529 static const struct software_node node = { .name = "sw" };
530 static const struct software_node node1 = { .name = "sw-1", .parent = &node};
531 static const struct software_node node2 = { .name = "sw-2", .parent = &node};
532 static const struct software_node node3 = { .name = "sw-3", .parent = &node};
533 static const struct software_node *group[] = { &node, &node1, &node2, &node3, NULL };
534
535 static const char * const of_child_array[] = { "of-1", "of-2", "of-3" };
536 static const char * const sw_child_array[] = { "sw-1", "sw-2", "sw-3" };
537 static const char * const of_sw_child_array[] = { "of-1", "of-2", "of-3",
538 "sw-1", "sw-2", "sw-3" };
539 static const char * const sw_of_child_array[] = { "sw-1", "sw-2", "sw-3",
540 "of-1", "of-2", "of-3" };
541
542 /* 1. Test OF node child iteration */
543
544 of_node = create_device_node(test, "of", "of", NULL);
545 create_device_node(test, "of", "of-3", to_of_node(of_node));
546 create_device_node(test, "of", "of-2", to_of_node(of_node));
547 of_node1 = create_device_node(test, "of", "of-1", to_of_node(of_node));
548
549 i = 0;
550 num = ARRAY_SIZE(of_child_array);
551 fwnode_for_each_child_node(of_node, child) {
552 KUNIT_ASSERT_LT(test, i, num);
553 KUNIT_EXPECT_STREQ(test, of_child_array[i++], fwnode_get_name(child));
554 }
555 KUNIT_EXPECT_PTR_EQ(test, child, NULL);
556
557 /* 2. Test SW node child iteration */
558
559 error = software_node_register_node_group(group);
560 KUNIT_ASSERT_EQ(test, error, 0);
561
562 sw_node = software_node_fwnode(&node);
563
564 i = 0;
565 num = ARRAY_SIZE(sw_child_array);
566 fwnode_for_each_child_node(sw_node, child) {
567 KUNIT_ASSERT_LT(test, i, num);
568 KUNIT_EXPECT_STREQ(test, sw_child_array[i++], fwnode_get_name(child));
569 }
570 KUNIT_EXPECT_PTR_EQ(test, child, NULL);
571
572 /* 3. Test OF (primary) + SW (secondary) node child iteration */
573
574 of_node->secondary = sw_node;
575 sw_node->secondary = ERR_PTR(-ENODEV);
576
577 i = 0;
578 num = ARRAY_SIZE(of_sw_child_array);
579 fwnode_for_each_child_node(of_node, child) {
580 KUNIT_ASSERT_LT(test, i, num);
581 KUNIT_EXPECT_STREQ(test, of_sw_child_array[i++], fwnode_get_name(child));
582 }
583 KUNIT_EXPECT_PTR_EQ(test, child, NULL);
584
585 /* 4. Test SW (primary) + OF (secondary) node child iteration */
586
587 sw_node->secondary = of_node;
588 of_node->secondary = ERR_PTR(-ENODEV);
589
590 i = 0;
591 num = ARRAY_SIZE(sw_of_child_array);
592 fwnode_for_each_child_node(sw_node, child) {
593 KUNIT_ASSERT_LT(test, i, num);
594 KUNIT_EXPECT_STREQ(test, sw_of_child_array[i++], fwnode_get_name(child));
595 }
596 KUNIT_EXPECT_PTR_EQ(test, child, NULL);
597
598 /* 5. Test OF (primary) + SW (secondary, but no children) node child iteration */
599
600 sw_node1 = software_node_fwnode(&node1);
601 of_node->secondary = sw_node1;
602 sw_node->secondary = ERR_PTR(-ENODEV);
603
604 i = 0;
605 num = ARRAY_SIZE(of_child_array);
606 fwnode_for_each_child_node(of_node, child) {
607 KUNIT_ASSERT_LT(test, i, num);
608 KUNIT_EXPECT_STREQ(test, of_child_array[i++], fwnode_get_name(child));
609 }
610 KUNIT_EXPECT_PTR_EQ(test, child, NULL);
611
612 /* 6. Test SW (primary) + OF (secondary, but no children) node child iteration */
613
614 sw_node->secondary = of_node1;
615 of_node->secondary = ERR_PTR(-ENODEV);
616
617 i = 0;
618 num = ARRAY_SIZE(sw_child_array);
619 fwnode_for_each_child_node(sw_node, child) {
620 KUNIT_ASSERT_LT(test, i, num);
621 KUNIT_EXPECT_STREQ(test, sw_child_array[i++], fwnode_get_name(child));
622 }
623 KUNIT_EXPECT_PTR_EQ(test, child, NULL);
624
625 of_node->secondary = NULL;
626 sw_node->secondary = NULL;
627 software_node_unregister_node_group(group);
628 }
629
630 static struct kunit_case property_entry_test_cases[] = {
631 KUNIT_CASE(pe_test_uints),
632 KUNIT_CASE(pe_test_uint_arrays),
633 KUNIT_CASE(pe_test_strings),
634 KUNIT_CASE(pe_test_bool),
635 KUNIT_CASE(pe_test_move_inline_u8),
636 KUNIT_CASE(pe_test_move_inline_str),
637 KUNIT_CASE(pe_test_reference),
638 KUNIT_CASE(pe_test_child_iteration),
639 { }
640 };
641
642 static struct kunit_suite property_entry_test_suite = {
643 .name = "property-entry",
644 .test_cases = property_entry_test_cases,
645 };
646
647 kunit_test_suite(property_entry_test_suite);
648
649 MODULE_DESCRIPTION("Test module for the property entry API");
650 MODULE_AUTHOR("Dmitry Torokhov <dtor@chromium.org>");
651 MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
652 MODULE_LICENSE("GPL");
653