Skip to content

Commit 505cb70

Browse files
committed
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.
2 parents eab5abd + 357a1eb commit 505cb70

1 file changed

Lines changed: 115 additions & 0 deletions

File tree

drivers/base/regmap/regmap-kunit.c

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ static struct regmap *gen_regmap(struct regmap_config *config,
9292
return ret;
9393
}
9494

95+
static bool reg_5_false(struct device *context, unsigned int reg)
96+
{
97+
return reg != 5;
98+
}
99+
95100
static void basic_read_write(struct kunit *test)
96101
{
97102
struct regcache_types *t = (struct regcache_types *)test->param_value;
@@ -191,6 +196,72 @@ static void bulk_read(struct kunit *test)
191196
regmap_exit(map);
192197
}
193198

199+
static void write_readonly(struct kunit *test)
200+
{
201+
struct regcache_types *t = (struct regcache_types *)test->param_value;
202+
struct regmap *map;
203+
struct regmap_config config;
204+
struct regmap_ram_data *data;
205+
unsigned int val;
206+
int i;
207+
208+
config = test_regmap_config;
209+
config.cache_type = t->type;
210+
config.num_reg_defaults = BLOCK_TEST_SIZE;
211+
config.writeable_reg = reg_5_false;
212+
213+
map = gen_regmap(&config, &data);
214+
KUNIT_ASSERT_FALSE(test, IS_ERR(map));
215+
if (IS_ERR(map))
216+
return;
217+
218+
get_random_bytes(&val, sizeof(val));
219+
220+
for (i = 0; i < BLOCK_TEST_SIZE; i++)
221+
data->written[i] = false;
222+
223+
/* Change the value of all registers, readonly should fail */
224+
for (i = 0; i < BLOCK_TEST_SIZE; i++)
225+
KUNIT_EXPECT_EQ(test, i != 5, regmap_write(map, i, val) == 0);
226+
227+
/* Did that match what we see on the device? */
228+
for (i = 0; i < BLOCK_TEST_SIZE; i++)
229+
KUNIT_EXPECT_EQ(test, i != 5, data->written[i]);
230+
231+
regmap_exit(map);
232+
}
233+
234+
static void read_writeonly(struct kunit *test)
235+
{
236+
struct regcache_types *t = (struct regcache_types *)test->param_value;
237+
struct regmap *map;
238+
struct regmap_config config;
239+
struct regmap_ram_data *data;
240+
unsigned int val;
241+
int i;
242+
243+
config = test_regmap_config;
244+
config.cache_type = t->type;
245+
config.readable_reg = reg_5_false;
246+
247+
map = gen_regmap(&config, &data);
248+
KUNIT_ASSERT_FALSE(test, IS_ERR(map));
249+
if (IS_ERR(map))
250+
return;
251+
252+
for (i = 0; i < BLOCK_TEST_SIZE; i++)
253+
data->read[i] = false;
254+
255+
/* Try to read all the registers, the writeonly one should fail */
256+
for (i = 0; i < BLOCK_TEST_SIZE; i++)
257+
KUNIT_EXPECT_EQ(test, i != 5, regmap_read(map, i, &val) == 0);
258+
259+
/* Did we trigger a hardware access? */
260+
KUNIT_EXPECT_FALSE(test, data->read[5]);
261+
262+
regmap_exit(map);
263+
}
264+
194265
static void reg_defaults(struct kunit *test)
195266
{
196267
struct regcache_types *t = (struct regcache_types *)test->param_value;
@@ -609,6 +680,47 @@ static void cache_sync_defaults(struct kunit *test)
609680
regmap_exit(map);
610681
}
611682

683+
static void cache_sync_readonly(struct kunit *test)
684+
{
685+
struct regcache_types *t = (struct regcache_types *)test->param_value;
686+
struct regmap *map;
687+
struct regmap_config config;
688+
struct regmap_ram_data *data;
689+
unsigned int val;
690+
int i;
691+
692+
config = test_regmap_config;
693+
config.cache_type = t->type;
694+
config.writeable_reg = reg_5_false;
695+
696+
map = gen_regmap(&config, &data);
697+
KUNIT_ASSERT_FALSE(test, IS_ERR(map));
698+
if (IS_ERR(map))
699+
return;
700+
701+
/* Read all registers to fill the cache */
702+
for (i = 0; i < BLOCK_TEST_SIZE; i++)
703+
KUNIT_EXPECT_EQ(test, 0, regmap_read(map, i, &val));
704+
705+
/* Change the value of all registers, readonly should fail */
706+
get_random_bytes(&val, sizeof(val));
707+
regcache_cache_only(map, true);
708+
for (i = 0; i < BLOCK_TEST_SIZE; i++)
709+
KUNIT_EXPECT_EQ(test, i != 5, regmap_write(map, i, val) == 0);
710+
regcache_cache_only(map, false);
711+
712+
/* Resync */
713+
for (i = 0; i < BLOCK_TEST_SIZE; i++)
714+
data->written[i] = false;
715+
KUNIT_EXPECT_EQ(test, 0, regcache_sync(map));
716+
717+
/* Did that match what we see on the device? */
718+
for (i = 0; i < BLOCK_TEST_SIZE; i++)
719+
KUNIT_EXPECT_EQ(test, i != 5, data->written[i]);
720+
721+
regmap_exit(map);
722+
}
723+
612724
static void cache_sync_patch(struct kunit *test)
613725
{
614726
struct regcache_types *t = (struct regcache_types *)test->param_value;
@@ -1037,6 +1149,8 @@ static struct kunit_case regmap_test_cases[] = {
10371149
KUNIT_CASE_PARAM(basic_read_write, regcache_types_gen_params),
10381150
KUNIT_CASE_PARAM(bulk_write, regcache_types_gen_params),
10391151
KUNIT_CASE_PARAM(bulk_read, regcache_types_gen_params),
1152+
KUNIT_CASE_PARAM(write_readonly, regcache_types_gen_params),
1153+
KUNIT_CASE_PARAM(read_writeonly, regcache_types_gen_params),
10401154
KUNIT_CASE_PARAM(reg_defaults, regcache_types_gen_params),
10411155
KUNIT_CASE_PARAM(reg_defaults_read_dev, regcache_types_gen_params),
10421156
KUNIT_CASE_PARAM(register_patch, regcache_types_gen_params),
@@ -1046,6 +1160,7 @@ static struct kunit_case regmap_test_cases[] = {
10461160
KUNIT_CASE_PARAM(cache_bypass, real_cache_types_gen_params),
10471161
KUNIT_CASE_PARAM(cache_sync, real_cache_types_gen_params),
10481162
KUNIT_CASE_PARAM(cache_sync_defaults, real_cache_types_gen_params),
1163+
KUNIT_CASE_PARAM(cache_sync_readonly, real_cache_types_gen_params),
10491164
KUNIT_CASE_PARAM(cache_sync_patch, real_cache_types_gen_params),
10501165
KUNIT_CASE_PARAM(cache_drop, sparse_cache_types_gen_params),
10511166

0 commit comments

Comments
 (0)