Commit b30f2db0 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 245b6f32 bb92804b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -93,6 +93,7 @@ struct regmap {
#endif

	unsigned int max_register;
	bool max_register_is_set;
	bool (*writeable_reg)(struct device *dev, unsigned int reg);
	bool (*readable_reg)(struct device *dev, unsigned int reg);
	bool (*volatile_reg)(struct device *dev, unsigned int reg);
+1 −1
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ static int regcache_flat_init(struct regmap *map)
	int i;
	unsigned int *cache;

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

	map->cache = kcalloc(regcache_flat_get_index(map, map->max_register)
+3 −1
Original line number Diff line number Diff line
@@ -187,8 +187,10 @@ int regcache_init(struct regmap *map, const struct regmap_config *config)
			return 0;
	}

	if (!map->max_register && map->num_reg_defaults_raw)
	if (!map->max_register_is_set && map->num_reg_defaults_raw) {
		map->max_register = (map->num_reg_defaults_raw  - 1) * map->reg_stride;
		map->max_register_is_set = true;
	}

	if (map->cache_ops->init) {
		dev_dbg(map->dev, "Initializing %s cache\n",
+66 −0
Original line number Diff line number Diff line
@@ -1341,6 +1341,71 @@ static void raw_sync(struct kunit *test)
	regmap_exit(map);
}

static void raw_ranges(struct kunit *test)
{
	struct raw_test_types *t = (struct raw_test_types *)test->param_value;
	struct regmap *map;
	struct regmap_config config;
	struct regmap_ram_data *data;
	unsigned int val;
	int i;

	config = raw_regmap_config;
	config.volatile_reg = test_range_all_volatile;
	config.ranges = &test_range;
	config.num_ranges = 1;
	config.max_register = test_range.range_max;

	map = gen_raw_regmap(&config, t, &data);
	KUNIT_ASSERT_FALSE(test, IS_ERR(map));
	if (IS_ERR(map))
		return;

	/* Reset the page to a non-zero value to trigger a change */
	KUNIT_EXPECT_EQ(test, 0, regmap_write(map, test_range.selector_reg,
					      test_range.range_max));

	/* Check we set the page and use the window for writes */
	data->written[test_range.selector_reg] = false;
	data->written[test_range.window_start] = false;
	KUNIT_EXPECT_EQ(test, 0, regmap_write(map, test_range.range_min, 0));
	KUNIT_EXPECT_TRUE(test, data->written[test_range.selector_reg]);
	KUNIT_EXPECT_TRUE(test, data->written[test_range.window_start]);

	data->written[test_range.selector_reg] = false;
	data->written[test_range.window_start] = false;
	KUNIT_EXPECT_EQ(test, 0, regmap_write(map,
					      test_range.range_min +
					      test_range.window_len,
					      0));
	KUNIT_EXPECT_TRUE(test, data->written[test_range.selector_reg]);
	KUNIT_EXPECT_TRUE(test, data->written[test_range.window_start]);

	/* Same for reads */
	data->written[test_range.selector_reg] = false;
	data->read[test_range.window_start] = false;
	KUNIT_EXPECT_EQ(test, 0, regmap_read(map, test_range.range_min, &val));
	KUNIT_EXPECT_TRUE(test, data->written[test_range.selector_reg]);
	KUNIT_EXPECT_TRUE(test, data->read[test_range.window_start]);

	data->written[test_range.selector_reg] = false;
	data->read[test_range.window_start] = false;
	KUNIT_EXPECT_EQ(test, 0, regmap_read(map,
					     test_range.range_min +
					     test_range.window_len,
					     &val));
	KUNIT_EXPECT_TRUE(test, data->written[test_range.selector_reg]);
	KUNIT_EXPECT_TRUE(test, data->read[test_range.window_start]);

	/* No physical access triggered in the virtual range */
	for (i = test_range.range_min; i < test_range.range_max; i++) {
		KUNIT_EXPECT_FALSE(test, data->read[i]);
		KUNIT_EXPECT_FALSE(test, data->written[i]);
	}

	regmap_exit(map);
}

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),
@@ -1368,6 +1433,7 @@ static struct kunit_case regmap_test_cases[] = {
	KUNIT_CASE_PARAM(raw_write, raw_test_types_gen_params),
	KUNIT_CASE_PARAM(raw_noinc_write, raw_test_types_gen_params),
	KUNIT_CASE_PARAM(raw_sync, raw_test_cache_types_gen_params),
	KUNIT_CASE_PARAM(raw_ranges, raw_test_cache_types_gen_params),
	{}
};

+6 −4
Original line number Diff line number Diff line
@@ -89,7 +89,7 @@ EXPORT_SYMBOL_GPL(regmap_check_range_table);

bool regmap_writeable(struct regmap *map, unsigned int reg)
{
	if (map->max_register && reg > map->max_register)
	if (map->max_register_is_set && reg > map->max_register)
		return false;

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

	if (map->max_register && reg > map->max_register)
	if (map->max_register_is_set && reg > map->max_register)
		return false;

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

	if (map->max_register && reg > map->max_register)
	if (map->max_register_is_set && reg > map->max_register)
		return false;

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

	map->max_register = config->max_register;
	map->max_register_is_set = map->max_register ?: config->max_register_is_0;
	map->writeable_reg = config->writeable_reg;
	map->readable_reg = config->readable_reg;
	map->volatile_reg = config->volatile_reg;
@@ -3383,7 +3385,7 @@ EXPORT_SYMBOL_GPL(regmap_get_val_bytes);
 */
int regmap_get_max_register(struct regmap *map)
{
	return map->max_register ? map->max_register : -EINVAL;
	return map->max_register_is_set ? map->max_register : -EINVAL;
}
EXPORT_SYMBOL_GPL(regmap_get_max_register);

Loading