All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/3] nvmem: migrate to const void * in reg_write
@ 2026-07-26 13:17 ` Link Mauve
  0 siblings, 0 replies; 10+ messages in thread
From: Link Mauve @ 2026-07-26 13:17 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Link Mauve, Andy Shevchenko, Neil Armstrong, Kevin Hilman,
	Jerome Brunet, Martin Blumenstingl, Sven Peter, Janne Grunau,
	Neal Gompa, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Vladimir Zapolskiy, André Draszik, Orson Zhai,
	Baolin Wang, Chunyan Zhang, Maxime Coquelin, Alexandre Torgue,
	Kalyani Akula, Michal Simek, Miguel Ojeda, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
	Alexandre Courbot, Onur Özkan, Johan Hovold, Ronald Claveau,
	Daniel Lezcano, linux-arm-kernel, linux-amlogic, linux-kernel,
	asahi, imx, linux-arm-msm, linux-stm32, rust-for-linux

This callback used to take a mutable void * for no reason, which causes
the compiler to be unaware that the val buffer should never be modified
by the callback.

This was found while drafting the nvmem-provider Rust abstraction.

Thanks to the guidance of Andy Shevchenko, this now introduces a new
callback and deprecates the existing one, with the goal of renaming the
new one into the old one once no user remains in the kernel.

Changes since v3:
- Link to v3:
  https://lore.kernel.org/rust-for-linux/20260716142415.28718-1-linkmauve@linkmauve.fr/T/
- Drop Apple SPMI patch, which had already been independently included
  in linux-next as 7089170e1df160f5f8fb395bc5aa2e2697b4e896.
- Reword the cover letter’s subject.
- Reorder the meson firmware patch before the other ones, so that every
  commit is always working correctly.

Changes since v2:
- Link to v2:
  https://lore.kernel.org/rust-for-linux/aljAqBNVXV1aVJqx@luna/T/
- Rebase on top of linux-next/master.
- Fix logic error which made all devices read-only.
- Remove a blanket cast of function pointers to void * in
  apple-spmi-nvmem (patch 3).
- Also fix constness of write buffer in firmware: meson, which is used
  exclusively by meson-efuse (patch 4).
- Re-review all changes to make sure the passed types are more correct
  than they were before.
- Actually test with COMPILE_TEST, which I forgot to enable before…

Changes since v1:
- Link to v1:
  https://lore.kernel.org/rust-for-linux/20260715175229.24672-1-linkmauve@linkmauve.fr/
- Removed all changes to other subsystems than nvmem.
- Added a new reg_write_const callback instead of changing the exisitng
  reg_write.
- Deprecated the existing reg_write callback, it will get removed once
  all users in the kernel will be done migrating to the new one.

Link Mauve (3):
  firmware: meson: pass a const buffer to meson_sm_call_write()
  nvmem: core: deprecate reg_write callback and add reg_write_const
  nvmem: make all reg_write callbacks take const void *

 drivers/firmware/meson/meson_sm.c       |  2 +-
 drivers/nvmem/apple-spmi-nvmem.c        |  4 ++--
 drivers/nvmem/bcm-ocotp.c               |  8 +++----
 drivers/nvmem/core.c                    | 28 ++++++++++++++-----------
 drivers/nvmem/imx-ocotp-scu.c           |  6 +++---
 drivers/nvmem/imx-ocotp.c               |  6 +++---
 drivers/nvmem/internals.h               |  1 +
 drivers/nvmem/lan9662-otpc.c            |  6 +++---
 drivers/nvmem/lpc18xx_eeprom.c          |  6 +++---
 drivers/nvmem/max77759-nvmem.c          |  4 ++--
 drivers/nvmem/meson-efuse.c             |  8 +++----
 drivers/nvmem/qcom-spmi-sdam.c          |  6 +++---
 drivers/nvmem/qfprom.c                  |  6 +++---
 drivers/nvmem/rave-sp-eeprom.c          |  6 +++---
 drivers/nvmem/snvs_lpgpr.c              |  4 ++--
 drivers/nvmem/sprd-efuse.c              |  6 +++---
 drivers/nvmem/stm32-bsec-optee-ta.c     |  2 +-
 drivers/nvmem/stm32-bsec-optee-ta.h     |  4 ++--
 drivers/nvmem/stm32-romem.c             | 10 ++++-----
 drivers/nvmem/zynqmp_nvmem.c            |  6 +++---
 include/linux/firmware/meson/meson_sm.h |  2 +-
 include/linux/nvmem-provider.h          |  6 +++++-
 22 files changed, 73 insertions(+), 64 deletions(-)


base-commit: 9eebf259d5352b87080d67758f483583d9e763d7
-- 
2.55.0



^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v4 0/3] nvmem: migrate to const void * in reg_write
@ 2026-07-26 13:17 ` Link Mauve
  0 siblings, 0 replies; 10+ messages in thread
From: Link Mauve @ 2026-07-26 13:17 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Link Mauve, Andy Shevchenko, Neil Armstrong, Kevin Hilman,
	Jerome Brunet, Martin Blumenstingl, Sven Peter, Janne Grunau,
	Neal Gompa, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Vladimir Zapolskiy, André Draszik, Orson Zhai,
	Baolin Wang, Chunyan Zhang, Maxime Coquelin, Alexandre Torgue,
	Kalyani Akula, Michal Simek, Miguel Ojeda, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
	Alexandre Courbot, Onur Özkan, Johan Hovold, Ronald Claveau,
	Daniel Lezcano, linux-arm-kernel, linux-amlogic, linux-kernel,
	asahi, imx, linux-arm-msm, linux-stm32, rust-for-linux

This callback used to take a mutable void * for no reason, which causes
the compiler to be unaware that the val buffer should never be modified
by the callback.

This was found while drafting the nvmem-provider Rust abstraction.

Thanks to the guidance of Andy Shevchenko, this now introduces a new
callback and deprecates the existing one, with the goal of renaming the
new one into the old one once no user remains in the kernel.

Changes since v3:
- Link to v3:
  https://lore.kernel.org/rust-for-linux/20260716142415.28718-1-linkmauve@linkmauve.fr/T/
- Drop Apple SPMI patch, which had already been independently included
  in linux-next as 7089170e1df160f5f8fb395bc5aa2e2697b4e896.
- Reword the cover letter’s subject.
- Reorder the meson firmware patch before the other ones, so that every
  commit is always working correctly.

Changes since v2:
- Link to v2:
  https://lore.kernel.org/rust-for-linux/aljAqBNVXV1aVJqx@luna/T/
- Rebase on top of linux-next/master.
- Fix logic error which made all devices read-only.
- Remove a blanket cast of function pointers to void * in
  apple-spmi-nvmem (patch 3).
- Also fix constness of write buffer in firmware: meson, which is used
  exclusively by meson-efuse (patch 4).
- Re-review all changes to make sure the passed types are more correct
  than they were before.
- Actually test with COMPILE_TEST, which I forgot to enable before…

Changes since v1:
- Link to v1:
  https://lore.kernel.org/rust-for-linux/20260715175229.24672-1-linkmauve@linkmauve.fr/
- Removed all changes to other subsystems than nvmem.
- Added a new reg_write_const callback instead of changing the exisitng
  reg_write.
- Deprecated the existing reg_write callback, it will get removed once
  all users in the kernel will be done migrating to the new one.

Link Mauve (3):
  firmware: meson: pass a const buffer to meson_sm_call_write()
  nvmem: core: deprecate reg_write callback and add reg_write_const
  nvmem: make all reg_write callbacks take const void *

 drivers/firmware/meson/meson_sm.c       |  2 +-
 drivers/nvmem/apple-spmi-nvmem.c        |  4 ++--
 drivers/nvmem/bcm-ocotp.c               |  8 +++----
 drivers/nvmem/core.c                    | 28 ++++++++++++++-----------
 drivers/nvmem/imx-ocotp-scu.c           |  6 +++---
 drivers/nvmem/imx-ocotp.c               |  6 +++---
 drivers/nvmem/internals.h               |  1 +
 drivers/nvmem/lan9662-otpc.c            |  6 +++---
 drivers/nvmem/lpc18xx_eeprom.c          |  6 +++---
 drivers/nvmem/max77759-nvmem.c          |  4 ++--
 drivers/nvmem/meson-efuse.c             |  8 +++----
 drivers/nvmem/qcom-spmi-sdam.c          |  6 +++---
 drivers/nvmem/qfprom.c                  |  6 +++---
 drivers/nvmem/rave-sp-eeprom.c          |  6 +++---
 drivers/nvmem/snvs_lpgpr.c              |  4 ++--
 drivers/nvmem/sprd-efuse.c              |  6 +++---
 drivers/nvmem/stm32-bsec-optee-ta.c     |  2 +-
 drivers/nvmem/stm32-bsec-optee-ta.h     |  4 ++--
 drivers/nvmem/stm32-romem.c             | 10 ++++-----
 drivers/nvmem/zynqmp_nvmem.c            |  6 +++---
 include/linux/firmware/meson/meson_sm.h |  2 +-
 include/linux/nvmem-provider.h          |  6 +++++-
 22 files changed, 73 insertions(+), 64 deletions(-)


base-commit: 9eebf259d5352b87080d67758f483583d9e763d7
-- 
2.55.0


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v4 1/3] firmware: meson: pass a const buffer to meson_sm_call_write()
  2026-07-26 13:17 ` Link Mauve
@ 2026-07-26 13:17   ` Link Mauve
  -1 siblings, 0 replies; 10+ messages in thread
From: Link Mauve @ 2026-07-26 13:17 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Link Mauve, Andy Shevchenko, Neil Armstrong, Kevin Hilman,
	Jerome Brunet, Martin Blumenstingl, Sven Peter, Janne Grunau,
	Neal Gompa, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Vladimir Zapolskiy, André Draszik, Orson Zhai,
	Baolin Wang, Chunyan Zhang, Maxime Coquelin, Alexandre Torgue,
	Kalyani Akula, Michal Simek, Miguel Ojeda, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
	Alexandre Courbot, Onur Özkan, Johan Hovold, Ronald Claveau,
	Daniel Lezcano, linux-arm-kernel, linux-amlogic, linux-kernel,
	asahi, imx, linux-arm-msm, linux-stm32, rust-for-linux

This was found while introducing the new nvmem-provider reg_write_const
callback in meson_sm_call_write()’s only user, in meson-efuse.

Signed-off-by: Link Mauve <linkmauve@linkmauve.fr>
---
 drivers/firmware/meson/meson_sm.c       | 2 +-
 drivers/nvmem/meson-efuse.c             | 4 ++--
 include/linux/firmware/meson/meson_sm.h | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/meson/meson_sm.c b/drivers/firmware/meson/meson_sm.c
index ab9751a59b55..5d4da2e3c3a9 100644
--- a/drivers/firmware/meson/meson_sm.c
+++ b/drivers/firmware/meson/meson_sm.c
@@ -196,7 +196,7 @@ EXPORT_SYMBOL(meson_sm_call_read);
  *
  * Return:	size of sent data on success, a negative value on error
  */
-int meson_sm_call_write(struct meson_sm_firmware *fw, void *buffer,
+int meson_sm_call_write(struct meson_sm_firmware *fw, const void *buffer,
 			unsigned int size, unsigned int cmd_index, u32 arg0,
 			u32 arg1, u32 arg2, u32 arg3, u32 arg4)
 {
diff --git a/drivers/nvmem/meson-efuse.c b/drivers/nvmem/meson-efuse.c
index d7f9ac99a212..f71854f89950 100644
--- a/drivers/nvmem/meson-efuse.c
+++ b/drivers/nvmem/meson-efuse.c
@@ -20,7 +20,7 @@ static int meson_efuse_read(void *context, unsigned int offset,
 	struct meson_sm_firmware *fw = context;
 	int ret;
 
-	ret = meson_sm_call_read(fw, (u8 *)val, bytes, SM_EFUSE_READ, offset,
+	ret = meson_sm_call_read(fw, val, bytes, SM_EFUSE_READ, offset,
 				 bytes, 0, 0, 0);
 
 	return ret < 0 ? ret : 0;
@@ -32,7 +32,7 @@ static int meson_efuse_write(void *context, unsigned int offset,
 	struct meson_sm_firmware *fw = context;
 	int ret;
 
-	ret = meson_sm_call_write(fw, (u8 *)val, bytes, SM_EFUSE_WRITE, offset,
+	ret = meson_sm_call_write(fw, val, bytes, SM_EFUSE_WRITE, offset,
 				  bytes, 0, 0, 0);
 
 	return ret < 0 ? ret : 0;
diff --git a/include/linux/firmware/meson/meson_sm.h b/include/linux/firmware/meson/meson_sm.h
index 3ebc2bd9a976..92cc61f3a1c0 100644
--- a/include/linux/firmware/meson/meson_sm.h
+++ b/include/linux/firmware/meson/meson_sm.h
@@ -21,7 +21,7 @@ struct meson_sm_firmware;
 
 int meson_sm_call(struct meson_sm_firmware *fw, unsigned int cmd_index,
 		  s32 *ret, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4);
-int meson_sm_call_write(struct meson_sm_firmware *fw, void *buffer,
+int meson_sm_call_write(struct meson_sm_firmware *fw, const void *buffer,
 			unsigned int b_size, unsigned int cmd_index, u32 arg0,
 			u32 arg1, u32 arg2, u32 arg3, u32 arg4);
 int meson_sm_call_read(struct meson_sm_firmware *fw, void *buffer,
-- 
2.55.0



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v4 1/3] firmware: meson: pass a const buffer to meson_sm_call_write()
@ 2026-07-26 13:17   ` Link Mauve
  0 siblings, 0 replies; 10+ messages in thread
From: Link Mauve @ 2026-07-26 13:17 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Link Mauve, Andy Shevchenko, Neil Armstrong, Kevin Hilman,
	Jerome Brunet, Martin Blumenstingl, Sven Peter, Janne Grunau,
	Neal Gompa, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Vladimir Zapolskiy, André Draszik, Orson Zhai,
	Baolin Wang, Chunyan Zhang, Maxime Coquelin, Alexandre Torgue,
	Kalyani Akula, Michal Simek, Miguel Ojeda, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
	Alexandre Courbot, Onur Özkan, Johan Hovold, Ronald Claveau,
	Daniel Lezcano, linux-arm-kernel, linux-amlogic, linux-kernel,
	asahi, imx, linux-arm-msm, linux-stm32, rust-for-linux

This was found while introducing the new nvmem-provider reg_write_const
callback in meson_sm_call_write()’s only user, in meson-efuse.

Signed-off-by: Link Mauve <linkmauve@linkmauve.fr>
---
 drivers/firmware/meson/meson_sm.c       | 2 +-
 drivers/nvmem/meson-efuse.c             | 4 ++--
 include/linux/firmware/meson/meson_sm.h | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/meson/meson_sm.c b/drivers/firmware/meson/meson_sm.c
index ab9751a59b55..5d4da2e3c3a9 100644
--- a/drivers/firmware/meson/meson_sm.c
+++ b/drivers/firmware/meson/meson_sm.c
@@ -196,7 +196,7 @@ EXPORT_SYMBOL(meson_sm_call_read);
  *
  * Return:	size of sent data on success, a negative value on error
  */
-int meson_sm_call_write(struct meson_sm_firmware *fw, void *buffer,
+int meson_sm_call_write(struct meson_sm_firmware *fw, const void *buffer,
 			unsigned int size, unsigned int cmd_index, u32 arg0,
 			u32 arg1, u32 arg2, u32 arg3, u32 arg4)
 {
diff --git a/drivers/nvmem/meson-efuse.c b/drivers/nvmem/meson-efuse.c
index d7f9ac99a212..f71854f89950 100644
--- a/drivers/nvmem/meson-efuse.c
+++ b/drivers/nvmem/meson-efuse.c
@@ -20,7 +20,7 @@ static int meson_efuse_read(void *context, unsigned int offset,
 	struct meson_sm_firmware *fw = context;
 	int ret;
 
-	ret = meson_sm_call_read(fw, (u8 *)val, bytes, SM_EFUSE_READ, offset,
+	ret = meson_sm_call_read(fw, val, bytes, SM_EFUSE_READ, offset,
 				 bytes, 0, 0, 0);
 
 	return ret < 0 ? ret : 0;
@@ -32,7 +32,7 @@ static int meson_efuse_write(void *context, unsigned int offset,
 	struct meson_sm_firmware *fw = context;
 	int ret;
 
-	ret = meson_sm_call_write(fw, (u8 *)val, bytes, SM_EFUSE_WRITE, offset,
+	ret = meson_sm_call_write(fw, val, bytes, SM_EFUSE_WRITE, offset,
 				  bytes, 0, 0, 0);
 
 	return ret < 0 ? ret : 0;
diff --git a/include/linux/firmware/meson/meson_sm.h b/include/linux/firmware/meson/meson_sm.h
index 3ebc2bd9a976..92cc61f3a1c0 100644
--- a/include/linux/firmware/meson/meson_sm.h
+++ b/include/linux/firmware/meson/meson_sm.h
@@ -21,7 +21,7 @@ struct meson_sm_firmware;
 
 int meson_sm_call(struct meson_sm_firmware *fw, unsigned int cmd_index,
 		  s32 *ret, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4);
-int meson_sm_call_write(struct meson_sm_firmware *fw, void *buffer,
+int meson_sm_call_write(struct meson_sm_firmware *fw, const void *buffer,
 			unsigned int b_size, unsigned int cmd_index, u32 arg0,
 			u32 arg1, u32 arg2, u32 arg3, u32 arg4);
 int meson_sm_call_read(struct meson_sm_firmware *fw, void *buffer,
-- 
2.55.0


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v4 2/3] nvmem: core: deprecate reg_write callback and add reg_write_const
  2026-07-26 13:17 ` Link Mauve
@ 2026-07-26 13:17   ` Link Mauve
  -1 siblings, 0 replies; 10+ messages in thread
From: Link Mauve @ 2026-07-26 13:17 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Link Mauve, Andy Shevchenko, Neil Armstrong, Kevin Hilman,
	Jerome Brunet, Martin Blumenstingl, Sven Peter, Janne Grunau,
	Neal Gompa, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Vladimir Zapolskiy, André Draszik, Orson Zhai,
	Baolin Wang, Chunyan Zhang, Maxime Coquelin, Alexandre Torgue,
	Kalyani Akula, Michal Simek, Miguel Ojeda, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
	Alexandre Courbot, Onur Özkan, Johan Hovold, Ronald Claveau,
	Daniel Lezcano, linux-arm-kernel, linux-amlogic, linux-kernel,
	asahi, imx, linux-arm-msm, linux-stm32, rust-for-linux

This callback used to take a mutable void * for no reason, which causes
the compiler to be unaware that the val buffer should never be modified
by the callback.

This was found while drafting the nvmem-provider Rust abstraction.

Signed-off-by: Link Mauve <linkmauve@linkmauve.fr>
---
 drivers/nvmem/core.c           | 28 ++++++++++++++++------------
 drivers/nvmem/internals.h      |  1 +
 include/linux/nvmem-provider.h |  6 +++++-
 3 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index f65aebe7837b..8e10fa34619f 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -71,7 +71,7 @@ static int __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
 }
 
 static int __nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset,
-			     void *val, size_t bytes)
+			     const void *val, size_t bytes)
 {
 	struct nvmem_operations *ops;
 	int ret, wr_ok;
@@ -81,14 +81,17 @@ static int __nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset,
 	if (!ops)
 		return -ENODEV;
 
-	if (!ops->reg_write)
+	if (!ops->reg_write && !ops->reg_write_const)
 		return -EOPNOTSUPP;
 
 	ret = gpiod_set_value_cansleep(nvmem->wp_gpio, 0);
 	if (ret)
 		return ret;
 
-	wr_ok = ops->reg_write(nvmem->priv, offset, val, bytes);
+	if (ops->reg_write_const)
+		wr_ok = ops->reg_write_const(nvmem->priv, offset, val, bytes);
+	else
+		wr_ok = ops->reg_write(nvmem->priv, offset, (void *)val, bytes);
 
 	ret = gpiod_set_value_cansleep(nvmem->wp_gpio, 1);
 	if (ret)
@@ -121,7 +124,7 @@ static int nvmem_access_with_keepouts(struct nvmem_device *nvmem,
 			kend = min(end, keepout->start);
 			ksize = kend - offset;
 			if (write)
-				rc = __nvmem_reg_write(nvmem, offset, val, ksize);
+				rc = __nvmem_reg_write(nvmem, offset, (const void *)val, ksize);
 			else
 				rc = __nvmem_reg_read(nvmem, offset, val, ksize);
 
@@ -153,7 +156,7 @@ static int nvmem_access_with_keepouts(struct nvmem_device *nvmem,
 	if (offset < end) {
 		ksize = end - offset;
 		if (write)
-			return __nvmem_reg_write(nvmem, offset, val, ksize);
+			return __nvmem_reg_write(nvmem, offset, (const void *)val, ksize);
 		else
 			return __nvmem_reg_read(nvmem, offset, val, ksize);
 	}
@@ -174,7 +177,7 @@ static int nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset,
 			   void *val, size_t bytes)
 {
 	if (!nvmem->nkeepout)
-		return __nvmem_reg_write(nvmem, offset, val, bytes);
+		return __nvmem_reg_write(nvmem, offset, (const void *)val, bytes);
 
 	return nvmem_access_with_keepouts(nvmem, offset, val, bytes, true);
 }
@@ -309,7 +312,7 @@ static umode_t nvmem_bin_attr_get_umode(struct nvmem_device *nvmem)
 	if (!nvmem->read_only)
 		mode |= 0200;
 
-	if (!ops->reg_write)
+	if (!ops->reg_write && !ops->reg_write_const)
 		mode &= ~0200;
 
 	if (!ops->reg_read)
@@ -346,13 +349,13 @@ static umode_t nvmem_attr_is_visible(struct kobject *kobj,
 	struct nvmem_operations *ops = rcu_dereference_raw(nvmem->ops);
 
 	/*
-	 * If the device has no .reg_write operation, do not allow
-	 * configuration as read-write.
+	 * If the device has no .reg_write or .reg_write_const operation, do
+	 * not allow configuration as read-write.
 	 * If the device is set as read-only by configuration, it
 	 * can be forced into read-write mode using the 'force_ro'
 	 * attribute.
 	 */
-	if (attr == &dev_attr_force_ro.attr && !ops->reg_write)
+	if (attr == &dev_attr_force_ro.attr && !ops->reg_write && !ops->reg_write_const)
 		return 0;	/* Attribute not visible */
 
 	return attr->mode;
@@ -904,7 +907,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 	if (!config->dev)
 		return ERR_PTR(-EINVAL);
 
-	if (!config->reg_read && !config->reg_write)
+	if (!config->reg_read && !config->reg_write && !config->reg_write_const)
 		return ERR_PTR(-EINVAL);
 
 	nvmem = kzalloc_obj(*nvmem);
@@ -960,6 +963,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 
 	ops->reg_read = config->reg_read;
 	ops->reg_write = config->reg_write;
+	ops->reg_write_const = config->reg_write_const;
 
 	nvmem->owner = config->owner;
 	if (!nvmem->owner && config->dev->driver)
@@ -995,7 +999,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 		goto err_put_device;
 
 	nvmem->read_only = device_property_present(config->dev, "read-only") ||
-			   config->read_only || !ops->reg_write;
+			   config->read_only || (!ops->reg_write && !ops->reg_write_const);
 
 #ifdef CONFIG_NVMEM_SYSFS
 	nvmem->dev.groups = nvmem_dev_groups;
diff --git a/drivers/nvmem/internals.h b/drivers/nvmem/internals.h
index bc7a99f5aefb..14243d44815d 100644
--- a/drivers/nvmem/internals.h
+++ b/drivers/nvmem/internals.h
@@ -12,6 +12,7 @@
 struct nvmem_operations {
 	nvmem_reg_read_t	reg_read;
 	nvmem_reg_write_t	reg_write;
+	nvmem_reg_write_const_t	reg_write_const;
 };
 
 struct nvmem_device {
diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h
index 6063fe5b7784..e944530999b4 100644
--- a/include/linux/nvmem-provider.h
+++ b/include/linux/nvmem-provider.h
@@ -20,6 +20,8 @@ typedef int (*nvmem_reg_read_t)(void *priv, unsigned int offset,
 				void *val, size_t bytes);
 typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset,
 				 void *val, size_t bytes);
+typedef int (*nvmem_reg_write_const_t)(void *priv, unsigned int offset,
+				       const 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,
@@ -93,7 +95,8 @@ struct nvmem_cell_info {
  * @root_only:	Device is accessibly to root only.
  * @of_node:	If given, this will be used instead of the parent's of_node.
  * @reg_read:	Callback to read data; return zero if successful.
- * @reg_write:	Callback to write data; return zero if successful.
+ * @reg_write:	**DEPRECATED** - please use reg_write_const instead.
+ * @reg_write_const:	Callback to write data; return zero if successful.
  * @size:	Device size.
  * @word_size:	Minimum read/write access granularity.
  * @stride:	Minimum read/write access stride.
@@ -128,6 +131,7 @@ struct nvmem_config {
 	struct device_node	*of_node;
 	nvmem_reg_read_t	reg_read;
 	nvmem_reg_write_t	reg_write;
+	nvmem_reg_write_const_t	reg_write_const;
 	int	size;
 	int	word_size;
 	int	stride;
-- 
2.55.0



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v4 2/3] nvmem: core: deprecate reg_write callback and add reg_write_const
@ 2026-07-26 13:17   ` Link Mauve
  0 siblings, 0 replies; 10+ messages in thread
From: Link Mauve @ 2026-07-26 13:17 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Link Mauve, Andy Shevchenko, Neil Armstrong, Kevin Hilman,
	Jerome Brunet, Martin Blumenstingl, Sven Peter, Janne Grunau,
	Neal Gompa, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Vladimir Zapolskiy, André Draszik, Orson Zhai,
	Baolin Wang, Chunyan Zhang, Maxime Coquelin, Alexandre Torgue,
	Kalyani Akula, Michal Simek, Miguel Ojeda, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
	Alexandre Courbot, Onur Özkan, Johan Hovold, Ronald Claveau,
	Daniel Lezcano, linux-arm-kernel, linux-amlogic, linux-kernel,
	asahi, imx, linux-arm-msm, linux-stm32, rust-for-linux

This callback used to take a mutable void * for no reason, which causes
the compiler to be unaware that the val buffer should never be modified
by the callback.

This was found while drafting the nvmem-provider Rust abstraction.

Signed-off-by: Link Mauve <linkmauve@linkmauve.fr>
---
 drivers/nvmem/core.c           | 28 ++++++++++++++++------------
 drivers/nvmem/internals.h      |  1 +
 include/linux/nvmem-provider.h |  6 +++++-
 3 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index f65aebe7837b..8e10fa34619f 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -71,7 +71,7 @@ static int __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
 }
 
 static int __nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset,
-			     void *val, size_t bytes)
+			     const void *val, size_t bytes)
 {
 	struct nvmem_operations *ops;
 	int ret, wr_ok;
@@ -81,14 +81,17 @@ static int __nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset,
 	if (!ops)
 		return -ENODEV;
 
-	if (!ops->reg_write)
+	if (!ops->reg_write && !ops->reg_write_const)
 		return -EOPNOTSUPP;
 
 	ret = gpiod_set_value_cansleep(nvmem->wp_gpio, 0);
 	if (ret)
 		return ret;
 
-	wr_ok = ops->reg_write(nvmem->priv, offset, val, bytes);
+	if (ops->reg_write_const)
+		wr_ok = ops->reg_write_const(nvmem->priv, offset, val, bytes);
+	else
+		wr_ok = ops->reg_write(nvmem->priv, offset, (void *)val, bytes);
 
 	ret = gpiod_set_value_cansleep(nvmem->wp_gpio, 1);
 	if (ret)
@@ -121,7 +124,7 @@ static int nvmem_access_with_keepouts(struct nvmem_device *nvmem,
 			kend = min(end, keepout->start);
 			ksize = kend - offset;
 			if (write)
-				rc = __nvmem_reg_write(nvmem, offset, val, ksize);
+				rc = __nvmem_reg_write(nvmem, offset, (const void *)val, ksize);
 			else
 				rc = __nvmem_reg_read(nvmem, offset, val, ksize);
 
@@ -153,7 +156,7 @@ static int nvmem_access_with_keepouts(struct nvmem_device *nvmem,
 	if (offset < end) {
 		ksize = end - offset;
 		if (write)
-			return __nvmem_reg_write(nvmem, offset, val, ksize);
+			return __nvmem_reg_write(nvmem, offset, (const void *)val, ksize);
 		else
 			return __nvmem_reg_read(nvmem, offset, val, ksize);
 	}
@@ -174,7 +177,7 @@ static int nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset,
 			   void *val, size_t bytes)
 {
 	if (!nvmem->nkeepout)
-		return __nvmem_reg_write(nvmem, offset, val, bytes);
+		return __nvmem_reg_write(nvmem, offset, (const void *)val, bytes);
 
 	return nvmem_access_with_keepouts(nvmem, offset, val, bytes, true);
 }
@@ -309,7 +312,7 @@ static umode_t nvmem_bin_attr_get_umode(struct nvmem_device *nvmem)
 	if (!nvmem->read_only)
 		mode |= 0200;
 
-	if (!ops->reg_write)
+	if (!ops->reg_write && !ops->reg_write_const)
 		mode &= ~0200;
 
 	if (!ops->reg_read)
@@ -346,13 +349,13 @@ static umode_t nvmem_attr_is_visible(struct kobject *kobj,
 	struct nvmem_operations *ops = rcu_dereference_raw(nvmem->ops);
 
 	/*
-	 * If the device has no .reg_write operation, do not allow
-	 * configuration as read-write.
+	 * If the device has no .reg_write or .reg_write_const operation, do
+	 * not allow configuration as read-write.
 	 * If the device is set as read-only by configuration, it
 	 * can be forced into read-write mode using the 'force_ro'
 	 * attribute.
 	 */
-	if (attr == &dev_attr_force_ro.attr && !ops->reg_write)
+	if (attr == &dev_attr_force_ro.attr && !ops->reg_write && !ops->reg_write_const)
 		return 0;	/* Attribute not visible */
 
 	return attr->mode;
@@ -904,7 +907,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 	if (!config->dev)
 		return ERR_PTR(-EINVAL);
 
-	if (!config->reg_read && !config->reg_write)
+	if (!config->reg_read && !config->reg_write && !config->reg_write_const)
 		return ERR_PTR(-EINVAL);
 
 	nvmem = kzalloc_obj(*nvmem);
@@ -960,6 +963,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 
 	ops->reg_read = config->reg_read;
 	ops->reg_write = config->reg_write;
+	ops->reg_write_const = config->reg_write_const;
 
 	nvmem->owner = config->owner;
 	if (!nvmem->owner && config->dev->driver)
@@ -995,7 +999,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 		goto err_put_device;
 
 	nvmem->read_only = device_property_present(config->dev, "read-only") ||
-			   config->read_only || !ops->reg_write;
+			   config->read_only || (!ops->reg_write && !ops->reg_write_const);
 
 #ifdef CONFIG_NVMEM_SYSFS
 	nvmem->dev.groups = nvmem_dev_groups;
diff --git a/drivers/nvmem/internals.h b/drivers/nvmem/internals.h
index bc7a99f5aefb..14243d44815d 100644
--- a/drivers/nvmem/internals.h
+++ b/drivers/nvmem/internals.h
@@ -12,6 +12,7 @@
 struct nvmem_operations {
 	nvmem_reg_read_t	reg_read;
 	nvmem_reg_write_t	reg_write;
+	nvmem_reg_write_const_t	reg_write_const;
 };
 
 struct nvmem_device {
diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h
index 6063fe5b7784..e944530999b4 100644
--- a/include/linux/nvmem-provider.h
+++ b/include/linux/nvmem-provider.h
@@ -20,6 +20,8 @@ typedef int (*nvmem_reg_read_t)(void *priv, unsigned int offset,
 				void *val, size_t bytes);
 typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset,
 				 void *val, size_t bytes);
+typedef int (*nvmem_reg_write_const_t)(void *priv, unsigned int offset,
+				       const 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,
@@ -93,7 +95,8 @@ struct nvmem_cell_info {
  * @root_only:	Device is accessibly to root only.
  * @of_node:	If given, this will be used instead of the parent's of_node.
  * @reg_read:	Callback to read data; return zero if successful.
- * @reg_write:	Callback to write data; return zero if successful.
+ * @reg_write:	**DEPRECATED** - please use reg_write_const instead.
+ * @reg_write_const:	Callback to write data; return zero if successful.
  * @size:	Device size.
  * @word_size:	Minimum read/write access granularity.
  * @stride:	Minimum read/write access stride.
@@ -128,6 +131,7 @@ struct nvmem_config {
 	struct device_node	*of_node;
 	nvmem_reg_read_t	reg_read;
 	nvmem_reg_write_t	reg_write;
+	nvmem_reg_write_const_t	reg_write_const;
 	int	size;
 	int	word_size;
 	int	stride;
-- 
2.55.0


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v4 3/3] nvmem: make all reg_write callbacks take const void *
  2026-07-26 13:17 ` Link Mauve
@ 2026-07-26 13:17   ` Link Mauve
  -1 siblings, 0 replies; 10+ messages in thread
From: Link Mauve @ 2026-07-26 13:17 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Link Mauve, Andy Shevchenko, Neil Armstrong, Kevin Hilman,
	Jerome Brunet, Martin Blumenstingl, Sven Peter, Janne Grunau,
	Neal Gompa, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Vladimir Zapolskiy, André Draszik, Orson Zhai,
	Baolin Wang, Chunyan Zhang, Maxime Coquelin, Alexandre Torgue,
	Kalyani Akula, Michal Simek, Miguel Ojeda, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
	Alexandre Courbot, Onur Özkan, Johan Hovold, Ronald Claveau,
	Daniel Lezcano, linux-arm-kernel, linux-amlogic, linux-kernel,
	asahi, imx, linux-arm-msm, linux-stm32, rust-for-linux

The previous commit switched from a pointer to mutable data to a pointer
to immutable data, so let’s fix all users of this API.

Signed-off-by: Link Mauve <linkmauve@linkmauve.fr>
---
 drivers/nvmem/apple-spmi-nvmem.c    |  4 ++--
 drivers/nvmem/bcm-ocotp.c           |  8 ++++----
 drivers/nvmem/imx-ocotp-scu.c       |  6 +++---
 drivers/nvmem/imx-ocotp.c           |  6 +++---
 drivers/nvmem/lan9662-otpc.c        |  6 +++---
 drivers/nvmem/lpc18xx_eeprom.c      |  6 +++---
 drivers/nvmem/max77759-nvmem.c      |  4 ++--
 drivers/nvmem/meson-efuse.c         |  4 ++--
 drivers/nvmem/qcom-spmi-sdam.c      |  6 +++---
 drivers/nvmem/qfprom.c              |  6 +++---
 drivers/nvmem/rave-sp-eeprom.c      |  6 +++---
 drivers/nvmem/snvs_lpgpr.c          |  4 ++--
 drivers/nvmem/sprd-efuse.c          |  6 +++---
 drivers/nvmem/stm32-bsec-optee-ta.c |  2 +-
 drivers/nvmem/stm32-bsec-optee-ta.h |  4 ++--
 drivers/nvmem/stm32-romem.c         | 10 +++++-----
 drivers/nvmem/zynqmp_nvmem.c        |  6 +++---
 17 files changed, 47 insertions(+), 47 deletions(-)

diff --git a/drivers/nvmem/apple-spmi-nvmem.c b/drivers/nvmem/apple-spmi-nvmem.c
index 7acb0c07d6ab..63b2b11d78f9 100644
--- a/drivers/nvmem/apple-spmi-nvmem.c
+++ b/drivers/nvmem/apple-spmi-nvmem.c
@@ -26,7 +26,7 @@ static int apple_spmi_nvmem_read(void *priv, unsigned int offset, void *val,
 	return regmap_bulk_read(map, offset, val, bytes);
 }
 
-static int apple_spmi_nvmem_write(void *priv, unsigned int offset, void *val,
+static int apple_spmi_nvmem_write(void *priv, unsigned int offset, const void *val,
 				  size_t bytes)
 {
 	struct regmap *map = priv;
@@ -45,7 +45,7 @@ static int apple_spmi_nvmem_probe(struct spmi_device *sdev)
 		.stride = 1,
 		.size = 0xffff,
 		.reg_read = apple_spmi_nvmem_read,
-		.reg_write = apple_spmi_nvmem_write,
+		.reg_write_const = apple_spmi_nvmem_write,
 	};
 
 	regmap = devm_regmap_init_spmi_ext(sdev, &apple_spmi_regmap_config);
diff --git a/drivers/nvmem/bcm-ocotp.c b/drivers/nvmem/bcm-ocotp.c
index 2490f44caa40..02adfd787de8 100644
--- a/drivers/nvmem/bcm-ocotp.c
+++ b/drivers/nvmem/bcm-ocotp.c
@@ -179,11 +179,11 @@ static int bcm_otpc_read(void *context, unsigned int offset, void *val,
 	return 0;
 }
 
-static int bcm_otpc_write(void *context, unsigned int offset, void *val,
-	size_t bytes)
+static int bcm_otpc_write(void *context, unsigned int offset, const void *val,
+			  size_t bytes)
 {
 	struct otpc_priv *priv = context;
-	u32 *buf = val;
+	const u32 *buf = val;
 	u32 bytes_written;
 	u32 address = offset / priv->config->word_size;
 	int i, ret;
@@ -223,7 +223,7 @@ static struct nvmem_config bcm_otpc_nvmem_config = {
 	.word_size = 4,
 	.stride = 4,
 	.reg_read = bcm_otpc_read,
-	.reg_write = bcm_otpc_write,
+	.reg_write_const = bcm_otpc_write,
 };
 
 static const struct of_device_id bcm_otpc_dt_ids[] = {
diff --git a/drivers/nvmem/imx-ocotp-scu.c b/drivers/nvmem/imx-ocotp-scu.c
index 517d83e11af2..57008228100f 100644
--- a/drivers/nvmem/imx-ocotp-scu.c
+++ b/drivers/nvmem/imx-ocotp-scu.c
@@ -178,11 +178,11 @@ static int imx_scu_ocotp_read(void *context, unsigned int offset,
 }
 
 static int imx_scu_ocotp_write(void *context, unsigned int offset,
-			       void *val, size_t bytes)
+			       const void *val, size_t bytes)
 {
 	struct ocotp_priv *priv = context;
 	struct arm_smccc_res res;
-	u32 *buf = val;
+	const u32 *buf = val;
 	u32 tmp;
 	u32 index;
 	int ret;
@@ -226,7 +226,7 @@ static struct nvmem_config imx_scu_ocotp_nvmem_config = {
 	.stride = 1,
 	.owner = THIS_MODULE,
 	.reg_read = imx_scu_ocotp_read,
-	.reg_write = imx_scu_ocotp_write,
+	.reg_write_const = imx_scu_ocotp_write,
 };
 
 static const struct of_device_id imx_scu_ocotp_dt_ids[] = {
diff --git a/drivers/nvmem/imx-ocotp.c b/drivers/nvmem/imx-ocotp.c
index 108d78d7f6cb..36d4a37aed93 100644
--- a/drivers/nvmem/imx-ocotp.c
+++ b/drivers/nvmem/imx-ocotp.c
@@ -310,11 +310,11 @@ static void imx_ocotp_set_imx7_timing(struct ocotp_priv *priv)
 	writel(timing, priv->base + IMX_OCOTP_ADDR_TIMING);
 }
 
-static int imx_ocotp_write(void *context, unsigned int offset, void *val,
+static int imx_ocotp_write(void *context, unsigned int offset, const void *val,
 			   size_t bytes)
 {
 	struct ocotp_priv *priv = context;
-	u32 *buf = val;
+	const u32 *buf = val;
 	int ret;
 
 	u32 ctrl;
@@ -483,7 +483,7 @@ static struct nvmem_config imx_ocotp_nvmem_config = {
 	.word_size = 4,
 	.stride = 1,
 	.reg_read = imx_ocotp_read,
-	.reg_write = imx_ocotp_write,
+	.reg_write_const = imx_ocotp_write,
 };
 
 static const struct ocotp_params imx6q_params = {
diff --git a/drivers/nvmem/lan9662-otpc.c b/drivers/nvmem/lan9662-otpc.c
index 62d1d6381bf8..f586ae4cd126 100644
--- a/drivers/nvmem/lan9662-otpc.c
+++ b/drivers/nvmem/lan9662-otpc.c
@@ -139,10 +139,10 @@ static int lan9662_otp_read(void *context, unsigned int offset,
 }
 
 static int lan9662_otp_write(void *context, unsigned int offset,
-			     void *_val, size_t bytes)
+			     const void *_val, size_t bytes)
 {
 	struct lan9662_otp *otp = context;
-	u8 *val = _val;
+	const u8 *val = _val;
 	u8 data, newdata;
 	int i, rc = 0;
 
@@ -174,7 +174,7 @@ static struct nvmem_config otp_config = {
 	.stride = 1,
 	.word_size = 1,
 	.reg_read = lan9662_otp_read,
-	.reg_write = lan9662_otp_write,
+	.reg_write_const = lan9662_otp_write,
 };
 
 static int lan9662_otp_probe(struct platform_device *pdev)
diff --git a/drivers/nvmem/lpc18xx_eeprom.c b/drivers/nvmem/lpc18xx_eeprom.c
index 504155e30bab..78a35ef095fb 100644
--- a/drivers/nvmem/lpc18xx_eeprom.c
+++ b/drivers/nvmem/lpc18xx_eeprom.c
@@ -87,7 +87,7 @@ static int lpc18xx_eeprom_busywait_until_prog(struct lpc18xx_eeprom_dev *eeprom)
 }
 
 static int lpc18xx_eeprom_gather_write(void *context, unsigned int reg,
-				       void *val, size_t bytes)
+				       const void *val, size_t bytes)
 {
 	struct lpc18xx_eeprom_dev *eeprom = context;
 	unsigned int offset = reg;
@@ -109,7 +109,7 @@ static int lpc18xx_eeprom_gather_write(void *context, unsigned int reg,
 	usleep_range(100, 200);
 
 	while (bytes) {
-		writel(*(u32 *)val, eeprom->mem_base + offset);
+		writel(*(const u32 *)val, eeprom->mem_base + offset);
 		ret = lpc18xx_eeprom_busywait_until_prog(eeprom);
 		if (ret < 0)
 			return ret;
@@ -155,7 +155,7 @@ static struct nvmem_config lpc18xx_nvmem_config = {
 	.stride = 4,
 	.word_size = 4,
 	.reg_read = lpc18xx_eeprom_read,
-	.reg_write = lpc18xx_eeprom_gather_write,
+	.reg_write_const = lpc18xx_eeprom_gather_write,
 };
 
 static int lpc18xx_eeprom_probe(struct platform_device *pdev)
diff --git a/drivers/nvmem/max77759-nvmem.c b/drivers/nvmem/max77759-nvmem.c
index 283000ec3a2c..86c025cfc2f6 100644
--- a/drivers/nvmem/max77759-nvmem.c
+++ b/drivers/nvmem/max77759-nvmem.c
@@ -59,7 +59,7 @@ static int max77759_nvmem_reg_read(void *priv, unsigned int offset,
 }
 
 static int max77759_nvmem_reg_write(void *priv, unsigned int offset,
-				    void *val, size_t bytes)
+				    const void *val, size_t bytes)
 {
 	struct max77759_nvmem *nvmem = priv;
 	DEFINE_FLEX(struct max77759_maxq_command, cmd, cmd, length,
@@ -99,7 +99,7 @@ static int max77759_nvmem_probe(struct platform_device *pdev)
 		.word_size = sizeof(u8),
 		.stride = sizeof(u8),
 		.reg_read = max77759_nvmem_reg_read,
-		.reg_write = max77759_nvmem_reg_write,
+		.reg_write_const = max77759_nvmem_reg_write,
 	};
 	struct max77759_nvmem *nvmem;
 
diff --git a/drivers/nvmem/meson-efuse.c b/drivers/nvmem/meson-efuse.c
index f71854f89950..5e056e707a96 100644
--- a/drivers/nvmem/meson-efuse.c
+++ b/drivers/nvmem/meson-efuse.c
@@ -27,7 +27,7 @@ static int meson_efuse_read(void *context, unsigned int offset,
 }
 
 static int meson_efuse_write(void *context, unsigned int offset,
-			     void *val, size_t bytes)
+			     const void *val, size_t bytes)
 {
 	struct meson_sm_firmware *fw = context;
 	int ret;
@@ -83,7 +83,7 @@ static int meson_efuse_probe(struct platform_device *pdev)
 	econfig->stride = 1;
 	econfig->word_size = 1;
 	econfig->reg_read = meson_efuse_read;
-	econfig->reg_write = meson_efuse_write;
+	econfig->reg_write_const = meson_efuse_write;
 	econfig->size = size;
 	econfig->priv = fw;
 
diff --git a/drivers/nvmem/qcom-spmi-sdam.c b/drivers/nvmem/qcom-spmi-sdam.c
index 4f1cca6eab71..10febaf9e427 100644
--- a/drivers/nvmem/qcom-spmi-sdam.c
+++ b/drivers/nvmem/qcom-spmi-sdam.c
@@ -81,8 +81,8 @@ static int sdam_read(void *priv, unsigned int offset, void *val,
 	return rc;
 }
 
-static int sdam_write(void *priv, unsigned int offset, void *val,
-				size_t bytes)
+static int sdam_write(void *priv, unsigned int offset, const void *val,
+		      size_t bytes)
 {
 	struct sdam_chip *sdam = priv;
 	struct device *dev = sdam->sdam_config.dev;
@@ -147,7 +147,7 @@ static int sdam_probe(struct platform_device *pdev)
 	sdam->sdam_config.size = sdam->size;
 	sdam->sdam_config.word_size = 1;
 	sdam->sdam_config.reg_read = sdam_read;
-	sdam->sdam_config.reg_write = sdam_write;
+	sdam->sdam_config.reg_write_const = sdam_write;
 	sdam->sdam_config.priv = sdam;
 
 	nvmem = devm_nvmem_register(&pdev->dev, &sdam->sdam_config);
diff --git a/drivers/nvmem/qfprom.c b/drivers/nvmem/qfprom.c
index 1de3435df116..16b7f647a3f6 100644
--- a/drivers/nvmem/qfprom.c
+++ b/drivers/nvmem/qfprom.c
@@ -252,13 +252,13 @@ static int qfprom_enable_fuse_blowing(const struct qfprom_priv *priv,
  *
  * Return: 0 or -err.
  */
-static int qfprom_reg_write(void *context, unsigned int reg, void *_val,
+static int qfprom_reg_write(void *context, unsigned int reg, const void *_val,
 			    size_t bytes)
 {
 	struct qfprom_priv *priv = context;
 	struct qfprom_touched_values old;
 	int words = bytes / 4;
-	u32 *value = _val;
+	const u32 *value = _val;
 	u32 blow_status;
 	int ret;
 	int i;
@@ -443,7 +443,7 @@ static int qfprom_probe(struct platform_device *pdev)
 
 		/* Only enable writing if we have SoC data and a valid clock */
 		if (priv->soc_data && priv->secclk)
-			econfig.reg_write = qfprom_reg_write;
+			econfig.reg_write_const = qfprom_reg_write;
 	}
 
 	pm_runtime_enable(dev);
diff --git a/drivers/nvmem/rave-sp-eeprom.c b/drivers/nvmem/rave-sp-eeprom.c
index 9ecf3873cbb7..c703d303eb6c 100644
--- a/drivers/nvmem/rave-sp-eeprom.c
+++ b/drivers/nvmem/rave-sp-eeprom.c
@@ -278,10 +278,10 @@ static int rave_sp_eeprom_reg_read(void *eeprom, unsigned int offset,
 }
 
 static int rave_sp_eeprom_reg_write(void *eeprom, unsigned int offset,
-				    void *val, size_t bytes)
+				    const void *val, size_t bytes)
 {
 	return rave_sp_eeprom_access(eeprom, RAVE_SP_EEPROM_WRITE,
-				     offset, val, bytes);
+				     offset, (void *)val, bytes);
 }
 
 static int rave_sp_eeprom_probe(struct platform_device *pdev)
@@ -331,7 +331,7 @@ static int rave_sp_eeprom_probe(struct platform_device *pdev)
 	config.add_legacy_fixed_of_cells	= true;
 	config.size		= size;
 	config.reg_read		= rave_sp_eeprom_reg_read;
-	config.reg_write	= rave_sp_eeprom_reg_write;
+	config.reg_write_const	= rave_sp_eeprom_reg_write;
 	config.word_size	= 1;
 	config.stride		= 1;
 
diff --git a/drivers/nvmem/snvs_lpgpr.c b/drivers/nvmem/snvs_lpgpr.c
index 89c27112320f..3e76d33dff20 100644
--- a/drivers/nvmem/snvs_lpgpr.c
+++ b/drivers/nvmem/snvs_lpgpr.c
@@ -50,7 +50,7 @@ static const struct snvs_lpgpr_cfg snvs_lpgpr_cfg_imx7d = {
 	.size		= 16,
 };
 
-static int snvs_lpgpr_write(void *context, unsigned int offset, void *val,
+static int snvs_lpgpr_write(void *context, unsigned int offset, const void *val,
 			    size_t bytes)
 {
 	struct snvs_lpgpr_priv *priv = context;
@@ -127,7 +127,7 @@ static int snvs_lpgpr_probe(struct platform_device *pdev)
 	cfg->size = dcfg->size;
 	cfg->owner = THIS_MODULE;
 	cfg->reg_read  = snvs_lpgpr_read;
-	cfg->reg_write = snvs_lpgpr_write;
+	cfg->reg_write_const = snvs_lpgpr_write;
 
 	nvmem = devm_nvmem_register(dev, cfg);
 
diff --git a/drivers/nvmem/sprd-efuse.c b/drivers/nvmem/sprd-efuse.c
index 1a7e4e5d8b86..f960fa8cb25c 100644
--- a/drivers/nvmem/sprd-efuse.c
+++ b/drivers/nvmem/sprd-efuse.c
@@ -192,7 +192,7 @@ static void sprd_efuse_set_prog_en(struct sprd_efuse *efuse, bool en)
 }
 
 static int sprd_efuse_raw_prog(struct sprd_efuse *efuse, u32 blk, bool doub,
-			       bool lock, u32 *data)
+			       bool lock, const u32 *data)
 {
 	u32 status;
 	int ret = 0;
@@ -321,7 +321,7 @@ static int sprd_efuse_read(void *context, u32 offset, void *val, size_t bytes)
 	return ret;
 }
 
-static int sprd_efuse_write(void *context, u32 offset, void *val, size_t bytes)
+static int sprd_efuse_write(void *context, u32 offset, const void *val, size_t bytes)
 {
 	struct sprd_efuse *efuse = context;
 	bool blk_double = efuse->data->blk_double;
@@ -410,7 +410,7 @@ static int sprd_efuse_probe(struct platform_device *pdev)
 	econfig.size = efuse->data->blk_nums * SPRD_EFUSE_BLOCK_WIDTH;
 	econfig.add_legacy_fixed_of_cells = true;
 	econfig.reg_read = sprd_efuse_read;
-	econfig.reg_write = sprd_efuse_write;
+	econfig.reg_write_const = sprd_efuse_write;
 	econfig.priv = efuse;
 	econfig.dev = &pdev->dev;
 	nvmem = devm_nvmem_register(&pdev->dev, &econfig);
diff --git a/drivers/nvmem/stm32-bsec-optee-ta.c b/drivers/nvmem/stm32-bsec-optee-ta.c
index f89ce791dd12..3184b976b1f9 100644
--- a/drivers/nvmem/stm32-bsec-optee-ta.c
+++ b/drivers/nvmem/stm32-bsec-optee-ta.c
@@ -203,7 +203,7 @@ int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
 
 /* stm32_bsec_optee_ta_write() - nvmem write access using PTA client driver */
 int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
-			      unsigned int offset, void *buf, size_t bytes)
+			      unsigned int offset, const void *buf, size_t bytes)
 {	struct tee_shm *shm;
 	struct tee_ioctl_invoke_arg arg;
 	struct tee_param param[2];
diff --git a/drivers/nvmem/stm32-bsec-optee-ta.h b/drivers/nvmem/stm32-bsec-optee-ta.h
index 3966a0535179..74658a54fe57 100644
--- a/drivers/nvmem/stm32-bsec-optee-ta.h
+++ b/drivers/nvmem/stm32-bsec-optee-ta.h
@@ -50,7 +50,7 @@ int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
  *	On success, 0. On failure, -errno.
  */
 int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
-			      unsigned int offset, void *buf, size_t bytes);
+			      unsigned int offset, const void *buf, size_t bytes);
 
 #else
 
@@ -72,7 +72,7 @@ static inline int stm32_bsec_optee_ta_read(struct tee_context *ctx,
 
 static inline int stm32_bsec_optee_ta_write(struct tee_context *ctx,
 					    unsigned int lower,
-					    unsigned int offset, void *buf,
+					    unsigned int offset, const void *buf,
 					    size_t bytes)
 {
 	return -EOPNOTSUPP;
diff --git a/drivers/nvmem/stm32-romem.c b/drivers/nvmem/stm32-romem.c
index 82879b1c9eb9..622093b0755c 100644
--- a/drivers/nvmem/stm32-romem.c
+++ b/drivers/nvmem/stm32-romem.c
@@ -118,12 +118,12 @@ static int stm32_bsec_read(void *context, unsigned int offset, void *buf,
 	return 0;
 }
 
-static int stm32_bsec_write(void *context, unsigned int offset, void *buf,
+static int stm32_bsec_write(void *context, unsigned int offset, const void *buf,
 			    size_t bytes)
 {
 	struct stm32_romem_priv *priv = context;
 	struct device *dev = priv->cfg.dev;
-	u32 *buf32 = buf;
+	const u32 *buf32 = buf;
 	int ret, i;
 
 	/* Allow only writing complete 32-bits aligned words */
@@ -153,7 +153,7 @@ static int stm32_bsec_pta_read(void *context, unsigned int offset, void *buf,
 	return stm32_bsec_optee_ta_read(priv->ctx, offset, buf, bytes);
 }
 
-static int stm32_bsec_pta_write(void *context, unsigned int offset, void *buf,
+static int stm32_bsec_pta_write(void *context, unsigned int offset, const void *buf,
 				size_t bytes)
 {
 	struct stm32_romem_priv *priv = context;
@@ -239,10 +239,10 @@ static int stm32_romem_probe(struct platform_device *pdev)
 				return rc;
 			}
 			priv->cfg.reg_read = stm32_bsec_pta_read;
-			priv->cfg.reg_write = stm32_bsec_pta_write;
+			priv->cfg.reg_write_const = stm32_bsec_pta_write;
 		} else {
 			priv->cfg.reg_read = stm32_bsec_read;
-			priv->cfg.reg_write = stm32_bsec_write;
+			priv->cfg.reg_write_const = stm32_bsec_write;
 		}
 	}
 
diff --git a/drivers/nvmem/zynqmp_nvmem.c b/drivers/nvmem/zynqmp_nvmem.c
index d297ff150dc0..54905a608157 100644
--- a/drivers/nvmem/zynqmp_nvmem.c
+++ b/drivers/nvmem/zynqmp_nvmem.c
@@ -183,7 +183,7 @@ static int zynqmp_nvmem_read(void *context, unsigned int offset, void *val, size
 }
 
 static int zynqmp_nvmem_write(void *context,
-			      unsigned int offset, void *val, size_t bytes)
+			      unsigned int offset, const void *val, size_t bytes)
 {
 	int pufflag = 0;
 
@@ -194,7 +194,7 @@ static int zynqmp_nvmem_write(void *context,
 		pufflag = 1;
 
 	return zynqmp_efuse_access(context, offset,
-				   val, bytes, EFUSE_WRITE, pufflag);
+				   (void *)val, bytes, EFUSE_WRITE, pufflag);
 }
 
 static const struct of_device_id zynqmp_nvmem_match[] = {
@@ -216,7 +216,7 @@ static int zynqmp_nvmem_probe(struct platform_device *pdev)
 	econfig.priv = dev;
 	econfig.add_legacy_fixed_of_cells = true;
 	econfig.reg_read = zynqmp_nvmem_read;
-	econfig.reg_write = zynqmp_nvmem_write;
+	econfig.reg_write_const = zynqmp_nvmem_write;
 
 	return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &econfig));
 }
-- 
2.55.0



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v4 3/3] nvmem: make all reg_write callbacks take const void *
@ 2026-07-26 13:17   ` Link Mauve
  0 siblings, 0 replies; 10+ messages in thread
From: Link Mauve @ 2026-07-26 13:17 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Link Mauve, Andy Shevchenko, Neil Armstrong, Kevin Hilman,
	Jerome Brunet, Martin Blumenstingl, Sven Peter, Janne Grunau,
	Neal Gompa, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Vladimir Zapolskiy, André Draszik, Orson Zhai,
	Baolin Wang, Chunyan Zhang, Maxime Coquelin, Alexandre Torgue,
	Kalyani Akula, Michal Simek, Miguel Ojeda, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
	Alexandre Courbot, Onur Özkan, Johan Hovold, Ronald Claveau,
	Daniel Lezcano, linux-arm-kernel, linux-amlogic, linux-kernel,
	asahi, imx, linux-arm-msm, linux-stm32, rust-for-linux

The previous commit switched from a pointer to mutable data to a pointer
to immutable data, so let’s fix all users of this API.

Signed-off-by: Link Mauve <linkmauve@linkmauve.fr>
---
 drivers/nvmem/apple-spmi-nvmem.c    |  4 ++--
 drivers/nvmem/bcm-ocotp.c           |  8 ++++----
 drivers/nvmem/imx-ocotp-scu.c       |  6 +++---
 drivers/nvmem/imx-ocotp.c           |  6 +++---
 drivers/nvmem/lan9662-otpc.c        |  6 +++---
 drivers/nvmem/lpc18xx_eeprom.c      |  6 +++---
 drivers/nvmem/max77759-nvmem.c      |  4 ++--
 drivers/nvmem/meson-efuse.c         |  4 ++--
 drivers/nvmem/qcom-spmi-sdam.c      |  6 +++---
 drivers/nvmem/qfprom.c              |  6 +++---
 drivers/nvmem/rave-sp-eeprom.c      |  6 +++---
 drivers/nvmem/snvs_lpgpr.c          |  4 ++--
 drivers/nvmem/sprd-efuse.c          |  6 +++---
 drivers/nvmem/stm32-bsec-optee-ta.c |  2 +-
 drivers/nvmem/stm32-bsec-optee-ta.h |  4 ++--
 drivers/nvmem/stm32-romem.c         | 10 +++++-----
 drivers/nvmem/zynqmp_nvmem.c        |  6 +++---
 17 files changed, 47 insertions(+), 47 deletions(-)

diff --git a/drivers/nvmem/apple-spmi-nvmem.c b/drivers/nvmem/apple-spmi-nvmem.c
index 7acb0c07d6ab..63b2b11d78f9 100644
--- a/drivers/nvmem/apple-spmi-nvmem.c
+++ b/drivers/nvmem/apple-spmi-nvmem.c
@@ -26,7 +26,7 @@ static int apple_spmi_nvmem_read(void *priv, unsigned int offset, void *val,
 	return regmap_bulk_read(map, offset, val, bytes);
 }
 
-static int apple_spmi_nvmem_write(void *priv, unsigned int offset, void *val,
+static int apple_spmi_nvmem_write(void *priv, unsigned int offset, const void *val,
 				  size_t bytes)
 {
 	struct regmap *map = priv;
@@ -45,7 +45,7 @@ static int apple_spmi_nvmem_probe(struct spmi_device *sdev)
 		.stride = 1,
 		.size = 0xffff,
 		.reg_read = apple_spmi_nvmem_read,
-		.reg_write = apple_spmi_nvmem_write,
+		.reg_write_const = apple_spmi_nvmem_write,
 	};
 
 	regmap = devm_regmap_init_spmi_ext(sdev, &apple_spmi_regmap_config);
diff --git a/drivers/nvmem/bcm-ocotp.c b/drivers/nvmem/bcm-ocotp.c
index 2490f44caa40..02adfd787de8 100644
--- a/drivers/nvmem/bcm-ocotp.c
+++ b/drivers/nvmem/bcm-ocotp.c
@@ -179,11 +179,11 @@ static int bcm_otpc_read(void *context, unsigned int offset, void *val,
 	return 0;
 }
 
-static int bcm_otpc_write(void *context, unsigned int offset, void *val,
-	size_t bytes)
+static int bcm_otpc_write(void *context, unsigned int offset, const void *val,
+			  size_t bytes)
 {
 	struct otpc_priv *priv = context;
-	u32 *buf = val;
+	const u32 *buf = val;
 	u32 bytes_written;
 	u32 address = offset / priv->config->word_size;
 	int i, ret;
@@ -223,7 +223,7 @@ static struct nvmem_config bcm_otpc_nvmem_config = {
 	.word_size = 4,
 	.stride = 4,
 	.reg_read = bcm_otpc_read,
-	.reg_write = bcm_otpc_write,
+	.reg_write_const = bcm_otpc_write,
 };
 
 static const struct of_device_id bcm_otpc_dt_ids[] = {
diff --git a/drivers/nvmem/imx-ocotp-scu.c b/drivers/nvmem/imx-ocotp-scu.c
index 517d83e11af2..57008228100f 100644
--- a/drivers/nvmem/imx-ocotp-scu.c
+++ b/drivers/nvmem/imx-ocotp-scu.c
@@ -178,11 +178,11 @@ static int imx_scu_ocotp_read(void *context, unsigned int offset,
 }
 
 static int imx_scu_ocotp_write(void *context, unsigned int offset,
-			       void *val, size_t bytes)
+			       const void *val, size_t bytes)
 {
 	struct ocotp_priv *priv = context;
 	struct arm_smccc_res res;
-	u32 *buf = val;
+	const u32 *buf = val;
 	u32 tmp;
 	u32 index;
 	int ret;
@@ -226,7 +226,7 @@ static struct nvmem_config imx_scu_ocotp_nvmem_config = {
 	.stride = 1,
 	.owner = THIS_MODULE,
 	.reg_read = imx_scu_ocotp_read,
-	.reg_write = imx_scu_ocotp_write,
+	.reg_write_const = imx_scu_ocotp_write,
 };
 
 static const struct of_device_id imx_scu_ocotp_dt_ids[] = {
diff --git a/drivers/nvmem/imx-ocotp.c b/drivers/nvmem/imx-ocotp.c
index 108d78d7f6cb..36d4a37aed93 100644
--- a/drivers/nvmem/imx-ocotp.c
+++ b/drivers/nvmem/imx-ocotp.c
@@ -310,11 +310,11 @@ static void imx_ocotp_set_imx7_timing(struct ocotp_priv *priv)
 	writel(timing, priv->base + IMX_OCOTP_ADDR_TIMING);
 }
 
-static int imx_ocotp_write(void *context, unsigned int offset, void *val,
+static int imx_ocotp_write(void *context, unsigned int offset, const void *val,
 			   size_t bytes)
 {
 	struct ocotp_priv *priv = context;
-	u32 *buf = val;
+	const u32 *buf = val;
 	int ret;
 
 	u32 ctrl;
@@ -483,7 +483,7 @@ static struct nvmem_config imx_ocotp_nvmem_config = {
 	.word_size = 4,
 	.stride = 1,
 	.reg_read = imx_ocotp_read,
-	.reg_write = imx_ocotp_write,
+	.reg_write_const = imx_ocotp_write,
 };
 
 static const struct ocotp_params imx6q_params = {
diff --git a/drivers/nvmem/lan9662-otpc.c b/drivers/nvmem/lan9662-otpc.c
index 62d1d6381bf8..f586ae4cd126 100644
--- a/drivers/nvmem/lan9662-otpc.c
+++ b/drivers/nvmem/lan9662-otpc.c
@@ -139,10 +139,10 @@ static int lan9662_otp_read(void *context, unsigned int offset,
 }
 
 static int lan9662_otp_write(void *context, unsigned int offset,
-			     void *_val, size_t bytes)
+			     const void *_val, size_t bytes)
 {
 	struct lan9662_otp *otp = context;
-	u8 *val = _val;
+	const u8 *val = _val;
 	u8 data, newdata;
 	int i, rc = 0;
 
@@ -174,7 +174,7 @@ static struct nvmem_config otp_config = {
 	.stride = 1,
 	.word_size = 1,
 	.reg_read = lan9662_otp_read,
-	.reg_write = lan9662_otp_write,
+	.reg_write_const = lan9662_otp_write,
 };
 
 static int lan9662_otp_probe(struct platform_device *pdev)
diff --git a/drivers/nvmem/lpc18xx_eeprom.c b/drivers/nvmem/lpc18xx_eeprom.c
index 504155e30bab..78a35ef095fb 100644
--- a/drivers/nvmem/lpc18xx_eeprom.c
+++ b/drivers/nvmem/lpc18xx_eeprom.c
@@ -87,7 +87,7 @@ static int lpc18xx_eeprom_busywait_until_prog(struct lpc18xx_eeprom_dev *eeprom)
 }
 
 static int lpc18xx_eeprom_gather_write(void *context, unsigned int reg,
-				       void *val, size_t bytes)
+				       const void *val, size_t bytes)
 {
 	struct lpc18xx_eeprom_dev *eeprom = context;
 	unsigned int offset = reg;
@@ -109,7 +109,7 @@ static int lpc18xx_eeprom_gather_write(void *context, unsigned int reg,
 	usleep_range(100, 200);
 
 	while (bytes) {
-		writel(*(u32 *)val, eeprom->mem_base + offset);
+		writel(*(const u32 *)val, eeprom->mem_base + offset);
 		ret = lpc18xx_eeprom_busywait_until_prog(eeprom);
 		if (ret < 0)
 			return ret;
@@ -155,7 +155,7 @@ static struct nvmem_config lpc18xx_nvmem_config = {
 	.stride = 4,
 	.word_size = 4,
 	.reg_read = lpc18xx_eeprom_read,
-	.reg_write = lpc18xx_eeprom_gather_write,
+	.reg_write_const = lpc18xx_eeprom_gather_write,
 };
 
 static int lpc18xx_eeprom_probe(struct platform_device *pdev)
diff --git a/drivers/nvmem/max77759-nvmem.c b/drivers/nvmem/max77759-nvmem.c
index 283000ec3a2c..86c025cfc2f6 100644
--- a/drivers/nvmem/max77759-nvmem.c
+++ b/drivers/nvmem/max77759-nvmem.c
@@ -59,7 +59,7 @@ static int max77759_nvmem_reg_read(void *priv, unsigned int offset,
 }
 
 static int max77759_nvmem_reg_write(void *priv, unsigned int offset,
-				    void *val, size_t bytes)
+				    const void *val, size_t bytes)
 {
 	struct max77759_nvmem *nvmem = priv;
 	DEFINE_FLEX(struct max77759_maxq_command, cmd, cmd, length,
@@ -99,7 +99,7 @@ static int max77759_nvmem_probe(struct platform_device *pdev)
 		.word_size = sizeof(u8),
 		.stride = sizeof(u8),
 		.reg_read = max77759_nvmem_reg_read,
-		.reg_write = max77759_nvmem_reg_write,
+		.reg_write_const = max77759_nvmem_reg_write,
 	};
 	struct max77759_nvmem *nvmem;
 
diff --git a/drivers/nvmem/meson-efuse.c b/drivers/nvmem/meson-efuse.c
index f71854f89950..5e056e707a96 100644
--- a/drivers/nvmem/meson-efuse.c
+++ b/drivers/nvmem/meson-efuse.c
@@ -27,7 +27,7 @@ static int meson_efuse_read(void *context, unsigned int offset,
 }
 
 static int meson_efuse_write(void *context, unsigned int offset,
-			     void *val, size_t bytes)
+			     const void *val, size_t bytes)
 {
 	struct meson_sm_firmware *fw = context;
 	int ret;
@@ -83,7 +83,7 @@ static int meson_efuse_probe(struct platform_device *pdev)
 	econfig->stride = 1;
 	econfig->word_size = 1;
 	econfig->reg_read = meson_efuse_read;
-	econfig->reg_write = meson_efuse_write;
+	econfig->reg_write_const = meson_efuse_write;
 	econfig->size = size;
 	econfig->priv = fw;
 
diff --git a/drivers/nvmem/qcom-spmi-sdam.c b/drivers/nvmem/qcom-spmi-sdam.c
index 4f1cca6eab71..10febaf9e427 100644
--- a/drivers/nvmem/qcom-spmi-sdam.c
+++ b/drivers/nvmem/qcom-spmi-sdam.c
@@ -81,8 +81,8 @@ static int sdam_read(void *priv, unsigned int offset, void *val,
 	return rc;
 }
 
-static int sdam_write(void *priv, unsigned int offset, void *val,
-				size_t bytes)
+static int sdam_write(void *priv, unsigned int offset, const void *val,
+		      size_t bytes)
 {
 	struct sdam_chip *sdam = priv;
 	struct device *dev = sdam->sdam_config.dev;
@@ -147,7 +147,7 @@ static int sdam_probe(struct platform_device *pdev)
 	sdam->sdam_config.size = sdam->size;
 	sdam->sdam_config.word_size = 1;
 	sdam->sdam_config.reg_read = sdam_read;
-	sdam->sdam_config.reg_write = sdam_write;
+	sdam->sdam_config.reg_write_const = sdam_write;
 	sdam->sdam_config.priv = sdam;
 
 	nvmem = devm_nvmem_register(&pdev->dev, &sdam->sdam_config);
diff --git a/drivers/nvmem/qfprom.c b/drivers/nvmem/qfprom.c
index 1de3435df116..16b7f647a3f6 100644
--- a/drivers/nvmem/qfprom.c
+++ b/drivers/nvmem/qfprom.c
@@ -252,13 +252,13 @@ static int qfprom_enable_fuse_blowing(const struct qfprom_priv *priv,
  *
  * Return: 0 or -err.
  */
-static int qfprom_reg_write(void *context, unsigned int reg, void *_val,
+static int qfprom_reg_write(void *context, unsigned int reg, const void *_val,
 			    size_t bytes)
 {
 	struct qfprom_priv *priv = context;
 	struct qfprom_touched_values old;
 	int words = bytes / 4;
-	u32 *value = _val;
+	const u32 *value = _val;
 	u32 blow_status;
 	int ret;
 	int i;
@@ -443,7 +443,7 @@ static int qfprom_probe(struct platform_device *pdev)
 
 		/* Only enable writing if we have SoC data and a valid clock */
 		if (priv->soc_data && priv->secclk)
-			econfig.reg_write = qfprom_reg_write;
+			econfig.reg_write_const = qfprom_reg_write;
 	}
 
 	pm_runtime_enable(dev);
diff --git a/drivers/nvmem/rave-sp-eeprom.c b/drivers/nvmem/rave-sp-eeprom.c
index 9ecf3873cbb7..c703d303eb6c 100644
--- a/drivers/nvmem/rave-sp-eeprom.c
+++ b/drivers/nvmem/rave-sp-eeprom.c
@@ -278,10 +278,10 @@ static int rave_sp_eeprom_reg_read(void *eeprom, unsigned int offset,
 }
 
 static int rave_sp_eeprom_reg_write(void *eeprom, unsigned int offset,
-				    void *val, size_t bytes)
+				    const void *val, size_t bytes)
 {
 	return rave_sp_eeprom_access(eeprom, RAVE_SP_EEPROM_WRITE,
-				     offset, val, bytes);
+				     offset, (void *)val, bytes);
 }
 
 static int rave_sp_eeprom_probe(struct platform_device *pdev)
@@ -331,7 +331,7 @@ static int rave_sp_eeprom_probe(struct platform_device *pdev)
 	config.add_legacy_fixed_of_cells	= true;
 	config.size		= size;
 	config.reg_read		= rave_sp_eeprom_reg_read;
-	config.reg_write	= rave_sp_eeprom_reg_write;
+	config.reg_write_const	= rave_sp_eeprom_reg_write;
 	config.word_size	= 1;
 	config.stride		= 1;
 
diff --git a/drivers/nvmem/snvs_lpgpr.c b/drivers/nvmem/snvs_lpgpr.c
index 89c27112320f..3e76d33dff20 100644
--- a/drivers/nvmem/snvs_lpgpr.c
+++ b/drivers/nvmem/snvs_lpgpr.c
@@ -50,7 +50,7 @@ static const struct snvs_lpgpr_cfg snvs_lpgpr_cfg_imx7d = {
 	.size		= 16,
 };
 
-static int snvs_lpgpr_write(void *context, unsigned int offset, void *val,
+static int snvs_lpgpr_write(void *context, unsigned int offset, const void *val,
 			    size_t bytes)
 {
 	struct snvs_lpgpr_priv *priv = context;
@@ -127,7 +127,7 @@ static int snvs_lpgpr_probe(struct platform_device *pdev)
 	cfg->size = dcfg->size;
 	cfg->owner = THIS_MODULE;
 	cfg->reg_read  = snvs_lpgpr_read;
-	cfg->reg_write = snvs_lpgpr_write;
+	cfg->reg_write_const = snvs_lpgpr_write;
 
 	nvmem = devm_nvmem_register(dev, cfg);
 
diff --git a/drivers/nvmem/sprd-efuse.c b/drivers/nvmem/sprd-efuse.c
index 1a7e4e5d8b86..f960fa8cb25c 100644
--- a/drivers/nvmem/sprd-efuse.c
+++ b/drivers/nvmem/sprd-efuse.c
@@ -192,7 +192,7 @@ static void sprd_efuse_set_prog_en(struct sprd_efuse *efuse, bool en)
 }
 
 static int sprd_efuse_raw_prog(struct sprd_efuse *efuse, u32 blk, bool doub,
-			       bool lock, u32 *data)
+			       bool lock, const u32 *data)
 {
 	u32 status;
 	int ret = 0;
@@ -321,7 +321,7 @@ static int sprd_efuse_read(void *context, u32 offset, void *val, size_t bytes)
 	return ret;
 }
 
-static int sprd_efuse_write(void *context, u32 offset, void *val, size_t bytes)
+static int sprd_efuse_write(void *context, u32 offset, const void *val, size_t bytes)
 {
 	struct sprd_efuse *efuse = context;
 	bool blk_double = efuse->data->blk_double;
@@ -410,7 +410,7 @@ static int sprd_efuse_probe(struct platform_device *pdev)
 	econfig.size = efuse->data->blk_nums * SPRD_EFUSE_BLOCK_WIDTH;
 	econfig.add_legacy_fixed_of_cells = true;
 	econfig.reg_read = sprd_efuse_read;
-	econfig.reg_write = sprd_efuse_write;
+	econfig.reg_write_const = sprd_efuse_write;
 	econfig.priv = efuse;
 	econfig.dev = &pdev->dev;
 	nvmem = devm_nvmem_register(&pdev->dev, &econfig);
diff --git a/drivers/nvmem/stm32-bsec-optee-ta.c b/drivers/nvmem/stm32-bsec-optee-ta.c
index f89ce791dd12..3184b976b1f9 100644
--- a/drivers/nvmem/stm32-bsec-optee-ta.c
+++ b/drivers/nvmem/stm32-bsec-optee-ta.c
@@ -203,7 +203,7 @@ int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
 
 /* stm32_bsec_optee_ta_write() - nvmem write access using PTA client driver */
 int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
-			      unsigned int offset, void *buf, size_t bytes)
+			      unsigned int offset, const void *buf, size_t bytes)
 {	struct tee_shm *shm;
 	struct tee_ioctl_invoke_arg arg;
 	struct tee_param param[2];
diff --git a/drivers/nvmem/stm32-bsec-optee-ta.h b/drivers/nvmem/stm32-bsec-optee-ta.h
index 3966a0535179..74658a54fe57 100644
--- a/drivers/nvmem/stm32-bsec-optee-ta.h
+++ b/drivers/nvmem/stm32-bsec-optee-ta.h
@@ -50,7 +50,7 @@ int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset,
  *	On success, 0. On failure, -errno.
  */
 int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower,
-			      unsigned int offset, void *buf, size_t bytes);
+			      unsigned int offset, const void *buf, size_t bytes);
 
 #else
 
@@ -72,7 +72,7 @@ static inline int stm32_bsec_optee_ta_read(struct tee_context *ctx,
 
 static inline int stm32_bsec_optee_ta_write(struct tee_context *ctx,
 					    unsigned int lower,
-					    unsigned int offset, void *buf,
+					    unsigned int offset, const void *buf,
 					    size_t bytes)
 {
 	return -EOPNOTSUPP;
diff --git a/drivers/nvmem/stm32-romem.c b/drivers/nvmem/stm32-romem.c
index 82879b1c9eb9..622093b0755c 100644
--- a/drivers/nvmem/stm32-romem.c
+++ b/drivers/nvmem/stm32-romem.c
@@ -118,12 +118,12 @@ static int stm32_bsec_read(void *context, unsigned int offset, void *buf,
 	return 0;
 }
 
-static int stm32_bsec_write(void *context, unsigned int offset, void *buf,
+static int stm32_bsec_write(void *context, unsigned int offset, const void *buf,
 			    size_t bytes)
 {
 	struct stm32_romem_priv *priv = context;
 	struct device *dev = priv->cfg.dev;
-	u32 *buf32 = buf;
+	const u32 *buf32 = buf;
 	int ret, i;
 
 	/* Allow only writing complete 32-bits aligned words */
@@ -153,7 +153,7 @@ static int stm32_bsec_pta_read(void *context, unsigned int offset, void *buf,
 	return stm32_bsec_optee_ta_read(priv->ctx, offset, buf, bytes);
 }
 
-static int stm32_bsec_pta_write(void *context, unsigned int offset, void *buf,
+static int stm32_bsec_pta_write(void *context, unsigned int offset, const void *buf,
 				size_t bytes)
 {
 	struct stm32_romem_priv *priv = context;
@@ -239,10 +239,10 @@ static int stm32_romem_probe(struct platform_device *pdev)
 				return rc;
 			}
 			priv->cfg.reg_read = stm32_bsec_pta_read;
-			priv->cfg.reg_write = stm32_bsec_pta_write;
+			priv->cfg.reg_write_const = stm32_bsec_pta_write;
 		} else {
 			priv->cfg.reg_read = stm32_bsec_read;
-			priv->cfg.reg_write = stm32_bsec_write;
+			priv->cfg.reg_write_const = stm32_bsec_write;
 		}
 	}
 
diff --git a/drivers/nvmem/zynqmp_nvmem.c b/drivers/nvmem/zynqmp_nvmem.c
index d297ff150dc0..54905a608157 100644
--- a/drivers/nvmem/zynqmp_nvmem.c
+++ b/drivers/nvmem/zynqmp_nvmem.c
@@ -183,7 +183,7 @@ static int zynqmp_nvmem_read(void *context, unsigned int offset, void *val, size
 }
 
 static int zynqmp_nvmem_write(void *context,
-			      unsigned int offset, void *val, size_t bytes)
+			      unsigned int offset, const void *val, size_t bytes)
 {
 	int pufflag = 0;
 
@@ -194,7 +194,7 @@ static int zynqmp_nvmem_write(void *context,
 		pufflag = 1;
 
 	return zynqmp_efuse_access(context, offset,
-				   val, bytes, EFUSE_WRITE, pufflag);
+				   (void *)val, bytes, EFUSE_WRITE, pufflag);
 }
 
 static const struct of_device_id zynqmp_nvmem_match[] = {
@@ -216,7 +216,7 @@ static int zynqmp_nvmem_probe(struct platform_device *pdev)
 	econfig.priv = dev;
 	econfig.add_legacy_fixed_of_cells = true;
 	econfig.reg_read = zynqmp_nvmem_read;
-	econfig.reg_write = zynqmp_nvmem_write;
+	econfig.reg_write_const = zynqmp_nvmem_write;
 
 	return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &econfig));
 }
-- 
2.55.0


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v4 3/3] nvmem: make all reg_write callbacks take const void *
  2026-07-26 13:17   ` Link Mauve
@ 2026-07-26 13:30     ` sashiko-bot
  -1 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-07-26 13:30 UTC (permalink / raw)
  To: Link Mauve; +Cc: neil.armstrong, linux-amlogic, ojeda, imx, Frank.Li

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:

New issues:
- [Medium] The patch claims to 'make all reg_write callbacks take const void *' and 'fix all users of this API', but it fails to migrate many nvmem drivers.

Pre-existing issues:
- [Critical] The `sprd_efuse_write` function reads out-of-bounds for small writes and silently truncates large writes, while `sprd_efuse_read` suffers from a stack buffer overflow.
- [High] The `bcm_otpc_write` function performs an out-of-bounds read when `bytes` is not a multiple of `otpc_row_size * word_size`.
- [High] The `lpc18xx_eeprom_gather_write` and `lpc18xx_eeprom_read` functions will enter an infinite loop and cause OOB memory access if `bytes` is not a multiple of 4.
--

--- Patch [3]: [PATCH v4 3/3] nvmem: make all reg_write callbacks take const void * ---
commit 4f1bd94da9f8c5ba3e21c869d089a1a71eeccbc7
Author: Link Mauve <linkmauve@linkmauve.fr>

nvmem: make all reg_write callbacks take const void *

The previous commit switched from a pointer to mutable data to a pointer
to immutable data, so let’s fix all users of this API.

> nvmem: make all reg_write callbacks take const void *
>
> The previous commit switched from a pointer to mutable data to a pointer
> to immutable data, so let’s fix all users of this API.

[Severity: Medium]
Is this commit message accurate regarding fixing all users?

Although many files are updated, prominent drivers like at24.c and at25.c
(and others outside drivers/nvmem/) still appear to use the legacy
.reg_write callback with the mutable void * signature.

Could the commit message be clarified to state that it only updates a subset
of drivers?

> diff --git a/drivers/nvmem/bcm-ocotp.c b/drivers/nvmem/bcm-ocotp.c
> index 2490f44caa409..02adfd787de85 100644
> --- a/drivers/nvmem/bcm-ocotp.c
> +++ b/drivers/nvmem/bcm-ocotp.c
[ ... ]
> @@ -179,11 +179,11 @@ static int bcm_otpc_read(void *context, unsigned int offset, void *val,
>  	return 0;
>  }
>  
> -static int bcm_otpc_write(void *context, unsigned int offset, void *val,
> -	size_t bytes)
> +static int bcm_otpc_write(void *context, unsigned int offset, const void *val,
> +			  size_t bytes)
>  {
>  	struct otpc_priv *priv = context;
> -	u32 *buf = val;
> +	const u32 *buf = val;
>  	u32 bytes_written;

[Severity: High]
This is a pre-existing issue, but does bcm_otpc_write() have an out-of-bounds
read if bytes is not a multiple of otpc_row_size * word_size?

If otpc_row_size > 1 (like 2 for the v2 map) and the nvmem core passes
bytes = 4, the inner loop iterates twice:

    for (i = 0; i < priv->map->otpc_row_size; i++) {
        writel(*buf, priv->base + priv->map->data_w_offset[i]);
        buf++;
        bytes_written += sizeof(*buf);
    }

Does this cause buf to advance beyond the provided length and read
uninitialized kernel memory into the hardware?

[ ... ]
> diff --git a/drivers/nvmem/lpc18xx_eeprom.c b/drivers/nvmem/lpc18xx_eeprom.c
> index 504155e30bab2..78a35ef095fbd 100644
> --- a/drivers/nvmem/lpc18xx_eeprom.c
> +++ b/drivers/nvmem/lpc18xx_eeprom.c
[ ... ]
> @@ -109,7 +109,7 @@ static int lpc18xx_eeprom_gather_write(void *context, unsigned int reg,
>  	usleep_range(100, 200);
>  
>  	while (bytes) {
> -		writel(*(u32 *)val, eeprom->mem_base + offset);
> +		writel(*(const u32 *)val, eeprom->mem_base + offset);
>  		ret = lpc18xx_eeprom_busywait_until_prog(eeprom);

[Severity: High]
This is a pre-existing issue, but can this loop run infinitely if bytes is
not a multiple of 4?

The loop decrements the unsigned bytes variable unconditionally by 4:

    bytes -= eeprom->val_bytes;

If the nvmem core passes an unaligned bytes value, does this subtraction
underflow and cause the loop to run indefinitely, leading to out-of-bounds
memory access? It appears lpc18xx_eeprom_read() shares this behavior.

[ ... ]
> diff --git a/drivers/nvmem/sprd-efuse.c b/drivers/nvmem/sprd-efuse.c
> index 1a7e4e5d8b86c..f960fa8cb25cf 100644
> --- a/drivers/nvmem/sprd-efuse.c
> +++ b/drivers/nvmem/sprd-efuse.c
> @@ -192,7 +192,7 @@ static void sprd_efuse_set_prog_en(struct sprd_efuse *efuse, bool en)
>  }
>  
>  static int sprd_efuse_raw_prog(struct sprd_efuse *efuse, u32 blk, bool doub,
> -			       bool lock, u32 *data)
> +			       bool lock, const u32 *data)
>  {

[Severity: Critical]
This is a pre-existing issue, but does sprd_efuse_raw_prog() read out of
bounds for small writes?

By dereferencing data as a 32-bit integer:

    writel(*data, efuse->base + SPRD_EFUSE_MEM(blk));

Could this cause an out-of-bounds read if the incoming buffer is less than
4 bytes long?

[ ... ]
> @@ -321,7 +321,7 @@ static int sprd_efuse_read(void *context, u32 offset, void *val, size_t bytes)
>  	return ret;
>  }
>  
> -static int sprd_efuse_write(void *context, u32 offset, void *val, size_t bytes)
> +static int sprd_efuse_write(void *context, u32 offset, const void *val, size_t bytes)
>  {

[Severity: Critical]
This is a pre-existing issue, but is there a stack memory leak in
sprd_efuse_read()?

When the nvmem core passes a length up to PAGE_SIZE (4096) for sysfs reads,
sprd_efuse_read() allocates a local 4-byte data variable on the stack:

    u32 data;
    ...
    memcpy(val, &data, bytes);

If bytes > 4, would this copy up to 4092 bytes of stack memory to the
output buffer?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260726131724.15299-1-linkmauve@linkmauve.fr?part=3

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v4 3/3] nvmem: make all reg_write callbacks take const void *
@ 2026-07-26 13:30     ` sashiko-bot
  0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-07-26 13:30 UTC (permalink / raw)
  To: Link Mauve; +Cc: neil.armstrong, linux-amlogic, ojeda, imx, Frank.Li

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:

New issues:
- [Medium] The patch claims to 'make all reg_write callbacks take const void *' and 'fix all users of this API', but it fails to migrate many nvmem drivers.

Pre-existing issues:
- [Critical] The `sprd_efuse_write` function reads out-of-bounds for small writes and silently truncates large writes, while `sprd_efuse_read` suffers from a stack buffer overflow.
- [High] The `bcm_otpc_write` function performs an out-of-bounds read when `bytes` is not a multiple of `otpc_row_size * word_size`.
- [High] The `lpc18xx_eeprom_gather_write` and `lpc18xx_eeprom_read` functions will enter an infinite loop and cause OOB memory access if `bytes` is not a multiple of 4.
--

--- Patch [3]: [PATCH v4 3/3] nvmem: make all reg_write callbacks take const void * ---
commit 4f1bd94da9f8c5ba3e21c869d089a1a71eeccbc7
Author: Link Mauve <linkmauve@linkmauve.fr>

nvmem: make all reg_write callbacks take const void *

The previous commit switched from a pointer to mutable data to a pointer
to immutable data, so let’s fix all users of this API.

> nvmem: make all reg_write callbacks take const void *
>
> The previous commit switched from a pointer to mutable data to a pointer
> to immutable data, so let’s fix all users of this API.

[Severity: Medium]
Is this commit message accurate regarding fixing all users?

Although many files are updated, prominent drivers like at24.c and at25.c
(and others outside drivers/nvmem/) still appear to use the legacy
.reg_write callback with the mutable void * signature.

Could the commit message be clarified to state that it only updates a subset
of drivers?

> diff --git a/drivers/nvmem/bcm-ocotp.c b/drivers/nvmem/bcm-ocotp.c
> index 2490f44caa409..02adfd787de85 100644
> --- a/drivers/nvmem/bcm-ocotp.c
> +++ b/drivers/nvmem/bcm-ocotp.c
[ ... ]
> @@ -179,11 +179,11 @@ static int bcm_otpc_read(void *context, unsigned int offset, void *val,
>  	return 0;
>  }
>  
> -static int bcm_otpc_write(void *context, unsigned int offset, void *val,
> -	size_t bytes)
> +static int bcm_otpc_write(void *context, unsigned int offset, const void *val,
> +			  size_t bytes)
>  {
>  	struct otpc_priv *priv = context;
> -	u32 *buf = val;
> +	const u32 *buf = val;
>  	u32 bytes_written;

[Severity: High]
This is a pre-existing issue, but does bcm_otpc_write() have an out-of-bounds
read if bytes is not a multiple of otpc_row_size * word_size?

If otpc_row_size > 1 (like 2 for the v2 map) and the nvmem core passes
bytes = 4, the inner loop iterates twice:

    for (i = 0; i < priv->map->otpc_row_size; i++) {
        writel(*buf, priv->base + priv->map->data_w_offset[i]);
        buf++;
        bytes_written += sizeof(*buf);
    }

Does this cause buf to advance beyond the provided length and read
uninitialized kernel memory into the hardware?

[ ... ]
> diff --git a/drivers/nvmem/lpc18xx_eeprom.c b/drivers/nvmem/lpc18xx_eeprom.c
> index 504155e30bab2..78a35ef095fbd 100644
> --- a/drivers/nvmem/lpc18xx_eeprom.c
> +++ b/drivers/nvmem/lpc18xx_eeprom.c
[ ... ]
> @@ -109,7 +109,7 @@ static int lpc18xx_eeprom_gather_write(void *context, unsigned int reg,
>  	usleep_range(100, 200);
>  
>  	while (bytes) {
> -		writel(*(u32 *)val, eeprom->mem_base + offset);
> +		writel(*(const u32 *)val, eeprom->mem_base + offset);
>  		ret = lpc18xx_eeprom_busywait_until_prog(eeprom);

[Severity: High]
This is a pre-existing issue, but can this loop run infinitely if bytes is
not a multiple of 4?

The loop decrements the unsigned bytes variable unconditionally by 4:

    bytes -= eeprom->val_bytes;

If the nvmem core passes an unaligned bytes value, does this subtraction
underflow and cause the loop to run indefinitely, leading to out-of-bounds
memory access? It appears lpc18xx_eeprom_read() shares this behavior.

[ ... ]
> diff --git a/drivers/nvmem/sprd-efuse.c b/drivers/nvmem/sprd-efuse.c
> index 1a7e4e5d8b86c..f960fa8cb25cf 100644
> --- a/drivers/nvmem/sprd-efuse.c
> +++ b/drivers/nvmem/sprd-efuse.c
> @@ -192,7 +192,7 @@ static void sprd_efuse_set_prog_en(struct sprd_efuse *efuse, bool en)
>  }
>  
>  static int sprd_efuse_raw_prog(struct sprd_efuse *efuse, u32 blk, bool doub,
> -			       bool lock, u32 *data)
> +			       bool lock, const u32 *data)
>  {

[Severity: Critical]
This is a pre-existing issue, but does sprd_efuse_raw_prog() read out of
bounds for small writes?

By dereferencing data as a 32-bit integer:

    writel(*data, efuse->base + SPRD_EFUSE_MEM(blk));

Could this cause an out-of-bounds read if the incoming buffer is less than
4 bytes long?

[ ... ]
> @@ -321,7 +321,7 @@ static int sprd_efuse_read(void *context, u32 offset, void *val, size_t bytes)
>  	return ret;
>  }
>  
> -static int sprd_efuse_write(void *context, u32 offset, void *val, size_t bytes)
> +static int sprd_efuse_write(void *context, u32 offset, const void *val, size_t bytes)
>  {

[Severity: Critical]
This is a pre-existing issue, but is there a stack memory leak in
sprd_efuse_read()?

When the nvmem core passes a length up to PAGE_SIZE (4096) for sysfs reads,
sprd_efuse_read() allocates a local 4-byte data variable on the stack:

    u32 data;
    ...
    memcpy(val, &data, bytes);

If bytes > 4, would this copy up to 4092 bytes of stack memory to the
output buffer?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260726131724.15299-1-linkmauve@linkmauve.fr?part=3

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-07-26 13:30 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-26 13:17 [PATCH v4 0/3] nvmem: migrate to const void * in reg_write Link Mauve
2026-07-26 13:17 ` Link Mauve
2026-07-26 13:17 ` [PATCH v4 1/3] firmware: meson: pass a const buffer to meson_sm_call_write() Link Mauve
2026-07-26 13:17   ` Link Mauve
2026-07-26 13:17 ` [PATCH v4 2/3] nvmem: core: deprecate reg_write callback and add reg_write_const Link Mauve
2026-07-26 13:17   ` Link Mauve
2026-07-26 13:17 ` [PATCH v4 3/3] nvmem: make all reg_write callbacks take const void * Link Mauve
2026-07-26 13:17   ` Link Mauve
2026-07-26 13:30   ` sashiko-bot
2026-07-26 13:30     ` sashiko-bot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.