[2/3] nvmem: core: allow .read_post_process() callbacks to adjust data length

Message ID 20230105171038.13649-2-zajec5@gmail.com
State New
Headers
Series [1/3] dt-bindings: nvmem: u-boot,env: add MAC's #nvmem-cell-cells |

Commit Message

Rafał Miłecki Jan. 5, 2023, 5:10 p.m. UTC
  From: Rafał Miłecki <rafal@milecki.pl>

Sometimes reading NVMEM cell value involves some data reformatting. It
requires passing updated size value to the caller. Support that.

It's required e.g. to provide properly formatted MAC address in case
it's stored in a non-binary format (e.g. using ASCII).

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
 drivers/nvmem/core.c             | 5 +++--
 drivers/nvmem/imx-ocotp.c        | 6 +++---
 drivers/nvmem/layouts/onie-tlv.c | 2 +-
 drivers/nvmem/layouts/sl28vpd.c  | 4 ++--
 include/linux/nvmem-provider.h   | 2 +-
 5 files changed, 10 insertions(+), 9 deletions(-)
  

Comments

Michael Walle Jan. 5, 2023, 9:22 p.m. UTC | #1
Hi,

Am 2023-01-05 18:10, schrieb Rafał Miłecki:
> From: Rafał Miłecki <rafal@milecki.pl>
> 
> Sometimes reading NVMEM cell value involves some data reformatting. It
> requires passing updated size value to the caller. Support that.

Wouldn't it make more sense to convert that driver to
proper nvmem layouts, where
  (1) you get that for free,
  (2) support others storages than just mtd
  (3) don't duplicate the mtd read code

-michael
  

Patch

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 1b61c8bf0de4..1daf5a1d3ec7 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -1537,6 +1537,7 @@  static int __nvmem_cell_read(struct nvmem_device *nvmem,
 			     struct nvmem_cell_entry *cell,
 			     void *buf, size_t *len, const char *id, int index)
 {
+	size_t bytes = cell->bytes;
 	int rc;
 
 	rc = nvmem_reg_read(nvmem, cell->offset, buf, cell->bytes);
@@ -1550,13 +1551,13 @@  static int __nvmem_cell_read(struct nvmem_device *nvmem,
 
 	if (cell->read_post_process) {
 		rc = cell->read_post_process(cell->priv, id, index,
-					     cell->offset, buf, cell->bytes);
+					     cell->offset, buf, &bytes);
 		if (rc)
 			return rc;
 	}
 
 	if (len)
-		*len = cell->bytes;
+		*len = bytes;
 
 	return 0;
 }
diff --git a/drivers/nvmem/imx-ocotp.c b/drivers/nvmem/imx-ocotp.c
index ac0edb6398f1..ebd0e9e0314e 100644
--- a/drivers/nvmem/imx-ocotp.c
+++ b/drivers/nvmem/imx-ocotp.c
@@ -223,15 +223,15 @@  static int imx_ocotp_read(void *context, unsigned int offset,
 }
 
 static int imx_ocotp_cell_pp(void *context, const char *id, int index,
-			     unsigned int offset, void *data, size_t bytes)
+			     unsigned int offset, void *data, size_t *bytes)
 {
 	u8 *buf = data;
 	int i;
 
 	/* Deal with some post processing of nvmem cell data */
 	if (id && !strcmp(id, "mac-address"))
-		for (i = 0; i < bytes / 2; i++)
-			swap(buf[i], buf[bytes - i - 1]);
+		for (i = 0; i < *bytes / 2; i++)
+			swap(buf[i], buf[*bytes - i - 1]);
 
 	return 0;
 }
diff --git a/drivers/nvmem/layouts/onie-tlv.c b/drivers/nvmem/layouts/onie-tlv.c
index 074c7c700845..2cb7112229ba 100644
--- a/drivers/nvmem/layouts/onie-tlv.c
+++ b/drivers/nvmem/layouts/onie-tlv.c
@@ -76,7 +76,7 @@  static const char *onie_tlv_cell_name(u8 type)
 
 static int onie_tlv_mac_read_cb(void *priv, const char *id, int index,
 				unsigned int offset, void *buf,
-				size_t bytes)
+				size_t *bytes)
 {
 	eth_addr_add(buf, index);
 
diff --git a/drivers/nvmem/layouts/sl28vpd.c b/drivers/nvmem/layouts/sl28vpd.c
index a36800f201a3..63c0da58ad60 100644
--- a/drivers/nvmem/layouts/sl28vpd.c
+++ b/drivers/nvmem/layouts/sl28vpd.c
@@ -23,9 +23,9 @@  struct sl28vpd_v1 {
 
 static int sl28vpd_mac_address_pp(void *priv, const char *id, int index,
 				  unsigned int offset, void *buf,
-				  size_t bytes)
+				  size_t *bytes)
 {
-	if (bytes != ETH_ALEN)
+	if (*bytes != ETH_ALEN)
 		return -EINVAL;
 
 	if (index < 0)
diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h
index 0cf9f9490514..5d896eec2f1c 100644
--- a/include/linux/nvmem-provider.h
+++ b/include/linux/nvmem-provider.h
@@ -21,7 +21,7 @@  typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset,
 /* used for vendor specific post processing of cell data */
 typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, int index,
 					 unsigned int offset, void *buf,
-					 size_t bytes);
+					 size_t *bytes);
 
 enum nvmem_type {
 	NVMEM_TYPE_UNKNOWN = 0,