1 // SPDX-License-Identifier: GPL-2.0
2 // Unit tests for property entries API
4 // Copyright 2019 Google LLC.
6 #include <kunit/test.h>
7 #include <linux/property.h>
8 #include <linux/types.h>
10 static void pe_test_uints(struct kunit
*test
)
12 static const struct property_entry entries
[] = {
13 PROPERTY_ENTRY_U8("prop-u8", 8),
14 PROPERTY_ENTRY_U16("prop-u16", 16),
15 PROPERTY_ENTRY_U32("prop-u32", 32),
16 PROPERTY_ENTRY_U64("prop-u64", 64),
20 struct fwnode_handle
*node
;
21 u8 val_u8
, array_u8
[2];
22 u16 val_u16
, array_u16
[2];
23 u32 val_u32
, array_u32
[2];
24 u64 val_u64
, array_u64
[2];
27 node
= fwnode_create_software_node(entries
, NULL
);
28 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, node
);
30 error
= fwnode_property_count_u8(node
, "prop-u8");
31 KUNIT_EXPECT_EQ(test
, error
, 1);
33 error
= fwnode_property_read_u8(node
, "prop-u8", &val_u8
);
34 KUNIT_EXPECT_EQ(test
, error
, 0);
35 KUNIT_EXPECT_EQ(test
, val_u8
, 8);
37 error
= fwnode_property_read_u8_array(node
, "prop-u8", array_u8
, 1);
38 KUNIT_EXPECT_EQ(test
, error
, 0);
39 KUNIT_EXPECT_EQ(test
, array_u8
[0], 8);
41 error
= fwnode_property_read_u8_array(node
, "prop-u8", array_u8
, 2);
42 KUNIT_EXPECT_NE(test
, error
, 0);
44 error
= fwnode_property_read_u8(node
, "no-prop-u8", &val_u8
);
45 KUNIT_EXPECT_NE(test
, error
, 0);
47 error
= fwnode_property_read_u8_array(node
, "no-prop-u8", array_u8
, 1);
48 KUNIT_EXPECT_NE(test
, error
, 0);
50 error
= fwnode_property_read_u16(node
, "prop-u16", &val_u16
);
51 KUNIT_EXPECT_EQ(test
, error
, 0);
52 KUNIT_EXPECT_EQ(test
, val_u16
, 16);
54 error
= fwnode_property_count_u16(node
, "prop-u16");
55 KUNIT_EXPECT_EQ(test
, error
, 1);
57 error
= fwnode_property_read_u16_array(node
, "prop-u16", array_u16
, 1);
58 KUNIT_EXPECT_EQ(test
, error
, 0);
59 KUNIT_EXPECT_EQ(test
, array_u16
[0], 16);
61 error
= fwnode_property_read_u16_array(node
, "prop-u16", array_u16
, 2);
62 KUNIT_EXPECT_NE(test
, error
, 0);
64 error
= fwnode_property_read_u16(node
, "no-prop-u16", &val_u16
);
65 KUNIT_EXPECT_NE(test
, error
, 0);
67 error
= fwnode_property_read_u16_array(node
, "no-prop-u16", array_u16
, 1);
68 KUNIT_EXPECT_NE(test
, error
, 0);
70 error
= fwnode_property_read_u32(node
, "prop-u32", &val_u32
);
71 KUNIT_EXPECT_EQ(test
, error
, 0);
72 KUNIT_EXPECT_EQ(test
, val_u32
, 32);
74 error
= fwnode_property_count_u32(node
, "prop-u32");
75 KUNIT_EXPECT_EQ(test
, error
, 1);
77 error
= fwnode_property_read_u32_array(node
, "prop-u32", array_u32
, 1);
78 KUNIT_EXPECT_EQ(test
, error
, 0);
79 KUNIT_EXPECT_EQ(test
, array_u32
[0], 32);
81 error
= fwnode_property_read_u32_array(node
, "prop-u32", array_u32
, 2);
82 KUNIT_EXPECT_NE(test
, error
, 0);
84 error
= fwnode_property_read_u32(node
, "no-prop-u32", &val_u32
);
85 KUNIT_EXPECT_NE(test
, error
, 0);
87 error
= fwnode_property_read_u32_array(node
, "no-prop-u32", array_u32
, 1);
88 KUNIT_EXPECT_NE(test
, error
, 0);
90 error
= fwnode_property_read_u64(node
, "prop-u64", &val_u64
);
91 KUNIT_EXPECT_EQ(test
, error
, 0);
92 KUNIT_EXPECT_EQ(test
, val_u64
, 64);
94 error
= fwnode_property_count_u64(node
, "prop-u64");
95 KUNIT_EXPECT_EQ(test
, error
, 1);
97 error
= fwnode_property_read_u64_array(node
, "prop-u64", array_u64
, 1);
98 KUNIT_EXPECT_EQ(test
, error
, 0);
99 KUNIT_EXPECT_EQ(test
, array_u64
[0], 64);
101 error
= fwnode_property_read_u64_array(node
, "prop-u64", array_u64
, 2);
102 KUNIT_EXPECT_NE(test
, error
, 0);
104 error
= fwnode_property_read_u64(node
, "no-prop-u64", &val_u64
);
105 KUNIT_EXPECT_NE(test
, error
, 0);
107 error
= fwnode_property_read_u64_array(node
, "no-prop-u64", array_u64
, 1);
108 KUNIT_EXPECT_NE(test
, error
, 0);
110 /* Count 64-bit values as 16-bit */
111 error
= fwnode_property_count_u16(node
, "prop-u64");
112 KUNIT_EXPECT_EQ(test
, error
, 4);
114 fwnode_remove_software_node(node
);
117 static void pe_test_uint_arrays(struct kunit
*test
)
119 static const u8 a_u8
[10] = { 8, 9 };
120 static const u16 a_u16
[10] = { 16, 17 };
121 static const u32 a_u32
[10] = { 32, 33 };
122 static const u64 a_u64
[10] = { 64, 65 };
123 static const struct property_entry entries
[] = {
124 PROPERTY_ENTRY_U8_ARRAY("prop-u8", a_u8
),
125 PROPERTY_ENTRY_U16_ARRAY("prop-u16", a_u16
),
126 PROPERTY_ENTRY_U32_ARRAY("prop-u32", a_u32
),
127 PROPERTY_ENTRY_U64_ARRAY("prop-u64", a_u64
),
131 struct fwnode_handle
*node
;
132 u8 val_u8
, array_u8
[32];
133 u16 val_u16
, array_u16
[32];
134 u32 val_u32
, array_u32
[32];
135 u64 val_u64
, array_u64
[32];
138 node
= fwnode_create_software_node(entries
, NULL
);
139 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, node
);
141 error
= fwnode_property_read_u8(node
, "prop-u8", &val_u8
);
142 KUNIT_EXPECT_EQ(test
, error
, 0);
143 KUNIT_EXPECT_EQ(test
, val_u8
, 8);
145 error
= fwnode_property_count_u8(node
, "prop-u8");
146 KUNIT_EXPECT_EQ(test
, error
, 10);
148 error
= fwnode_property_read_u8_array(node
, "prop-u8", array_u8
, 1);
149 KUNIT_EXPECT_EQ(test
, error
, 0);
150 KUNIT_EXPECT_EQ(test
, array_u8
[0], 8);
152 error
= fwnode_property_read_u8_array(node
, "prop-u8", array_u8
, 2);
153 KUNIT_EXPECT_EQ(test
, error
, 0);
154 KUNIT_EXPECT_EQ(test
, array_u8
[0], 8);
155 KUNIT_EXPECT_EQ(test
, array_u8
[1], 9);
157 error
= fwnode_property_read_u8_array(node
, "prop-u8", array_u8
, 17);
158 KUNIT_EXPECT_NE(test
, error
, 0);
160 error
= fwnode_property_read_u8(node
, "no-prop-u8", &val_u8
);
161 KUNIT_EXPECT_NE(test
, error
, 0);
163 error
= fwnode_property_read_u8_array(node
, "no-prop-u8", array_u8
, 1);
164 KUNIT_EXPECT_NE(test
, error
, 0);
166 error
= fwnode_property_read_u16(node
, "prop-u16", &val_u16
);
167 KUNIT_EXPECT_EQ(test
, error
, 0);
168 KUNIT_EXPECT_EQ(test
, val_u16
, 16);
170 error
= fwnode_property_count_u16(node
, "prop-u16");
171 KUNIT_EXPECT_EQ(test
, error
, 10);
173 error
= fwnode_property_read_u16_array(node
, "prop-u16", array_u16
, 1);
174 KUNIT_EXPECT_EQ(test
, error
, 0);
175 KUNIT_EXPECT_EQ(test
, array_u16
[0], 16);
177 error
= fwnode_property_read_u16_array(node
, "prop-u16", array_u16
, 2);
178 KUNIT_EXPECT_EQ(test
, error
, 0);
179 KUNIT_EXPECT_EQ(test
, array_u16
[0], 16);
180 KUNIT_EXPECT_EQ(test
, array_u16
[1], 17);
182 error
= fwnode_property_read_u16_array(node
, "prop-u16", array_u16
, 17);
183 KUNIT_EXPECT_NE(test
, error
, 0);
185 error
= fwnode_property_read_u16(node
, "no-prop-u16", &val_u16
);
186 KUNIT_EXPECT_NE(test
, error
, 0);
188 error
= fwnode_property_read_u16_array(node
, "no-prop-u16", array_u16
, 1);
189 KUNIT_EXPECT_NE(test
, error
, 0);
191 error
= fwnode_property_read_u32(node
, "prop-u32", &val_u32
);
192 KUNIT_EXPECT_EQ(test
, error
, 0);
193 KUNIT_EXPECT_EQ(test
, val_u32
, 32);
195 error
= fwnode_property_count_u32(node
, "prop-u32");
196 KUNIT_EXPECT_EQ(test
, error
, 10);
198 error
= fwnode_property_read_u32_array(node
, "prop-u32", array_u32
, 1);
199 KUNIT_EXPECT_EQ(test
, error
, 0);
200 KUNIT_EXPECT_EQ(test
, array_u32
[0], 32);
202 error
= fwnode_property_read_u32_array(node
, "prop-u32", array_u32
, 2);
203 KUNIT_EXPECT_EQ(test
, error
, 0);
204 KUNIT_EXPECT_EQ(test
, array_u32
[0], 32);
205 KUNIT_EXPECT_EQ(test
, array_u32
[1], 33);
207 error
= fwnode_property_read_u32_array(node
, "prop-u32", array_u32
, 17);
208 KUNIT_EXPECT_NE(test
, error
, 0);
210 error
= fwnode_property_read_u32(node
, "no-prop-u32", &val_u32
);
211 KUNIT_EXPECT_NE(test
, error
, 0);
213 error
= fwnode_property_read_u32_array(node
, "no-prop-u32", array_u32
, 1);
214 KUNIT_EXPECT_NE(test
, error
, 0);
216 error
= fwnode_property_read_u64(node
, "prop-u64", &val_u64
);
217 KUNIT_EXPECT_EQ(test
, error
, 0);
218 KUNIT_EXPECT_EQ(test
, val_u64
, 64);
220 error
= fwnode_property_count_u64(node
, "prop-u64");
221 KUNIT_EXPECT_EQ(test
, error
, 10);
223 error
= fwnode_property_read_u64_array(node
, "prop-u64", array_u64
, 1);
224 KUNIT_EXPECT_EQ(test
, error
, 0);
225 KUNIT_EXPECT_EQ(test
, array_u64
[0], 64);
227 error
= fwnode_property_read_u64_array(node
, "prop-u64", array_u64
, 2);
228 KUNIT_EXPECT_EQ(test
, error
, 0);
229 KUNIT_EXPECT_EQ(test
, array_u64
[0], 64);
230 KUNIT_EXPECT_EQ(test
, array_u64
[1], 65);
232 error
= fwnode_property_read_u64_array(node
, "prop-u64", array_u64
, 17);
233 KUNIT_EXPECT_NE(test
, error
, 0);
235 error
= fwnode_property_read_u64(node
, "no-prop-u64", &val_u64
);
236 KUNIT_EXPECT_NE(test
, error
, 0);
238 error
= fwnode_property_read_u64_array(node
, "no-prop-u64", array_u64
, 1);
239 KUNIT_EXPECT_NE(test
, error
, 0);
241 /* Count 64-bit values as 16-bit */
242 error
= fwnode_property_count_u16(node
, "prop-u64");
243 KUNIT_EXPECT_EQ(test
, error
, 40);
245 /* Other way around */
246 error
= fwnode_property_count_u64(node
, "prop-u16");
247 KUNIT_EXPECT_EQ(test
, error
, 2);
249 fwnode_remove_software_node(node
);
252 static void pe_test_strings(struct kunit
*test
)
254 static const char *strings
[] = {
259 static const struct property_entry entries
[] = {
260 PROPERTY_ENTRY_STRING("str", "single"),
261 PROPERTY_ENTRY_STRING("empty", ""),
262 PROPERTY_ENTRY_STRING_ARRAY("strs", strings
),
266 struct fwnode_handle
*node
;
268 const char *strs
[10];
271 node
= fwnode_create_software_node(entries
, NULL
);
272 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, node
);
274 error
= fwnode_property_read_string(node
, "str", &str
);
275 KUNIT_EXPECT_EQ(test
, error
, 0);
276 KUNIT_EXPECT_STREQ(test
, str
, "single");
278 error
= fwnode_property_string_array_count(node
, "str");
279 KUNIT_EXPECT_EQ(test
, error
, 1);
281 error
= fwnode_property_read_string_array(node
, "str", strs
, 1);
282 KUNIT_EXPECT_EQ(test
, error
, 1);
283 KUNIT_EXPECT_STREQ(test
, strs
[0], "single");
285 /* asking for more data returns what we have */
286 error
= fwnode_property_read_string_array(node
, "str", strs
, 2);
287 KUNIT_EXPECT_EQ(test
, error
, 1);
288 KUNIT_EXPECT_STREQ(test
, strs
[0], "single");
290 error
= fwnode_property_read_string(node
, "no-str", &str
);
291 KUNIT_EXPECT_NE(test
, error
, 0);
293 error
= fwnode_property_read_string_array(node
, "no-str", strs
, 1);
294 KUNIT_EXPECT_LT(test
, error
, 0);
296 error
= fwnode_property_read_string(node
, "empty", &str
);
297 KUNIT_EXPECT_EQ(test
, error
, 0);
298 KUNIT_EXPECT_STREQ(test
, str
, "");
300 error
= fwnode_property_string_array_count(node
, "strs");
301 KUNIT_EXPECT_EQ(test
, error
, 2);
303 error
= fwnode_property_read_string_array(node
, "strs", strs
, 3);
304 KUNIT_EXPECT_EQ(test
, error
, 2);
305 KUNIT_EXPECT_STREQ(test
, strs
[0], "string-a");
306 KUNIT_EXPECT_STREQ(test
, strs
[1], "string-b");
308 error
= fwnode_property_read_string_array(node
, "strs", strs
, 1);
309 KUNIT_EXPECT_EQ(test
, error
, 1);
310 KUNIT_EXPECT_STREQ(test
, strs
[0], "string-a");
312 /* NULL argument -> returns size */
313 error
= fwnode_property_read_string_array(node
, "strs", NULL
, 0);
314 KUNIT_EXPECT_EQ(test
, error
, 2);
316 /* accessing array as single value */
317 error
= fwnode_property_read_string(node
, "strs", &str
);
318 KUNIT_EXPECT_EQ(test
, error
, 0);
319 KUNIT_EXPECT_STREQ(test
, str
, "string-a");
321 fwnode_remove_software_node(node
);
324 static void pe_test_bool(struct kunit
*test
)
326 static const struct property_entry entries
[] = {
327 PROPERTY_ENTRY_BOOL("prop"),
331 struct fwnode_handle
*node
;
333 node
= fwnode_create_software_node(entries
, NULL
);
334 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, node
);
336 KUNIT_EXPECT_TRUE(test
, fwnode_property_read_bool(node
, "prop"));
337 KUNIT_EXPECT_FALSE(test
, fwnode_property_read_bool(node
, "not-prop"));
339 fwnode_remove_software_node(node
);
342 /* Verifies that small U8 array is stored inline when property is copied */
343 static void pe_test_move_inline_u8(struct kunit
*test
)
345 static const u8 u8_array_small
[8] = { 1, 2, 3, 4 };
346 static const u8 u8_array_big
[128] = { 5, 6, 7, 8 };
347 static const struct property_entry entries
[] = {
348 PROPERTY_ENTRY_U8_ARRAY("small", u8_array_small
),
349 PROPERTY_ENTRY_U8_ARRAY("big", u8_array_big
),
353 struct property_entry
*copy
;
356 copy
= property_entries_dup(entries
);
357 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, copy
);
359 KUNIT_EXPECT_TRUE(test
, copy
[0].is_inline
);
360 data_ptr
= (u8
*)©
[0].value
;
361 KUNIT_EXPECT_EQ(test
, data_ptr
[0], 1);
362 KUNIT_EXPECT_EQ(test
, data_ptr
[1], 2);
364 KUNIT_EXPECT_FALSE(test
, copy
[1].is_inline
);
365 data_ptr
= copy
[1].pointer
;
366 KUNIT_EXPECT_EQ(test
, data_ptr
[0], 5);
367 KUNIT_EXPECT_EQ(test
, data_ptr
[1], 6);
369 property_entries_free(copy
);
372 /* Verifies that single string array is stored inline when property is copied */
373 static void pe_test_move_inline_str(struct kunit
*test
)
375 static char *str_array_small
[] = { "a" };
376 static char *str_array_big
[] = { "b", "c", "d", "e" };
377 static char *str_array_small_empty
[] = { "" };
378 static struct property_entry entries
[] = {
379 PROPERTY_ENTRY_STRING_ARRAY("small", str_array_small
),
380 PROPERTY_ENTRY_STRING_ARRAY("big", str_array_big
),
381 PROPERTY_ENTRY_STRING_ARRAY("small-empty", str_array_small_empty
),
385 struct property_entry
*copy
;
386 const char * const *data_ptr
;
388 copy
= property_entries_dup(entries
);
389 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, copy
);
391 KUNIT_EXPECT_TRUE(test
, copy
[0].is_inline
);
392 KUNIT_EXPECT_STREQ(test
, copy
[0].value
.str
[0], "a");
394 KUNIT_EXPECT_FALSE(test
, copy
[1].is_inline
);
395 data_ptr
= copy
[1].pointer
;
396 KUNIT_EXPECT_STREQ(test
, data_ptr
[0], "b");
397 KUNIT_EXPECT_STREQ(test
, data_ptr
[1], "c");
399 KUNIT_EXPECT_TRUE(test
, copy
[2].is_inline
);
400 KUNIT_EXPECT_STREQ(test
, copy
[2].value
.str
[0], "");
402 property_entries_free(copy
);
405 /* Handling of reference properties */
406 static void pe_test_reference(struct kunit
*test
)
408 static const struct software_node node1
= { .name
= "1" };
409 static const struct software_node node2
= { .name
= "2" };
410 static const struct software_node
*group
[] = { &node1
, &node2
, NULL
};
412 static const struct software_node_ref_args refs
[] = {
413 SOFTWARE_NODE_REFERENCE(&node1
),
414 SOFTWARE_NODE_REFERENCE(&node2
, 3, 4),
417 const struct property_entry entries
[] = {
418 PROPERTY_ENTRY_REF("ref-1", &node1
),
419 PROPERTY_ENTRY_REF("ref-2", &node2
, 1, 2),
420 PROPERTY_ENTRY_REF_ARRAY("ref-3", refs
),
424 struct fwnode_handle
*node
;
425 struct fwnode_reference_args ref
;
428 error
= software_node_register_node_group(group
);
429 KUNIT_ASSERT_EQ(test
, error
, 0);
431 node
= fwnode_create_software_node(entries
, NULL
);
432 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, node
);
434 error
= fwnode_property_get_reference_args(node
, "ref-1", NULL
,
436 KUNIT_ASSERT_EQ(test
, error
, 0);
437 KUNIT_EXPECT_PTR_EQ(test
, to_software_node(ref
.fwnode
), &node1
);
438 KUNIT_EXPECT_EQ(test
, ref
.nargs
, 0U);
441 error
= fwnode_property_get_reference_args(node
, "ref-1", NULL
,
443 KUNIT_EXPECT_NE(test
, error
, 0);
445 error
= fwnode_property_get_reference_args(node
, "ref-2", NULL
,
447 KUNIT_ASSERT_EQ(test
, error
, 0);
448 KUNIT_EXPECT_PTR_EQ(test
, to_software_node(ref
.fwnode
), &node2
);
449 KUNIT_EXPECT_EQ(test
, ref
.nargs
, 1U);
450 KUNIT_EXPECT_EQ(test
, ref
.args
[0], 1LLU);
452 /* asking for more args, padded with zero data */
453 error
= fwnode_property_get_reference_args(node
, "ref-2", NULL
,
455 KUNIT_ASSERT_EQ(test
, error
, 0);
456 KUNIT_EXPECT_PTR_EQ(test
, to_software_node(ref
.fwnode
), &node2
);
457 KUNIT_EXPECT_EQ(test
, ref
.nargs
, 3U);
458 KUNIT_EXPECT_EQ(test
, ref
.args
[0], 1LLU);
459 KUNIT_EXPECT_EQ(test
, ref
.args
[1], 2LLU);
460 KUNIT_EXPECT_EQ(test
, ref
.args
[2], 0LLU);
463 error
= fwnode_property_get_reference_args(node
, "ref-2", NULL
,
465 KUNIT_EXPECT_NE(test
, error
, 0);
467 /* array of references */
468 error
= fwnode_property_get_reference_args(node
, "ref-3", NULL
,
470 KUNIT_ASSERT_EQ(test
, error
, 0);
471 KUNIT_EXPECT_PTR_EQ(test
, to_software_node(ref
.fwnode
), &node1
);
472 KUNIT_EXPECT_EQ(test
, ref
.nargs
, 0U);
474 /* second reference in the array */
475 error
= fwnode_property_get_reference_args(node
, "ref-3", NULL
,
477 KUNIT_ASSERT_EQ(test
, error
, 0);
478 KUNIT_EXPECT_PTR_EQ(test
, to_software_node(ref
.fwnode
), &node2
);
479 KUNIT_EXPECT_EQ(test
, ref
.nargs
, 2U);
480 KUNIT_EXPECT_EQ(test
, ref
.args
[0], 3LLU);
481 KUNIT_EXPECT_EQ(test
, ref
.args
[1], 4LLU);
484 error
= fwnode_property_get_reference_args(node
, "ref-1", NULL
,
486 KUNIT_EXPECT_NE(test
, error
, 0);
488 fwnode_remove_software_node(node
);
489 software_node_unregister_node_group(group
);
492 static struct kunit_case property_entry_test_cases
[] = {
493 KUNIT_CASE(pe_test_uints
),
494 KUNIT_CASE(pe_test_uint_arrays
),
495 KUNIT_CASE(pe_test_strings
),
496 KUNIT_CASE(pe_test_bool
),
497 KUNIT_CASE(pe_test_move_inline_u8
),
498 KUNIT_CASE(pe_test_move_inline_str
),
499 KUNIT_CASE(pe_test_reference
),
503 static struct kunit_suite property_entry_test_suite
= {
504 .name
= "property-entry",
505 .test_cases
= property_entry_test_cases
,
508 kunit_test_suite(property_entry_test_suite
);
510 MODULE_DESCRIPTION("Test module for the property entry API");
511 MODULE_AUTHOR("Dmitry Torokhov <dtor@chromium.org>");
512 MODULE_LICENSE("GPL");