Merge tag 'for-linus' of git://github.com/openrisc/linux
[linux-2.6-microblaze.git] / drivers / base / test / property-entry-test.c
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 #include <linux/property.h>
8 #include <linux/types.h>
9
10 static void pe_test_uints(struct kunit *test)
11 {
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),
17                 { }
18         };
19
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];
25         int error;
26
27         node = fwnode_create_software_node(entries, NULL);
28         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node);
29
30         error = fwnode_property_read_u8(node, "prop-u8", &val_u8);
31         KUNIT_EXPECT_EQ(test, error, 0);
32         KUNIT_EXPECT_EQ(test, (int)val_u8, 8);
33
34         error = fwnode_property_read_u8_array(node, "prop-u8", array_u8, 1);
35         KUNIT_EXPECT_EQ(test, error, 0);
36         KUNIT_EXPECT_EQ(test, (int)array_u8[0], 8);
37
38         error = fwnode_property_read_u8_array(node, "prop-u8", array_u8, 2);
39         KUNIT_EXPECT_NE(test, error, 0);
40
41         error = fwnode_property_read_u8(node, "no-prop-u8", &val_u8);
42         KUNIT_EXPECT_NE(test, error, 0);
43
44         error = fwnode_property_read_u8_array(node, "no-prop-u8", array_u8, 1);
45         KUNIT_EXPECT_NE(test, error, 0);
46
47         error = fwnode_property_read_u16(node, "prop-u16", &val_u16);
48         KUNIT_EXPECT_EQ(test, error, 0);
49         KUNIT_EXPECT_EQ(test, (int)val_u16, 16);
50
51         error = fwnode_property_read_u16_array(node, "prop-u16", array_u16, 1);
52         KUNIT_EXPECT_EQ(test, error, 0);
53         KUNIT_EXPECT_EQ(test, (int)array_u16[0], 16);
54
55         error = fwnode_property_read_u16_array(node, "prop-u16", array_u16, 2);
56         KUNIT_EXPECT_NE(test, error, 0);
57
58         error = fwnode_property_read_u16(node, "no-prop-u16", &val_u16);
59         KUNIT_EXPECT_NE(test, error, 0);
60
61         error = fwnode_property_read_u16_array(node, "no-prop-u16", array_u16, 1);
62         KUNIT_EXPECT_NE(test, error, 0);
63
64         error = fwnode_property_read_u32(node, "prop-u32", &val_u32);
65         KUNIT_EXPECT_EQ(test, error, 0);
66         KUNIT_EXPECT_EQ(test, (int)val_u32, 32);
67
68         error = fwnode_property_read_u32_array(node, "prop-u32", array_u32, 1);
69         KUNIT_EXPECT_EQ(test, error, 0);
70         KUNIT_EXPECT_EQ(test, (int)array_u32[0], 32);
71
72         error = fwnode_property_read_u32_array(node, "prop-u32", array_u32, 2);
73         KUNIT_EXPECT_NE(test, error, 0);
74
75         error = fwnode_property_read_u32(node, "no-prop-u32", &val_u32);
76         KUNIT_EXPECT_NE(test, error, 0);
77
78         error = fwnode_property_read_u32_array(node, "no-prop-u32", array_u32, 1);
79         KUNIT_EXPECT_NE(test, error, 0);
80
81         error = fwnode_property_read_u64(node, "prop-u64", &val_u64);
82         KUNIT_EXPECT_EQ(test, error, 0);
83         KUNIT_EXPECT_EQ(test, (int)val_u64, 64);
84
85         error = fwnode_property_read_u64_array(node, "prop-u64", array_u64, 1);
86         KUNIT_EXPECT_EQ(test, error, 0);
87         KUNIT_EXPECT_EQ(test, (int)array_u64[0], 64);
88
89         error = fwnode_property_read_u64_array(node, "prop-u64", array_u64, 2);
90         KUNIT_EXPECT_NE(test, error, 0);
91
92         error = fwnode_property_read_u64(node, "no-prop-u64", &val_u64);
93         KUNIT_EXPECT_NE(test, error, 0);
94
95         error = fwnode_property_read_u64_array(node, "no-prop-u64", array_u64, 1);
96         KUNIT_EXPECT_NE(test, error, 0);
97
98         fwnode_remove_software_node(node);
99 }
100
101 static void pe_test_uint_arrays(struct kunit *test)
102 {
103         static const u8 a_u8[16] = { 8, 9 };
104         static const u16 a_u16[16] = { 16, 17 };
105         static const u32 a_u32[16] = { 32, 33 };
106         static const u64 a_u64[16] = { 64, 65 };
107         static const struct property_entry entries[] = {
108                 PROPERTY_ENTRY_U8_ARRAY("prop-u8", a_u8),
109                 PROPERTY_ENTRY_U16_ARRAY("prop-u16", a_u16),
110                 PROPERTY_ENTRY_U32_ARRAY("prop-u32", a_u32),
111                 PROPERTY_ENTRY_U64_ARRAY("prop-u64", a_u64),
112                 { }
113         };
114
115         struct fwnode_handle *node;
116         u8 val_u8, array_u8[32];
117         u16 val_u16, array_u16[32];
118         u32 val_u32, array_u32[32];
119         u64 val_u64, array_u64[32];
120         int error;
121
122         node = fwnode_create_software_node(entries, NULL);
123         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node);
124
125         error = fwnode_property_read_u8(node, "prop-u8", &val_u8);
126         KUNIT_EXPECT_EQ(test, error, 0);
127         KUNIT_EXPECT_EQ(test, (int)val_u8, 8);
128
129         error = fwnode_property_read_u8_array(node, "prop-u8", array_u8, 1);
130         KUNIT_EXPECT_EQ(test, error, 0);
131         KUNIT_EXPECT_EQ(test, (int)array_u8[0], 8);
132
133         error = fwnode_property_read_u8_array(node, "prop-u8", array_u8, 2);
134         KUNIT_EXPECT_EQ(test, error, 0);
135         KUNIT_EXPECT_EQ(test, (int)array_u8[0], 8);
136         KUNIT_EXPECT_EQ(test, (int)array_u8[1], 9);
137
138         error = fwnode_property_read_u8_array(node, "prop-u8", array_u8, 17);
139         KUNIT_EXPECT_NE(test, error, 0);
140
141         error = fwnode_property_read_u8(node, "no-prop-u8", &val_u8);
142         KUNIT_EXPECT_NE(test, error, 0);
143
144         error = fwnode_property_read_u8_array(node, "no-prop-u8", array_u8, 1);
145         KUNIT_EXPECT_NE(test, error, 0);
146
147         error = fwnode_property_read_u16(node, "prop-u16", &val_u16);
148         KUNIT_EXPECT_EQ(test, error, 0);
149         KUNIT_EXPECT_EQ(test, (int)val_u16, 16);
150
151         error = fwnode_property_read_u16_array(node, "prop-u16", array_u16, 1);
152         KUNIT_EXPECT_EQ(test, error, 0);
153         KUNIT_EXPECT_EQ(test, (int)array_u16[0], 16);
154
155         error = fwnode_property_read_u16_array(node, "prop-u16", array_u16, 2);
156         KUNIT_EXPECT_EQ(test, error, 0);
157         KUNIT_EXPECT_EQ(test, (int)array_u16[0], 16);
158         KUNIT_EXPECT_EQ(test, (int)array_u16[1], 17);
159
160         error = fwnode_property_read_u16_array(node, "prop-u16", array_u16, 17);
161         KUNIT_EXPECT_NE(test, error, 0);
162
163         error = fwnode_property_read_u16(node, "no-prop-u16", &val_u16);
164         KUNIT_EXPECT_NE(test, error, 0);
165
166         error = fwnode_property_read_u16_array(node, "no-prop-u16", array_u16, 1);
167         KUNIT_EXPECT_NE(test, error, 0);
168
169         error = fwnode_property_read_u32(node, "prop-u32", &val_u32);
170         KUNIT_EXPECT_EQ(test, error, 0);
171         KUNIT_EXPECT_EQ(test, (int)val_u32, 32);
172
173         error = fwnode_property_read_u32_array(node, "prop-u32", array_u32, 1);
174         KUNIT_EXPECT_EQ(test, error, 0);
175         KUNIT_EXPECT_EQ(test, (int)array_u32[0], 32);
176
177         error = fwnode_property_read_u32_array(node, "prop-u32", array_u32, 2);
178         KUNIT_EXPECT_EQ(test, error, 0);
179         KUNIT_EXPECT_EQ(test, (int)array_u32[0], 32);
180         KUNIT_EXPECT_EQ(test, (int)array_u32[1], 33);
181
182         error = fwnode_property_read_u32_array(node, "prop-u32", array_u32, 17);
183         KUNIT_EXPECT_NE(test, error, 0);
184
185         error = fwnode_property_read_u32(node, "no-prop-u32", &val_u32);
186         KUNIT_EXPECT_NE(test, error, 0);
187
188         error = fwnode_property_read_u32_array(node, "no-prop-u32", array_u32, 1);
189         KUNIT_EXPECT_NE(test, error, 0);
190
191         error = fwnode_property_read_u64(node, "prop-u64", &val_u64);
192         KUNIT_EXPECT_EQ(test, error, 0);
193         KUNIT_EXPECT_EQ(test, (int)val_u64, 64);
194
195         error = fwnode_property_read_u64_array(node, "prop-u64", array_u64, 1);
196         KUNIT_EXPECT_EQ(test, error, 0);
197         KUNIT_EXPECT_EQ(test, (int)array_u64[0], 64);
198
199         error = fwnode_property_read_u64_array(node, "prop-u64", array_u64, 2);
200         KUNIT_EXPECT_EQ(test, error, 0);
201         KUNIT_EXPECT_EQ(test, (int)array_u64[0], 64);
202         KUNIT_EXPECT_EQ(test, (int)array_u64[1], 65);
203
204         error = fwnode_property_read_u64_array(node, "prop-u64", array_u64, 17);
205         KUNIT_EXPECT_NE(test, error, 0);
206
207         error = fwnode_property_read_u64(node, "no-prop-u64", &val_u64);
208         KUNIT_EXPECT_NE(test, error, 0);
209
210         error = fwnode_property_read_u64_array(node, "no-prop-u64", array_u64, 1);
211         KUNIT_EXPECT_NE(test, error, 0);
212
213         fwnode_remove_software_node(node);
214 }
215
216 static void pe_test_strings(struct kunit *test)
217 {
218         static const char *strings[] = {
219                 "string-a",
220                 "string-b",
221         };
222
223         static const struct property_entry entries[] = {
224                 PROPERTY_ENTRY_STRING("str", "single"),
225                 PROPERTY_ENTRY_STRING("empty", ""),
226                 PROPERTY_ENTRY_STRING_ARRAY("strs", strings),
227                 { }
228         };
229
230         struct fwnode_handle *node;
231         const char *str;
232         const char *strs[10];
233         int error;
234
235         node = fwnode_create_software_node(entries, NULL);
236         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node);
237
238         error = fwnode_property_read_string(node, "str", &str);
239         KUNIT_EXPECT_EQ(test, error, 0);
240         KUNIT_EXPECT_STREQ(test, str, "single");
241
242         error = fwnode_property_read_string_array(node, "str", strs, 1);
243         KUNIT_EXPECT_EQ(test, error, 1);
244         KUNIT_EXPECT_STREQ(test, strs[0], "single");
245
246         /* asking for more data returns what we have */
247         error = fwnode_property_read_string_array(node, "str", strs, 2);
248         KUNIT_EXPECT_EQ(test, error, 1);
249         KUNIT_EXPECT_STREQ(test, strs[0], "single");
250
251         error = fwnode_property_read_string(node, "no-str", &str);
252         KUNIT_EXPECT_NE(test, error, 0);
253
254         error = fwnode_property_read_string_array(node, "no-str", strs, 1);
255         KUNIT_EXPECT_LT(test, error, 0);
256
257         error = fwnode_property_read_string(node, "empty", &str);
258         KUNIT_EXPECT_EQ(test, error, 0);
259         KUNIT_EXPECT_STREQ(test, str, "");
260
261         error = fwnode_property_read_string_array(node, "strs", strs, 3);
262         KUNIT_EXPECT_EQ(test, error, 2);
263         KUNIT_EXPECT_STREQ(test, strs[0], "string-a");
264         KUNIT_EXPECT_STREQ(test, strs[1], "string-b");
265
266         error = fwnode_property_read_string_array(node, "strs", strs, 1);
267         KUNIT_EXPECT_EQ(test, error, 1);
268         KUNIT_EXPECT_STREQ(test, strs[0], "string-a");
269
270         /* NULL argument -> returns size */
271         error = fwnode_property_read_string_array(node, "strs", NULL, 0);
272         KUNIT_EXPECT_EQ(test, error, 2);
273
274         /* accessing array as single value */
275         error = fwnode_property_read_string(node, "strs", &str);
276         KUNIT_EXPECT_EQ(test, error, 0);
277         KUNIT_EXPECT_STREQ(test, str, "string-a");
278
279         fwnode_remove_software_node(node);
280 }
281
282 static void pe_test_bool(struct kunit *test)
283 {
284         static const struct property_entry entries[] = {
285                 PROPERTY_ENTRY_BOOL("prop"),
286                 { }
287         };
288
289         struct fwnode_handle *node;
290
291         node = fwnode_create_software_node(entries, NULL);
292         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node);
293
294         KUNIT_EXPECT_TRUE(test, fwnode_property_read_bool(node, "prop"));
295         KUNIT_EXPECT_FALSE(test, fwnode_property_read_bool(node, "not-prop"));
296
297         fwnode_remove_software_node(node);
298 }
299
300 /* Verifies that small U8 array is stored inline when property is copied */
301 static void pe_test_move_inline_u8(struct kunit *test)
302 {
303         static const u8 u8_array_small[8] = { 1, 2, 3, 4 };
304         static const u8 u8_array_big[128] = { 5, 6, 7, 8 };
305         static const struct property_entry entries[] = {
306                 PROPERTY_ENTRY_U8_ARRAY("small", u8_array_small),
307                 PROPERTY_ENTRY_U8_ARRAY("big", u8_array_big),
308                 { }
309         };
310
311         struct property_entry *copy;
312         const u8 *data_ptr;
313
314         copy = property_entries_dup(entries);
315         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, copy);
316
317         KUNIT_EXPECT_TRUE(test, copy[0].is_inline);
318         data_ptr = (u8 *)&copy[0].value;
319         KUNIT_EXPECT_EQ(test, (int)data_ptr[0], 1);
320         KUNIT_EXPECT_EQ(test, (int)data_ptr[1], 2);
321
322         KUNIT_EXPECT_FALSE(test, copy[1].is_inline);
323         data_ptr = copy[1].pointer;
324         KUNIT_EXPECT_EQ(test, (int)data_ptr[0], 5);
325         KUNIT_EXPECT_EQ(test, (int)data_ptr[1], 6);
326
327         property_entries_free(copy);
328 }
329
330 /* Verifies that single string array is stored inline when property is copied */
331 static void pe_test_move_inline_str(struct kunit *test)
332 {
333         static char *str_array_small[] = { "a" };
334         static char *str_array_big[] = { "b", "c", "d", "e" };
335         static char *str_array_small_empty[] = { "" };
336         static struct property_entry entries[] = {
337                 PROPERTY_ENTRY_STRING_ARRAY("small", str_array_small),
338                 PROPERTY_ENTRY_STRING_ARRAY("big", str_array_big),
339                 PROPERTY_ENTRY_STRING_ARRAY("small-empty", str_array_small_empty),
340                 { }
341         };
342
343         struct property_entry *copy;
344         const char * const *data_ptr;
345
346         copy = property_entries_dup(entries);
347         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, copy);
348
349         KUNIT_EXPECT_TRUE(test, copy[0].is_inline);
350         KUNIT_EXPECT_STREQ(test, copy[0].value.str[0], "a");
351
352         KUNIT_EXPECT_FALSE(test, copy[1].is_inline);
353         data_ptr = copy[1].pointer;
354         KUNIT_EXPECT_STREQ(test, data_ptr[0], "b");
355         KUNIT_EXPECT_STREQ(test, data_ptr[1], "c");
356
357         KUNIT_EXPECT_TRUE(test, copy[2].is_inline);
358         KUNIT_EXPECT_STREQ(test, copy[2].value.str[0], "");
359
360         property_entries_free(copy);
361 }
362
363 /* Handling of reference properties */
364 static void pe_test_reference(struct kunit *test)
365 {
366         static const struct software_node nodes[] = {
367                 { .name = "1", },
368                 { .name = "2", },
369                 { }
370         };
371
372         static const struct software_node_ref_args refs[] = {
373                 {
374                         .node = &nodes[0],
375                         .nargs = 0,
376                 },
377                 {
378                         .node = &nodes[1],
379                         .nargs = 2,
380                         .args = { 3, 4 },
381                 },
382         };
383
384         const struct property_entry entries[] = {
385                 PROPERTY_ENTRY_REF("ref-1", &nodes[0]),
386                 PROPERTY_ENTRY_REF("ref-2", &nodes[1], 1, 2),
387                 PROPERTY_ENTRY_REF_ARRAY("ref-3", refs),
388                 { }
389         };
390
391         struct fwnode_handle *node;
392         struct fwnode_reference_args ref;
393         int error;
394
395         error = software_node_register_nodes(nodes);
396         KUNIT_ASSERT_EQ(test, error, 0);
397
398         node = fwnode_create_software_node(entries, NULL);
399         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node);
400
401         error = fwnode_property_get_reference_args(node, "ref-1", NULL,
402                                                    0, 0, &ref);
403         KUNIT_ASSERT_EQ(test, error, 0);
404         KUNIT_EXPECT_PTR_EQ(test, to_software_node(ref.fwnode), &nodes[0]);
405         KUNIT_EXPECT_EQ(test, ref.nargs, 0U);
406
407         /* wrong index */
408         error = fwnode_property_get_reference_args(node, "ref-1", NULL,
409                                                    0, 1, &ref);
410         KUNIT_EXPECT_NE(test, error, 0);
411
412         error = fwnode_property_get_reference_args(node, "ref-2", NULL,
413                                                    1, 0, &ref);
414         KUNIT_ASSERT_EQ(test, error, 0);
415         KUNIT_EXPECT_PTR_EQ(test, to_software_node(ref.fwnode), &nodes[1]);
416         KUNIT_EXPECT_EQ(test, ref.nargs, 1U);
417         KUNIT_EXPECT_EQ(test, ref.args[0], 1LLU);
418
419         /* asking for more args, padded with zero data */
420         error = fwnode_property_get_reference_args(node, "ref-2", NULL,
421                                                    3, 0, &ref);
422         KUNIT_ASSERT_EQ(test, error, 0);
423         KUNIT_EXPECT_PTR_EQ(test, to_software_node(ref.fwnode), &nodes[1]);
424         KUNIT_EXPECT_EQ(test, ref.nargs, 3U);
425         KUNIT_EXPECT_EQ(test, ref.args[0], 1LLU);
426         KUNIT_EXPECT_EQ(test, ref.args[1], 2LLU);
427         KUNIT_EXPECT_EQ(test, ref.args[2], 0LLU);
428
429         /* wrong index */
430         error = fwnode_property_get_reference_args(node, "ref-2", NULL,
431                                                    2, 1, &ref);
432         KUNIT_EXPECT_NE(test, error, 0);
433
434         /* array of references */
435         error = fwnode_property_get_reference_args(node, "ref-3", NULL,
436                                                    0, 0, &ref);
437         KUNIT_ASSERT_EQ(test, error, 0);
438         KUNIT_EXPECT_PTR_EQ(test, to_software_node(ref.fwnode), &nodes[0]);
439         KUNIT_EXPECT_EQ(test, ref.nargs, 0U);
440
441         /* second reference in the array */
442         error = fwnode_property_get_reference_args(node, "ref-3", NULL,
443                                                    2, 1, &ref);
444         KUNIT_ASSERT_EQ(test, error, 0);
445         KUNIT_EXPECT_PTR_EQ(test, to_software_node(ref.fwnode), &nodes[1]);
446         KUNIT_EXPECT_EQ(test, ref.nargs, 2U);
447         KUNIT_EXPECT_EQ(test, ref.args[0], 3LLU);
448         KUNIT_EXPECT_EQ(test, ref.args[1], 4LLU);
449
450         /* wrong index */
451         error = fwnode_property_get_reference_args(node, "ref-1", NULL,
452                                                    0, 2, &ref);
453         KUNIT_EXPECT_NE(test, error, 0);
454
455         fwnode_remove_software_node(node);
456         software_node_unregister_nodes(nodes);
457 }
458
459 static struct kunit_case property_entry_test_cases[] = {
460         KUNIT_CASE(pe_test_uints),
461         KUNIT_CASE(pe_test_uint_arrays),
462         KUNIT_CASE(pe_test_strings),
463         KUNIT_CASE(pe_test_bool),
464         KUNIT_CASE(pe_test_move_inline_u8),
465         KUNIT_CASE(pe_test_move_inline_str),
466         KUNIT_CASE(pe_test_reference),
467         { }
468 };
469
470 static struct kunit_suite property_entry_test_suite = {
471         .name = "property-entry",
472         .test_cases = property_entry_test_cases,
473 };
474
475 kunit_test_suite(property_entry_test_suite);