Commit 40033248 authored by Dmitry Baryshkov's avatar Dmitry Baryshkov Committed by Mark Brown

regmap: fix page selection for noinc reads

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.orgSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent d36cb020
...@@ -2472,7 +2472,7 @@ int regmap_raw_write_async(struct regmap *map, unsigned int reg, ...@@ -2472,7 +2472,7 @@ int regmap_raw_write_async(struct regmap *map, unsigned int reg,
EXPORT_SYMBOL_GPL(regmap_raw_write_async); EXPORT_SYMBOL_GPL(regmap_raw_write_async);
static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, 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; struct regmap_range_node *range;
int ret; int ret;
...@@ -2485,7 +2485,7 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, ...@@ -2485,7 +2485,7 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
range = _regmap_range_lookup(map, reg); range = _regmap_range_lookup(map, reg);
if (range) { if (range) {
ret = _regmap_select_page(map, &reg, 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) if (ret != 0)
return ret; return ret;
} }
...@@ -2523,7 +2523,7 @@ static int _regmap_bus_read(void *context, unsigned int reg, ...@@ -2523,7 +2523,7 @@ static int _regmap_bus_read(void *context, unsigned int reg,
if (!map->format.parse_val) if (!map->format.parse_val)
return -EINVAL; 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) if (ret == 0)
*val = map->format.parse_val(work_val); *val = map->format.parse_val(work_val);
...@@ -2639,7 +2639,7 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val, ...@@ -2639,7 +2639,7 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
/* Read bytes that fit into whole chunks */ /* Read bytes that fit into whole chunks */
for (i = 0; i < chunk_count; i++) { 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) if (ret != 0)
goto out; goto out;
...@@ -2650,7 +2650,7 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val, ...@@ -2650,7 +2650,7 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
/* Read remaining bytes */ /* Read remaining bytes */
if (val_len) { 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) if (ret != 0)
goto out; goto out;
} }
...@@ -2725,7 +2725,7 @@ int regmap_noinc_read(struct regmap *map, unsigned int reg, ...@@ -2725,7 +2725,7 @@ int regmap_noinc_read(struct regmap *map, unsigned int reg,
read_len = map->max_raw_read; read_len = map->max_raw_read;
else else
read_len = val_len; 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) if (ret)
goto out_unlock; goto out_unlock;
val = ((u8 *)val) + read_len; val = ((u8 *)val) + read_len;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment