regmap: Add KUnit tests for read/write checking

Merge series from Mark Brown <broonie@kernel.org>:

Since Takashi found an issue with maple tree syncing registers it
shouldn't do add some test cases that catch that case and some more
potential issues, ideally we'd run through the combination of
readability with all possible I/O calls but that's lifting for another
day.  We did find one issue with missing readability checks which will
be fixed separately.
This commit is contained in:
Mark Brown 2023-06-14 18:35:13 +01:00
commit 505cb70cd2
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0

View File

@ -92,6 +92,11 @@ static struct regmap *gen_regmap(struct regmap_config *config,
return ret;
}
static bool reg_5_false(struct device *context, unsigned int reg)
{
return reg != 5;
}
static void basic_read_write(struct kunit *test)
{
struct regcache_types *t = (struct regcache_types *)test->param_value;
@ -191,6 +196,72 @@ static void bulk_read(struct kunit *test)
regmap_exit(map);
}
static void write_readonly(struct kunit *test)
{
struct regcache_types *t = (struct regcache_types *)test->param_value;
struct regmap *map;
struct regmap_config config;
struct regmap_ram_data *data;
unsigned int val;
int i;
config = test_regmap_config;
config.cache_type = t->type;
config.num_reg_defaults = BLOCK_TEST_SIZE;
config.writeable_reg = reg_5_false;
map = gen_regmap(&config, &data);
KUNIT_ASSERT_FALSE(test, IS_ERR(map));
if (IS_ERR(map))
return;
get_random_bytes(&val, sizeof(val));
for (i = 0; i < BLOCK_TEST_SIZE; i++)
data->written[i] = false;
/* Change the value of all registers, readonly should fail */
for (i = 0; i < BLOCK_TEST_SIZE; i++)
KUNIT_EXPECT_EQ(test, i != 5, regmap_write(map, i, val) == 0);
/* Did that match what we see on the device? */
for (i = 0; i < BLOCK_TEST_SIZE; i++)
KUNIT_EXPECT_EQ(test, i != 5, data->written[i]);
regmap_exit(map);
}
static void read_writeonly(struct kunit *test)
{
struct regcache_types *t = (struct regcache_types *)test->param_value;
struct regmap *map;
struct regmap_config config;
struct regmap_ram_data *data;
unsigned int val;
int i;
config = test_regmap_config;
config.cache_type = t->type;
config.readable_reg = reg_5_false;
map = gen_regmap(&config, &data);
KUNIT_ASSERT_FALSE(test, IS_ERR(map));
if (IS_ERR(map))
return;
for (i = 0; i < BLOCK_TEST_SIZE; i++)
data->read[i] = false;
/* Try to read all the registers, the writeonly one should fail */
for (i = 0; i < BLOCK_TEST_SIZE; i++)
KUNIT_EXPECT_EQ(test, i != 5, regmap_read(map, i, &val) == 0);
/* Did we trigger a hardware access? */
KUNIT_EXPECT_FALSE(test, data->read[5]);
regmap_exit(map);
}
static void reg_defaults(struct kunit *test)
{
struct regcache_types *t = (struct regcache_types *)test->param_value;
@ -609,6 +680,47 @@ static void cache_sync_defaults(struct kunit *test)
regmap_exit(map);
}
static void cache_sync_readonly(struct kunit *test)
{
struct regcache_types *t = (struct regcache_types *)test->param_value;
struct regmap *map;
struct regmap_config config;
struct regmap_ram_data *data;
unsigned int val;
int i;
config = test_regmap_config;
config.cache_type = t->type;
config.writeable_reg = reg_5_false;
map = gen_regmap(&config, &data);
KUNIT_ASSERT_FALSE(test, IS_ERR(map));
if (IS_ERR(map))
return;
/* Read all registers to fill the cache */
for (i = 0; i < BLOCK_TEST_SIZE; i++)
KUNIT_EXPECT_EQ(test, 0, regmap_read(map, i, &val));
/* Change the value of all registers, readonly should fail */
get_random_bytes(&val, sizeof(val));
regcache_cache_only(map, true);
for (i = 0; i < BLOCK_TEST_SIZE; i++)
KUNIT_EXPECT_EQ(test, i != 5, regmap_write(map, i, val) == 0);
regcache_cache_only(map, false);
/* Resync */
for (i = 0; i < BLOCK_TEST_SIZE; i++)
data->written[i] = false;
KUNIT_EXPECT_EQ(test, 0, regcache_sync(map));
/* Did that match what we see on the device? */
for (i = 0; i < BLOCK_TEST_SIZE; i++)
KUNIT_EXPECT_EQ(test, i != 5, data->written[i]);
regmap_exit(map);
}
static void cache_sync_patch(struct kunit *test)
{
struct regcache_types *t = (struct regcache_types *)test->param_value;
@ -1037,6 +1149,8 @@ static struct kunit_case regmap_test_cases[] = {
KUNIT_CASE_PARAM(basic_read_write, regcache_types_gen_params),
KUNIT_CASE_PARAM(bulk_write, regcache_types_gen_params),
KUNIT_CASE_PARAM(bulk_read, regcache_types_gen_params),
KUNIT_CASE_PARAM(write_readonly, regcache_types_gen_params),
KUNIT_CASE_PARAM(read_writeonly, regcache_types_gen_params),
KUNIT_CASE_PARAM(reg_defaults, regcache_types_gen_params),
KUNIT_CASE_PARAM(reg_defaults_read_dev, regcache_types_gen_params),
KUNIT_CASE_PARAM(register_patch, regcache_types_gen_params),
@ -1046,6 +1160,7 @@ static struct kunit_case regmap_test_cases[] = {
KUNIT_CASE_PARAM(cache_bypass, real_cache_types_gen_params),
KUNIT_CASE_PARAM(cache_sync, real_cache_types_gen_params),
KUNIT_CASE_PARAM(cache_sync_defaults, real_cache_types_gen_params),
KUNIT_CASE_PARAM(cache_sync_readonly, real_cache_types_gen_params),
KUNIT_CASE_PARAM(cache_sync_patch, real_cache_types_gen_params),
KUNIT_CASE_PARAM(cache_drop, sparse_cache_types_gen_params),