* [PATCH v2 0/2] Raspberry Pi 5 RTC driver
@ 2026-09-17 12:21 Sander Speetjens
2026-09-17 12:21 ` [PATCH v2 1/2] dt-bindings: rtc: Add property for Raspberry Pi 5 RTC Sander Speetjens
2026-09-17 12:21 ` [PATCH v2 2/2] rtc: Add Raspberry Pi 5 RTC driver Sander Speetjens
0 siblings, 2 replies; 5+ messages in thread
From: Sander Speetjens @ 2026-09-17 12:21 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
Jonathan Bell, Stefan Wahren, linux-rtc, devicetree,
linux-rpi-kernel, linux-arm-kernel, sander.speetjens
The Raspberry Pi 5 has a battery-backed RTC located on the DA9091 PMIC accessed via the I2C bus[1].
Access to the RTC is provided exclusively through the VideoCore firmware
mailbox interface (not via a direct I2C register interface).
As stated by jamesh on the Rasperry Pi forum [2], "There are no plans to release a public datasheet for the DA9091." So we are stuck with the firmware interface for now. PhilE also states that "The firmware needs full control of the DA9091, sometimes with extremely low latency, otherwise there's a risk the supply could just cut the power."
This series adds:
- a DT property for the charging voltage of the RTC battery
- the RTC driver that talks to the firmware
The driver and binding are based on (and largely taken from) the
downstream Raspberry Pi kernel. The main changes for upstream are
the addition of a dt binding property for setting the charging voltage and
binding the driver from the raspberrypi-firmware driver instead of from
the DT.
The driver supports time read/write, alarm, and optional trickle
charging voltage configuration via the device-tree.
Testing
-------
- Hardware: Raspberry Pi 5 Model B revC
- Kernel: v7.2
- dt_binding_check: passed
- Basic RTC operations (read/write time, alarm) verified
[1] https://www.raspberrypi.com/news/introducing-raspberry-pi-5/
[2] https://forums.raspberrypi.com/viewtopic.php?t=359073
Sander Speetjens (2):
dt-bindings: rtc: Add property for Raspberry Pi 5 RTC
rtc: Add Raspberry Pi 5 RTC driver
.../arm/bcm/raspberrypi,bcm2835-firmware.yaml | 7 +
drivers/firmware/raspberrypi.c | 19 ++
drivers/rtc/Kconfig | 11 +
drivers/rtc/Makefile | 1 +
drivers/rtc/rtc-raspberrypi.c | 277 ++++++++++++++++++
5 files changed, 315 insertions(+)
create mode 100644 drivers/rtc/rtc-raspberrypi.c
base-commit: fd73f4a6659897191fa0d40695fe370925dd3780
--
2.55.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 1/2] dt-bindings: rtc: Add property for Raspberry Pi 5 RTC
2026-09-17 12:21 [PATCH v2 0/2] Raspberry Pi 5 RTC driver Sander Speetjens
@ 2026-09-17 12:21 ` Sander Speetjens
2026-09-17 12:30 ` sashiko-bot
2026-09-17 12:21 ` [PATCH v2 2/2] rtc: Add Raspberry Pi 5 RTC driver Sander Speetjens
1 sibling, 1 reply; 5+ messages in thread
From: Sander Speetjens @ 2026-09-17 12:21 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
Jonathan Bell, Stefan Wahren, linux-rtc, devicetree,
linux-rpi-kernel, linux-arm-kernel, sander.speetjens
Add charging-voltage-millivolt property for the Raspberry Pi 5 RTC.
V1 -> V2: As discussed with Krzysztof Kozlowski, this property is folded into
the existing raspberrypi,bcm2835-firmware properties.
Signed-off-by: Sander Speetjens <sander.speetjens@gmail.com>
---
.../bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml b/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
index 983ea80eaec9..1a0432510bee 100644
--- a/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
+++ b/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
@@ -133,6 +133,11 @@ properties:
required:
- compatible
+ charging-voltage-millivolt:
+ $ref: /schemas/rtc/rtc.yaml#/properties/charging-voltage-millivolt
+ minimum: 1300
+ maximum: 5000
+
required:
- compatible
- mboxes
@@ -171,5 +176,7 @@ examples:
touchscreen-size-x = <800>;
touchscreen-size-y = <480>;
};
+
+ trickle-charge-millivolt = <3300>;
};
...
--
2.55.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 2/2] rtc: Add Raspberry Pi 5 RTC driver
2026-09-17 12:21 [PATCH v2 0/2] Raspberry Pi 5 RTC driver Sander Speetjens
2026-09-17 12:21 ` [PATCH v2 1/2] dt-bindings: rtc: Add property for Raspberry Pi 5 RTC Sander Speetjens
@ 2026-09-17 12:21 ` Sander Speetjens
2026-09-17 12:40 ` sashiko-bot
1 sibling, 1 reply; 5+ messages in thread
From: Sander Speetjens @ 2026-09-17 12:21 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
Jonathan Bell, Stefan Wahren, linux-rtc, devicetree,
linux-rpi-kernel, linux-arm-kernel, sander.speetjens, Dom Cobley
Upstreaming the downstream Raspberry Pi 5 RTC driver.
This driver supports the custom DA9091, which is accessed through the firmware mailbox.
V1 -> V2:
Instead of the original driver, which was directly bound to the device tree. This driver is bound to the Raspberry Pi firmware device by creating a child device in the firmware driver probe function. The child device is then bound to this driver, which uses the firmware mailbox to access the RTC.
A couple of minor changes have been made to the driver since it was originally written, including:
- Checking if the model is a Raspberry Pi 5, as the RTC is only present on that model.
- Using the new devm_rpi_firmware_get() and devm_init_wakeup() helper to get the firmware device and avoid leaking memory.
- Using millivolts instead of microvolts for the trickle charge voltage, to match the RTC standard.
- Instead of setting the trickle charge voltage to 0 to disable trickle charging, the property is now optional. If the property is not present, trickle charging is disabled, per the RTC standard.
- Renaming the driver dt match compatible to "raspberrypi,firmware-rtc" to match the other firmware bindings.
- Renaming the driver name to "raspberrypi-rtc" to match the other firmware drivers.
Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
Signed-off-by: Dom Cobley <popcornmix@gmail.com>
Signed-off-by: Sander Speetjens <sander.speetjens@gmail.com>
---
drivers/firmware/raspberrypi.c | 19 +++
drivers/rtc/Kconfig | 11 ++
drivers/rtc/Makefile | 1 +
drivers/rtc/rtc-raspberrypi.c | 277 +++++++++++++++++++++++++++++++++
4 files changed, 308 insertions(+)
create mode 100644 drivers/rtc/rtc-raspberrypi.c
diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c
index 0aa322e9a2e7..b284c689f782 100644
--- a/drivers/firmware/raspberrypi.c
+++ b/drivers/firmware/raspberrypi.c
@@ -24,6 +24,7 @@
static struct platform_device *rpi_hwmon;
static struct platform_device *rpi_clk;
+static struct platform_device *rpi_rtc;
struct rpi_firmware {
struct mbox_client cl;
@@ -231,6 +232,21 @@ static void rpi_register_clk_driver(struct device *dev)
-1, NULL, 0);
}
+static void rpi_register_rtc_driver(struct device *dev)
+{
+ struct device_node *firmware;
+
+ firmware = of_get_compatible_child(dev->of_node,
+ "raspberrypi,firmware-rtc");
+ if (firmware) {
+ of_node_put(firmware);
+ return;
+ }
+
+ rpi_rtc = platform_device_register_data(dev, "raspberrypi-rtc",
+ -1, NULL, 0);
+}
+
unsigned int rpi_firmware_clk_get_max_rate(struct rpi_firmware *fw, unsigned int id)
{
struct rpi_firmware_clk_rate_request msg =
@@ -305,6 +321,7 @@ static int rpi_firmware_probe(struct platform_device *pdev)
rpi_firmware_print_firmware_revision(fw);
rpi_register_hwmon_driver(dev, fw);
rpi_register_clk_driver(dev);
+ rpi_register_rtc_driver(dev);
return 0;
}
@@ -327,6 +344,8 @@ static void rpi_firmware_remove(struct platform_device *pdev)
rpi_hwmon = NULL;
platform_device_unregister(rpi_clk);
rpi_clk = NULL;
+ platform_device_unregister(rpi_rtc);
+ rpi_rtc = NULL;
rpi_firmware_put(fw);
}
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 05b9233b9418..382973d46e06 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1999,6 +1999,17 @@ config RTC_DRV_R7301
This driver can also be built as a module. If so, the module
will be called rtc-r7301.
+config RTC_DRV_RPI
+ tristate "Raspberry Pi RTC"
+ depends on ARCH_BRCMSTB || COMPILE_TEST
+ default ARCH_BRCMSTB
+ help
+ If you say yes here you get support for the RTC found on
+ Raspberry Pi devices.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-rpi.
+
config RTC_DRV_STM32
tristate "STM32 RTC"
select REGMAP_MMIO
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 0347645b021f..46f1a0fc2416 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -144,6 +144,7 @@ obj-$(CONFIG_RTC_DRV_PS3) += rtc-ps3.o
obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o
obj-$(CONFIG_RTC_DRV_R7301) += rtc-r7301.o
obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o
+obj-$(CONFIG_RTC_DRV_RPI) += rtc-raspberrypi.o
obj-$(CONFIG_RTC_DRV_RC5T583) += rtc-rc5t583.o
obj-$(CONFIG_RTC_DRV_RC5T619) += rtc-rc5t619.o
obj-$(CONFIG_RTC_DRV_RK808) += rtc-rk808.o
diff --git a/drivers/rtc/rtc-raspberrypi.c b/drivers/rtc/rtc-raspberrypi.c
new file mode 100644
index 000000000000..af775ae55a87
--- /dev/null
+++ b/drivers/rtc/rtc-raspberrypi.c
@@ -0,0 +1,277 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/**
+ * rtc-rpi.c
+ *
+ * RTC driver using firmware mailbox
+ * Supports battery backed RTC and wake alarms
+ *
+ * Based on rtc-meson-vrtc by Neil Armstrong
+ *
+ * Copyright (c) 2023, Raspberry Pi Ltd.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/of.h>
+#include <soc/bcm2835/raspberrypi-firmware.h>
+
+struct rpi_rtc_data {
+ struct rtc_device *rtc;
+ struct rpi_firmware *fw;
+ u32 bbat_vchg_millivolts;
+};
+
+#define RPI_FIRMWARE_GET_RTC_REG 0x00030087
+#define RPI_FIRMWARE_SET_RTC_REG 0x00038087
+
+enum {
+ RTC_TIME,
+ RTC_ALARM,
+ RTC_ALARM_PENDING,
+ RTC_ALARM_ENABLE,
+ RTC_BBAT_CHG_VOLTS,
+ RTC_BBAT_CHG_VOLTS_MIN,
+ RTC_BBAT_CHG_VOLTS_MAX,
+ RTC_BBAT_VOLTS
+};
+
+static int rpi_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ struct rpi_rtc_data *vrtc = dev_get_drvdata(dev);
+ u32 data[2] = {RTC_TIME};
+ int err;
+
+ err = rpi_firmware_property(vrtc->fw, RPI_FIRMWARE_GET_RTC_REG,
+ &data, sizeof(data));
+ rtc_time64_to_tm(data[1], tm);
+ return err;
+}
+
+static int rpi_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct rpi_rtc_data *vrtc = dev_get_drvdata(dev);
+ u32 data[2] = {RTC_TIME, rtc_tm_to_time64(tm)};
+
+ return rpi_firmware_property(vrtc->fw, RPI_FIRMWARE_SET_RTC_REG,
+ &data, sizeof(data));
+}
+
+static int rpi_rtc_alarm_irq_is_enabled(struct device *dev, unsigned char *enabled)
+{
+ struct rpi_rtc_data *vrtc = dev_get_drvdata(dev);
+ u32 data[2] = {RTC_ALARM_ENABLE};
+ s32 err = 0;
+
+ err = rpi_firmware_property(vrtc->fw, RPI_FIRMWARE_GET_RTC_REG,
+ &data, sizeof(data));
+ *enabled = data[1] & 0x1;
+ return err;
+}
+
+static int rpi_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+ struct rpi_rtc_data *vrtc = dev_get_drvdata(dev);
+ u32 data[2] = {RTC_ALARM_ENABLE, enabled};
+
+ return rpi_firmware_property(vrtc->fw, RPI_FIRMWARE_SET_RTC_REG,
+ &data, sizeof(data));
+}
+
+static int rpi_rtc_alarm_clear_pending(struct device *dev)
+{
+ struct rpi_rtc_data *vrtc = dev_get_drvdata(dev);
+ u32 data[2] = {RTC_ALARM_PENDING, 1};
+
+ return rpi_firmware_property(vrtc->fw, RPI_FIRMWARE_SET_RTC_REG,
+ &data, sizeof(data));
+}
+
+static int rpi_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+ struct rpi_rtc_data *vrtc = dev_get_drvdata(dev);
+ u32 data[2] = {RTC_ALARM};
+ s32 err = 0;
+
+ err = rpi_rtc_alarm_irq_is_enabled(dev, &alarm->enabled);
+ if (!err)
+ err = rpi_firmware_property(vrtc->fw, RPI_FIRMWARE_GET_RTC_REG,
+ &data, sizeof(data));
+ rtc_time64_to_tm(data[1], &alarm->time);
+
+ return err;
+}
+
+static int rpi_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+ struct rpi_rtc_data *vrtc = dev_get_drvdata(dev);
+ u32 data[2] = {RTC_ALARM, rtc_tm_to_time64(&alarm->time)};
+ int err;
+
+ err = rpi_firmware_property(vrtc->fw, RPI_FIRMWARE_SET_RTC_REG,
+ &data, sizeof(data));
+
+ if (err == 0)
+ err = rpi_rtc_alarm_irq_enable(dev, alarm->enabled);
+
+ return err;
+}
+
+static const struct rtc_class_ops rpi_rtc_ops = {
+ .read_time = rpi_rtc_read_time,
+ .set_time = rpi_rtc_set_time,
+ .read_alarm = rpi_rtc_read_alarm,
+ .set_alarm = rpi_rtc_set_alarm,
+ .alarm_irq_enable = rpi_rtc_alarm_irq_enable,
+};
+
+static int rpi_rtc_set_charge_voltage(struct device *dev)
+{
+ struct rpi_rtc_data *vrtc = dev_get_drvdata(dev);
+ u32 data[2] = {RTC_BBAT_CHG_VOLTS, vrtc->bbat_vchg_millivolts * 1000U};
+ int err;
+
+ err = rpi_firmware_property(vrtc->fw, RPI_FIRMWARE_SET_RTC_REG,
+ &data, sizeof(data));
+
+ if (err)
+ dev_err(dev, "failed to set trickle charge voltage to %umV: %d\n",
+ vrtc->bbat_vchg_millivolts, err);
+ else if (vrtc->bbat_vchg_millivolts)
+ dev_info(dev, "trickle charging enabled at %umV\n",
+ vrtc->bbat_vchg_millivolts);
+
+ return err;
+}
+
+static ssize_t rpi_rtc_print_uint_reg(struct device *dev, char *buf, u32 reg)
+{
+ struct rpi_rtc_data *vrtc = dev_get_drvdata(dev->parent);
+ u32 data[2] = {reg, 0};
+ int ret = 0;
+
+ ret = rpi_firmware_property(vrtc->fw, RPI_FIRMWARE_GET_RTC_REG,
+ &data, sizeof(data));
+ if (ret < 0)
+ return ret;
+
+ return sprintf(buf, "%u\n", data[1]);
+}
+
+static ssize_t charging_voltage_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return rpi_rtc_print_uint_reg(dev, buf, RTC_BBAT_CHG_VOLTS);
+}
+static DEVICE_ATTR_RO(charging_voltage);
+
+static ssize_t charging_voltage_min_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return rpi_rtc_print_uint_reg(dev, buf, RTC_BBAT_CHG_VOLTS_MIN);
+}
+static DEVICE_ATTR_RO(charging_voltage_min);
+
+static ssize_t charging_voltage_max_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return rpi_rtc_print_uint_reg(dev, buf, RTC_BBAT_CHG_VOLTS_MAX);
+}
+static DEVICE_ATTR_RO(charging_voltage_max);
+
+static ssize_t battery_voltage_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return rpi_rtc_print_uint_reg(dev, buf, RTC_BBAT_VOLTS);
+}
+static DEVICE_ATTR_RO(battery_voltage);
+
+static struct attribute *rpi_rtc_attrs[] = {
+ &dev_attr_charging_voltage.attr,
+ &dev_attr_charging_voltage_min.attr,
+ &dev_attr_charging_voltage_max.attr,
+ &dev_attr_battery_voltage.attr,
+ NULL
+};
+
+static const struct attribute_group rpi_rtc_sysfs_files = {
+ .attrs = rpi_rtc_attrs,
+};
+
+static int rpi_rtc_probe(struct platform_device *pdev)
+{
+ struct rpi_rtc_data *vrtc;
+ struct device *dev = &pdev->dev;
+ struct rpi_firmware *firmware;
+ int ret;
+
+ // Check if our model is a Raspberry Pi 5, as the RTC is only present on that model.
+ const char *model = of_get_property(of_root, "model", NULL);
+ if (!model || strncmp(model, "Raspberry Pi 5", 14) != 0) {
+ dev_err(dev, "RTC is only available on Raspberry Pi 5\n");
+ return -ENODEV;
+ }
+
+ // Get the firmware device from the parent device
+ firmware = devm_rpi_firmware_get(dev, dev->parent->of_node);
+
+ if (!firmware)
+ return -EPROBE_DEFER;
+
+ vrtc = devm_kzalloc(dev, sizeof(*vrtc), GFP_KERNEL);
+ if (!vrtc)
+ return -ENOMEM;
+
+ vrtc->fw = firmware;
+
+ devm_device_init_wakeup(dev);
+
+ platform_set_drvdata(pdev, vrtc);
+
+ vrtc->rtc = devm_rtc_allocate_device(dev);
+ if (IS_ERR(vrtc->rtc))
+ return PTR_ERR(vrtc->rtc);
+
+ vrtc->rtc->range_max = U32_MAX; /* 2106-02-07 */
+
+ set_bit(RTC_FEATURE_ALARM_WAKEUP_ONLY, vrtc->rtc->features);
+ clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, vrtc->rtc->features);
+
+ vrtc->rtc->ops = &rpi_rtc_ops;
+ ret = rtc_add_group(vrtc->rtc, &rpi_rtc_sysfs_files);
+ if (ret)
+ return ret;
+
+ rpi_rtc_alarm_clear_pending(dev);
+
+ vrtc->bbat_vchg_millivolts = 0;
+ of_property_read_u32(dev->parent->of_node, "trickle-charge-millivolt",
+ &vrtc->bbat_vchg_millivolts);
+
+ rpi_rtc_set_charge_voltage(dev);
+
+ return devm_rtc_register_device(vrtc->rtc);
+}
+
+static const struct of_device_id rpi_rtc_dt_match[] = {
+ { .compatible = "raspberrypi,firmware-rtc"},
+ {},
+};
+MODULE_DEVICE_TABLE(of, rpi_rtc_dt_match);
+
+static struct platform_driver rpi_rtc_driver = {
+ .probe = rpi_rtc_probe,
+ .driver = {
+ .name = "raspberrypi-rtc",
+ .of_match_table = rpi_rtc_dt_match,
+ },
+};
+
+module_platform_driver(rpi_rtc_driver);
+
+MODULE_DESCRIPTION("Raspberry Pi RTC driver");
+MODULE_LICENSE("GPL");
--
2.55.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v2 1/2] dt-bindings: rtc: Add property for Raspberry Pi 5 RTC
2026-09-17 12:21 ` [PATCH v2 1/2] dt-bindings: rtc: Add property for Raspberry Pi 5 RTC Sander Speetjens
@ 2026-09-17 12:30 ` sashiko-bot
0 siblings, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-09-17 12:30 UTC (permalink / raw)
To: Sander Speetjens; +Cc: Alexandre Belloni, conor+dt, linux-rtc, devicetree, robh
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] dt-bindings: invalid $ref to non-existent property charging-voltage-millivolt
- [Medium] dt-bindings: undeclared property trickle-charge-millivolt in example
--
commit 387f082415e97ddf81bc4779459443584085928f
Author: Sander Speetjens <sander.speetjens@gmail.com>
dt-bindings: rtc: Add property for Raspberry Pi 5 RTC
This commit adds a new property to configure the charging voltage for the
Raspberry Pi 5 RTC within the bcm2835-firmware binding.
> diff --git a/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml b/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
> index 983ea80eaec97..1a0432510beeb 100644
> --- a/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
> +++ b/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
> @@ -133,6 +133,11 @@ properties:
> required:
> - compatible
>
> + charging-voltage-millivolt:
> + $ref: /schemas/rtc/rtc.yaml#/properties/charging-voltage-millivolt
[Severity: Medium]
Does the standard rtc.yaml define charging-voltage-millivolt?
Looking at the standard RTC binding (rtc.yaml), it does not define this
property. The correct standard name appears to be trickle-voltage-millivolt.
This invalid schema reference will cause make dt_binding_check to fail to
resolve the path and import constraints, breaking schema validation.
> + minimum: 1300
> + maximum: 5000
> +
> required:
> - compatible
[ ... ]
> @@ -171,5 +176,7 @@ examples:
> touchscreen-size-x = <800>;
> touchscreen-size-y = <480>;
> };
> +
> + trickle-charge-millivolt = <3300>;
[Severity: Medium]
Should this example property name match the one declared above?
The patch defines charging-voltage-millivolt in the properties block, but
the example uses trickle-charge-millivolt. Because additional properties are
restricted by the schema rules, the use of an undeclared property in the
example will trigger a strict validation failure during make dt_binding_check.
> };
> ...
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260917122144.703221-1-sander.speetjens@gmail.com?part=1
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2 2/2] rtc: Add Raspberry Pi 5 RTC driver
2026-09-17 12:21 ` [PATCH v2 2/2] rtc: Add Raspberry Pi 5 RTC driver Sander Speetjens
@ 2026-09-17 12:40 ` sashiko-bot
0 siblings, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-09-17 12:40 UTC (permalink / raw)
To: Sander Speetjens; +Cc: robh, conor+dt, devicetree, Alexandre Belloni, linux-rtc
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [Medium] rtc: unconditional dev_err on unsupported platforms
- [Medium] rtc: dt property name mismatch with schema and standard
- [Medium] rtc: ignored devm_device_init_wakeup return value
- [Low] kconfig: missing dependency on RASPBERRYPI_FIRMWARE
--
commit 63b49baa5affb33b58f7190d1f915c0156fa6365
Author: Sander Speetjens <sander.speetjens@gmail.com>
rtc: Add Raspberry Pi 5 RTC driver
This commit upstream supports the Raspberry Pi 5 RTC by interacting with
the custom DA9091 over the firmware mailbox. It binds as a child of the
firmware device and configures trickle charging based on device tree
settings.
> diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c
> index 0aa322e9a2e73..b284c689f7828 100644
> --- a/drivers/firmware/raspberrypi.c
> +++ b/drivers/firmware/raspberrypi.c
[ ... ]
> @@ -231,6 +232,21 @@ static void rpi_register_clk_driver(struct device *dev)
> -1, NULL, 0);
> }
>
> +static void rpi_register_rtc_driver(struct device *dev)
> +{
> + struct device_node *firmware;
> +
> + firmware = of_get_compatible_child(dev->of_node,
> + "raspberrypi,firmware-rtc");
> + if (firmware) {
> + of_node_put(firmware);
> + return;
> + }
> +
> + rpi_rtc = platform_device_register_data(dev, "raspberrypi-rtc",
> + -1, NULL, 0);
[Severity: Medium]
Will this unconditionally register the rtc platform device on legacy
Raspberry Pi models?
If rpi_rtc is registered on all models, the probe function will run
universally. When rpi_rtc_probe() executes on a model other than the
Raspberry Pi 5, it prints an error message via dev_err() and aborts:
if (!model || strncmp(model, "Raspberry Pi 5", 14) != 0) {
dev_err(dev, "RTC is only available on Raspberry Pi 5\n");
return -ENODEV;
}
This seems like it would produce a spurious error message in the kernel log
on every boot for all older models where the hardware doesn't exist.
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index 05b9233b94189..382973d46e06d 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
[ ... ]
> @@ -1999,6 +1999,17 @@ config RTC_DRV_R7301
> This driver can also be built as a module. If so, the module
> will be called rtc-r7301.
>
> +config RTC_DRV_RPI
> + tristate "Raspberry Pi RTC"
> + depends on ARCH_BRCMSTB || COMPILE_TEST
> + default ARCH_BRCMSTB
[Severity: Low]
Does this configuration allow RTC_DRV_RPI to be built-in when
RASPBERRYPI_FIRMWARE is built as a module?
The driver calls devm_rpi_firmware_get() and rpi_firmware_property(),
which are exported by the raspberrypi-firmware module. If the RTC driver
is built-in and the firmware driver is a module, this will result in an
undefined reference linker error. Should there be a dependency on
RASPBERRYPI_FIRMWARE?
> diff --git a/drivers/rtc/rtc-raspberrypi.c b/drivers/rtc/rtc-raspberrypi.c
> new file mode 100644
> index 0000000000000..af775ae55a871
> --- /dev/null
> +++ b/drivers/rtc/rtc-raspberrypi.c
[ ... ]
> +static int rpi_rtc_probe(struct platform_device *pdev)
> +{
> + struct rpi_rtc_data *vrtc;
> + struct device *dev = &pdev->dev;
> + struct rpi_firmware *firmware;
> + int ret;
[ ... ]
> + vrtc = devm_kzalloc(dev, sizeof(*vrtc), GFP_KERNEL);
> + if (!vrtc)
> + return -ENOMEM;
> +
> + vrtc->fw = firmware;
> +
> + devm_device_init_wakeup(dev);
[Severity: Medium]
Should the return value of devm_device_init_wakeup() be checked here?
This function registers a devres action and can fail, for instance, due to
an out of memory condition. By ignoring the integer error code, the driver
might continue with an uninitialized or broken wakeup state on failure.
> +
> + platform_set_drvdata(pdev, vrtc);
[ ... ]
> + rpi_rtc_alarm_clear_pending(dev);
> +
> + vrtc->bbat_vchg_millivolts = 0;
> + of_property_read_u32(dev->parent->of_node, "trickle-charge-millivolt",
> + &vrtc->bbat_vchg_millivolts);
[Severity: Medium]
Does this device tree property name match the binding schemas?
The standard RTC bindings typically use trickle-voltage-millivolt, and the
driver's own schema might define charging-voltage-millivolt, but this
attempts to read trickle-charge-millivolt. If a device tree follows the
standard schema, this property lookup will fail and leave trickle charging
silently disabled.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260917122144.703221-1-sander.speetjens@gmail.com?part=2
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-09-17 12:40 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-17 12:21 [PATCH v2 0/2] Raspberry Pi 5 RTC driver Sander Speetjens
2026-09-17 12:21 ` [PATCH v2 1/2] dt-bindings: rtc: Add property for Raspberry Pi 5 RTC Sander Speetjens
2026-09-17 12:30 ` sashiko-bot
2026-09-17 12:21 ` [PATCH v2 2/2] rtc: Add Raspberry Pi 5 RTC driver Sander Speetjens
2026-09-17 12:40 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox