Skip to content

Commit b30f2db

Browse files
committed
Merge tag 'regmap-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap
Pull regmap updates from Mark Brown: "Just two updates this time around, a rework of max_register handling which enables us to support devices with only one register better and a new test which will be used to validate use of some new SPI optimisations which will be coming in during this merge window" * tag 'regmap-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap: regmap: kunit: Add a test for ranges in combination with windows regmap: rework ->max_register handling
2 parents 245b6f3 + bb92804 commit b30f2db

File tree

6 files changed

+82
-6
lines changed

6 files changed

+82
-6
lines changed

drivers/base/regmap/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ struct regmap {
9393
#endif
9494

9595
unsigned int max_register;
96+
bool max_register_is_set;
9697
bool (*writeable_reg)(struct device *dev, unsigned int reg);
9798
bool (*readable_reg)(struct device *dev, unsigned int reg);
9899
bool (*volatile_reg)(struct device *dev, unsigned int reg);

drivers/base/regmap/regcache-flat.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ static int regcache_flat_init(struct regmap *map)
2323
int i;
2424
unsigned int *cache;
2525

26-
if (!map || map->reg_stride_order < 0 || !map->max_register)
26+
if (!map || map->reg_stride_order < 0 || !map->max_register_is_set)
2727
return -EINVAL;
2828

2929
map->cache = kcalloc(regcache_flat_get_index(map, map->max_register)

drivers/base/regmap/regcache.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,10 @@ int regcache_init(struct regmap *map, const struct regmap_config *config)
187187
return 0;
188188
}
189189

190-
if (!map->max_register && map->num_reg_defaults_raw)
190+
if (!map->max_register_is_set && map->num_reg_defaults_raw) {
191191
map->max_register = (map->num_reg_defaults_raw - 1) * map->reg_stride;
192+
map->max_register_is_set = true;
193+
}
192194

193195
if (map->cache_ops->init) {
194196
dev_dbg(map->dev, "Initializing %s cache\n",

drivers/base/regmap/regmap-kunit.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,6 +1341,71 @@ static void raw_sync(struct kunit *test)
13411341
regmap_exit(map);
13421342
}
13431343

1344+
static void raw_ranges(struct kunit *test)
1345+
{
1346+
struct raw_test_types *t = (struct raw_test_types *)test->param_value;
1347+
struct regmap *map;
1348+
struct regmap_config config;
1349+
struct regmap_ram_data *data;
1350+
unsigned int val;
1351+
int i;
1352+
1353+
config = raw_regmap_config;
1354+
config.volatile_reg = test_range_all_volatile;
1355+
config.ranges = &test_range;
1356+
config.num_ranges = 1;
1357+
config.max_register = test_range.range_max;
1358+
1359+
map = gen_raw_regmap(&config, t, &data);
1360+
KUNIT_ASSERT_FALSE(test, IS_ERR(map));
1361+
if (IS_ERR(map))
1362+
return;
1363+
1364+
/* Reset the page to a non-zero value to trigger a change */
1365+
KUNIT_EXPECT_EQ(test, 0, regmap_write(map, test_range.selector_reg,
1366+
test_range.range_max));
1367+
1368+
/* Check we set the page and use the window for writes */
1369+
data->written[test_range.selector_reg] = false;
1370+
data->written[test_range.window_start] = false;
1371+
KUNIT_EXPECT_EQ(test, 0, regmap_write(map, test_range.range_min, 0));
1372+
KUNIT_EXPECT_TRUE(test, data->written[test_range.selector_reg]);
1373+
KUNIT_EXPECT_TRUE(test, data->written[test_range.window_start]);
1374+
1375+
data->written[test_range.selector_reg] = false;
1376+
data->written[test_range.window_start] = false;
1377+
KUNIT_EXPECT_EQ(test, 0, regmap_write(map,
1378+
test_range.range_min +
1379+
test_range.window_len,
1380+
0));
1381+
KUNIT_EXPECT_TRUE(test, data->written[test_range.selector_reg]);
1382+
KUNIT_EXPECT_TRUE(test, data->written[test_range.window_start]);
1383+
1384+
/* Same for reads */
1385+
data->written[test_range.selector_reg] = false;
1386+
data->read[test_range.window_start] = false;
1387+
KUNIT_EXPECT_EQ(test, 0, regmap_read(map, test_range.range_min, &val));
1388+
KUNIT_EXPECT_TRUE(test, data->written[test_range.selector_reg]);
1389+
KUNIT_EXPECT_TRUE(test, data->read[test_range.window_start]);
1390+
1391+
data->written[test_range.selector_reg] = false;
1392+
data->read[test_range.window_start] = false;
1393+
KUNIT_EXPECT_EQ(test, 0, regmap_read(map,
1394+
test_range.range_min +
1395+
test_range.window_len,
1396+
&val));
1397+
KUNIT_EXPECT_TRUE(test, data->written[test_range.selector_reg]);
1398+
KUNIT_EXPECT_TRUE(test, data->read[test_range.window_start]);
1399+
1400+
/* No physical access triggered in the virtual range */
1401+
for (i = test_range.range_min; i < test_range.range_max; i++) {
1402+
KUNIT_EXPECT_FALSE(test, data->read[i]);
1403+
KUNIT_EXPECT_FALSE(test, data->written[i]);
1404+
}
1405+
1406+
regmap_exit(map);
1407+
}
1408+
13441409
static struct kunit_case regmap_test_cases[] = {
13451410
KUNIT_CASE_PARAM(basic_read_write, regcache_types_gen_params),
13461411
KUNIT_CASE_PARAM(bulk_write, regcache_types_gen_params),
@@ -1368,6 +1433,7 @@ static struct kunit_case regmap_test_cases[] = {
13681433
KUNIT_CASE_PARAM(raw_write, raw_test_types_gen_params),
13691434
KUNIT_CASE_PARAM(raw_noinc_write, raw_test_types_gen_params),
13701435
KUNIT_CASE_PARAM(raw_sync, raw_test_cache_types_gen_params),
1436+
KUNIT_CASE_PARAM(raw_ranges, raw_test_cache_types_gen_params),
13711437
{}
13721438
};
13731439

drivers/base/regmap/regmap.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ EXPORT_SYMBOL_GPL(regmap_check_range_table);
8989

9090
bool regmap_writeable(struct regmap *map, unsigned int reg)
9191
{
92-
if (map->max_register && reg > map->max_register)
92+
if (map->max_register_is_set && reg > map->max_register)
9393
return false;
9494

9595
if (map->writeable_reg)
@@ -112,7 +112,7 @@ bool regmap_cached(struct regmap *map, unsigned int reg)
112112
if (!map->cache_ops)
113113
return false;
114114

115-
if (map->max_register && reg > map->max_register)
115+
if (map->max_register_is_set && reg > map->max_register)
116116
return false;
117117

118118
map->lock(map->lock_arg);
@@ -129,7 +129,7 @@ bool regmap_readable(struct regmap *map, unsigned int reg)
129129
if (!map->reg_read)
130130
return false;
131131

132-
if (map->max_register && reg > map->max_register)
132+
if (map->max_register_is_set && reg > map->max_register)
133133
return false;
134134

135135
if (map->format.format_write)
@@ -787,6 +787,7 @@ struct regmap *__regmap_init(struct device *dev,
787787
map->bus = bus;
788788
map->bus_context = bus_context;
789789
map->max_register = config->max_register;
790+
map->max_register_is_set = map->max_register ?: config->max_register_is_0;
790791
map->wr_table = config->wr_table;
791792
map->rd_table = config->rd_table;
792793
map->volatile_table = config->volatile_table;
@@ -1412,6 +1413,7 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
14121413
regmap_debugfs_exit(map);
14131414

14141415
map->max_register = config->max_register;
1416+
map->max_register_is_set = map->max_register ?: config->max_register_is_0;
14151417
map->writeable_reg = config->writeable_reg;
14161418
map->readable_reg = config->readable_reg;
14171419
map->volatile_reg = config->volatile_reg;
@@ -3383,7 +3385,7 @@ EXPORT_SYMBOL_GPL(regmap_get_val_bytes);
33833385
*/
33843386
int regmap_get_max_register(struct regmap *map)
33853387
{
3386-
return map->max_register ? map->max_register : -EINVAL;
3388+
return map->max_register_is_set ? map->max_register : -EINVAL;
33873389
}
33883390
EXPORT_SYMBOL_GPL(regmap_get_max_register);
33893391

include/linux/regmap.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,10 @@ typedef void (*regmap_unlock)(void *);
332332
* @io_port: Support IO port accessors. Makes sense only when MMIO vs. IO port
333333
* access can be distinguished.
334334
* @max_register: Optional, specifies the maximum valid register address.
335+
* @max_register_is_0: Optional, specifies that zero value in @max_register
336+
* should be taken into account. This is a workaround to
337+
* apply handling of @max_register for regmap that contains
338+
* only one register.
335339
* @wr_table: Optional, points to a struct regmap_access_table specifying
336340
* valid ranges for write access.
337341
* @rd_table: As above, for read access.
@@ -422,6 +426,7 @@ struct regmap_config {
422426
bool io_port;
423427

424428
unsigned int max_register;
429+
bool max_register_is_0;
425430
const struct regmap_access_table *wr_table;
426431
const struct regmap_access_table *rd_table;
427432
const struct regmap_access_table *volatile_table;

0 commit comments

Comments
 (0)