xref: /linux/drivers/base/test/property-entry-test.c (revision 59e6295fac26b8e85c1ea859cdd89fa1e47519d7)
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 
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 
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 
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 
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 */
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 *)&copy[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 */
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 */
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 
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 */
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 	static const struct software_node node = { .name = "sw" };
527 	static const struct software_node node1 = { .name = "sw-1", .parent = &node};
528 	static const struct software_node node2 = { .name = "sw-2", .parent = &node};
529 	static const struct software_node node3 = { .name = "sw-3", .parent = &node};
530 	static const struct software_node *group[] = { &node, &node1, &node2, &node3, NULL };
531 
532 	static const char * const of_child_array[] = { "of-1", "of-2", "of-3" };
533 	static const char * const sw_child_array[] = { "sw-1", "sw-2", "sw-3" };
534 	static const char * const of_sw_child_array[] = { "of-1", "of-2", "of-3",
535 							  "sw-1", "sw-2", "sw-3" };
536 	static const char * const sw_of_child_array[] = { "sw-1", "sw-2", "sw-3",
537 							  "of-1", "of-2", "of-3" };
538 
539 	/* 1. Test OF node child iteration */
540 
541 	of_node = create_device_node(test, "of", "of", NULL);
542 	create_device_node(test, "of", "of-3", to_of_node(of_node));
543 	create_device_node(test, "of", "of-2", to_of_node(of_node));
544 	of_node1 = create_device_node(test, "of", "of-1", to_of_node(of_node));
545 
546 	i = 0;
547 	num = ARRAY_SIZE(of_child_array);
548 	fwnode_for_each_child_node(of_node, child) {
549 		KUNIT_ASSERT_LT(test, i, num);
550 		KUNIT_EXPECT_STREQ(test, of_child_array[i++], fwnode_get_name(child));
551 	}
552 	KUNIT_EXPECT_PTR_EQ(test, child, NULL);
553 
554 	/* 2. Test SW node child iteration */
555 
556 	error = software_node_register_node_group(group);
557 	KUNIT_ASSERT_EQ(test, error, 0);
558 
559 	sw_node = software_node_fwnode(&node);
560 
561 	i = 0;
562 	num = ARRAY_SIZE(sw_child_array);
563 	fwnode_for_each_child_node(sw_node, child) {
564 		KUNIT_ASSERT_LT(test, i, num);
565 		KUNIT_EXPECT_STREQ(test, sw_child_array[i++], fwnode_get_name(child));
566 	}
567 	KUNIT_EXPECT_PTR_EQ(test, child, NULL);
568 
569 	/* 3. Test OF (primary) + SW (secondary) node child iteration */
570 
571 	of_node->secondary = sw_node;
572 	sw_node->secondary = ERR_PTR(-ENODEV);
573 
574 	i = 0;
575 	num = ARRAY_SIZE(of_sw_child_array);
576 	fwnode_for_each_child_node(of_node, child) {
577 		KUNIT_ASSERT_LT(test, i, num);
578 		KUNIT_EXPECT_STREQ(test, of_sw_child_array[i++], fwnode_get_name(child));
579 	}
580 	KUNIT_EXPECT_PTR_EQ(test, child, NULL);
581 
582 	/* 4. Test SW (primary) + OF (secondary) node child iteration */
583 
584 	sw_node->secondary = of_node;
585 	of_node->secondary = ERR_PTR(-ENODEV);
586 
587 	i = 0;
588 	num = ARRAY_SIZE(sw_of_child_array);
589 	fwnode_for_each_child_node(sw_node, child) {
590 		KUNIT_ASSERT_LT(test, i, num);
591 		KUNIT_EXPECT_STREQ(test, sw_of_child_array[i++], fwnode_get_name(child));
592 	}
593 	KUNIT_EXPECT_PTR_EQ(test, child, NULL);
594 
595 	/* 5. Test OF (primary) + SW (secondary, but no children) node child iteration */
596 
597 	sw_node1 = software_node_fwnode(&node1);
598 	of_node->secondary = sw_node1;
599 	sw_node->secondary = ERR_PTR(-ENODEV);
600 
601 	i = 0;
602 	num = ARRAY_SIZE(of_child_array);
603 	fwnode_for_each_child_node(of_node, child) {
604 		KUNIT_ASSERT_LT(test, i, num);
605 		KUNIT_EXPECT_STREQ(test, of_child_array[i++], fwnode_get_name(child));
606 	}
607 	KUNIT_EXPECT_PTR_EQ(test, child, NULL);
608 
609 	/* 6. Test SW (primary) + OF (secondary, but no children) node child iteration */
610 
611 	sw_node->secondary = of_node1;
612 	of_node->secondary = ERR_PTR(-ENODEV);
613 
614 	i = 0;
615 	num = ARRAY_SIZE(sw_child_array);
616 	fwnode_for_each_child_node(sw_node, child) {
617 		KUNIT_ASSERT_LT(test, i, num);
618 		KUNIT_EXPECT_STREQ(test, sw_child_array[i++], fwnode_get_name(child));
619 	}
620 	KUNIT_EXPECT_PTR_EQ(test, child, NULL);
621 
622 	of_node->secondary = NULL;
623 	sw_node->secondary = NULL;
624 	software_node_unregister_node_group(group);
625 }
626 
627 static struct kunit_case property_entry_test_cases[] = {
628 	KUNIT_CASE(pe_test_uints),
629 	KUNIT_CASE(pe_test_uint_arrays),
630 	KUNIT_CASE(pe_test_strings),
631 	KUNIT_CASE(pe_test_bool),
632 	KUNIT_CASE(pe_test_move_inline_u8),
633 	KUNIT_CASE(pe_test_move_inline_str),
634 	KUNIT_CASE(pe_test_reference),
635 	KUNIT_CASE(pe_test_child_iteration),
636 	{ }
637 };
638 
639 static struct kunit_suite property_entry_test_suite = {
640 	.name = "property-entry",
641 	.test_cases = property_entry_test_cases,
642 };
643 
644 kunit_test_suite(property_entry_test_suite);
645 
646 MODULE_DESCRIPTION("Test module for the property entry API");
647 MODULE_AUTHOR("Dmitry Torokhov <dtor@chromium.org>");
648 MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
649 MODULE_LICENSE("GPL");
650