Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7b038e4d authored by Dmitry Baryshkov's avatar Dmitry Baryshkov Committed by Greg Kroah-Hartman
Browse files

regmap: fix page selection for noinc reads



[ Upstream commit 4003324856311faebb46cbd56a1616bd3f3b67c2 ]

Non-incrementing reads can fail if register + length crosses page
border. However for non-incrementing reads we should not check for page
border crossing. Fix this by passing additional flag to _regmap_raw_read
and passing length to _regmap_select_page basing on the flag.

Signed-off-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Fixes: 74fe7b55 ("regmap: Add regmap_noinc_read API")
Link: https://lore.kernel.org/r/20200917153405.3139200-1-dmitry.baryshkov@linaro.org


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent f37ace9a
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -2367,7 +2367,7 @@ int regmap_raw_write_async(struct regmap *map, unsigned int reg,
EXPORT_SYMBOL_GPL(regmap_raw_write_async);

static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
			    unsigned int val_len)
			    unsigned int val_len, bool noinc)
{
	struct regmap_range_node *range;
	int ret;
@@ -2380,7 +2380,7 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
	range = _regmap_range_lookup(map, reg);
	if (range) {
		ret = _regmap_select_page(map, &reg, range,
					  val_len / map->format.val_bytes);
					  noinc ? 1 : val_len / map->format.val_bytes);
		if (ret != 0)
			return ret;
	}
@@ -2418,7 +2418,7 @@ static int _regmap_bus_read(void *context, unsigned int reg,
	if (!map->format.parse_val)
		return -EINVAL;

	ret = _regmap_raw_read(map, reg, work_val, map->format.val_bytes);
	ret = _regmap_raw_read(map, reg, work_val, map->format.val_bytes, false);
	if (ret == 0)
		*val = map->format.parse_val(work_val);

@@ -2536,7 +2536,7 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,

		/* Read bytes that fit into whole chunks */
		for (i = 0; i < chunk_count; i++) {
			ret = _regmap_raw_read(map, reg, val, chunk_bytes);
			ret = _regmap_raw_read(map, reg, val, chunk_bytes, false);
			if (ret != 0)
				goto out;

@@ -2547,7 +2547,7 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,

		/* Read remaining bytes */
		if (val_len) {
			ret = _regmap_raw_read(map, reg, val, val_len);
			ret = _regmap_raw_read(map, reg, val, val_len, false);
			if (ret != 0)
				goto out;
		}
@@ -2622,7 +2622,7 @@ int regmap_noinc_read(struct regmap *map, unsigned int reg,
			read_len = map->max_raw_read;
		else
			read_len = val_len;
		ret = _regmap_raw_read(map, reg, val, read_len);
		ret = _regmap_raw_read(map, reg, val, read_len, true);
		if (ret)
			goto out_unlock;
		val = ((u8 *)val) + read_len;