* [PATCH 00/12] Add RTC support for Renesas RZ/T2H and RZ/N2H SoCs
@ 2026-06-15 15:47 Prabhakar
2026-06-15 15:47 ` [PATCH 01/12] dt-bindings: rtc: renesas,rzn1-rtc: Add RZ/T2H and RZ/N2H support Prabhakar
` (11 more replies)
0 siblings, 12 replies; 22+ messages in thread
From: Prabhakar @ 2026-06-15 15:47 UTC (permalink / raw)
To: Miquel Raynal, Alexandre Belloni, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, Wolfram Sang
Cc: linux-rtc, linux-renesas-soc, devicetree, linux-kernel, Prabhakar,
Biju Das, Fabrizio Castro, Lad Prabhakar
From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Hi all,
This series adds support for the RTC IP found on the Renesas RZ/T2H and
RZ/N2H SoCs.
The RTC block is closely related to the RZ/N1 implementation and can
reuse the existing driver infrastructure when operating in SCMP mode,
which is required on these SoCs due to their 195.3 kHz RTC input clock.
While the RZ/T2H and RZ/N2H variants do not implement the RTCA0SUBU and
RTCA0TCR registers present on RZ/N1, those registers are not accessed by
the driver in SCMP mode, allowing support to be added with minimal
changes.
The RZ/T2H RTC variant also supports a 1 Hz output signal on the
RTCAT1HZ pin, controlled by the RTCA0CTL1[RTCA01HZE] bit. This bit is
marked as reserved in the RZ/N1 hardware manual, making RZ/T2H a
distinct RTC variant despite its overall compatibility with the RZ/N1
implementation.
The series consists of:
dt-bindings updates to describe the RZ/T2H and RZ/N2H RTC variants,
driver updates to recognize the new compatible string and enable
support for these SoCs.
Cheers,
Prabhakar
Lad Prabhakar (12):
dt-bindings: rtc: renesas,rzn1-rtc: Add RZ/T2H and RZ/N2H support
rtc: rzn1: Handle EPROBE_DEFER for optional pps interrupt
rtc: rzn1: Fix malformed MODULE_AUTHOR string
rtc: Kconfig: Broaden RTC_DRV_RZN1 dependency to ARCH_RENESAS
rtc: rzn1: Add system suspend/resume support and wakeup capability
rtc: rzn1: Sort headers alphabetically
rtc: rzn1: fix alarm range check truncation on 32-bit systems
rtc: rzn1: Dynamically calculate synchronization delay based on clock
rate
rtc: rzn1: Use temporary variable for struct device
rtc: rzn1: Consistently use dev_err_probe()
rtc: rzn1: use FIELD_PREP/FIELD_GET and GENMASK for register access
rtc: rzn1: Add support for Renesas RZ/T2H and RZ/N2H SoCs
.../bindings/rtc/renesas,rzn1-rtc.yaml | 35 +++-
drivers/rtc/Kconfig | 5 +-
drivers/rtc/rtc-rzn1.c | 182 ++++++++++++++----
3 files changed, 173 insertions(+), 49 deletions(-)
--
2.54.0
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 01/12] dt-bindings: rtc: renesas,rzn1-rtc: Add RZ/T2H and RZ/N2H support
2026-06-15 15:47 [PATCH 00/12] Add RTC support for Renesas RZ/T2H and RZ/N2H SoCs Prabhakar
@ 2026-06-15 15:47 ` Prabhakar
2026-06-15 15:56 ` sashiko-bot
2026-06-15 16:22 ` Conor Dooley
2026-06-15 15:47 ` [PATCH 02/12] rtc: rzn1: Handle EPROBE_DEFER for optional pps interrupt Prabhakar
` (10 subsequent siblings)
11 siblings, 2 replies; 22+ messages in thread
From: Prabhakar @ 2026-06-15 15:47 UTC (permalink / raw)
To: Miquel Raynal, Alexandre Belloni, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, Wolfram Sang
Cc: linux-rtc, linux-renesas-soc, devicetree, linux-kernel, Prabhakar,
Biju Das, Fabrizio Castro, Lad Prabhakar
From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Add compatible strings for the RTC block found on the Renesas RZ/T2H
(R9A09G077) and RZ/N2H (R9A09G087) SoCs.
These SoCs integrate a closely related variant of the RZ/N1 RTC IP.
Unlike RZ/N1, they do not implement the RTCA0SUBU and RTCA0TCR
registers. This is not a limitation for Linux support, as these
registers are not used when the RTC operates in "scmp" clock mode, which
is required on RZ/T2H and RZ/N2H due to their 195.3 kHz input clock.
The RZ/T2H RTC variant also supports a 1Hz output signal on the
RTCAT1HZ pin, controlled by the RTCA0CTL1[RTCA01HZE] bit. This bit is
marked as reserved in the RZ/N1 hardware manual.
Update the binding schema to require the additional clock inputs used by
these SoCs.
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
.../bindings/rtc/renesas,rzn1-rtc.yaml | 35 +++++++++++++++----
1 file changed, 28 insertions(+), 7 deletions(-)
diff --git a/Documentation/devicetree/bindings/rtc/renesas,rzn1-rtc.yaml b/Documentation/devicetree/bindings/rtc/renesas,rzn1-rtc.yaml
index 1860f0e4c31a..ea7b039a91e7 100644
--- a/Documentation/devicetree/bindings/rtc/renesas,rzn1-rtc.yaml
+++ b/Documentation/devicetree/bindings/rtc/renesas,rzn1-rtc.yaml
@@ -9,15 +9,19 @@ title: Renesas RZ/N1 SoCs Real-Time Clock
maintainers:
- Miquel Raynal <miquel.raynal@bootlin.com>
-allOf:
- - $ref: rtc.yaml#
-
properties:
compatible:
- items:
- - enum:
- - renesas,r9a06g032-rtc
- - const: renesas,rzn1-rtc
+ oneOf:
+ - items:
+ - enum:
+ - renesas,r9a06g032-rtc
+ - const: renesas,rzn1-rtc
+
+ - const: renesas,r9a09g077-rtc
+
+ - items:
+ - const: renesas,r9a09g087-rtc
+ - const: renesas,r9a09g077-rtc
reg:
maxItems: 1
@@ -54,6 +58,23 @@ required:
- clock-names
- power-domains
+allOf:
+ - $ref: rtc.yaml#
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - renesas,r9a09g077-rtc
+ - renesas,r9a09g087-rtc
+ then:
+ properties:
+ clocks:
+ minItems: 2
+ clock-names:
+ minItems: 2
+
unevaluatedProperties: false
examples:
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 02/12] rtc: rzn1: Handle EPROBE_DEFER for optional pps interrupt
2026-06-15 15:47 [PATCH 00/12] Add RTC support for Renesas RZ/T2H and RZ/N2H SoCs Prabhakar
2026-06-15 15:47 ` [PATCH 01/12] dt-bindings: rtc: renesas,rzn1-rtc: Add RZ/T2H and RZ/N2H support Prabhakar
@ 2026-06-15 15:47 ` Prabhakar
2026-06-15 15:58 ` sashiko-bot
2026-06-15 15:47 ` [PATCH 03/12] rtc: rzn1: Fix malformed MODULE_AUTHOR string Prabhakar
` (9 subsequent siblings)
11 siblings, 1 reply; 22+ messages in thread
From: Prabhakar @ 2026-06-15 15:47 UTC (permalink / raw)
To: Miquel Raynal, Alexandre Belloni, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, Wolfram Sang
Cc: linux-rtc, linux-renesas-soc, devicetree, linux-kernel, Prabhakar,
Biju Das, Fabrizio Castro, Lad Prabhakar, stable
From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Check for -EPROBE_DEFER from platform_get_irq_byname_optional() and handle
the deferred probe request properly.
Although the "pps" interrupt is optional, an error code of -EPROBE_DEFER
indicates that the interrupt subsystem is not yet ready. Intercept this
specific error condition, assign it to the return value, and jump to the
dis_runtime_pm label to avoid ignoring a valid probe deferral.
Fixes: eea7791e00f33 ("rtc: rzn1: implement one-second accuracy for alarms")
Cc: stable@vger.kernel.org
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
drivers/rtc/rtc-rzn1.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
index c4ed43735457..f81d691c8b9a 100644
--- a/drivers/rtc/rtc-rzn1.c
+++ b/drivers/rtc/rtc-rzn1.c
@@ -465,6 +465,10 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
}
irq = platform_get_irq_byname_optional(pdev, "pps");
+ if (irq == -EPROBE_DEFER) {
+ ret = irq;
+ goto dis_runtime_pm;
+ }
if (irq >= 0)
ret = devm_request_irq(&pdev->dev, irq, rzn1_rtc_1s_irq, 0, "RZN1 RTC 1s", rtc);
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 03/12] rtc: rzn1: Fix malformed MODULE_AUTHOR string
2026-06-15 15:47 [PATCH 00/12] Add RTC support for Renesas RZ/T2H and RZ/N2H SoCs Prabhakar
2026-06-15 15:47 ` [PATCH 01/12] dt-bindings: rtc: renesas,rzn1-rtc: Add RZ/T2H and RZ/N2H support Prabhakar
2026-06-15 15:47 ` [PATCH 02/12] rtc: rzn1: Handle EPROBE_DEFER for optional pps interrupt Prabhakar
@ 2026-06-15 15:47 ` Prabhakar
2026-06-15 15:47 ` [PATCH 04/12] rtc: Kconfig: Broaden RTC_DRV_RZN1 dependency to ARCH_RENESAS Prabhakar
` (8 subsequent siblings)
11 siblings, 0 replies; 22+ messages in thread
From: Prabhakar @ 2026-06-15 15:47 UTC (permalink / raw)
To: Miquel Raynal, Alexandre Belloni, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, Wolfram Sang
Cc: linux-rtc, linux-renesas-soc, devicetree, linux-kernel, Prabhakar,
Biju Das, Fabrizio Castro, Lad Prabhakar
From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Fix a malformed MODULE_AUTHOR macro in the rtc-rzn1 driver where a missing
closing angle bracket on the second author entry creates an invalid format.
Correct it to the standard "Name <email>" format.
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
drivers/rtc/rtc-rzn1.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
index f81d691c8b9a..866ff595188d 100644
--- a/drivers/rtc/rtc-rzn1.c
+++ b/drivers/rtc/rtc-rzn1.c
@@ -517,6 +517,6 @@ static struct platform_driver rzn1_rtc_driver = {
module_platform_driver(rzn1_rtc_driver);
MODULE_AUTHOR("Michel Pollet <buserror@gmail.com>");
-MODULE_AUTHOR("Miquel Raynal <miquel.raynal@bootlin.com");
+MODULE_AUTHOR("Miquel Raynal <miquel.raynal@bootlin.com>");
MODULE_DESCRIPTION("RZ/N1 RTC driver");
MODULE_LICENSE("GPL");
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 04/12] rtc: Kconfig: Broaden RTC_DRV_RZN1 dependency to ARCH_RENESAS
2026-06-15 15:47 [PATCH 00/12] Add RTC support for Renesas RZ/T2H and RZ/N2H SoCs Prabhakar
` (2 preceding siblings ...)
2026-06-15 15:47 ` [PATCH 03/12] rtc: rzn1: Fix malformed MODULE_AUTHOR string Prabhakar
@ 2026-06-15 15:47 ` Prabhakar
2026-06-15 15:47 ` [PATCH 05/12] rtc: rzn1: Add system suspend/resume support and wakeup capability Prabhakar
` (7 subsequent siblings)
11 siblings, 0 replies; 22+ messages in thread
From: Prabhakar @ 2026-06-15 15:47 UTC (permalink / raw)
To: Miquel Raynal, Alexandre Belloni, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, Wolfram Sang
Cc: linux-rtc, linux-renesas-soc, devicetree, linux-kernel, Prabhakar,
Biju Das, Fabrizio Castro, Lad Prabhakar
From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Replace the ARCH_RZN1 dependency with ARCH_RENESAS for the RTC_DRV_RZN1
config option to make the driver available across both ARM32 and ARM64
Renesas architectures.
The newer RZ/T2H and RZ/N2H ARM64 SoCs integrate a closely related variant
of the RTC IP block found on the RZ/N1 SoCs. Update the build dependency
and expand the Kconfig help text to allow this driver to be selected for
these additional platforms.
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
drivers/rtc/Kconfig | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 364afc73f8ab..764f8b9ff742 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1635,10 +1635,11 @@ config RTC_DRV_RS5C313
config RTC_DRV_RZN1
tristate "Renesas RZ/N1 RTC"
- depends on ARCH_RZN1 || COMPILE_TEST
+ depends on ARCH_RENESAS || COMPILE_TEST
depends on OF && HAS_IOMEM
help
- If you say yes here you get support for the Renesas RZ/N1 RTC.
+ If you say yes here you get support for the RTC found on Renesas RZ/N1,
+ RZ/N2H, and RZ/T2H SoCs.
config RTC_DRV_GENERIC
tristate "Generic RTC support"
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 05/12] rtc: rzn1: Add system suspend/resume support and wakeup capability
2026-06-15 15:47 [PATCH 00/12] Add RTC support for Renesas RZ/T2H and RZ/N2H SoCs Prabhakar
` (3 preceding siblings ...)
2026-06-15 15:47 ` [PATCH 04/12] rtc: Kconfig: Broaden RTC_DRV_RZN1 dependency to ARCH_RENESAS Prabhakar
@ 2026-06-15 15:47 ` Prabhakar
2026-06-15 15:59 ` sashiko-bot
2026-06-15 15:47 ` [PATCH 06/12] rtc: rzn1: Sort headers alphabetically Prabhakar
` (6 subsequent siblings)
11 siblings, 1 reply; 22+ messages in thread
From: Prabhakar @ 2026-06-15 15:47 UTC (permalink / raw)
To: Miquel Raynal, Alexandre Belloni, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, Wolfram Sang
Cc: linux-rtc, linux-renesas-soc, devicetree, linux-kernel, Prabhakar,
Biju Das, Fabrizio Castro, Lad Prabhakar
From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Add system-wide power management support along with wakeup capability to
the rtc-rzn1 driver.
The hardware alarm module inside this RTC variant lacks a dedicated seconds
match register, meaning native hardware alarms can only be programmed with
minute-level granularity. For awake states, the driver bridges sub-minute
gaps by switching from a standard alarm interrupt (ALME) to a 1-second
periodic broadcast loop (1SE).
To support device wakeup from low-power states, initialize the device as a
system wakeup source during probe and configure both the hardware alarm IRQ
and the 1-second periodic IRQ as wakeup sources via enable_irq_wake() in the
suspend path. Because of hardware tracking design constraints across the
internal timer blocks, precise point-in-time wakeup alignment cannot be
guaranteed. Emit an explicit warning message during system suspend to notify
the user of this architectural layout limitation.
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
drivers/rtc/rtc-rzn1.c | 80 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 80 insertions(+)
diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
index 866ff595188d..12a319e9112c 100644
--- a/drivers/rtc/rtc-rzn1.c
+++ b/drivers/rtc/rtc-rzn1.c
@@ -70,6 +70,9 @@ struct rzn1_rtc {
*/
spinlock_t ctl1_access_lock;
struct rtc_time tm_alarm;
+ int alarm_irq;
+ int sec_irq;
+ bool alarm_enabled;
};
static void rzn1_rtc_get_time_snapshot(struct rzn1_rtc *rtc, struct rtc_time *tm)
@@ -219,6 +222,8 @@ static int rzn1_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
writel(ctl1, rtc->base + RZN1_RTC_CTL1);
}
+ rtc->alarm_enabled = enable;
+
return 0;
}
@@ -398,6 +403,7 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
irq = platform_get_irq_byname(pdev, "alarm");
if (irq < 0)
return irq;
+ rtc->alarm_irq = irq;
rtc->rtcdev = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc->rtcdev))
@@ -476,8 +482,13 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->rtcdev->features);
clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->rtcdev->features);
dev_warn(&pdev->dev, "RTC pps interrupt not available. Alarm has only minute accuracy\n");
+ rtc->sec_irq = -ENXIO;
+ } else {
+ rtc->sec_irq = irq;
}
+ device_init_wakeup(&pdev->dev, true);
+
ret = devm_rtc_register_device(rtc->rtcdev);
if (ret)
goto dis_runtime_pm;
@@ -500,6 +511,74 @@ static void rzn1_rtc_remove(struct platform_device *pdev)
pm_runtime_put(&pdev->dev);
}
+static int rzn1_rtc_suspend(struct device *dev)
+{
+ struct rzn1_rtc *rtc = dev_get_drvdata(dev);
+ int ret;
+
+ if (!device_may_wakeup(dev))
+ return 0;
+
+ /*
+ * Note on HW Wakeup Granularity Limitations:
+ * True second-level accuracy cannot be guaranteed for device wakeups due
+ * to hardware design tracking limitations across the three available blocks:
+ * - Alarm Interrupt (RTC_ALM): Only matches on day-of-week, hour, and minute.
+ * It completely lacks a seconds comparator field.
+ * - 1-Second Interrupt (RTC_1S): A free-running broadcast that fires every
+ * second. Activating it as a wakeup source triggers an immediate resume
+ * on the very next 1-second boundary, bypassing target accuracy.
+ * - Fixed Interval Interrupt (RTC_PRD): Periodic broadcast options (0.25s,
+ * 0.5s, 1s, 1min, 1hr, 1day, or 1month) lack point-in-time matching,
+ * offering no targeted relief.
+ *
+ * Consequently, due to the absence of a seconds comparator, if a wakeup is
+ * requested within the current minute, the system will resume on the very next
+ * 1-second tick regardless of the actual target alarm time. When the alarm
+ * target is scheduled for a future minute, the system will resume early at the
+ * start of that target minute boundary (00 seconds), failing to guarantee
+ * second-level accuracy for the initial hardware wakeup event.
+ */
+ if (rtc->alarm_enabled)
+ dev_crit(dev, "second/minute-level wakeup accuracy cannot be guaranteed by HW\n");
+ ret = enable_irq_wake(rtc->alarm_irq);
+ if (ret)
+ return ret;
+ if (rtc->sec_irq >= 0) {
+ ret = enable_irq_wake(rtc->sec_irq);
+ if (ret) {
+ disable_irq_wake(rtc->alarm_irq);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int rzn1_rtc_resume(struct device *dev)
+{
+ struct rzn1_rtc *rtc = dev_get_drvdata(dev);
+ int ret;
+
+ if (!device_may_wakeup(dev))
+ return 0;
+
+ ret = disable_irq_wake(rtc->alarm_irq);
+ if (ret)
+ return ret;
+ if (rtc->sec_irq >= 0) {
+ ret = disable_irq_wake(rtc->sec_irq);
+ if (ret) {
+ enable_irq_wake(rtc->alarm_irq);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(rzn1_rtc_pm_ops, rzn1_rtc_suspend, rzn1_rtc_resume);
+
static const struct of_device_id rzn1_rtc_of_match[] = {
{ .compatible = "renesas,rzn1-rtc" },
{},
@@ -512,6 +591,7 @@ static struct platform_driver rzn1_rtc_driver = {
.driver = {
.name = "rzn1-rtc",
.of_match_table = rzn1_rtc_of_match,
+ .pm = pm_ptr(&rzn1_rtc_pm_ops),
},
};
module_platform_driver(rzn1_rtc_driver);
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 06/12] rtc: rzn1: Sort headers alphabetically
2026-06-15 15:47 [PATCH 00/12] Add RTC support for Renesas RZ/T2H and RZ/N2H SoCs Prabhakar
` (4 preceding siblings ...)
2026-06-15 15:47 ` [PATCH 05/12] rtc: rzn1: Add system suspend/resume support and wakeup capability Prabhakar
@ 2026-06-15 15:47 ` Prabhakar
2026-06-15 15:48 ` [PATCH 07/12] rtc: rzn1: fix alarm range check truncation on 32-bit systems Prabhakar
` (5 subsequent siblings)
11 siblings, 0 replies; 22+ messages in thread
From: Prabhakar @ 2026-06-15 15:47 UTC (permalink / raw)
To: Miquel Raynal, Alexandre Belloni, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, Wolfram Sang
Cc: linux-rtc, linux-renesas-soc, devicetree, linux-kernel, Prabhakar,
Biju Das, Fabrizio Castro, Lad Prabhakar
From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Sorting headers alphabetically helps locating duplicates, and make it
easier to figure out where to insert new headers.
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
drivers/rtc/rtc-rzn1.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
index 12a319e9112c..fe21fa624288 100644
--- a/drivers/rtc/rtc-rzn1.c
+++ b/drivers/rtc/rtc-rzn1.c
@@ -15,8 +15,8 @@
#include <linux/clk.h>
#include <linux/init.h>
#include <linux/iopoll.h>
-#include <linux/module.h>
#include <linux/mod_devicetable.h>
+#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/rtc.h>
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 07/12] rtc: rzn1: fix alarm range check truncation on 32-bit systems
2026-06-15 15:47 [PATCH 00/12] Add RTC support for Renesas RZ/T2H and RZ/N2H SoCs Prabhakar
` (5 preceding siblings ...)
2026-06-15 15:47 ` [PATCH 06/12] rtc: rzn1: Sort headers alphabetically Prabhakar
@ 2026-06-15 15:48 ` Prabhakar
2026-06-15 16:00 ` sashiko-bot
2026-06-15 15:48 ` [PATCH 08/12] rtc: rzn1: Dynamically calculate synchronization delay based on clock rate Prabhakar
` (4 subsequent siblings)
11 siblings, 1 reply; 22+ messages in thread
From: Prabhakar @ 2026-06-15 15:48 UTC (permalink / raw)
To: Miquel Raynal, Alexandre Belloni, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, Wolfram Sang
Cc: linux-rtc, linux-renesas-soc, devicetree, linux-kernel, Prabhakar,
Biju Das, Fabrizio Castro, Lad Prabhakar
From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
alarm and farest were declared as unsigned long, but
rtc_tm_to_time64() returns time64_t (s64). On 32-bit systems where
unsigned long is 32 bits, the assignment silently truncates the upper
32 bits of the timestamp.
Fix by declaring alarm and farest as time64_t and replacing
time_after() with a direct signed comparison, which is correct for
time64_t values that will never realistically overflow.
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
drivers/rtc/rtc-rzn1.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
index fe21fa624288..06339adae71f 100644
--- a/drivers/rtc/rtc-rzn1.c
+++ b/drivers/rtc/rtc-rzn1.c
@@ -21,6 +21,7 @@
#include <linux/pm_runtime.h>
#include <linux/rtc.h>
#include <linux/spinlock.h>
+#include <linux/time64.h>
#define RZN1_RTC_CTL0 0x00
#define RZN1_RTC_CTL0_SLSB_SCMP BIT(4)
@@ -265,8 +266,8 @@ static int rzn1_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct rzn1_rtc *rtc = dev_get_drvdata(dev);
struct rtc_time *tm = &alrm->time, tm_now;
- unsigned long alarm, farest;
unsigned int days_ahead, wday;
+ time64_t alarm, farest;
int ret;
ret = rzn1_rtc_read_time(dev, &tm_now);
@@ -276,7 +277,7 @@ static int rzn1_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
/* We cannot set alarms more than one week ahead */
farest = rtc_tm_to_time64(&tm_now) + rtc->rtcdev->alarm_offset_max;
alarm = rtc_tm_to_time64(tm);
- if (time_after(alarm, farest))
+ if (alarm > farest)
return -ERANGE;
/* Convert alarm day into week day */
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 08/12] rtc: rzn1: Dynamically calculate synchronization delay based on clock rate
2026-06-15 15:47 [PATCH 00/12] Add RTC support for Renesas RZ/T2H and RZ/N2H SoCs Prabhakar
` (6 preceding siblings ...)
2026-06-15 15:48 ` [PATCH 07/12] rtc: rzn1: fix alarm range check truncation on 32-bit systems Prabhakar
@ 2026-06-15 15:48 ` Prabhakar
2026-06-15 15:57 ` sashiko-bot
2026-06-15 15:48 ` [PATCH 09/12] rtc: rzn1: Use temporary variable for struct device Prabhakar
` (3 subsequent siblings)
11 siblings, 1 reply; 22+ messages in thread
From: Prabhakar @ 2026-06-15 15:48 UTC (permalink / raw)
To: Miquel Raynal, Alexandre Belloni, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, Wolfram Sang
Cc: linux-rtc, linux-renesas-soc, devicetree, linux-kernel, Prabhakar,
Biju Das, Fabrizio Castro, Lad Prabhakar
From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Replace the hardcoded hardware synchronization delays with a calculated
time window derived from the operating sub-clock frequency.
The driver currently hardcodes microsecond ranges assuming a fixed
sub-clock frequency of 32.768 kHz. Newer SoC variants, such as the
RZ/T2H, drive this hardware block using a much faster clock rate
(~195.3 kHz). Hardcoding these wait windows forces faster blocks to
over-sleep, introducing unnecessary delays during clock initialization
and register configuration.
Calculate the duration of the required clock cycles in microseconds based
on the runtime clock rate, and store this value in the driver private
structure to adjust the usleep_range() and readl_poll_timeout() boundaries
dynamically.
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
drivers/rtc/rtc-rzn1.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
index 06339adae71f..bc6af59744e4 100644
--- a/drivers/rtc/rtc-rzn1.c
+++ b/drivers/rtc/rtc-rzn1.c
@@ -71,6 +71,7 @@ struct rzn1_rtc {
*/
spinlock_t ctl1_access_lock;
struct rtc_time tm_alarm;
+ unsigned long sync_time;
int alarm_irq;
int sec_irq;
bool alarm_enabled;
@@ -124,8 +125,8 @@ static int rzn1_rtc_set_time(struct device *dev, struct rtc_time *tm)
/* Hold the counter if it was counting up */
writel(RZN1_RTC_CTL2_WAIT, rtc->base + RZN1_RTC_CTL2);
- /* Wait for the counter to stop: two 32k clock cycles */
- usleep_range(61, 100);
+ /* Wait for the counter to stop: two RTC_PCLK clock cycles */
+ usleep_range(rtc->sync_time, rtc->sync_time + 100);
ret = readl_poll_timeout(rtc->base + RZN1_RTC_CTL2, val,
val & RZN1_RTC_CTL2_WST, 0, 100);
if (ret)
@@ -433,17 +434,25 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
ret = -EOPNOTSUPP;
goto dis_runtime_pm;
}
-
if (rate != 32768)
scmp_val = RZN1_RTC_CTL0_SLSB_SCMP;
+
+ /*
+ * The internal clock counter operates in synchronization with the
+ * RTC_PCLK clock. Calculate the duration of two RTC_PCLK clock
+ * cycles in microseconds required for operations to complete.
+ */
+ rtc->sync_time = DIV_ROUND_UP(2 * NSEC_PER_MSEC, rate);
+
}
/* Disable controller during SUBU/SCMP setup */
val = readl(rtc->base + RZN1_RTC_CTL0) & ~RZN1_RTC_CTL0_CE;
writel(val, rtc->base + RZN1_RTC_CTL0);
- /* Wait 2-4 32k clock cycles for the disabled controller */
+ /* Wait 2-4 RTC_PCLK clock cycles for the disabled controller to stop */
ret = readl_poll_timeout(rtc->base + RZN1_RTC_CTL0, val,
- !(val & RZN1_RTC_CTL0_CEST), 62, 123);
+ !(val & RZN1_RTC_CTL0_CEST), rtc->sync_time,
+ rtc->sync_time * 2);
if (ret)
goto dis_runtime_pm;
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 09/12] rtc: rzn1: Use temporary variable for struct device
2026-06-15 15:47 [PATCH 00/12] Add RTC support for Renesas RZ/T2H and RZ/N2H SoCs Prabhakar
` (7 preceding siblings ...)
2026-06-15 15:48 ` [PATCH 08/12] rtc: rzn1: Dynamically calculate synchronization delay based on clock rate Prabhakar
@ 2026-06-15 15:48 ` Prabhakar
2026-06-15 17:56 ` sashiko-bot
2026-06-15 15:48 ` [PATCH 10/12] rtc: rzn1: Consistently use dev_err_probe() Prabhakar
` (2 subsequent siblings)
11 siblings, 1 reply; 22+ messages in thread
From: Prabhakar @ 2026-06-15 15:48 UTC (permalink / raw)
To: Miquel Raynal, Alexandre Belloni, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, Wolfram Sang
Cc: linux-rtc, linux-renesas-soc, devicetree, linux-kernel, Prabhakar,
Biju Das, Fabrizio Castro, Lad Prabhakar
From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Use a temporary variable for the struct device pointers to avoid
dereferencing.
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
drivers/rtc/rtc-rzn1.c | 25 +++++++++++++------------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
index bc6af59744e4..25cad9213147 100644
--- a/drivers/rtc/rtc-rzn1.c
+++ b/drivers/rtc/rtc-rzn1.c
@@ -386,13 +386,14 @@ static const struct rtc_class_ops rzn1_rtc_ops_scmp = {
static int rzn1_rtc_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct rzn1_rtc *rtc;
u32 val, scmp_val = 0;
struct clk *xtal;
unsigned long rate;
int irq, ret;
- rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
+ rtc = devm_kzalloc(dev, sizeof(*rtc), GFP_KERNEL);
if (!rtc)
return -ENOMEM;
@@ -400,14 +401,14 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
rtc->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rtc->base))
- return dev_err_probe(&pdev->dev, PTR_ERR(rtc->base), "Missing reg\n");
+ return dev_err_probe(dev, PTR_ERR(rtc->base), "Missing reg\n");
irq = platform_get_irq_byname(pdev, "alarm");
if (irq < 0)
return irq;
rtc->alarm_irq = irq;
- rtc->rtcdev = devm_rtc_allocate_device(&pdev->dev);
+ rtc->rtcdev = devm_rtc_allocate_device(dev);
if (IS_ERR(rtc->rtcdev))
return PTR_ERR(rtc->rtcdev);
@@ -415,15 +416,15 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
rtc->rtcdev->range_max = RTC_TIMESTAMP_END_2099;
rtc->rtcdev->alarm_offset_max = 7 * 86400;
- ret = devm_pm_runtime_enable(&pdev->dev);
+ ret = devm_pm_runtime_enable(dev);
if (ret < 0)
return ret;
- ret = pm_runtime_resume_and_get(&pdev->dev);
+ ret = pm_runtime_resume_and_get(dev);
if (ret < 0)
return ret;
/* Only switch to scmp if we have an xtal clock with a valid rate and != 32768 */
- xtal = devm_clk_get_optional(&pdev->dev, "xtal");
+ xtal = devm_clk_get_optional(dev, "xtal");
if (IS_ERR(xtal)) {
ret = PTR_ERR(xtal);
goto dis_runtime_pm;
@@ -474,9 +475,9 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
spin_lock_init(&rtc->ctl1_access_lock);
- ret = devm_request_irq(&pdev->dev, irq, rzn1_rtc_alarm_irq, 0, "RZN1 RTC Alarm", rtc);
+ ret = devm_request_irq(dev, irq, rzn1_rtc_alarm_irq, 0, "RZN1 RTC Alarm", rtc);
if (ret) {
- dev_err(&pdev->dev, "RTC alarm interrupt not available\n");
+ dev_err(dev, "RTC alarm interrupt not available\n");
goto dis_runtime_pm;
}
@@ -486,18 +487,18 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
goto dis_runtime_pm;
}
if (irq >= 0)
- ret = devm_request_irq(&pdev->dev, irq, rzn1_rtc_1s_irq, 0, "RZN1 RTC 1s", rtc);
+ ret = devm_request_irq(dev, irq, rzn1_rtc_1s_irq, 0, "RZN1 RTC 1s", rtc);
if (irq < 0 || ret) {
set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->rtcdev->features);
clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->rtcdev->features);
- dev_warn(&pdev->dev, "RTC pps interrupt not available. Alarm has only minute accuracy\n");
+ dev_warn(dev, "RTC pps interrupt not available. Alarm has only minute accuracy\n");
rtc->sec_irq = -ENXIO;
} else {
rtc->sec_irq = irq;
}
- device_init_wakeup(&pdev->dev, true);
+ device_init_wakeup(dev, true);
ret = devm_rtc_register_device(rtc->rtcdev);
if (ret)
@@ -506,7 +507,7 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
return 0;
dis_runtime_pm:
- pm_runtime_put(&pdev->dev);
+ pm_runtime_put(dev);
return ret;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 10/12] rtc: rzn1: Consistently use dev_err_probe()
2026-06-15 15:47 [PATCH 00/12] Add RTC support for Renesas RZ/T2H and RZ/N2H SoCs Prabhakar
` (8 preceding siblings ...)
2026-06-15 15:48 ` [PATCH 09/12] rtc: rzn1: Use temporary variable for struct device Prabhakar
@ 2026-06-15 15:48 ` Prabhakar
2026-06-15 15:48 ` [PATCH 11/12] rtc: rzn1: use FIELD_PREP/FIELD_GET and GENMASK for register access Prabhakar
2026-06-15 15:48 ` [PATCH 12/12] rtc: rzn1: Add support for Renesas RZ/T2H and RZ/N2H SoCs Prabhakar
11 siblings, 0 replies; 22+ messages in thread
From: Prabhakar @ 2026-06-15 15:48 UTC (permalink / raw)
To: Miquel Raynal, Alexandre Belloni, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, Wolfram Sang
Cc: linux-rtc, linux-renesas-soc, devicetree, linux-kernel, Prabhakar,
Biju Das, Fabrizio Castro, Lad Prabhakar
From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Use dev_err_probe() in the IRQ request error path to make error handling
consistent with the rest of rzn1_rtc_probe().
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
drivers/rtc/rtc-rzn1.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
index 25cad9213147..c7ef3c81180f 100644
--- a/drivers/rtc/rtc-rzn1.c
+++ b/drivers/rtc/rtc-rzn1.c
@@ -477,7 +477,7 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
ret = devm_request_irq(dev, irq, rzn1_rtc_alarm_irq, 0, "RZN1 RTC Alarm", rtc);
if (ret) {
- dev_err(dev, "RTC alarm interrupt not available\n");
+ dev_err_probe(dev, ret, "RTC alarm interrupt not available\n");
goto dis_runtime_pm;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 11/12] rtc: rzn1: use FIELD_PREP/FIELD_GET and GENMASK for register access
2026-06-15 15:47 [PATCH 00/12] Add RTC support for Renesas RZ/T2H and RZ/N2H SoCs Prabhakar
` (9 preceding siblings ...)
2026-06-15 15:48 ` [PATCH 10/12] rtc: rzn1: Consistently use dev_err_probe() Prabhakar
@ 2026-06-15 15:48 ` Prabhakar
2026-06-15 15:57 ` sashiko-bot
2026-06-15 15:48 ` [PATCH 12/12] rtc: rzn1: Add support for Renesas RZ/T2H and RZ/N2H SoCs Prabhakar
11 siblings, 1 reply; 22+ messages in thread
From: Prabhakar @ 2026-06-15 15:48 UTC (permalink / raw)
To: Miquel Raynal, Alexandre Belloni, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, Wolfram Sang
Cc: linux-rtc, linux-renesas-soc, devicetree, linux-kernel, Prabhakar,
Biju Das, Fabrizio Castro, Lad Prabhakar
From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Replace open-coded shift and mask operations with the bitfield API.
Note that the weekday field is changed from an explicit 0x0f mask to
an 8-bit field definition, matching the hardware manual. This does not
change behaviour, as valid weekday values cannot exceed 7.
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
drivers/rtc/rtc-rzn1.c | 46 ++++++++++++++++++++++++------------------
1 file changed, 26 insertions(+), 20 deletions(-)
diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
index c7ef3c81180f..9f9cf9882fc4 100644
--- a/drivers/rtc/rtc-rzn1.c
+++ b/drivers/rtc/rtc-rzn1.c
@@ -12,6 +12,8 @@
*/
#include <linux/bcd.h>
+#include <linux/bitfield.h>
+#include <linux/bits.h>
#include <linux/clk.h>
#include <linux/init.h>
#include <linux/iopoll.h>
@@ -40,14 +42,18 @@
#define RZN1_RTC_CTL2_STOPPED (RZN1_RTC_CTL2_WAIT | RZN1_RTC_CTL2_WST)
#define RZN1_RTC_TIME 0x30
-#define RZN1_RTC_TIME_MIN_SHIFT 8
-#define RZN1_RTC_TIME_HOUR_SHIFT 16
+#define RZN1_RTC_TIME_SEC GENMASK(7, 0)
+#define RZN1_RTC_TIME_MIN GENMASK(15, 8)
+#define RZN1_RTC_TIME_HOUR GENMASK(23, 16)
+
#define RZN1_RTC_CAL 0x34
-#define RZN1_RTC_CAL_DAY_SHIFT 8
-#define RZN1_RTC_CAL_MON_SHIFT 16
-#define RZN1_RTC_CAL_YEAR_SHIFT 24
+#define RZN1_RTC_CAL_WDAY GENMASK(7, 0)
+#define RZN1_RTC_CAL_DAY GENMASK(15, 8)
+#define RZN1_RTC_CAL_MON GENMASK(23, 16)
+#define RZN1_RTC_CAL_YEAR GENMASK(31, 24)
#define RZN1_RTC_SUBU 0x38
+#define RZN1_RTC_SUBU_RTCA0FX GENMASK(5, 0)
#define RZN1_RTC_SUBU_DEV BIT(7)
#define RZN1_RTC_SUBU_DECR BIT(6)
@@ -82,15 +88,15 @@ static void rzn1_rtc_get_time_snapshot(struct rzn1_rtc *rtc, struct rtc_time *tm
u32 val;
val = readl(rtc->base + RZN1_RTC_TIMEC);
- tm->tm_sec = bcd2bin(val);
- tm->tm_min = bcd2bin(val >> RZN1_RTC_TIME_MIN_SHIFT);
- tm->tm_hour = bcd2bin(val >> RZN1_RTC_TIME_HOUR_SHIFT);
+ tm->tm_sec = bcd2bin(FIELD_GET(RZN1_RTC_TIME_SEC, val));
+ tm->tm_min = bcd2bin(FIELD_GET(RZN1_RTC_TIME_MIN, val));
+ tm->tm_hour = bcd2bin(FIELD_GET(RZN1_RTC_TIME_HOUR, val));
val = readl(rtc->base + RZN1_RTC_CALC);
- tm->tm_wday = val & 0x0f;
- tm->tm_mday = bcd2bin(val >> RZN1_RTC_CAL_DAY_SHIFT);
- tm->tm_mon = bcd2bin(val >> RZN1_RTC_CAL_MON_SHIFT) - 1;
- tm->tm_year = bcd2bin(val >> RZN1_RTC_CAL_YEAR_SHIFT) + 100;
+ tm->tm_wday = FIELD_GET(RZN1_RTC_CAL_WDAY, val);
+ tm->tm_mday = bcd2bin(FIELD_GET(RZN1_RTC_CAL_DAY, val));
+ tm->tm_mon = bcd2bin(FIELD_GET(RZN1_RTC_CAL_MON, val)) - 1;
+ tm->tm_year = bcd2bin(FIELD_GET(RZN1_RTC_CAL_YEAR, val)) + 100;
}
static int rzn1_rtc_read_time(struct device *dev, struct rtc_time *tm)
@@ -133,15 +139,15 @@ static int rzn1_rtc_set_time(struct device *dev, struct rtc_time *tm)
return ret;
}
- val = bin2bcd(tm->tm_sec);
- val |= bin2bcd(tm->tm_min) << RZN1_RTC_TIME_MIN_SHIFT;
- val |= bin2bcd(tm->tm_hour) << RZN1_RTC_TIME_HOUR_SHIFT;
+ val = FIELD_PREP(RZN1_RTC_TIME_SEC, bin2bcd(tm->tm_sec)) |
+ FIELD_PREP(RZN1_RTC_TIME_MIN, bin2bcd(tm->tm_min)) |
+ FIELD_PREP(RZN1_RTC_TIME_HOUR, bin2bcd(tm->tm_hour));
writel(val, rtc->base + RZN1_RTC_TIME);
- val = tm->tm_wday;
- val |= bin2bcd(tm->tm_mday) << RZN1_RTC_CAL_DAY_SHIFT;
- val |= bin2bcd(tm->tm_mon + 1) << RZN1_RTC_CAL_MON_SHIFT;
- val |= bin2bcd(tm->tm_year - 100) << RZN1_RTC_CAL_YEAR_SHIFT;
+ val = FIELD_PREP(RZN1_RTC_CAL_WDAY, tm->tm_wday) |
+ FIELD_PREP(RZN1_RTC_CAL_DAY, bin2bcd(tm->tm_mday)) |
+ FIELD_PREP(RZN1_RTC_CAL_MON, bin2bcd(tm->tm_mon + 1)) |
+ FIELD_PREP(RZN1_RTC_CAL_YEAR, bin2bcd(tm->tm_year - 100));
writel(val, rtc->base + RZN1_RTC_CAL);
writel(0, rtc->base + RZN1_RTC_CTL2);
@@ -306,7 +312,7 @@ static int rzn1_rtc_read_offset(struct device *dev, long *offset)
val = readl(rtc->base + RZN1_RTC_SUBU);
ppb_per_step = val & RZN1_RTC_SUBU_DEV ? 1017 : 3051;
subtract = val & RZN1_RTC_SUBU_DECR;
- val &= 0x3F;
+ val = FIELD_GET(RZN1_RTC_SUBU_RTCA0FX, val);
if (!val)
*offset = 0;
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 12/12] rtc: rzn1: Add support for Renesas RZ/T2H and RZ/N2H SoCs
2026-06-15 15:47 [PATCH 00/12] Add RTC support for Renesas RZ/T2H and RZ/N2H SoCs Prabhakar
` (10 preceding siblings ...)
2026-06-15 15:48 ` [PATCH 11/12] rtc: rzn1: use FIELD_PREP/FIELD_GET and GENMASK for register access Prabhakar
@ 2026-06-15 15:48 ` Prabhakar
2026-06-15 15:58 ` sashiko-bot
11 siblings, 1 reply; 22+ messages in thread
From: Prabhakar @ 2026-06-15 15:48 UTC (permalink / raw)
To: Miquel Raynal, Alexandre Belloni, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, Wolfram Sang
Cc: linux-rtc, linux-renesas-soc, devicetree, linux-kernel, Prabhakar,
Biju Das, Fabrizio Castro, Lad Prabhakar
From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Add a new compatible string "renesas,r9a09g077-rtc" to the OF match table
to support the RTC IP variant found on the RZ/T2H and RZ/N2H SoCs.
These newer SoCs integrate a closely related variant of the RZ/N1 RTC IP.
The RZ/T2H and RZ/N2H variants lack the RTCA0SUBU and RTCA0TCR registers,
those registers are not accessed or used when operating under the
rzn1_rtc_ops_scmp configurations, making the current infrastructure
compatible.
The RZ/T2H RTC variant also supports a 1 Hz output signal on the
RTCAT1HZ pin, controlled by the RTCA0CTL1[RTCA01HZE] bit. This bit is
marked as reserved in the RZ/N1 hardware manual, making RZ/T2H a
distinct RTC variant despite its overall compatibility with the RZ/N1
implementation.
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
drivers/rtc/rtc-rzn1.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
index 9f9cf9882fc4..dfff8dc8c321 100644
--- a/drivers/rtc/rtc-rzn1.c
+++ b/drivers/rtc/rtc-rzn1.c
@@ -597,6 +597,7 @@ static int rzn1_rtc_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(rzn1_rtc_pm_ops, rzn1_rtc_suspend, rzn1_rtc_resume);
static const struct of_device_id rzn1_rtc_of_match[] = {
+ { .compatible = "renesas,r9a09g077-rtc" },
{ .compatible = "renesas,rzn1-rtc" },
{},
};
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 01/12] dt-bindings: rtc: renesas,rzn1-rtc: Add RZ/T2H and RZ/N2H support
2026-06-15 15:47 ` [PATCH 01/12] dt-bindings: rtc: renesas,rzn1-rtc: Add RZ/T2H and RZ/N2H support Prabhakar
@ 2026-06-15 15:56 ` sashiko-bot
2026-06-15 16:22 ` Conor Dooley
1 sibling, 0 replies; 22+ messages in thread
From: sashiko-bot @ 2026-06-15 15:56 UTC (permalink / raw)
To: Prabhakar; +Cc: conor+dt, devicetree, wsa+renesas, robh
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The binding schema enforces a non-existent `timer` interrupt for the new RZ/T2H and RZ/N2H SoC variants.
--
commit be9b5c77c196688e72ded5e0e7c0ff1038239897
Author: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
dt-bindings: rtc: renesas,rzn1-rtc: Add RZ/T2H and RZ/N2H support
This commit adds compatible strings for the RTC block on the Renesas RZ/T2H
and RZ/N2H SoCs. It notes that these variants do not implement the RTCA0SUBU
and RTCA0TCR registers and updates the binding schema to require additional
clock inputs.
> diff --git a/Documentation/devicetree/bindings/rtc/renesas,rzn1-rtc.yaml b/Documentation/devicetree/bindings/rtc/renesas,rzn1-rtc.yaml
> index 1860f0e4c31a2..ea7b039a91e77 100644
> --- a/Documentation/devicetree/bindings/rtc/renesas,rzn1-rtc.yaml
> +++ b/Documentation/devicetree/bindings/rtc/renesas,rzn1-rtc.yaml
[ ... ]
> @@ -54,6 +58,23 @@ required:
> - clock-names
> - power-domains
>
> +allOf:
> + - $ref: rtc.yaml#
> +
> + - if:
> + properties:
> + compatible:
> + contains:
> + enum:
> + - renesas,r9a09g077-rtc
> + - renesas,r9a09g087-rtc
> + then:
> + properties:
> + clocks:
> + minItems: 2
> + clock-names:
> + minItems: 2
[Severity: Medium]
The commit message mentions that these new SoC variants do not implement the
RTCA0TCR (Timer Control Register). Does this mean the hardware also lacks
the timer interrupt?
If the timer interrupt is not present on these variants, should this
conditional block also relax the interrupts and interrupt-names constraints?
The base binding expects three interrupts (alarm, timer, and pps). Without
an override here, won't device tree validation fail for accurately described
hardware that omits the timer interrupt?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260615154805.1619693-1-prabhakar.mahadev-lad.rj@bp.renesas.com?part=1
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 11/12] rtc: rzn1: use FIELD_PREP/FIELD_GET and GENMASK for register access
2026-06-15 15:48 ` [PATCH 11/12] rtc: rzn1: use FIELD_PREP/FIELD_GET and GENMASK for register access Prabhakar
@ 2026-06-15 15:57 ` sashiko-bot
0 siblings, 0 replies; 22+ messages in thread
From: sashiko-bot @ 2026-06-15 15:57 UTC (permalink / raw)
To: Prabhakar; +Cc: robh, devicetree, conor+dt, wsa+renesas
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] Incomplete refactoring: open-coded logic remains for RZN1_RTC_SUBU_RTCA0FX
--
commit 2e16f66c80c483d619655d20fbb859a42e9d1b6d
Author: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
rtc: rzn1: use FIELD_PREP/FIELD_GET and GENMASK for register access
This commit replaces open-coded shift and mask operations with the bitfield
API in the rzn1 RTC driver to improve readability and match the hardware
manual.
> diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
> index c7ef3c81180f4..9f9cf9882fc49 100644
> --- a/drivers/rtc/rtc-rzn1.c
> +++ b/drivers/rtc/rtc-rzn1.c
[ ... ]
> @@ -306,7 +312,7 @@ static int rzn1_rtc_read_offset(struct device *dev, long *offset)
> val = readl(rtc->base + RZN1_RTC_SUBU);
> ppb_per_step = val & RZN1_RTC_SUBU_DEV ? 1017 : 3051;
> subtract = val & RZN1_RTC_SUBU_DECR;
> - val &= 0x3F;
> + val = FIELD_GET(RZN1_RTC_SUBU_RTCA0FX, val);
>
> if (!val)
> *offset = 0;
[Severity: Low]
Since the stated goal of this patch is to replace open-coded masks with the
bitfield API, should the remaining 0x3F masks for this register be updated as
well?
In rzn1_rtc_read_offset() just below this change, there is still an explicit
mask used when calculating the offset:
*offset = -(((~val) & 0x3F) + 1) * ppb_per_step;
Additionally, it looks like the write path in rzn1_rtc_set_offset() was missed
entirely during the refactoring. It continues to use open-coded logic rather
than FIELD_PREP when constructing the RZN1_RTC_SUBU register:
subu |= RZN1_RTC_SUBU_DECR;
subu |= (~(-steps - 1)) & 0x3F;
Would it make sense to update these locations so the bitfield access is
consistent across the driver?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260615154805.1619693-1-prabhakar.mahadev-lad.rj@bp.renesas.com?part=11
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 08/12] rtc: rzn1: Dynamically calculate synchronization delay based on clock rate
2026-06-15 15:48 ` [PATCH 08/12] rtc: rzn1: Dynamically calculate synchronization delay based on clock rate Prabhakar
@ 2026-06-15 15:57 ` sashiko-bot
0 siblings, 0 replies; 22+ messages in thread
From: sashiko-bot @ 2026-06-15 15:57 UTC (permalink / raw)
To: Prabhakar; +Cc: conor+dt, devicetree, robh, wsa+renesas
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Uninitialized `rtc->sync_time` causing infinite polling loop and missing hardware delays when optional `xtal` clock is absent.
- [Low] Semantic unit mismatch using `NSEC_PER_MSEC` for microsecond duration calculation.
--
commit 1c4e11a547342229c6e4a580cb676efaab170aba
Author: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
rtc: rzn1: Dynamically calculate synchronization delay based on clock rate
This commit replaces hardcoded hardware synchronization delays with a
dynamically calculated time window derived from the runtime clock rate.
It stores the calculated clock cycles in the driver private structure to
adjust sleep boundaries dynamically.
> diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
> index 06339adae71f6..bc6af59744e48 100644
> --- a/drivers/rtc/rtc-rzn1.c
> +++ b/drivers/rtc/rtc-rzn1.c
[ ... ]
> @@ -124,8 +125,8 @@ static int rzn1_rtc_set_time(struct device *dev, struct rtc_time *tm)
> /* Hold the counter if it was counting up */
> writel(RZN1_RTC_CTL2_WAIT, rtc->base + RZN1_RTC_CTL2);
>
> - /* Wait for the counter to stop: two 32k clock cycles */
> - usleep_range(61, 100);
> + /* Wait for the counter to stop: two RTC_PCLK clock cycles */
> + usleep_range(rtc->sync_time, rtc->sync_time + 100);
[Severity: High]
If the optional xtal clock is missing, rtc->sync_time remains 0 because the
calculation block in rzn1_rtc_probe() is skipped.
Does this evaluate to usleep_range(0, 100), bypassing the hardware's
required minimum 2-cycle synchronization wait period?
[ ... ]
> @@ -433,17 +434,25 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
> ret = -EOPNOTSUPP;
> goto dis_runtime_pm;
> }
> -
> if (rate != 32768)
> scmp_val = RZN1_RTC_CTL0_SLSB_SCMP;
> +
> + /*
> + * The internal clock counter operates in synchronization with the
> + * RTC_PCLK clock. Calculate the duration of two RTC_PCLK clock
> + * cycles in microseconds required for operations to complete.
> + */
> + rtc->sync_time = DIV_ROUND_UP(2 * NSEC_PER_MSEC, rate);
[Severity: Low]
This isn't a bug, but the calculation uses NSEC_PER_MSEC to compute
microseconds. While mathematically equivalent to 1,000,000, could this
use USEC_PER_SEC to clearly reflect a Hz-to-microseconds conversion?
[Severity: High]
The driver retrieves the xtal clock using devm_clk_get_optional() earlier
in rzn1_rtc_probe(). If the clock is missing, the else if (xtal) block is
skipped entirely.
Does this leave rtc->sync_time uninitialized at 0 for the default internal
clock?
> +
> }
>
> /* Disable controller during SUBU/SCMP setup */
> val = readl(rtc->base + RZN1_RTC_CTL0) & ~RZN1_RTC_CTL0_CE;
> writel(val, rtc->base + RZN1_RTC_CTL0);
> - /* Wait 2-4 32k clock cycles for the disabled controller */
> + /* Wait 2-4 RTC_PCLK clock cycles for the disabled controller to stop */
> ret = readl_poll_timeout(rtc->base + RZN1_RTC_CTL0, val,
> - !(val & RZN1_RTC_CTL0_CEST), 62, 123);
> + !(val & RZN1_RTC_CTL0_CEST), rtc->sync_time,
> + rtc->sync_time * 2);
[Severity: High]
If rtc->sync_time is 0 from the missing optional clock, the timeout argument
(rtc->sync_time * 2) evaluates to 0.
Since readl_poll_timeout() treats a 0 timeout as explicitly disabling the
timeout check, will this turn the wait into an infinite tight loop if the
hardware fails to respond?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260615154805.1619693-1-prabhakar.mahadev-lad.rj@bp.renesas.com?part=8
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 12/12] rtc: rzn1: Add support for Renesas RZ/T2H and RZ/N2H SoCs
2026-06-15 15:48 ` [PATCH 12/12] rtc: rzn1: Add support for Renesas RZ/T2H and RZ/N2H SoCs Prabhakar
@ 2026-06-15 15:58 ` sashiko-bot
0 siblings, 0 replies; 22+ messages in thread
From: sashiko-bot @ 2026-06-15 15:58 UTC (permalink / raw)
To: Prabhakar; +Cc: devicetree, wsa+renesas, conor+dt, robh
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [High] Missing validation allows RZ/T2H variants to fall back to SUBU mode, which accesses physically non-existent registers, potentially causing an SError or Data Abort.
Pre-existing issues:
- [High] If the optional `xtal` clock is omitted in the device tree, `rtc->sync_time` remains 0, leading to infinite tight-polling in `readl_poll_timeout`.
--
commit af1aa184c32ed0a36cb0e267cb73522f881de94d
Author: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
rtc: rzn1: Add support for Renesas RZ/T2H and RZ/N2H SoCs
Add a new compatible string "renesas,r9a09g077-rtc" to the OF match table
to support the RTC IP variant found on the RZ/T2H and RZ/N2H SoCs. These
newer SoCs integrate a closely related variant of the RZ/N1 RTC IP but lack
the RTCA0SUBU and RTCA0TCR registers.
> diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
> index 9f9cf9882fc49..dfff8dc8c3212 100644
> --- a/drivers/rtc/rtc-rzn1.c
> +++ b/drivers/rtc/rtc-rzn1.c
> @@ -597,6 +597,7 @@ static int rzn1_rtc_resume(struct device *dev)
> static DEFINE_SIMPLE_DEV_PM_OPS(rzn1_rtc_pm_ops, rzn1_rtc_suspend, rzn1_rtc_resume);
>
> static const struct of_device_id rzn1_rtc_of_match[] = {
> + { .compatible = "renesas,r9a09g077-rtc" },
[Severity: High]
The commit message notes that the new RZ/T2H variants lack the RTCA0SUBU
register and rely on rzn1_rtc_ops_scmp configurations. However, is it safe to
rely on the clock configuration to select between SCMP and SUBU operations?
In rzn1_rtc_probe(), the fallback to SUBU mode is based solely on the xtal
clock:
drivers/rtc/rtc-rzn1.c:rzn1_rtc_probe() {
if (xtal) {
rate = clk_get_rate(xtal);
...
if (rate != 32768)
scmp_val = RZN1_RTC_CTL0_SLSB_SCMP;
...
}
if (scmp_val) {
writel(rate - 1, rtc->base + RZN1_RTC_SCMP);
rtc->rtcdev->ops = &rzn1_rtc_ops_scmp;
} else {
rtc->rtcdev->ops = &rzn1_rtc_ops_subu;
}
}
If the device tree misconfigures the clock (e.g., rate is exactly 32768) or
omits the optional xtal clock entirely, scmp_val will be 0. The driver will
dynamically assign rzn1_rtc_ops_subu as the ops.
Subsequent operations like rzn1_rtc_read_offset() will directly access the
missing register:
drivers/rtc/rtc-rzn1.c:rzn1_rtc_read_offset() {
val = readl(rtc->base + RZN1_RTC_SUBU);
}
Could this cause an unhandled SError or Data Abort when accessing the
physically non-existent SUBU register on RZ/T2H? Should the driver explicitly
enforce the use of SCMP operations for this compatible string regardless of the
clock configuration?
[Severity: High]
This is a pre-existing issue, but if the optional xtal clock is omitted in the
device tree, rtc->sync_time remains 0 since it is initialized by devm_kzalloc()
and the calculation block is skipped.
Later in rzn1_rtc_probe():
/* Wait 2-4 RTC_PCLK clock cycles for the disabled controller to stop */
ret = readl_poll_timeout(rtc->base + RZN1_RTC_CTL0, val,
!(val & RZN1_RTC_CTL0_CEST), rtc->sync_time,
rtc->sync_time * 2);
Passing a timeout of 0 to readl_poll_timeout() instructs it to never time out.
Combined with a sleep_us of 0, could this result in an infinite tight loop
if the hardware condition !(val & RZN1_RTC_CTL0_CEST) is never met during
probe?
> { .compatible = "renesas,rzn1-rtc" },
> {},
> };
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260615154805.1619693-1-prabhakar.mahadev-lad.rj@bp.renesas.com?part=12
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 02/12] rtc: rzn1: Handle EPROBE_DEFER for optional pps interrupt
2026-06-15 15:47 ` [PATCH 02/12] rtc: rzn1: Handle EPROBE_DEFER for optional pps interrupt Prabhakar
@ 2026-06-15 15:58 ` sashiko-bot
0 siblings, 0 replies; 22+ messages in thread
From: sashiko-bot @ 2026-06-15 15:58 UTC (permalink / raw)
To: Prabhakar; +Cc: robh, conor+dt, wsa+renesas, devicetree
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] If the optional 'xtal' clock is not present, `rtc->sync_time` remains 0, causing `readl_poll_timeout` to use a 0 timeout (infinite wait) and `usleep_range` to use a 0 delay.
--
commit 5d75a1049c228d2049afaf29833f1b2f212837d4
Author: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Subject: rtc: rzn1: Handle EPROBE_DEFER for optional pps interrupt
This commit checks for -EPROBE_DEFER from platform_get_irq_byname_optional()
and handles the deferred probe request properly. It intercepts this specific
error condition, assigns it to the return value, and jumps to the
dis_runtime_pm label to avoid ignoring a valid probe deferral.
Fixes: eea7791e00f33 ("rtc: rzn1: implement one-second accuracy for alarms")
Cc: stable@vger.kernel.org
> diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
> index c4ed437354574..f81d691c8b9a2 100644
> --- a/drivers/rtc/rtc-rzn1.c
> +++ b/drivers/rtc/rtc-rzn1.c
> @@ -465,6 +465,10 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
> }
>
> irq = platform_get_irq_byname_optional(pdev, "pps");
> + if (irq == -EPROBE_DEFER) {
> + ret = irq;
> + goto dis_runtime_pm;
> + }
> if (irq >= 0)
> ret = devm_request_irq(&pdev->dev, irq, rzn1_rtc_1s_irq, 0, "RZN1 RTC 1s", rtc);
[Severity: High]
If the optional xtal clock is not present, does rtc->sync_time remain 0,
causing readl_poll_timeout() to use a 0 timeout (infinite wait) and
usleep_range() to use a 0 delay?
devm_clk_get_optional() returns NULL if the clock is absent in the device
tree, skipping the calculation:
drivers/rtc/rtc-rzn1.c:rzn1_rtc_probe() {
...
xtal = devm_clk_get_optional(dev, "xtal");
if (IS_ERR(xtal)) {
...
} else if (xtal) {
rate = clk_get_rate(xtal);
...
rtc->sync_time = DIV_ROUND_UP(2 * NSEC_PER_MSEC, rate);
}
...
ret = readl_poll_timeout(rtc->base + RZN1_RTC_CTL0, val,
!(val & RZN1_RTC_CTL0_CEST), rtc->sync_time,
rtc->sync_time * 2);
...
}
In include/linux/iopoll.h, a timeout_us of 0 skips the timeout check
entirely, which could lead to a tight infinite loop and a kernel hard lockup
if the hardware fails to clear the CEST bit.
Additionally, rtc->sync_time being 0 causes usleep_range(0, 100) in
rzn1_rtc_set_time(), which may return almost immediately and violate the
hardware's explicit 2-clock-cycle delay requirement (previously hardcoded to
61us).
This regression was introduced by the commit 'rtc: rzn1: Dynamically
calculate synchronization delay based on clock rate' later in this series.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260615154805.1619693-1-prabhakar.mahadev-lad.rj@bp.renesas.com?part=2
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 05/12] rtc: rzn1: Add system suspend/resume support and wakeup capability
2026-06-15 15:47 ` [PATCH 05/12] rtc: rzn1: Add system suspend/resume support and wakeup capability Prabhakar
@ 2026-06-15 15:59 ` sashiko-bot
0 siblings, 0 replies; 22+ messages in thread
From: sashiko-bot @ 2026-06-15 15:59 UTC (permalink / raw)
To: Prabhakar; +Cc: wsa+renesas, conor+dt, robh, devicetree
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
New issues:
- [Medium] Incorrect error rollback and returning errors from rzn1_rtc_resume() breaks wakeup configuration.
- [Medium] A hardware limitation is logged as a critical error on every suspend.
Pre-existing issues:
- [High] Asynchronous pm_runtime_put() is used before devres pm_runtime_disable(), leaving hardware powered on.
--
commit 65fe5cbeb3fc2e52fb88cf7b501a98dd6399fa39
Author: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
rtc: rzn1: Add system suspend/resume support and wakeup capability
Add system-wide power management support along with wakeup capability to
the rtc-rzn1 driver, bridging sub-minute gaps with a 1-second periodic
broadcast loop.
> diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
> index 866ff595188d8..12a319e9112c1 100644
> --- a/drivers/rtc/rtc-rzn1.c
> +++ b/drivers/rtc/rtc-rzn1.c
[ ... ]
> @@ -500,6 +511,74 @@ static void rzn1_rtc_remove(struct platform_device *pdev)
> pm_runtime_put(&pdev->dev);
> }
[Severity: High]
This is a pre-existing issue, but does using pm_runtime_put() here and in
the dis_runtime_pm error path of rzn1_rtc_probe() leave the hardware
powered on?
The driver initializes runtime PM using devm_pm_runtime_enable(), which
registers a devres action to call pm_runtime_disable() upon probe failure
or device removal. By calling the asynchronous pm_runtime_put(), the
suspend operation is queued but immediately cancelled by the subsequent
pm_runtime_disable() devres action.
Should pm_runtime_put_sync() be used instead when pm_runtime_disable()
follows immediately to ensure the device is properly suspended?
> +static int rzn1_rtc_suspend(struct device *dev)
> +{
> + struct rzn1_rtc *rtc = dev_get_drvdata(dev);
> + int ret;
[ ... ]
> + if (rtc->alarm_enabled)
> + dev_crit(dev, "second/minute-level wakeup accuracy cannot be guaranteed by HW\n");
[Severity: Medium]
Does this unconditionally log a critical message on every suspend if the
alarm is enabled?
Since this is a known architectural limitation rather than an acute failure,
this will spam the kernel log with critical severity messages during normal
system suspend operations.
Would it be better to downgrade this to dev_warn() or dev_info()?
> + ret = enable_irq_wake(rtc->alarm_irq);
> + if (ret)
> + return ret;
> + if (rtc->sec_irq >= 0) {
> + ret = enable_irq_wake(rtc->sec_irq);
> + if (ret) {
> + disable_irq_wake(rtc->alarm_irq);
> + return ret;
> + }
> + }
> +
> + return 0;
> +}
> +
> +static int rzn1_rtc_resume(struct device *dev)
> +{
> + struct rzn1_rtc *rtc = dev_get_drvdata(dev);
> + int ret;
> +
> + if (!device_may_wakeup(dev))
> + return 0;
> +
> + ret = disable_irq_wake(rtc->alarm_irq);
> + if (ret)
> + return ret;
> + if (rtc->sec_irq >= 0) {
> + ret = disable_irq_wake(rtc->sec_irq);
> + if (ret) {
> + enable_irq_wake(rtc->alarm_irq);
> + return ret;
> + }
> + }
[Severity: Medium]
Is it correct to re-enable the alarm_irq wakeup source and return an error
here in rzn1_rtc_resume() if disable_irq_wake() fails?
Because the PM core ignores device resume failures and continues the
system resume sequence, returning an error here and re-enabling alarm_irq
leaves it permanently configured as a wakeup source while the system is
active. This unbalanced state could lead to spurious wakeups.
Should the rollback logic be reconsidered or removed for the resume path?
> +
> + return 0;
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260615154805.1619693-1-prabhakar.mahadev-lad.rj@bp.renesas.com?part=5
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 07/12] rtc: rzn1: fix alarm range check truncation on 32-bit systems
2026-06-15 15:48 ` [PATCH 07/12] rtc: rzn1: fix alarm range check truncation on 32-bit systems Prabhakar
@ 2026-06-15 16:00 ` sashiko-bot
0 siblings, 0 replies; 22+ messages in thread
From: sashiko-bot @ 2026-06-15 16:00 UTC (permalink / raw)
To: Prabhakar; +Cc: devicetree, robh, conor+dt, wsa+renesas
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
Pre-existing issues:
- [High] Incorrect hardware alarm weekday assignment due to unsigned underflow when the alarm crosses a month boundary.
- [High] Unconfigured alarms in `rzn1_rtc_read_alarm` can return an invalid `tm_wday` value of `-1`, risking out-of-bounds array access in userspace.
- [High] Potential spurious interrupt when sequentially updating active hardware alarm registers.
--
commit d278abd6309a65fff235820bea9a8e8631da47be
Author: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Subject: rtc: rzn1: fix alarm range check truncation on 32-bit systems
This commit fixes a silent truncation issue on 32-bit systems by changing
the alarm and farest variables from unsigned long to time64_t. It also
replaces the time_after() macro with a direct signed comparison.
> diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
> index fe21fa6242881..06339adae71f6 100644
> --- a/drivers/rtc/rtc-rzn1.c
> +++ b/drivers/rtc/rtc-rzn1.c
[ ... ]
> @@ -265,8 +266,8 @@ static int rzn1_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
> {
> struct rzn1_rtc *rtc = dev_get_drvdata(dev);
> struct rtc_time *tm = &alrm->time, tm_now;
> - unsigned long alarm, farest;
> unsigned int days_ahead, wday;
> + time64_t alarm, farest;
> int ret;
>
> ret = rzn1_rtc_read_time(dev, &tm_now);
> @@ -276,7 +277,7 @@ static int rzn1_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
> /* We cannot set alarms more than one week ahead */
> farest = rtc_tm_to_time64(&tm_now) + rtc->rtcdev->alarm_offset_max;
> alarm = rtc_tm_to_time64(tm);
> - if (time_after(alarm, farest))
> + if (alarm > farest)
> return -ERANGE;
>
> /* Convert alarm day into week day */
[Severity: High]
This isn't a bug introduced by this patch, but does the calculation for
days_ahead underflow if the alarm crosses a month boundary?
In rzn1_rtc_set_alarm(), days_ahead is typed as an unsigned int and is
calculated like this:
days_ahead = tm->tm_mday - tm_now.tm_mday;
wday = (tm_now.tm_wday + days_ahead) % 7;
If the alarm is set for the 1st of the next month, and today is the 31st,
the subtraction results in -30. When assigned to an unsigned int, this
underflows. Because 2^32 % 7 evaluates to 4, the resulting wday calculation
shifts the weekday by exactly 4 days, causing the hardware alarm register
to be programmed for the wrong day.
[Severity: High]
This is a pre-existing issue, but is there a risk of a spurious interrupt
when updating the active hardware alarm registers?
Just below this hunk in rzn1_rtc_set_alarm(), the match registers are
updated sequentially:
writel(bin2bcd(tm->tm_min), rtc->base + RZN1_RTC_ALM);
writel(bin2bcd(tm->tm_hour), rtc->base + RZN1_RTC_ALH);
writel(BIT(wday), rtc->base + RZN1_RTC_ALW);
The RTC core can invoke this function without first disabling the hardware
alarm if replacing an existing timer. If the hardware alarm interrupt is
active, modifying these registers sequentially could cause the intermediate
hardware state to momentarily match the current time, triggering a spurious
interrupt and prematurely expiring the next timer in the queue.
[Severity: High]
This is a pre-existing issue, but what happens in rzn1_rtc_read_alarm() if
the hardware alarm is unconfigured?
If the hardware alarm register reads 0, fls(0) - 1 evaluates to -1:
drivers/rtc/rtc-rzn1.c:rzn1_rtc_read_alarm() {
...
wday = readl(rtc->base + RZN1_RTC_ALW);
...
delta_days = ((fls(wday) - 1) - tm->tm_wday + 7) % 7;
tm->tm_wday = fls(wday) - 1;
...
}
If the current weekday is Saturday (6), delta_days evaluates to 0:
((-1 - 6 + 7) % 7) == 0.
Because delta_days is 0, the rtc_time64_to_tm() block is skipped, and the
function returns with tm->tm_wday = -1. Since rtc_valid_tm() does not
bound-check tm_wday, this -1 is passed to userspace where tools commonly
use it as an array index, which could cause an out-of-bounds memory read.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260615154805.1619693-1-prabhakar.mahadev-lad.rj@bp.renesas.com?part=7
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 01/12] dt-bindings: rtc: renesas,rzn1-rtc: Add RZ/T2H and RZ/N2H support
2026-06-15 15:47 ` [PATCH 01/12] dt-bindings: rtc: renesas,rzn1-rtc: Add RZ/T2H and RZ/N2H support Prabhakar
2026-06-15 15:56 ` sashiko-bot
@ 2026-06-15 16:22 ` Conor Dooley
1 sibling, 0 replies; 22+ messages in thread
From: Conor Dooley @ 2026-06-15 16:22 UTC (permalink / raw)
To: Prabhakar
Cc: Miquel Raynal, Alexandre Belloni, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, Wolfram Sang, linux-rtc, linux-renesas-soc,
devicetree, linux-kernel, Biju Das, Fabrizio Castro,
Lad Prabhakar
[-- Attachment #1: Type: text/plain, Size: 75 bytes --]
Acked-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: not-applicable
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 09/12] rtc: rzn1: Use temporary variable for struct device
2026-06-15 15:48 ` [PATCH 09/12] rtc: rzn1: Use temporary variable for struct device Prabhakar
@ 2026-06-15 17:56 ` sashiko-bot
0 siblings, 0 replies; 22+ messages in thread
From: sashiko-bot @ 2026-06-15 17:56 UTC (permalink / raw)
To: Prabhakar; +Cc: devicetree, robh, conor+dt, wsa+renesas
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
Pre-existing issues:
- [High] Asynchronous pm_runtime_put() is used instead of pm_runtime_put_sync() before runtime PM is disabled, potentially leaving the device powered on.
- [High] If the optional 'xtal' clock is missing, readl_poll_timeout() loops forever with a 0 timeout, risking a boot hang.
- [High] The driver's `remove` callback prematurely disables hardware interrupts and drops the runtime PM reference while the RTC device is still fully registered.
--
commit b7f73c7d0932a6e78b12419c5912ad3243637b8f
Author: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
rtc: rzn1: Use temporary variable for struct device
This patch simplifies the rzn1_rtc_probe function by using a local temporary
variable for the struct device pointer. This avoids repeated dereferences of
pdev->dev throughout the function.
> diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
> index bc6af59744e48..25cad9213147d 100644
> --- a/drivers/rtc/rtc-rzn1.c
> +++ b/drivers/rtc/rtc-rzn1.c
[ ... ]
> @@ -415,15 +416,15 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
[ ... ]
> /* Only switch to scmp if we have an xtal clock with a valid rate and != 32768 */
> - xtal = devm_clk_get_optional(&pdev->dev, "xtal");
> + xtal = devm_clk_get_optional(dev, "xtal");
[Severity: High]
This is a pre-existing issue, but if the optional xtal clock is not present,
devm_clk_get_optional() sets xtal to NULL. In this scenario, rtc->sync_time
remains uninitialized and defaults to 0.
Further down in rzn1_rtc_probe(), readl_poll_timeout() is called:
ret = readl_poll_timeout(rtc->base + RZN1_RTC_CTL0, val,
!(val & RZN1_RTC_CTL0_CEST), rtc->sync_time,
rtc->sync_time * 2);
With rtc->sync_time at 0, the timeout evaluation becomes 0. Does this cause
readl_poll_timeout() to loop indefinitely and hang the boot if the hardware
fails to clear the RZN1_RTC_CTL0_CEST bit?
> if (IS_ERR(xtal)) {
> ret = PTR_ERR(xtal);
> goto dis_runtime_pm;
[ ... ]
> @@ -486,18 +487,18 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
[ ... ]
> device_init_wakeup(dev, true);
>
> ret = devm_rtc_register_device(rtc->rtcdev);
[Severity: High]
This isn't a bug introduced by this patch, but does registering the RTC
device using devm_rtc_register_device() create a race condition during
teardown?
In rzn1_rtc_remove(), the driver manually disables interrupts and calls
pm_runtime_put() before devres has unregistered the RTC device:
writel(0, rtc->base + RZN1_RTC_CTL1);
pm_runtime_put(&pdev->dev);
Could userspace still interact with the RTC during this window via ioctls
or sysfs, potentially causing synchronous bus faults since the hardware is
already suspended? Should teardown be bound using
devm_add_action_or_reset() to guarantee correct reverse execution order?
> if (ret)
> @@ -506,7 +507,7 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
> return 0;
>
> dis_runtime_pm:
> - pm_runtime_put(&pdev->dev);
> + pm_runtime_put(dev);
[Severity: High]
This is a pre-existing issue, but does using pm_runtime_put() here (and in
rzn1_rtc_remove) leave the device powered on indefinitely?
Since devm_pm_runtime_enable(dev) schedules pm_runtime_disable() to
execute during devres cleanup, calling pm_runtime_put() only queues an
asynchronous idle check. The immediate return triggers devres cleanup,
which executes a barrier that explicitly cancels pending async operations.
Should this use pm_runtime_put_sync() instead to ensure the device is
synchronously suspended before teardown?
> return ret;
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260615154805.1619693-1-prabhakar.mahadev-lad.rj@bp.renesas.com?part=9
^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2026-06-15 17:56 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-15 15:47 [PATCH 00/12] Add RTC support for Renesas RZ/T2H and RZ/N2H SoCs Prabhakar
2026-06-15 15:47 ` [PATCH 01/12] dt-bindings: rtc: renesas,rzn1-rtc: Add RZ/T2H and RZ/N2H support Prabhakar
2026-06-15 15:56 ` sashiko-bot
2026-06-15 16:22 ` Conor Dooley
2026-06-15 15:47 ` [PATCH 02/12] rtc: rzn1: Handle EPROBE_DEFER for optional pps interrupt Prabhakar
2026-06-15 15:58 ` sashiko-bot
2026-06-15 15:47 ` [PATCH 03/12] rtc: rzn1: Fix malformed MODULE_AUTHOR string Prabhakar
2026-06-15 15:47 ` [PATCH 04/12] rtc: Kconfig: Broaden RTC_DRV_RZN1 dependency to ARCH_RENESAS Prabhakar
2026-06-15 15:47 ` [PATCH 05/12] rtc: rzn1: Add system suspend/resume support and wakeup capability Prabhakar
2026-06-15 15:59 ` sashiko-bot
2026-06-15 15:47 ` [PATCH 06/12] rtc: rzn1: Sort headers alphabetically Prabhakar
2026-06-15 15:48 ` [PATCH 07/12] rtc: rzn1: fix alarm range check truncation on 32-bit systems Prabhakar
2026-06-15 16:00 ` sashiko-bot
2026-06-15 15:48 ` [PATCH 08/12] rtc: rzn1: Dynamically calculate synchronization delay based on clock rate Prabhakar
2026-06-15 15:57 ` sashiko-bot
2026-06-15 15:48 ` [PATCH 09/12] rtc: rzn1: Use temporary variable for struct device Prabhakar
2026-06-15 17:56 ` sashiko-bot
2026-06-15 15:48 ` [PATCH 10/12] rtc: rzn1: Consistently use dev_err_probe() Prabhakar
2026-06-15 15:48 ` [PATCH 11/12] rtc: rzn1: use FIELD_PREP/FIELD_GET and GENMASK for register access Prabhakar
2026-06-15 15:57 ` sashiko-bot
2026-06-15 15:48 ` [PATCH 12/12] rtc: rzn1: Add support for Renesas RZ/T2H and RZ/N2H SoCs Prabhakar
2026-06-15 15:58 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox