* [PATCH v3 0/4] nvmem: Add Raspberry Pi OTP nvmem driver
@ 2026-05-06 12:28 Gregor Herburger
2026-05-06 12:28 ` [PATCH v3 1/4] dt-bindings: raspberrypi,bcm2835-firmware: Add bcm2712-firmware compatible Gregor Herburger
` (4 more replies)
0 siblings, 5 replies; 9+ messages in thread
From: Gregor Herburger @ 2026-05-06 12:28 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
Ray Jui, Scott Branden, Broadcom internal kernel review list,
Eric Anholt, Stefan Wahren, Srinivas Kandagatla, Kees Cook,
Gustavo A. R. Silva
Cc: devicetree, linux-rpi-kernel, linux-arm-kernel, linux-kernel,
linux-hardening, Gregor Herburger
Hi,
This series adds support for the Raspberry Pis OTP registers. The
Raspberry Pi has one or more OTP regions. These registers are accessible
through the firmware. Add a driver for it and add updates the devicetree
for the Raspberry Pi 5.
---
Changes in v3:
- dts: add "raspberrypi,bcm2835-firmware" as fallback and fix dt-bindings
- Fix Kconfig depends
- Changed firmware data fields to __le32
- Add MODULE_ALIAS
- Link to v2: https://patch.msgid.link/20260505-rpi-otp-driver-v2-0-e9176ec72837@linutronix.de
Changes in v2:
- register nvmem driver from firmware driver and drop firmware sub nodes
- Use struct_size and __counted_by for dynamic array
- Drop unneeded comment in Kconfig
- Use NVMEM_DEVID_NONE
- Use kzalloc
- Update module description
- Link to v1: https://patch.msgid.link/20260408-rpi-otp-driver-v1-0-e02d1dbe6008@linutronix.de
---
Gregor Herburger (4):
dt-bindings: raspberrypi,bcm2835-firmware: Add bcm2712-firmware compatible
nvmem: Add the Raspberry Pi OTP driver
firmware: raspberrypi: register nvmem driver
arm64: dts: broadcom: bcm2712: add raspberrypi,bcm2712-firmware compatible
.../arm/bcm/raspberrypi,bcm2835-firmware.yaml | 13 ++-
.../boot/dts/broadcom/bcm2712-rpi-5-b-base.dtsi | 4 +-
drivers/firmware/raspberrypi.c | 59 +++++++++-
drivers/nvmem/Kconfig | 10 ++
drivers/nvmem/Makefile | 1 +
drivers/nvmem/raspberrypi-otp.c | 120 +++++++++++++++++++++
include/soc/bcm2835/raspberrypi-firmware.h | 14 +++
7 files changed, 216 insertions(+), 5 deletions(-)
---
base-commit: f3e6330d7fe42b204af05a2dbc68b379e0ad179e
change-id: 20260408-rpi-otp-driver-75fce1dcff7d
Best regards,
--
Gregor Herburger <gregor.herburger@linutronix.de>
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v3 1/4] dt-bindings: raspberrypi,bcm2835-firmware: Add bcm2712-firmware compatible
2026-05-06 12:28 [PATCH v3 0/4] nvmem: Add Raspberry Pi OTP nvmem driver Gregor Herburger
@ 2026-05-06 12:28 ` Gregor Herburger
2026-05-06 16:50 ` Conor Dooley
2026-05-06 12:28 ` [PATCH v3 2/4] nvmem: Add the Raspberry Pi OTP driver Gregor Herburger
` (3 subsequent siblings)
4 siblings, 1 reply; 9+ messages in thread
From: Gregor Herburger @ 2026-05-06 12:28 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
Ray Jui, Scott Branden, Broadcom internal kernel review list,
Eric Anholt, Stefan Wahren, Srinivas Kandagatla, Kees Cook,
Gustavo A. R. Silva
Cc: devicetree, linux-rpi-kernel, linux-arm-kernel, linux-kernel,
linux-hardening, Gregor Herburger
Add a compatible string for the bcm2712 firmware.
Signed-off-by: Gregor Herburger <gregor.herburger@linutronix.de>
---
.../bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml b/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
index 983ea80eaec9..fbcfa2bc168a 100644
--- a/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
+++ b/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
@@ -21,9 +21,16 @@ select:
properties:
compatible:
- items:
- - const: raspberrypi,bcm2835-firmware
- - const: simple-mfd
+ oneOf:
+ - items:
+ - enum:
+ - raspberrypi,bcm2712-firmware
+ - raspberrypi,bcm2835-firmware
+ - const: simple-mfd
+ - items:
+ - const: raspberrypi,bcm2712-firmware
+ - const: raspberrypi,bcm2835-firmware
+ - const: simple-mfd
mboxes:
maxItems: 1
--
2.47.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v3 2/4] nvmem: Add the Raspberry Pi OTP driver
2026-05-06 12:28 [PATCH v3 0/4] nvmem: Add Raspberry Pi OTP nvmem driver Gregor Herburger
2026-05-06 12:28 ` [PATCH v3 1/4] dt-bindings: raspberrypi,bcm2835-firmware: Add bcm2712-firmware compatible Gregor Herburger
@ 2026-05-06 12:28 ` Gregor Herburger
2026-05-06 12:28 ` [PATCH v3 3/4] firmware: raspberrypi: register nvmem driver Gregor Herburger
` (2 subsequent siblings)
4 siblings, 0 replies; 9+ messages in thread
From: Gregor Herburger @ 2026-05-06 12:28 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
Ray Jui, Scott Branden, Broadcom internal kernel review list,
Eric Anholt, Stefan Wahren, Srinivas Kandagatla, Kees Cook,
Gustavo A. R. Silva
Cc: devicetree, linux-rpi-kernel, linux-arm-kernel, linux-kernel,
linux-hardening, Gregor Herburger
Raspberry Pis have OTP registers which can be accessed through the
videocore firmware. Add a nvmem driver to support these OTP registers.
Signed-off-by: Gregor Herburger <gregor.herburger@linutronix.de>
---
drivers/nvmem/Kconfig | 10 +++
drivers/nvmem/Makefile | 1 +
drivers/nvmem/raspberrypi-otp.c | 120 +++++++++++++++++++++++++++++
include/soc/bcm2835/raspberrypi-firmware.h | 9 +++
4 files changed, 140 insertions(+)
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 74ddbd0f79b0..aac31f43385e 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -483,4 +483,14 @@ config NVMEM_QORIQ_EFUSE
This driver can also be built as a module. If so, the module
will be called nvmem_qoriq_efuse.
+config NVMEM_RASPBERRYPI_OTP
+ tristate "Raspberry Pi OTP support"
+ depends on RASPBERRYPI_FIRMWARE || (COMPILE_TEST && !RASPBERRYPI_FIRMWARE)
+ help
+ This driver provides access to the Raspberry Pi OTP memory via the
+ nvmem subsystem. The driver supports the customer OTP as well as the
+ device specific private key OTP (BCM2712 only).
+
+ This driver can also be built as a module. If so, the module
+ will be called raspberrypi-otp.
endif
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index 7252b8ec88d4..8ca2095e068f 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -95,3 +95,4 @@ obj-$(CONFIG_NVMEM_ZYNQMP) += nvmem_zynqmp_nvmem.o
nvmem_zynqmp_nvmem-y := zynqmp_nvmem.o
obj-$(CONFIG_NVMEM_QORIQ_EFUSE) += nvmem-qoriq-efuse.o
nvmem-qoriq-efuse-y := qoriq-efuse.o
+obj-$(CONFIG_NVMEM_RASPBERRYPI_OTP) += raspberrypi-otp.o
diff --git a/drivers/nvmem/raspberrypi-otp.c b/drivers/nvmem/raspberrypi-otp.c
new file mode 100644
index 000000000000..1edf2d5538d0
--- /dev/null
+++ b/drivers/nvmem/raspberrypi-otp.c
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/overflow.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/platform_device.h>
+#include <soc/bcm2835/raspberrypi-firmware.h>
+
+struct rpi_otp_priv {
+ struct rpi_firmware *fw;
+ struct device *dev;
+ u32 read_tag;
+ u32 write_tag;
+};
+
+struct rpi_otp_header {
+ __le32 start;
+ __le32 count;
+ __le32 data[] __counted_by(count);
+};
+
+static int rpi_otp_read(void *context, unsigned int offset, void *buf, size_t bytes)
+{
+ struct rpi_otp_priv *priv = context;
+ struct rpi_otp_header *fwbuf;
+ u32 count = bytes / 4;
+ int ret;
+
+ fwbuf = kzalloc(struct_size(fwbuf, data, count), GFP_KERNEL);
+ if (!fwbuf)
+ return -ENOMEM;
+
+ fwbuf->start = cpu_to_le32(offset / 4);
+ fwbuf->count = cpu_to_le32(count);
+
+ ret = rpi_firmware_property(priv->fw, priv->read_tag, fwbuf,
+ sizeof(struct rpi_otp_header) + bytes);
+ if (ret)
+ goto out;
+
+ memcpy(buf, fwbuf->data, bytes);
+
+out:
+ kfree(fwbuf);
+ return ret;
+}
+
+static int rpi_otp_write(void *context, unsigned int offset, void *val, size_t bytes)
+{
+ struct rpi_otp_priv *priv = context;
+ struct rpi_otp_header *fwbuf;
+ u32 count = bytes / 4;
+ int ret;
+
+ fwbuf = kzalloc(struct_size(fwbuf, data, count), GFP_KERNEL);
+ if (!fwbuf)
+ return -ENOMEM;
+
+ fwbuf->start = cpu_to_le32(offset / 4);
+ fwbuf->count = cpu_to_le32(count);
+ memcpy(fwbuf->data, val, bytes);
+
+ ret = rpi_firmware_property(priv->fw, priv->write_tag, fwbuf,
+ sizeof(struct rpi_otp_header) + bytes);
+
+ kfree(fwbuf);
+ return ret;
+}
+
+static int rpi_otp_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct nvmem_device *nvmem;
+ struct rpi_otp_priv *priv;
+ const struct rpi_otp_driver_data *data;
+ struct nvmem_config config = {
+ .read_only = false,
+ .word_size = 4,
+ .stride = 4,
+ .reg_read = rpi_otp_read,
+ .reg_write = rpi_otp_write,
+ .id = NVMEM_DEVID_NONE,
+ };
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ data = dev_get_platdata(dev);
+ if (!data)
+ return -ENODEV;
+
+ priv->fw = dev_get_drvdata(dev->parent);
+ priv->dev = dev;
+ priv->read_tag = data->read_tag;
+ priv->write_tag = data->write_tag;
+ config.dev = dev;
+ config.priv = priv;
+ config.name = data->name;
+ config.size = data->size;
+
+ nvmem = devm_nvmem_register(dev, &config);
+ if (IS_ERR(nvmem))
+ return dev_err_probe(dev, PTR_ERR(nvmem), "error registering nvmem config\n");
+
+ return 0;
+}
+
+static struct platform_driver raspberry_otp_driver = {
+ .probe = rpi_otp_probe,
+ .driver = {
+ .name = "raspberrypi-otp",
+ },
+};
+module_platform_driver(raspberry_otp_driver);
+
+MODULE_AUTHOR("Gregor Herburger <gregor.herburger@linutronix.de>");
+MODULE_DESCRIPTION("Raspberry Pi OTP driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:raspberrypi-otp");
diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h
index e1f87fbfe554..ae73c9cd19ba 100644
--- a/include/soc/bcm2835/raspberrypi-firmware.h
+++ b/include/soc/bcm2835/raspberrypi-firmware.h
@@ -92,6 +92,8 @@ enum rpi_firmware_property_tag {
RPI_FIRMWARE_SET_POE_HAT_VAL = 0x00030050,
RPI_FIRMWARE_NOTIFY_XHCI_RESET = 0x00030058,
RPI_FIRMWARE_NOTIFY_DISPLAY_DONE = 0x00030066,
+ RPI_FIRMWARE_GET_PRIVATE_OTP = 0x00030081,
+ RPI_FIRMWARE_SET_PRIVATE_OTP = 0x00038081,
/* Dispmanx TAGS */
RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001,
@@ -174,6 +176,13 @@ struct rpi_firmware_clk_rate_request {
.id = cpu_to_le32(_id), \
}
+struct rpi_otp_driver_data {
+ const char *name;
+ u32 read_tag;
+ u32 write_tag;
+ int size;
+};
+
#if IS_ENABLED(CONFIG_RASPBERRYPI_FIRMWARE)
int rpi_firmware_property(struct rpi_firmware *fw,
u32 tag, void *data, size_t len);
--
2.47.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v3 3/4] firmware: raspberrypi: register nvmem driver
2026-05-06 12:28 [PATCH v3 0/4] nvmem: Add Raspberry Pi OTP nvmem driver Gregor Herburger
2026-05-06 12:28 ` [PATCH v3 1/4] dt-bindings: raspberrypi,bcm2835-firmware: Add bcm2712-firmware compatible Gregor Herburger
2026-05-06 12:28 ` [PATCH v3 2/4] nvmem: Add the Raspberry Pi OTP driver Gregor Herburger
@ 2026-05-06 12:28 ` Gregor Herburger
2026-05-06 12:28 ` [PATCH v3 4/4] arm64: dts: broadcom: bcm2712: add raspberrypi,bcm2712-firmware compatible Gregor Herburger
2026-05-07 12:10 ` [PATCH v3 0/4] nvmem: Add Raspberry Pi OTP nvmem driver Gregor Herburger
4 siblings, 0 replies; 9+ messages in thread
From: Gregor Herburger @ 2026-05-06 12:28 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
Ray Jui, Scott Branden, Broadcom internal kernel review list,
Eric Anholt, Stefan Wahren, Srinivas Kandagatla, Kees Cook,
Gustavo A. R. Silva
Cc: devicetree, linux-rpi-kernel, linux-arm-kernel, linux-kernel,
linux-hardening, Gregor Herburger
The Raspberry Pi firmware exposes two regions with otp registers. The
first region called "customer otp" is available on all Raspberry Pi
models. The second is only available on the Raspberry Pi 5 (bcm2712).
Signed-off-by: Gregor Herburger <gregor.herburger@linutronix.de>
---
drivers/firmware/raspberrypi.c | 59 +++++++++++++++++++++++++++++-
include/soc/bcm2835/raspberrypi-firmware.h | 5 +++
2 files changed, 63 insertions(+), 1 deletion(-)
diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c
index 0aa322e9a2e7..b363ec7bc5b4 100644
--- a/drivers/firmware/raspberrypi.c
+++ b/drivers/firmware/raspberrypi.c
@@ -24,12 +24,15 @@
static struct platform_device *rpi_hwmon;
static struct platform_device *rpi_clk;
+static struct platform_device *rpi_otp_customer;
+static struct platform_device *rpi_otp_private;
struct rpi_firmware {
struct mbox_client cl;
struct mbox_chan *chan; /* The property channel. */
struct completion c;
u32 enabled;
+ enum rpi_firmware_soc soc;
struct kref consumers;
};
@@ -231,6 +234,45 @@ static void rpi_register_clk_driver(struct device *dev)
-1, NULL, 0);
}
+static const struct rpi_otp_driver_data rpi_otp_customer_data = {
+ .name = "rpi-otp-customer",
+ .read_tag = RPI_FIRMWARE_GET_CUSTOMER_OTP,
+ .write_tag = RPI_FIRMWARE_SET_CUSTOMER_OTP,
+ .size = 32,
+};
+
+static const struct rpi_otp_driver_data rpi_otp_private_data = {
+ .name = "rpi-otp-private",
+ .read_tag = RPI_FIRMWARE_GET_PRIVATE_OTP,
+ .write_tag = RPI_FIRMWARE_SET_PRIVATE_OTP,
+ .size = 32,
+};
+
+static void rpi_register_otp_driver(struct device *dev)
+{
+ struct rpi_firmware *fw = dev_get_drvdata(dev);
+
+ rpi_otp_customer = platform_device_register_data(dev, "raspberrypi-otp",
+ PLATFORM_DEVID_AUTO,
+ &rpi_otp_customer_data,
+ sizeof(rpi_otp_customer_data));
+
+ if (IS_ERR(rpi_otp_customer))
+ dev_err(dev, "Failed to register customer OTP device: %ld\n",
+ PTR_ERR(rpi_otp_customer));
+
+ if (fw->soc == RPI_FIRMWARE_SOC_BCM2712) {
+ rpi_otp_private = platform_device_register_data(dev, "raspberrypi-otp",
+ PLATFORM_DEVID_AUTO,
+ &rpi_otp_private_data,
+ sizeof(rpi_otp_private_data));
+
+ if (IS_ERR(rpi_otp_private))
+ dev_err(dev, "Failed to register private OTP device: %ld\n",
+ PTR_ERR(rpi_otp_private));
+ }
+}
+
unsigned int rpi_firmware_clk_get_max_rate(struct rpi_firmware *fw, unsigned int id)
{
struct rpi_firmware_clk_rate_request msg =
@@ -299,12 +341,14 @@ static int rpi_firmware_probe(struct platform_device *pdev)
init_completion(&fw->c);
kref_init(&fw->consumers);
+ fw->soc = (uintptr_t)device_get_match_data(dev);
platform_set_drvdata(pdev, fw);
rpi_firmware_print_firmware_revision(fw);
rpi_register_hwmon_driver(dev, fw);
rpi_register_clk_driver(dev);
+ rpi_register_otp_driver(dev);
return 0;
}
@@ -327,12 +371,25 @@ static void rpi_firmware_remove(struct platform_device *pdev)
rpi_hwmon = NULL;
platform_device_unregister(rpi_clk);
rpi_clk = NULL;
+ platform_device_unregister(rpi_otp_customer);
+ rpi_otp_customer = NULL;
+ if (rpi_otp_private)
+ platform_device_unregister(rpi_otp_private);
+
+ rpi_otp_private = NULL;
rpi_firmware_put(fw);
}
static const struct of_device_id rpi_firmware_of_match[] = {
- { .compatible = "raspberrypi,bcm2835-firmware", },
+ {
+ .compatible = "raspberrypi,bcm2835-firmware",
+ .data = (void *)RPI_FIRMWARE_SOC_BCM2835,
+ },
+ {
+ .compatible = "raspberrypi,bcm2712-firmware",
+ .data = (void *)RPI_FIRMWARE_SOC_BCM2712,
+ },
{},
};
MODULE_DEVICE_TABLE(of, rpi_firmware_of_match);
diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h
index ae73c9cd19ba..17595a96e90b 100644
--- a/include/soc/bcm2835/raspberrypi-firmware.h
+++ b/include/soc/bcm2835/raspberrypi-firmware.h
@@ -9,6 +9,11 @@
#include <linux/types.h>
#include <linux/of_device.h>
+enum rpi_firmware_soc {
+ RPI_FIRMWARE_SOC_BCM2835,
+ RPI_FIRMWARE_SOC_BCM2712,
+};
+
struct rpi_firmware;
enum rpi_firmware_property_status {
--
2.47.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v3 4/4] arm64: dts: broadcom: bcm2712: add raspberrypi,bcm2712-firmware compatible
2026-05-06 12:28 [PATCH v3 0/4] nvmem: Add Raspberry Pi OTP nvmem driver Gregor Herburger
` (2 preceding siblings ...)
2026-05-06 12:28 ` [PATCH v3 3/4] firmware: raspberrypi: register nvmem driver Gregor Herburger
@ 2026-05-06 12:28 ` Gregor Herburger
2026-05-07 12:10 ` [PATCH v3 0/4] nvmem: Add Raspberry Pi OTP nvmem driver Gregor Herburger
4 siblings, 0 replies; 9+ messages in thread
From: Gregor Herburger @ 2026-05-06 12:28 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
Ray Jui, Scott Branden, Broadcom internal kernel review list,
Eric Anholt, Stefan Wahren, Srinivas Kandagatla, Kees Cook,
Gustavo A. R. Silva
Cc: devicetree, linux-rpi-kernel, linux-arm-kernel, linux-kernel,
linux-hardening, Gregor Herburger
The Raspberry Pi 5 (BCM2712) firmware exposes additional features such
as the additional OTP register region called 'private OTP'.
Add the raspberrypi,bcm2712-firmware compatible to allow drivers to
distinguish this hardware variant while keeping
raspberrypi,bcm2835-firmware as a fallback for backward compatibility
with existing drivers.
Signed-off-by: Gregor Herburger <gregor.herburger@linutronix.de>
---
arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b-base.dtsi | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b-base.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b-base.dtsi
index b7a6bc34ae1a..4aa8ec7601b8 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b-base.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b-base.dtsi
@@ -46,7 +46,9 @@ power_button: power-button {
firmware {
firmware: rpi-firmware {
- compatible = "raspberrypi,bcm2835-firmware", "simple-mfd";
+ compatible = "raspberrypi,bcm2712-firmware",
+ "raspberrypi,bcm2835-firmware",
+ "simple-mfd";
mboxes = <&mailbox>;
--
2.47.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v3 1/4] dt-bindings: raspberrypi,bcm2835-firmware: Add bcm2712-firmware compatible
2026-05-06 12:28 ` [PATCH v3 1/4] dt-bindings: raspberrypi,bcm2835-firmware: Add bcm2712-firmware compatible Gregor Herburger
@ 2026-05-06 16:50 ` Conor Dooley
2026-05-07 7:42 ` Gregor Herburger
0 siblings, 1 reply; 9+ messages in thread
From: Conor Dooley @ 2026-05-06 16:50 UTC (permalink / raw)
To: Gregor Herburger
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
Ray Jui, Scott Branden, Broadcom internal kernel review list,
Eric Anholt, Stefan Wahren, Srinivas Kandagatla, Kees Cook,
Gustavo A. R. Silva, devicetree, linux-rpi-kernel,
linux-arm-kernel, linux-kernel, linux-hardening
[-- Attachment #1: Type: text/plain, Size: 1473 bytes --]
On Wed, May 06, 2026 at 02:28:15PM +0200, Gregor Herburger wrote:
> Add a compatible string for the bcm2712 firmware.
>
> Signed-off-by: Gregor Herburger <gregor.herburger@linutronix.de>
> ---
> .../bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml | 13 ++++++++++---
> 1 file changed, 10 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml b/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
> index 983ea80eaec9..fbcfa2bc168a 100644
> --- a/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
> +++ b/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
> @@ -21,9 +21,16 @@ select:
>
> properties:
> compatible:
> - items:
> - - const: raspberrypi,bcm2835-firmware
> - - const: simple-mfd
> + oneOf:
> + - items:
> + - enum:
> + - raspberrypi,bcm2712-firmware
> + - raspberrypi,bcm2835-firmware
> + - const: simple-mfd
> + - items:
> + - const: raspberrypi,bcm2712-firmware
> + - const: raspberrypi,bcm2835-firmware
> + - const: simple-mfd
This diff doesn't make sense, either the new firmware is compatible with
the old one or it is not. It shouldn't appear twice.
pw-bot: changes-requested
Cheers,
Conor.
>
> mboxes:
> maxItems: 1
>
> --
> 2.47.3
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 1/4] dt-bindings: raspberrypi,bcm2835-firmware: Add bcm2712-firmware compatible
2026-05-06 16:50 ` Conor Dooley
@ 2026-05-07 7:42 ` Gregor Herburger
2026-05-07 17:05 ` Conor Dooley
0 siblings, 1 reply; 9+ messages in thread
From: Gregor Herburger @ 2026-05-07 7:42 UTC (permalink / raw)
To: Conor Dooley
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
Ray Jui, Scott Branden, Broadcom internal kernel review list,
Eric Anholt, Stefan Wahren, Srinivas Kandagatla, Kees Cook,
Gustavo A. R. Silva, devicetree, linux-rpi-kernel,
linux-arm-kernel, linux-kernel, linux-hardening
On Wed, May 06, 2026 at 05:50:42PM +0100, Conor Dooley wrote:
> On Wed, May 06, 2026 at 02:28:15PM +0200, Gregor Herburger wrote:
> > Add a compatible string for the bcm2712 firmware.
> >
> > Signed-off-by: Gregor Herburger <gregor.herburger@linutronix.de>
> > ---
> > .../bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml | 13 ++++++++++---
> > 1 file changed, 10 insertions(+), 3 deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml b/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
> > index 983ea80eaec9..fbcfa2bc168a 100644
> > --- a/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
> > +++ b/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
> > @@ -21,9 +21,16 @@ select:
> >
> > properties:
> > compatible:
> > - items:
> > - - const: raspberrypi,bcm2835-firmware
> > - - const: simple-mfd
> > + oneOf:
> > + - items:
> > + - enum:
> > + - raspberrypi,bcm2712-firmware
> > + - raspberrypi,bcm2835-firmware
> > + - const: simple-mfd
> > + - items:
> > + - const: raspberrypi,bcm2712-firmware
> > + - const: raspberrypi,bcm2835-firmware
> > + - const: simple-mfd
>
> This diff doesn't make sense, either the new firmware is compatible with
> the old one or it is not. It shouldn't appear twice.
Ok. I will change it to:
- items:
- - const: raspberrypi,bcm2835-firmware
- - const: simple-mfd
+ oneOf:
+ - items:
+ - const: raspberrypi,bcm2835-firmware
+ - const: simple-mfd
+ - items:
+ - const: raspberrypi,bcm2712-firmware
+ - const: raspberrypi,bcm2835-firmware
+ - const: simple-mfd
While reading the writing-schema.rst documentation I saw that it says most
bindings shouldn't need a select. Imho the select in this file doesn't add
anything which isn't covered witht the compatible. I wonder if I should drop the
select block?
Regards
Gregor
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 0/4] nvmem: Add Raspberry Pi OTP nvmem driver
2026-05-06 12:28 [PATCH v3 0/4] nvmem: Add Raspberry Pi OTP nvmem driver Gregor Herburger
` (3 preceding siblings ...)
2026-05-06 12:28 ` [PATCH v3 4/4] arm64: dts: broadcom: bcm2712: add raspberrypi,bcm2712-firmware compatible Gregor Herburger
@ 2026-05-07 12:10 ` Gregor Herburger
4 siblings, 0 replies; 9+ messages in thread
From: Gregor Herburger @ 2026-05-07 12:10 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
Ray Jui, Scott Branden, Broadcom internal kernel review list,
Eric Anholt, Stefan Wahren, Srinivas Kandagatla, Kees Cook,
Gustavo A. R. Silva
Cc: devicetree, linux-rpi-kernel, linux-arm-kernel, linux-kernel,
linux-hardening
Hi,
replying to sashiko
>commit ee93b9620650bb02f494ab88ef4e18464c95770f
>Author: Gregor Herburger <gregor.herburger@linutronix.de>
>nvmem: Add the Raspberry Pi OTP driver
>This commit adds a new nvmem driver to support OTP registers on Raspberry Pi
>platforms. It accesses the OTP memory through the videocore firmware
>interface.
>> diff --git a/drivers/nvmem/raspberrypi-otp.c b/drivers/nvmem/raspberrypi-otp.c
>> new file mode 100644
>> index 0000000000000..1edf2d5538d04
>> --- /dev/null
>> +++ b/drivers/nvmem/raspberrypi-otp.c
>> @@ -0,0 +1,120 @@
>[ ... ]
>> +struct rpi_otp_priv {
>> + struct rpi_firmware *fw;
>> + struct device *dev;
>> + u32 read_tag;
>> + u32 write_tag;
>> +};
>> +
>> +struct rpi_otp_header {
>> + __le32 start;
>> + __le32 count;
>> + __le32 data[] __counted_by(count);
>Is the __counted_by attribute safe to use with explicitly endian types?
>On big-endian architectures (which are supported via COMPILE_TEST), the
>native bounds checking logic will evaluate the byte-swapped __le32 value as a
>massive integer (e.g., a count of 1 evaluates to 16777216).
>Does this unintentionally bypass the bounds checking defenses?
Yes that is right on compile tests on big-endian it will bypass the run time
check. I can use the __counted_by_le() macro to disable it on big-endian and
keep it on little-endian.
>> +};
>> +
>> +static int rpi_otp_read(void *context, unsigned int offset, void *buf, size_t bytes)
>> +{
>> + struct rpi_otp_priv *priv = context;
>> + struct rpi_otp_header *fwbuf;
>> + u32 count = bytes / 4;
>> + int ret;
>> +
>> + fwbuf = kzalloc(struct_size(fwbuf, data, count), GFP_KERNEL);
>Could an unaligned length request cause an out-of-bounds write here?
>If a caller requests an unaligned length (e.g., bytes = 3), count truncates
>to 0, allocating an 8-byte structure.
I first thought that alignment is checked in the nvmem system (with
nvmem_device::stride and nvmem_device::word_size) but that is only true for
sysfs accesses. The nvmem_device_read/nvmem_device_write functions call directly
into the callback function of the driver. I guess there should be an alignment
check in this functions as well.
For now I will add an alignment check into my functions.
>> + if (!fwbuf)
>> + return -ENOMEM;
>> +
>> + fwbuf->start = cpu_to_le32(offset / 4);
>> + fwbuf->count = cpu_to_le32(count);
>> +
>> + ret = rpi_firmware_property(priv->fw, priv->read_tag, fwbuf,
>> + sizeof(struct rpi_otp_header) + bytes);
>> + if (ret)
>> + goto out;
>> +
>> + memcpy(buf, fwbuf->data, bytes);
>With an unaligned bytes request, would this memcpy write past the bounds of
>the 0-count fwbuf array?
>Should there be an explicit alignment check for bytes and offset at the start
>of the function?
Yes see above.
>> +
>> +out:
>> + kfree(fwbuf);
>> + return ret;
>> +}
>> +
>> +static int rpi_otp_write(void *context, unsigned int offset, void *val, size_t bytes)
>> +{
>> + struct rpi_otp_priv *priv = context;
>> + struct rpi_otp_header *fwbuf;
>> + u32 count = bytes / 4;
>> + int ret;
>> +
>> + fwbuf = kzalloc(struct_size(fwbuf, data, count), GFP_KERNEL);
>> + if (!fwbuf)
>> + return -ENOMEM;
>> +
>> + fwbuf->start = cpu_to_le32(offset / 4);
>> + fwbuf->count = cpu_to_le32(count);
>> + memcpy(fwbuf->data, val, bytes);
>Similarly, could this memcpy write out-of-bounds if bytes is not aligned to
>a 4-byte boundary?
Yes see above.
>> +
>> + ret = rpi_firmware_property(priv->fw, priv->write_tag, fwbuf,
>> + sizeof(struct rpi_otp_header) + bytes);
>> +
>> + kfree(fwbuf);
>> + return ret;
>> +}
>> +
>> +static int rpi_otp_probe(struct platform_device *pdev)
>> +{
>> + struct device *dev = &pdev->dev;
>> + struct nvmem_device *nvmem;
>> + struct rpi_otp_priv *priv;
>> + const struct rpi_otp_driver_data *data;
>> + struct nvmem_config config = {
>> + .read_only = false,
>> + .word_size = 4,
>> + .stride = 4,
>> + .reg_read = rpi_otp_read,
>> + .reg_write = rpi_otp_write,
>> + .id = NVMEM_DEVID_NONE,
>> + };
>> +
>> + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
>> + if (!priv)
>> + return -ENOMEM;
>> +
>> + data = dev_get_platdata(dev);
>> + if (!data)
>> + return -ENODEV;
>> +
>> + priv->fw = dev_get_drvdata(dev->parent);
>> + priv->dev = dev;
>> + priv->read_tag = data->read_tag;
>> + priv->write_tag = data->write_tag;
>> + config.dev = dev;
>> + config.priv = priv;
>> + config.name = data->name;
>> + config.size = data->size;
>> +
>> + nvmem = devm_nvmem_register(dev, &config);
>Does this devres usage introduce a use-after-free risk during device unbind?
>If an in-kernel consumer holds a reference to the nvmem device,
>devm_nvmem_unregister() drops its refcount but returns while the consumer's
>reference keeps the device alive.
>The devres framework will then proceed to free the priv structure.
>If the consumer subsequently calls nvmem_device_read(), will it dereference
>the freed priv pointer inside rpi_otp_read()?
Wow good catch. This took me a while to understand but i guess it can indeed
cause an use-after-free error error for in-kernel consumers. I will look into
it.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 1/4] dt-bindings: raspberrypi,bcm2835-firmware: Add bcm2712-firmware compatible
2026-05-07 7:42 ` Gregor Herburger
@ 2026-05-07 17:05 ` Conor Dooley
0 siblings, 0 replies; 9+ messages in thread
From: Conor Dooley @ 2026-05-07 17:05 UTC (permalink / raw)
To: Gregor Herburger
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
Ray Jui, Scott Branden, Broadcom internal kernel review list,
Eric Anholt, Stefan Wahren, Srinivas Kandagatla, Kees Cook,
Gustavo A. R. Silva, devicetree, linux-rpi-kernel,
linux-arm-kernel, linux-kernel, linux-hardening
[-- Attachment #1: Type: text/plain, Size: 2451 bytes --]
On Thu, May 07, 2026 at 09:42:54AM +0200, Gregor Herburger wrote:
> On Wed, May 06, 2026 at 05:50:42PM +0100, Conor Dooley wrote:
> > On Wed, May 06, 2026 at 02:28:15PM +0200, Gregor Herburger wrote:
> > > Add a compatible string for the bcm2712 firmware.
> > >
> > > Signed-off-by: Gregor Herburger <gregor.herburger@linutronix.de>
> > > ---
> > > .../bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml | 13 ++++++++++---
> > > 1 file changed, 10 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml b/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
> > > index 983ea80eaec9..fbcfa2bc168a 100644
> > > --- a/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
> > > +++ b/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
> > > @@ -21,9 +21,16 @@ select:
> > >
> > > properties:
> > > compatible:
> > > - items:
> > > - - const: raspberrypi,bcm2835-firmware
> > > - - const: simple-mfd
> > > + oneOf:
> > > + - items:
> > > + - enum:
> > > + - raspberrypi,bcm2712-firmware
> > > + - raspberrypi,bcm2835-firmware
> > > + - const: simple-mfd
> > > + - items:
> > > + - const: raspberrypi,bcm2712-firmware
> > > + - const: raspberrypi,bcm2835-firmware
> > > + - const: simple-mfd
> >
> > This diff doesn't make sense, either the new firmware is compatible with
> > the old one or it is not. It shouldn't appear twice.
>
> Ok. I will change it to:
> - items:
> - - const: raspberrypi,bcm2835-firmware
> - - const: simple-mfd
> + oneOf:
> + - items:
> + - const: raspberrypi,bcm2835-firmware
> + - const: simple-mfd
> + - items:
> + - const: raspberrypi,bcm2712-firmware
> + - const: raspberrypi,bcm2835-firmware
> + - const: simple-mfd
>
> While reading the writing-schema.rst documentation I saw that it says most
> bindings shouldn't need a select. Imho the select in this file doesn't add
> anything which isn't covered witht the compatible. I wonder if I should drop the
> select block?
That shouldn't be required, other simple-mfd users do not have it.
Remove it and run dt_binding_check just to be sure. It'd be a separate
patch from this one FWIW.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-05-07 17:06 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-06 12:28 [PATCH v3 0/4] nvmem: Add Raspberry Pi OTP nvmem driver Gregor Herburger
2026-05-06 12:28 ` [PATCH v3 1/4] dt-bindings: raspberrypi,bcm2835-firmware: Add bcm2712-firmware compatible Gregor Herburger
2026-05-06 16:50 ` Conor Dooley
2026-05-07 7:42 ` Gregor Herburger
2026-05-07 17:05 ` Conor Dooley
2026-05-06 12:28 ` [PATCH v3 2/4] nvmem: Add the Raspberry Pi OTP driver Gregor Herburger
2026-05-06 12:28 ` [PATCH v3 3/4] firmware: raspberrypi: register nvmem driver Gregor Herburger
2026-05-06 12:28 ` [PATCH v3 4/4] arm64: dts: broadcom: bcm2712: add raspberrypi,bcm2712-firmware compatible Gregor Herburger
2026-05-07 12:10 ` [PATCH v3 0/4] nvmem: Add Raspberry Pi OTP nvmem driver Gregor Herburger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox