summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>2019-04-13 11:32:58 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-06-22 08:17:15 +0200
commitfaa4dc52b4b227344bd66ac0fda6475749263d8b (patch)
tree776d6f99c221d8ec616e1d3d54cb63d0f5487e36
parent5844c4b20d5fab7f05b171e1a959e3c19355fa8b (diff)
nvmem: core: fix read buffer in place
[ Upstream commit 2fe518fecb3a4727393be286db9804cd82ee2d91 ] When the bit_offset in the cell is zero, the pointer to the msb will not be properly initialized (ie, will still be pointing to the first byte in the buffer). This being the case, if there are bits to clear in the msb, those will be left untouched while the mask will incorrectly clear bit positions on the first byte. This commit also makes sure that any byte unused in the cell is cleared. Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/nvmem/core.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 824e282cd80e..bb2f79933b17 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -934,7 +934,7 @@ static inline void nvmem_shift_read_buffer_in_place(struct nvmem_cell *cell,
void *buf)
{
u8 *p, *b;
- int i, bit_offset = cell->bit_offset;
+ int i, extra, bit_offset = cell->bit_offset;
p = b = buf;
if (bit_offset) {
@@ -949,11 +949,16 @@ static inline void nvmem_shift_read_buffer_in_place(struct nvmem_cell *cell,
p = b;
*b++ >>= bit_offset;
}
-
- /* result fits in less bytes */
- if (cell->bytes != DIV_ROUND_UP(cell->nbits, BITS_PER_BYTE))
- *p-- = 0;
+ } else {
+ /* point to the msb */
+ p += cell->bytes - 1;
}
+
+ /* result fits in less bytes */
+ extra = cell->bytes - DIV_ROUND_UP(cell->nbits, BITS_PER_BYTE);
+ while (--extra >= 0)
+ *p-- = 0;
+
/* clear msb bits if any leftover in the last byte */
*p &= GENMASK((cell->nbits%BITS_PER_BYTE) - 1, 0);
}