Messages in this thread Patch in this message | | | From | Jose Diaz de Grenu <> | Subject | [PATCH 2/2] nvmem: imx-ocotp: allow reads with arbitrary size and offset | Date | Tue, 23 Jul 2019 17:32:43 +0200 |
| |
Currently the driver only allows to read 32 aligned 32-bit chunks. This is inconvenient when defining nvmem-cells, as they are rarely a multiple of 32 bits in size, and that makes the nvmem-consumer hardcode offsets and masks to extract the real value.
Remove the limitation but keep reading in 32-bit chunks from the hardware to ensure there is no change in the behaviour.
Signed-off-by: Jose Diaz de Grenu <Jose.DiazdeGrenu@digi.com> --- drivers/nvmem/imx-ocotp.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-)
diff --git a/drivers/nvmem/imx-ocotp.c b/drivers/nvmem/imx-ocotp.c index dc86d863563a..9590eeab85d8 100644 --- a/drivers/nvmem/imx-ocotp.c +++ b/drivers/nvmem/imx-ocotp.c @@ -121,16 +121,8 @@ static int imx_ocotp_read(void *context, unsigned int offset, void *val, size_t bytes) { struct ocotp_priv *priv = context; - unsigned int count; - u32 *buf = val; + u8 *buf = val; int i, ret; - u32 index; - - index = offset >> 2; - count = bytes >> 2; - - if (count > (priv->params->nregs - index)) - count = priv->params->nregs - index; mutex_lock(&ocotp_mutex); @@ -147,9 +139,9 @@ static int imx_ocotp_read(void *context, unsigned int offset, goto read_end; } - for (i = index; i < (index + count); i++) { - *buf++ = readl(priv->base + IMX_OCOTP_OFFSET_B0W0 + - i * IMX_OCOTP_OFFSET_PER_WORD); + for (i = offset; i < (bytes + offset); i++) { + u32 word_val = readl(priv->base + IMX_OCOTP_OFFSET_B0W0 + + (i >> 2) * IMX_OCOTP_OFFSET_PER_WORD); /* 47.3.1.2 * For "read locked" registers 0xBADABADA will be returned and @@ -157,9 +149,14 @@ static int imx_ocotp_read(void *context, unsigned int offset, * software before any new write, read or reload access can be * issued */ - if (*(buf - 1) == IMX_OCOTP_READ_LOCKED_VAL) + if (word_val == IMX_OCOTP_READ_LOCKED_VAL) imx_ocotp_clr_err_if_set(priv->base); + + word_val >>= (i % 4) * 8; + + *buf++ = (u8) (word_val & 0xFF); } + ret = 0; read_end: @@ -415,8 +412,8 @@ static int imx_ocotp_write(void *context, unsigned int offset, void *val, static struct nvmem_config imx_ocotp_nvmem_config = { .name = "imx-ocotp", .read_only = false, - .word_size = 4, - .stride = 4, + .word_size = 1, + .stride = 1, .reg_read = imx_ocotp_read, .reg_write = imx_ocotp_write, };
| |