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 <[email protected]>
---
 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,
 };

Reply via email to