Path: blob/master/drivers/base/test/property-entry-test.c
26428 views
// SPDX-License-Identifier: GPL-2.01// Unit tests for property entries API2//3// Copyright 2019 Google LLC.45#include <kunit/test.h>6#include <linux/property.h>7#include <linux/types.h>89static void pe_test_uints(struct kunit *test)10{11static const struct property_entry entries[] = {12PROPERTY_ENTRY_U8("prop-u8", 8),13PROPERTY_ENTRY_U16("prop-u16", 16),14PROPERTY_ENTRY_U32("prop-u32", 32),15PROPERTY_ENTRY_U64("prop-u64", 64),16{ }17};1819struct fwnode_handle *node;20u8 val_u8, array_u8[2];21u16 val_u16, array_u16[2];22u32 val_u32, array_u32[2];23u64 val_u64, array_u64[2];24int error;2526node = fwnode_create_software_node(entries, NULL);27KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node);2829error = fwnode_property_count_u8(node, "prop-u8");30KUNIT_EXPECT_EQ(test, error, 1);3132error = fwnode_property_read_u8(node, "prop-u8", &val_u8);33KUNIT_EXPECT_EQ(test, error, 0);34KUNIT_EXPECT_EQ(test, val_u8, 8);3536error = fwnode_property_read_u8_array(node, "prop-u8", array_u8, 1);37KUNIT_EXPECT_EQ(test, error, 0);38KUNIT_EXPECT_EQ(test, array_u8[0], 8);3940error = fwnode_property_read_u8_array(node, "prop-u8", array_u8, 2);41KUNIT_EXPECT_NE(test, error, 0);4243error = fwnode_property_read_u8(node, "no-prop-u8", &val_u8);44KUNIT_EXPECT_NE(test, error, 0);4546error = fwnode_property_read_u8_array(node, "no-prop-u8", array_u8, 1);47KUNIT_EXPECT_NE(test, error, 0);4849error = fwnode_property_read_u16(node, "prop-u16", &val_u16);50KUNIT_EXPECT_EQ(test, error, 0);51KUNIT_EXPECT_EQ(test, val_u16, 16);5253error = fwnode_property_count_u16(node, "prop-u16");54KUNIT_EXPECT_EQ(test, error, 1);5556error = fwnode_property_read_u16_array(node, "prop-u16", array_u16, 1);57KUNIT_EXPECT_EQ(test, error, 0);58KUNIT_EXPECT_EQ(test, array_u16[0], 16);5960error = fwnode_property_read_u16_array(node, "prop-u16", array_u16, 2);61KUNIT_EXPECT_NE(test, error, 0);6263error = fwnode_property_read_u16(node, "no-prop-u16", &val_u16);64KUNIT_EXPECT_NE(test, error, 0);6566error = fwnode_property_read_u16_array(node, "no-prop-u16", array_u16, 1);67KUNIT_EXPECT_NE(test, error, 0);6869error = fwnode_property_read_u32(node, "prop-u32", &val_u32);70KUNIT_EXPECT_EQ(test, error, 0);71KUNIT_EXPECT_EQ(test, val_u32, 32);7273error = fwnode_property_count_u32(node, "prop-u32");74KUNIT_EXPECT_EQ(test, error, 1);7576error = fwnode_property_read_u32_array(node, "prop-u32", array_u32, 1);77KUNIT_EXPECT_EQ(test, error, 0);78KUNIT_EXPECT_EQ(test, array_u32[0], 32);7980error = fwnode_property_read_u32_array(node, "prop-u32", array_u32, 2);81KUNIT_EXPECT_NE(test, error, 0);8283error = fwnode_property_read_u32(node, "no-prop-u32", &val_u32);84KUNIT_EXPECT_NE(test, error, 0);8586error = fwnode_property_read_u32_array(node, "no-prop-u32", array_u32, 1);87KUNIT_EXPECT_NE(test, error, 0);8889error = fwnode_property_read_u64(node, "prop-u64", &val_u64);90KUNIT_EXPECT_EQ(test, error, 0);91KUNIT_EXPECT_EQ(test, val_u64, 64);9293error = fwnode_property_count_u64(node, "prop-u64");94KUNIT_EXPECT_EQ(test, error, 1);9596error = fwnode_property_read_u64_array(node, "prop-u64", array_u64, 1);97KUNIT_EXPECT_EQ(test, error, 0);98KUNIT_EXPECT_EQ(test, array_u64[0], 64);99100error = fwnode_property_read_u64_array(node, "prop-u64", array_u64, 2);101KUNIT_EXPECT_NE(test, error, 0);102103error = fwnode_property_read_u64(node, "no-prop-u64", &val_u64);104KUNIT_EXPECT_NE(test, error, 0);105106error = fwnode_property_read_u64_array(node, "no-prop-u64", array_u64, 1);107KUNIT_EXPECT_NE(test, error, 0);108109/* Count 64-bit values as 16-bit */110error = fwnode_property_count_u16(node, "prop-u64");111KUNIT_EXPECT_EQ(test, error, 4);112113fwnode_remove_software_node(node);114}115116static void pe_test_uint_arrays(struct kunit *test)117{118static const u8 a_u8[10] = { 8, 9 };119static const u16 a_u16[10] = { 16, 17 };120static const u32 a_u32[10] = { 32, 33 };121static const u64 a_u64[10] = { 64, 65 };122static const struct property_entry entries[] = {123PROPERTY_ENTRY_U8_ARRAY("prop-u8", a_u8),124PROPERTY_ENTRY_U16_ARRAY("prop-u16", a_u16),125PROPERTY_ENTRY_U32_ARRAY("prop-u32", a_u32),126PROPERTY_ENTRY_U64_ARRAY("prop-u64", a_u64),127{ }128};129130struct fwnode_handle *node;131u8 val_u8, array_u8[32];132u16 val_u16, array_u16[32];133u32 val_u32, array_u32[32];134u64 val_u64, array_u64[32];135int error;136137node = fwnode_create_software_node(entries, NULL);138KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node);139140error = fwnode_property_read_u8(node, "prop-u8", &val_u8);141KUNIT_EXPECT_EQ(test, error, 0);142KUNIT_EXPECT_EQ(test, val_u8, 8);143144error = fwnode_property_count_u8(node, "prop-u8");145KUNIT_EXPECT_EQ(test, error, 10);146147error = fwnode_property_read_u8_array(node, "prop-u8", array_u8, 1);148KUNIT_EXPECT_EQ(test, error, 0);149KUNIT_EXPECT_EQ(test, array_u8[0], 8);150151error = fwnode_property_read_u8_array(node, "prop-u8", array_u8, 2);152KUNIT_EXPECT_EQ(test, error, 0);153KUNIT_EXPECT_EQ(test, array_u8[0], 8);154KUNIT_EXPECT_EQ(test, array_u8[1], 9);155156error = fwnode_property_read_u8_array(node, "prop-u8", array_u8, 17);157KUNIT_EXPECT_NE(test, error, 0);158159error = fwnode_property_read_u8(node, "no-prop-u8", &val_u8);160KUNIT_EXPECT_NE(test, error, 0);161162error = fwnode_property_read_u8_array(node, "no-prop-u8", array_u8, 1);163KUNIT_EXPECT_NE(test, error, 0);164165error = fwnode_property_read_u16(node, "prop-u16", &val_u16);166KUNIT_EXPECT_EQ(test, error, 0);167KUNIT_EXPECT_EQ(test, val_u16, 16);168169error = fwnode_property_count_u16(node, "prop-u16");170KUNIT_EXPECT_EQ(test, error, 10);171172error = fwnode_property_read_u16_array(node, "prop-u16", array_u16, 1);173KUNIT_EXPECT_EQ(test, error, 0);174KUNIT_EXPECT_EQ(test, array_u16[0], 16);175176error = fwnode_property_read_u16_array(node, "prop-u16", array_u16, 2);177KUNIT_EXPECT_EQ(test, error, 0);178KUNIT_EXPECT_EQ(test, array_u16[0], 16);179KUNIT_EXPECT_EQ(test, array_u16[1], 17);180181error = fwnode_property_read_u16_array(node, "prop-u16", array_u16, 17);182KUNIT_EXPECT_NE(test, error, 0);183184error = fwnode_property_read_u16(node, "no-prop-u16", &val_u16);185KUNIT_EXPECT_NE(test, error, 0);186187error = fwnode_property_read_u16_array(node, "no-prop-u16", array_u16, 1);188KUNIT_EXPECT_NE(test, error, 0);189190error = fwnode_property_read_u32(node, "prop-u32", &val_u32);191KUNIT_EXPECT_EQ(test, error, 0);192KUNIT_EXPECT_EQ(test, val_u32, 32);193194error = fwnode_property_count_u32(node, "prop-u32");195KUNIT_EXPECT_EQ(test, error, 10);196197error = fwnode_property_read_u32_array(node, "prop-u32", array_u32, 1);198KUNIT_EXPECT_EQ(test, error, 0);199KUNIT_EXPECT_EQ(test, array_u32[0], 32);200201error = fwnode_property_read_u32_array(node, "prop-u32", array_u32, 2);202KUNIT_EXPECT_EQ(test, error, 0);203KUNIT_EXPECT_EQ(test, array_u32[0], 32);204KUNIT_EXPECT_EQ(test, array_u32[1], 33);205206error = fwnode_property_read_u32_array(node, "prop-u32", array_u32, 17);207KUNIT_EXPECT_NE(test, error, 0);208209error = fwnode_property_read_u32(node, "no-prop-u32", &val_u32);210KUNIT_EXPECT_NE(test, error, 0);211212error = fwnode_property_read_u32_array(node, "no-prop-u32", array_u32, 1);213KUNIT_EXPECT_NE(test, error, 0);214215error = fwnode_property_read_u64(node, "prop-u64", &val_u64);216KUNIT_EXPECT_EQ(test, error, 0);217KUNIT_EXPECT_EQ(test, val_u64, 64);218219error = fwnode_property_count_u64(node, "prop-u64");220KUNIT_EXPECT_EQ(test, error, 10);221222error = fwnode_property_read_u64_array(node, "prop-u64", array_u64, 1);223KUNIT_EXPECT_EQ(test, error, 0);224KUNIT_EXPECT_EQ(test, array_u64[0], 64);225226error = fwnode_property_read_u64_array(node, "prop-u64", array_u64, 2);227KUNIT_EXPECT_EQ(test, error, 0);228KUNIT_EXPECT_EQ(test, array_u64[0], 64);229KUNIT_EXPECT_EQ(test, array_u64[1], 65);230231error = fwnode_property_read_u64_array(node, "prop-u64", array_u64, 17);232KUNIT_EXPECT_NE(test, error, 0);233234error = fwnode_property_read_u64(node, "no-prop-u64", &val_u64);235KUNIT_EXPECT_NE(test, error, 0);236237error = fwnode_property_read_u64_array(node, "no-prop-u64", array_u64, 1);238KUNIT_EXPECT_NE(test, error, 0);239240/* Count 64-bit values as 16-bit */241error = fwnode_property_count_u16(node, "prop-u64");242KUNIT_EXPECT_EQ(test, error, 40);243244/* Other way around */245error = fwnode_property_count_u64(node, "prop-u16");246KUNIT_EXPECT_EQ(test, error, 2);247248fwnode_remove_software_node(node);249}250251static void pe_test_strings(struct kunit *test)252{253static const char *strings[] = {254"string-a",255"string-b",256};257258static const struct property_entry entries[] = {259PROPERTY_ENTRY_STRING("str", "single"),260PROPERTY_ENTRY_STRING("empty", ""),261PROPERTY_ENTRY_STRING_ARRAY("strs", strings),262{ }263};264265struct fwnode_handle *node;266const char *str;267const char *strs[10];268int error;269270node = fwnode_create_software_node(entries, NULL);271KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node);272273error = fwnode_property_read_string(node, "str", &str);274KUNIT_EXPECT_EQ(test, error, 0);275KUNIT_EXPECT_STREQ(test, str, "single");276277error = fwnode_property_string_array_count(node, "str");278KUNIT_EXPECT_EQ(test, error, 1);279280error = fwnode_property_read_string_array(node, "str", strs, 1);281KUNIT_EXPECT_EQ(test, error, 1);282KUNIT_EXPECT_STREQ(test, strs[0], "single");283284/* asking for more data returns what we have */285error = fwnode_property_read_string_array(node, "str", strs, 2);286KUNIT_EXPECT_EQ(test, error, 1);287KUNIT_EXPECT_STREQ(test, strs[0], "single");288289error = fwnode_property_read_string(node, "no-str", &str);290KUNIT_EXPECT_NE(test, error, 0);291292error = fwnode_property_read_string_array(node, "no-str", strs, 1);293KUNIT_EXPECT_LT(test, error, 0);294295error = fwnode_property_read_string(node, "empty", &str);296KUNIT_EXPECT_EQ(test, error, 0);297KUNIT_EXPECT_STREQ(test, str, "");298299error = fwnode_property_string_array_count(node, "strs");300KUNIT_EXPECT_EQ(test, error, 2);301302error = fwnode_property_read_string_array(node, "strs", strs, 3);303KUNIT_EXPECT_EQ(test, error, 2);304KUNIT_EXPECT_STREQ(test, strs[0], "string-a");305KUNIT_EXPECT_STREQ(test, strs[1], "string-b");306307error = fwnode_property_read_string_array(node, "strs", strs, 1);308KUNIT_EXPECT_EQ(test, error, 1);309KUNIT_EXPECT_STREQ(test, strs[0], "string-a");310311/* NULL argument -> returns size */312error = fwnode_property_read_string_array(node, "strs", NULL, 0);313KUNIT_EXPECT_EQ(test, error, 2);314315/* accessing array as single value */316error = fwnode_property_read_string(node, "strs", &str);317KUNIT_EXPECT_EQ(test, error, 0);318KUNIT_EXPECT_STREQ(test, str, "string-a");319320fwnode_remove_software_node(node);321}322323static void pe_test_bool(struct kunit *test)324{325static const struct property_entry entries[] = {326PROPERTY_ENTRY_BOOL("prop"),327{ }328};329330struct fwnode_handle *node;331332node = fwnode_create_software_node(entries, NULL);333KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node);334335KUNIT_EXPECT_TRUE(test, fwnode_property_read_bool(node, "prop"));336KUNIT_EXPECT_FALSE(test, fwnode_property_read_bool(node, "not-prop"));337338fwnode_remove_software_node(node);339}340341/* Verifies that small U8 array is stored inline when property is copied */342static void pe_test_move_inline_u8(struct kunit *test)343{344static const u8 u8_array_small[8] = { 1, 2, 3, 4 };345static const u8 u8_array_big[128] = { 5, 6, 7, 8 };346static const struct property_entry entries[] = {347PROPERTY_ENTRY_U8_ARRAY("small", u8_array_small),348PROPERTY_ENTRY_U8_ARRAY("big", u8_array_big),349{ }350};351352struct property_entry *copy;353const u8 *data_ptr;354355copy = property_entries_dup(entries);356KUNIT_ASSERT_NOT_ERR_OR_NULL(test, copy);357358KUNIT_EXPECT_TRUE(test, copy[0].is_inline);359data_ptr = (u8 *)©[0].value;360KUNIT_EXPECT_EQ(test, data_ptr[0], 1);361KUNIT_EXPECT_EQ(test, data_ptr[1], 2);362363KUNIT_EXPECT_FALSE(test, copy[1].is_inline);364data_ptr = copy[1].pointer;365KUNIT_EXPECT_EQ(test, data_ptr[0], 5);366KUNIT_EXPECT_EQ(test, data_ptr[1], 6);367368property_entries_free(copy);369}370371/* Verifies that single string array is stored inline when property is copied */372static void pe_test_move_inline_str(struct kunit *test)373{374static char *str_array_small[] = { "a" };375static char *str_array_big[] = { "b", "c", "d", "e" };376static char *str_array_small_empty[] = { "" };377static struct property_entry entries[] = {378PROPERTY_ENTRY_STRING_ARRAY("small", str_array_small),379PROPERTY_ENTRY_STRING_ARRAY("big", str_array_big),380PROPERTY_ENTRY_STRING_ARRAY("small-empty", str_array_small_empty),381{ }382};383384struct property_entry *copy;385const char * const *data_ptr;386387copy = property_entries_dup(entries);388KUNIT_ASSERT_NOT_ERR_OR_NULL(test, copy);389390KUNIT_EXPECT_TRUE(test, copy[0].is_inline);391KUNIT_EXPECT_STREQ(test, copy[0].value.str[0], "a");392393KUNIT_EXPECT_FALSE(test, copy[1].is_inline);394data_ptr = copy[1].pointer;395KUNIT_EXPECT_STREQ(test, data_ptr[0], "b");396KUNIT_EXPECT_STREQ(test, data_ptr[1], "c");397398KUNIT_EXPECT_TRUE(test, copy[2].is_inline);399KUNIT_EXPECT_STREQ(test, copy[2].value.str[0], "");400401property_entries_free(copy);402}403404/* Handling of reference properties */405static void pe_test_reference(struct kunit *test)406{407static const struct software_node node1 = { .name = "1" };408static const struct software_node node2 = { .name = "2" };409static const struct software_node *group[] = { &node1, &node2, NULL };410411static const struct software_node_ref_args refs[] = {412SOFTWARE_NODE_REFERENCE(&node1),413SOFTWARE_NODE_REFERENCE(&node2, 3, 4),414};415416const struct property_entry entries[] = {417PROPERTY_ENTRY_REF("ref-1", &node1),418PROPERTY_ENTRY_REF("ref-2", &node2, 1, 2),419PROPERTY_ENTRY_REF_ARRAY("ref-3", refs),420{ }421};422423struct fwnode_handle *node;424struct fwnode_reference_args ref;425int error;426427error = software_node_register_node_group(group);428KUNIT_ASSERT_EQ(test, error, 0);429430node = fwnode_create_software_node(entries, NULL);431KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node);432433error = fwnode_property_get_reference_args(node, "ref-1", NULL,4340, 0, &ref);435KUNIT_ASSERT_EQ(test, error, 0);436KUNIT_EXPECT_PTR_EQ(test, to_software_node(ref.fwnode), &node1);437KUNIT_EXPECT_EQ(test, ref.nargs, 0U);438439/* wrong index */440error = fwnode_property_get_reference_args(node, "ref-1", NULL,4410, 1, &ref);442KUNIT_EXPECT_NE(test, error, 0);443444error = fwnode_property_get_reference_args(node, "ref-2", NULL,4451, 0, &ref);446KUNIT_ASSERT_EQ(test, error, 0);447KUNIT_EXPECT_PTR_EQ(test, to_software_node(ref.fwnode), &node2);448KUNIT_EXPECT_EQ(test, ref.nargs, 1U);449KUNIT_EXPECT_EQ(test, ref.args[0], 1LLU);450451/* asking for more args, padded with zero data */452error = fwnode_property_get_reference_args(node, "ref-2", NULL,4533, 0, &ref);454KUNIT_ASSERT_EQ(test, error, 0);455KUNIT_EXPECT_PTR_EQ(test, to_software_node(ref.fwnode), &node2);456KUNIT_EXPECT_EQ(test, ref.nargs, 3U);457KUNIT_EXPECT_EQ(test, ref.args[0], 1LLU);458KUNIT_EXPECT_EQ(test, ref.args[1], 2LLU);459KUNIT_EXPECT_EQ(test, ref.args[2], 0LLU);460461/* wrong index */462error = fwnode_property_get_reference_args(node, "ref-2", NULL,4632, 1, &ref);464KUNIT_EXPECT_NE(test, error, 0);465466/* array of references */467error = fwnode_property_get_reference_args(node, "ref-3", NULL,4680, 0, &ref);469KUNIT_ASSERT_EQ(test, error, 0);470KUNIT_EXPECT_PTR_EQ(test, to_software_node(ref.fwnode), &node1);471KUNIT_EXPECT_EQ(test, ref.nargs, 0U);472473/* second reference in the array */474error = fwnode_property_get_reference_args(node, "ref-3", NULL,4752, 1, &ref);476KUNIT_ASSERT_EQ(test, error, 0);477KUNIT_EXPECT_PTR_EQ(test, to_software_node(ref.fwnode), &node2);478KUNIT_EXPECT_EQ(test, ref.nargs, 2U);479KUNIT_EXPECT_EQ(test, ref.args[0], 3LLU);480KUNIT_EXPECT_EQ(test, ref.args[1], 4LLU);481482/* wrong index */483error = fwnode_property_get_reference_args(node, "ref-1", NULL,4840, 2, &ref);485KUNIT_EXPECT_NE(test, error, 0);486487fwnode_remove_software_node(node);488software_node_unregister_node_group(group);489}490491static struct kunit_case property_entry_test_cases[] = {492KUNIT_CASE(pe_test_uints),493KUNIT_CASE(pe_test_uint_arrays),494KUNIT_CASE(pe_test_strings),495KUNIT_CASE(pe_test_bool),496KUNIT_CASE(pe_test_move_inline_u8),497KUNIT_CASE(pe_test_move_inline_str),498KUNIT_CASE(pe_test_reference),499{ }500};501502static struct kunit_suite property_entry_test_suite = {503.name = "property-entry",504.test_cases = property_entry_test_cases,505};506507kunit_test_suite(property_entry_test_suite);508509MODULE_DESCRIPTION("Test module for the property entry API");510MODULE_AUTHOR("Dmitry Torokhov <[email protected]>");511MODULE_LICENSE("GPL");512513514