devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Rafał Miłecki" <zajec5@gmail.com>
To: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>,
	Rob Herring <robh+dt@kernel.org>,
	Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
Cc: "Shawn Guo" <shawnguo@kernel.org>,
	"Sascha Hauer" <s.hauer@pengutronix.de>,
	"Pengutronix Kernel Team" <kernel@pengutronix.de>,
	"Fabio Estevam" <festevam@gmail.com>,
	"NXP Linux Team" <linux-imx@nxp.com>,
	"Miquel Raynal" <miquel.raynal@bootlin.com>,
	"Michael Walle" <michael@walle.cc>,
	devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, u-boot@lists.denx.de,
	"Rafał Miłecki" <rafal@milecki.pl>
Subject: [PATCH V2 2/6] nvmem: core: allow .read_post_process() callbacks to adjust buffer
Date: Wed, 11 Jan 2023 08:30:58 +0100	[thread overview]
Message-ID: <20230111073102.8147-2-zajec5@gmail.com> (raw)
In-Reply-To: <20230111073102.8147-1-zajec5@gmail.com>

From: Rafał Miłecki <rafal@milecki.pl>

Sometimes reading NVMEM cell value involves some data reformatting. it
may require resizing available buffer. 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>
---
V2: Pass buffer pointer to allow krealloc() if needed
---
 drivers/nvmem/core.c             | 27 ++++++++++++++++-----------
 drivers/nvmem/imx-ocotp.c        |  8 ++++----
 drivers/nvmem/layouts/onie-tlv.c |  5 ++---
 drivers/nvmem/layouts/sl28vpd.c  | 10 +++++-----
 include/linux/nvmem-provider.h   |  5 ++---
 5 files changed, 29 insertions(+), 26 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 32f7fb81375a..2c9e4ac8a772 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -1539,29 +1539,26 @@ static void nvmem_shift_read_buffer_in_place(struct nvmem_cell_entry *cell, void
 
 static int __nvmem_cell_read(struct nvmem_device *nvmem,
 			     struct nvmem_cell_entry *cell,
-			     void *buf, size_t *len, const char *id, int index)
+			     void **buf, size_t *len, const char *id, int index)
 {
 	int rc;
 
-	rc = nvmem_reg_read(nvmem, cell->offset, buf, cell->bytes);
+	rc = nvmem_reg_read(nvmem, cell->offset, *buf, *len);
 
 	if (rc)
 		return rc;
 
 	/* shift bits in-place */
 	if (cell->bit_offset || cell->nbits)
-		nvmem_shift_read_buffer_in_place(cell, buf);
+		nvmem_shift_read_buffer_in_place(cell, *buf);
 
 	if (cell->read_post_process) {
 		rc = cell->read_post_process(cell->priv, id, index,
-					     cell->offset, buf, cell->bytes);
+					     cell->offset, buf, len);
 		if (rc)
 			return rc;
 	}
 
-	if (len)
-		*len = cell->bytes;
-
 	return 0;
 }
 
@@ -1578,22 +1575,26 @@ static int __nvmem_cell_read(struct nvmem_device *nvmem,
 void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len)
 {
 	struct nvmem_device *nvmem = cell->entry->nvmem;
-	u8 *buf;
+	size_t bytes = cell->entry->bytes;
+	void *buf;
 	int rc;
 
 	if (!nvmem)
 		return ERR_PTR(-EINVAL);
 
-	buf = kzalloc(cell->entry->bytes, GFP_KERNEL);
+	buf = kzalloc(bytes, GFP_KERNEL);
 	if (!buf)
 		return ERR_PTR(-ENOMEM);
 
-	rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id, cell->index);
+	rc = __nvmem_cell_read(nvmem, cell->entry, &buf, &bytes, cell->id, cell->index);
 	if (rc) {
 		kfree(buf);
 		return ERR_PTR(rc);
 	}
 
+	if (len)
+		*len = bytes;
+
 	return buf;
 }
 EXPORT_SYMBOL_GPL(nvmem_cell_read);
@@ -1905,11 +1906,15 @@ ssize_t nvmem_device_cell_read(struct nvmem_device *nvmem,
 	if (!nvmem)
 		return -EINVAL;
 
+	/* Cells with read_post_process hook may realloc buffer we can't allow here */
+	if (info->read_post_process)
+		return -EINVAL;
+
 	rc = nvmem_cell_info_to_nvmem_cell_entry_nodup(nvmem, info, &cell);
 	if (rc)
 		return rc;
 
-	rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL, 0);
+	rc = __nvmem_cell_read(nvmem, &cell, &buf, &cell.bytes, NULL, 0);
 	if (rc)
 		return rc;
 
diff --git a/drivers/nvmem/imx-ocotp.c b/drivers/nvmem/imx-ocotp.c
index ac0edb6398f1..e17500bc0acc 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;
+	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 767f39fff717..f26bcce2a44d 100644
--- a/drivers/nvmem/layouts/onie-tlv.c
+++ b/drivers/nvmem/layouts/onie-tlv.c
@@ -75,10 +75,9 @@ 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)
+				unsigned int offset, void **buf, size_t *bytes)
 {
-	eth_addr_add(buf, index);
+	eth_addr_add(*buf, index);
 
 	return 0;
 }
diff --git a/drivers/nvmem/layouts/sl28vpd.c b/drivers/nvmem/layouts/sl28vpd.c
index a36800f201a3..869cb513d79a 100644
--- a/drivers/nvmem/layouts/sl28vpd.c
+++ b/drivers/nvmem/layouts/sl28vpd.c
@@ -22,19 +22,19 @@ struct sl28vpd_v1 {
 } __packed;
 
 static int sl28vpd_mac_address_pp(void *priv, const char *id, int index,
-				  unsigned int offset, void *buf,
-				  size_t bytes)
+				  unsigned int offset, void **buf,
+				  size_t *bytes)
 {
-	if (bytes != ETH_ALEN)
+	if (*bytes != ETH_ALEN)
 		return -EINVAL;
 
 	if (index < 0)
 		return -EINVAL;
 
-	if (!is_valid_ether_addr(buf))
+	if (!is_valid_ether_addr(*buf))
 		return -EINVAL;
 
-	eth_addr_add(buf, index);
+	eth_addr_add(*buf, index);
 
 	return 0;
 }
diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h
index 0cf9f9490514..e70766013f97 100644
--- a/include/linux/nvmem-provider.h
+++ b/include/linux/nvmem-provider.h
@@ -19,9 +19,8 @@ typedef int (*nvmem_reg_read_t)(void *priv, unsigned int offset,
 typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset,
 				 void *val, size_t bytes);
 /* 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);
+typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, int index, unsigned int offset,
+					 void **buf, size_t *bytes);
 
 enum nvmem_type {
 	NVMEM_TYPE_UNKNOWN = 0,
-- 
2.34.1


  reply	other threads:[~2023-01-11  7:31 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-11  7:30 [PATCH V2 1/6] nvmem: core: add nvmem_dev_size() helper Rafał Miłecki
2023-01-11  7:30 ` Rafał Miłecki [this message]
2023-01-11 11:07   ` [PATCH V2 2/6] nvmem: core: allow .read_post_process() callbacks to adjust buffer kernel test robot
2023-01-11  7:30 ` [PATCH V2 3/6] dt-bindings: nvmem: convert U-Boot env vars to NVMEM layout Rafał Miłecki
2023-01-13 16:46   ` Rob Herring
2023-01-11  7:31 ` [PATCH V2 4/6] nvmem: u-boot-env: convert to layout driver Rafał Miłecki
2023-01-11  7:31 ` [PATCH V2 5/6] dt-bindings: nvmem: u-boot,env: add MAC's #nvmem-cell-cells Rafał Miłecki
2023-01-13 16:47   ` Rob Herring
2023-01-11  7:31 ` [PATCH V2 6/6] nvmem: u-boot-env: post process "ethaddr" env variable Rafał Miłecki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230111073102.8147-2-zajec5@gmail.com \
    --to=zajec5@gmail.com \
    --cc=devicetree@vger.kernel.org \
    --cc=festevam@gmail.com \
    --cc=kernel@pengutronix.de \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-imx@nxp.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=michael@walle.cc \
    --cc=miquel.raynal@bootlin.com \
    --cc=rafal@milecki.pl \
    --cc=robh+dt@kernel.org \
    --cc=s.hauer@pengutronix.de \
    --cc=shawnguo@kernel.org \
    --cc=srinivas.kandagatla@linaro.org \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).