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_count_u8(node, "prop-u8"); 31 KUNIT_EXPECT_EQ(test, error, 1); 32 33 error = fwnode_property_read_u8(node, "prop-u8", &val_u8); 34 KUNIT_EXPECT_EQ(test, error, 0); 35 KUNIT_EXPECT_EQ(test, (int)val_u8, 8); 36 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, (int)array_u8[0], 8); 40 41 error = fwnode_property_read_u8_array(node, "prop-u8", array_u8, 2); 42 KUNIT_EXPECT_NE(test, error, 0); 43 44 error = fwnode_property_read_u8(node, "no-prop-u8", &val_u8); 45 KUNIT_EXPECT_NE(test, error, 0); 46 47 error = fwnode_property_read_u8_array(node, "no-prop-u8", array_u8, 1); 48 KUNIT_EXPECT_NE(test, error, 0); 49 50 error = fwnode_property_read_u16(node, "prop-u16", &val_u16); 51 KUNIT_EXPECT_EQ(test, error, 0); 52 KUNIT_EXPECT_EQ(test, (int)val_u16, 16); 53 54 error = fwnode_property_count_u16(node, "prop-u16"); 55 KUNIT_EXPECT_EQ(test, error, 1); 56 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, (int)array_u16[0], 16); 60 61 error = fwnode_property_read_u16_array(node, "prop-u16", array_u16, 2); 62 KUNIT_EXPECT_NE(test, error, 0); 63 64 error = fwnode_property_read_u16(node, "no-prop-u16", &val_u16); 65 KUNIT_EXPECT_NE(test, error, 0); 66 67 error = fwnode_property_read_u16_array(node, "no-prop-u16", array_u16, 1); 68 KUNIT_EXPECT_NE(test, error, 0); 69 70 error = fwnode_property_read_u32(node, "prop-u32", &val_u32); 71 KUNIT_EXPECT_EQ(test, error, 0); 72 KUNIT_EXPECT_EQ(test, (int)val_u32, 32); 73 74 error = fwnode_property_count_u32(node, "prop-u32"); 75 KUNIT_EXPECT_EQ(test, error, 1); 76 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, (int)array_u32[0], 32); 80 81 error = fwnode_property_read_u32_array(node, "prop-u32", array_u32, 2); 82 KUNIT_EXPECT_NE(test, error, 0); 83 84 error = fwnode_property_read_u32(node, "no-prop-u32", &val_u32); 85 KUNIT_EXPECT_NE(test, error, 0); 86 87 error = fwnode_property_read_u32_array(node, "no-prop-u32", array_u32, 1); 88 KUNIT_EXPECT_NE(test, error, 0); 89 90 error = fwnode_property_read_u64(node, "prop-u64", &val_u64); 91 KUNIT_EXPECT_EQ(test, error, 0); 92 KUNIT_EXPECT_EQ(test, (int)val_u64, 64); 93 94 error = fwnode_property_count_u64(node, "prop-u64"); 95 KUNIT_EXPECT_EQ(test, error, 1); 96 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, (int)array_u64[0], 64); 100 101 error = fwnode_property_read_u64_array(node, "prop-u64", array_u64, 2); 102 KUNIT_EXPECT_NE(test, error, 0); 103 104 error = fwnode_property_read_u64(node, "no-prop-u64", &val_u64); 105 KUNIT_EXPECT_NE(test, error, 0); 106 107 error = fwnode_property_read_u64_array(node, "no-prop-u64", array_u64, 1); 108 KUNIT_EXPECT_NE(test, error, 0); 109 110 /* Count 64-bit values as 16-bit */ 111 error = fwnode_property_count_u16(node, "prop-u64"); 112 KUNIT_EXPECT_EQ(test, error, 4); 113 114 fwnode_remove_software_node(node); 115 } 116 117 static void pe_test_uint_arrays(struct kunit *test) 118 { 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), 128 { } 129 }; 130 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]; 136 int error; 137 138 node = fwnode_create_software_node(entries, NULL); 139 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node); 140 141 error = fwnode_property_read_u8(node, "prop-u8", &val_u8); 142 KUNIT_EXPECT_EQ(test, error, 0); 143 KUNIT_EXPECT_EQ(test, (int)val_u8, 8); 144 145 error = fwnode_property_count_u8(node, "prop-u8"); 146 KUNIT_EXPECT_EQ(test, error, 10); 147 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, (int)array_u8[0], 8); 151 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, (int)array_u8[0], 8); 155 KUNIT_EXPECT_EQ(test, (int)array_u8[1], 9); 156 157 error = fwnode_property_read_u8_array(node, "prop-u8", array_u8, 17); 158 KUNIT_EXPECT_NE(test, error, 0); 159 160 error = fwnode_property_read_u8(node, "no-prop-u8", &val_u8); 161 KUNIT_EXPECT_NE(test, error, 0); 162 163 error = fwnode_property_read_u8_array(node, "no-prop-u8", array_u8, 1); 164 KUNIT_EXPECT_NE(test, error, 0); 165 166 error = fwnode_property_read_u16(node, "prop-u16", &val_u16); 167 KUNIT_EXPECT_EQ(test, error, 0); 168 KUNIT_EXPECT_EQ(test, (int)val_u16, 16); 169 170 error = fwnode_property_count_u16(node, "prop-u16"); 171 KUNIT_EXPECT_EQ(test, error, 10); 172 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, (int)array_u16[0], 16); 176 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, (int)array_u16[0], 16); 180 KUNIT_EXPECT_EQ(test, (int)array_u16[1], 17); 181 182 error = fwnode_property_read_u16_array(node, "prop-u16", array_u16, 17); 183 KUNIT_EXPECT_NE(test, error, 0); 184 185 error = fwnode_property_read_u16(node, "no-prop-u16", &val_u16); 186 KUNIT_EXPECT_NE(test, error, 0); 187 188 error = fwnode_property_read_u16_array(node, "no-prop-u16", array_u16, 1); 189 KUNIT_EXPECT_NE(test, error, 0); 190 191 error = fwnode_property_read_u32(node, "prop-u32", &val_u32); 192 KUNIT_EXPECT_EQ(test, error, 0); 193 KUNIT_EXPECT_EQ(test, (int)val_u32, 32); 194 195 error = fwnode_property_count_u32(node, "prop-u32"); 196 KUNIT_EXPECT_EQ(test, error, 10); 197 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, (int)array_u32[0], 32); 201 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, (int)array_u32[0], 32); 205 KUNIT_EXPECT_EQ(test, (int)array_u32[1], 33); 206 207 error = fwnode_property_read_u32_array(node, "prop-u32", array_u32, 17); 208 KUNIT_EXPECT_NE(test, error, 0); 209 210 error = fwnode_property_read_u32(node, "no-prop-u32", &val_u32); 211 KUNIT_EXPECT_NE(test, error, 0); 212 213 error = fwnode_property_read_u32_array(node, "no-prop-u32", array_u32, 1); 214 KUNIT_EXPECT_NE(test, error, 0); 215 216 error = fwnode_property_read_u64(node, "prop-u64", &val_u64); 217 KUNIT_EXPECT_EQ(test, error, 0); 218 KUNIT_EXPECT_EQ(test, (int)val_u64, 64); 219 220 error = fwnode_property_count_u64(node, "prop-u64"); 221 KUNIT_EXPECT_EQ(test, error, 10); 222 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, (int)array_u64[0], 64); 226 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, (int)array_u64[0], 64); 230 KUNIT_EXPECT_EQ(test, (int)array_u64[1], 65); 231 232 error = fwnode_property_read_u64_array(node, "prop-u64", array_u64, 17); 233 KUNIT_EXPECT_NE(test, error, 0); 234 235 error = fwnode_property_read_u64(node, "no-prop-u64", &val_u64); 236 KUNIT_EXPECT_NE(test, error, 0); 237 238 error = fwnode_property_read_u64_array(node, "no-prop-u64", array_u64, 1); 239 KUNIT_EXPECT_NE(test, error, 0); 240 241 /* Count 64-bit values as 16-bit */ 242 error = fwnode_property_count_u16(node, "prop-u64"); 243 KUNIT_EXPECT_EQ(test, error, 40); 244 245 /* Other way around */ 246 error = fwnode_property_count_u64(node, "prop-u16"); 247 KUNIT_EXPECT_EQ(test, error, 2); 248 249 fwnode_remove_software_node(node); 250 } 251 252 static void pe_test_strings(struct kunit *test) 253 { 254 static const char *strings[] = { 255 "string-a", 256 "string-b", 257 }; 258 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), 263 { } 264 }; 265 266 struct fwnode_handle *node; 267 const char *str; 268 const char *strs[10]; 269 int error; 270 271 node = fwnode_create_software_node(entries, NULL); 272 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node); 273 274 error = fwnode_property_read_string(node, "str", &str); 275 KUNIT_EXPECT_EQ(test, error, 0); 276 KUNIT_EXPECT_STREQ(test, str, "single"); 277 278 error = fwnode_property_string_array_count(node, "str"); 279 KUNIT_EXPECT_EQ(test, error, 1); 280 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"); 284 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"); 289 290 error = fwnode_property_read_string(node, "no-str", &str); 291 KUNIT_EXPECT_NE(test, error, 0); 292 293 error = fwnode_property_read_string_array(node, "no-str", strs, 1); 294 KUNIT_EXPECT_LT(test, error, 0); 295 296 error = fwnode_property_read_string(node, "empty", &str); 297 KUNIT_EXPECT_EQ(test, error, 0); 298 KUNIT_EXPECT_STREQ(test, str, ""); 299 300 error = fwnode_property_string_array_count(node, "strs"); 301 KUNIT_EXPECT_EQ(test, error, 2); 302 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"); 307 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"); 311 312 /* NULL argument -> returns size */ 313 error = fwnode_property_read_string_array(node, "strs", NULL, 0); 314 KUNIT_EXPECT_EQ(test, error, 2); 315 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"); 320 321 fwnode_remove_software_node(node); 322 } 323 324 static void pe_test_bool(struct kunit *test) 325 { 326 static const struct property_entry entries[] = { 327 PROPERTY_ENTRY_BOOL("prop"), 328 { } 329 }; 330 331 struct fwnode_handle *node; 332 333 node = fwnode_create_software_node(entries, NULL); 334 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node); 335 336 KUNIT_EXPECT_TRUE(test, fwnode_property_read_bool(node, "prop")); 337 KUNIT_EXPECT_FALSE(test, fwnode_property_read_bool(node, "not-prop")); 338 339 fwnode_remove_software_node(node); 340 } 341 342 /* Verifies that small U8 array is stored inline when property is copied */ 343 static void pe_test_move_inline_u8(struct kunit *test) 344 { 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), 350 { } 351 }; 352 353 struct property_entry *copy; 354 const u8 *data_ptr; 355 356 copy = property_entries_dup(entries); 357 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, copy); 358 359 KUNIT_EXPECT_TRUE(test, copy[0].is_inline); 360 data_ptr = (u8 *)©[0].value; 361 KUNIT_EXPECT_EQ(test, (int)data_ptr[0], 1); 362 KUNIT_EXPECT_EQ(test, (int)data_ptr[1], 2); 363 364 KUNIT_EXPECT_FALSE(test, copy[1].is_inline); 365 data_ptr = copy[1].pointer; 366 KUNIT_EXPECT_EQ(test, (int)data_ptr[0], 5); 367 KUNIT_EXPECT_EQ(test, (int)data_ptr[1], 6); 368 369 property_entries_free(copy); 370 } 371 372 /* Verifies that single string array is stored inline when property is copied */ 373 static void pe_test_move_inline_str(struct kunit *test) 374 { 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), 382 { } 383 }; 384 385 struct property_entry *copy; 386 const char * const *data_ptr; 387 388 copy = property_entries_dup(entries); 389 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, copy); 390 391 KUNIT_EXPECT_TRUE(test, copy[0].is_inline); 392 KUNIT_EXPECT_STREQ(test, copy[0].value.str[0], "a"); 393 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"); 398 399 KUNIT_EXPECT_TRUE(test, copy[2].is_inline); 400 KUNIT_EXPECT_STREQ(test, copy[2].value.str[0], ""); 401 402 property_entries_free(copy); 403 } 404 405 /* Handling of reference properties */ 406 static void pe_test_reference(struct kunit *test) 407 { 408 static const struct software_node nodes[] = { 409 { .name = "1", }, 410 { .name = "2", }, 411 { } 412 }; 413 414 static const struct software_node_ref_args refs[] = { 415 SOFTWARE_NODE_REFERENCE(&nodes[0]), 416 SOFTWARE_NODE_REFERENCE(&nodes[1], 3, 4), 417 }; 418 419 const struct property_entry entries[] = { 420 PROPERTY_ENTRY_REF("ref-1", &nodes[0]), 421 PROPERTY_ENTRY_REF("ref-2", &nodes[1], 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_nodes(nodes); 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), &nodes[0]); 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), &nodes[1]); 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), &nodes[1]); 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), &nodes[0]); 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), &nodes[1]); 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_nodes(nodes); 492 } 493 494 static struct kunit_case property_entry_test_cases[] = { 495 KUNIT_CASE(pe_test_uints), 496 KUNIT_CASE(pe_test_uint_arrays), 497 KUNIT_CASE(pe_test_strings), 498 KUNIT_CASE(pe_test_bool), 499 KUNIT_CASE(pe_test_move_inline_u8), 500 KUNIT_CASE(pe_test_move_inline_str), 501 KUNIT_CASE(pe_test_reference), 502 { } 503 }; 504 505 static struct kunit_suite property_entry_test_suite = { 506 .name = "property-entry", 507 .test_cases = property_entry_test_cases, 508 }; 509 510 kunit_test_suite(property_entry_test_suite); 511