From: Dmitry Baryshkov <dmitry.barysh...@linaro.org>

[ 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: Dmitry Baryshkov <dmitry.barysh...@linaro.org>
Fixes: 74fe7b551f33 ("regmap: Add regmap_noinc_read API")
Link: 
https://lore.kernel.org/r/20200917153405.3139200-1-dmitry.barysh...@linaro.org
Signed-off-by: Mark Brown <broo...@kernel.org>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 drivers/base/regmap/regmap.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 927ebde1607be..7244319dd2d52 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -2454,7 +2454,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;
@@ -2467,7 +2467,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;
        }
@@ -2505,7 +2505,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);
 
@@ -2621,7 +2621,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;
 
@@ -2632,7 +2632,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;
                }
@@ -2707,7 +2707,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;
-- 
2.25.1



Reply via email to