From f9ecfd9bfedba9fd9d4b015b33b847571f7fdd42 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Mon, 22 Dec 2025 03:56:48 +0000 Subject: [PATCH 01/19] rtc: nvvrs: Add ARCH_TEGRA to the NV VRS RTC driver The NV VRS RTC driver currently is only supported on the Tegra platform so add a dep for ARCH_TEGRA and compile test so it doesn't show up universally across all arches/platforms. Fixes: 9d6d6b06933c8 ("rtc: nvvrs: add NVIDIA VRS RTC device driver") Cc: Shubhi Garg Cc: Jon Hunter Signed-off-by: Peter Robinson Acked-by: Jon Hunter Link: https://patch.msgid.link/20251222035651.433603-1-pbrobinson@gmail.com Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 50dc779f7f98..50ba48609d74 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -418,6 +418,7 @@ config RTC_DRV_SPACEMIT_P1 config RTC_DRV_NVIDIA_VRS10 tristate "NVIDIA VRS10 RTC device" + depends on ARCH_TEGRA || COMPILE_TEST help If you say yes here you will get support for the battery backed RTC device of NVIDIA VRS (Voltage Regulator Specification). The RTC is connected via From d5aca9a17f6de884febc56018f92d743b8ea1298 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 7 Jan 2026 20:54:32 -0800 Subject: [PATCH 02/19] rtc: max31335: use correct CONFIG symbol in IS_REACHABLE() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IS_REACHABLE() is meant to be used with full symbol names from a kernel .config file, not the shortened symbols used in Kconfig files, so change HWMON to CONFIG_HWMON in 3 places. Fixes: dedaf03b99d6 ("rtc: max31335: add driver support") Signed-off-by: Randy Dunlap Acked-by: Nuno Sá Link: https://patch.msgid.link/20260108045432.2705691-1-rdunlap@infradead.org Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-max31335.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/rtc/rtc-max31335.c b/drivers/rtc/rtc-max31335.c index 23b7bf16b4cd..952b455071d6 100644 --- a/drivers/rtc/rtc-max31335.c +++ b/drivers/rtc/rtc-max31335.c @@ -591,7 +591,7 @@ static struct nvmem_config max31335_nvmem_cfg = { .size = MAX31335_RAM_SIZE, }; -#if IS_REACHABLE(HWMON) +#if IS_REACHABLE(CONFIG_HWMON) static int max31335_read_temp(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, long *val) { @@ -672,7 +672,7 @@ static int max31335_clkout_register(struct device *dev) static int max31335_probe(struct i2c_client *client) { struct max31335_data *max31335; -#if IS_REACHABLE(HWMON) +#if IS_REACHABLE(CONFIG_HWMON) struct device *hwmon; #endif const struct chip_desc *match; @@ -727,7 +727,7 @@ static int max31335_probe(struct i2c_client *client) return dev_err_probe(&client->dev, ret, "cannot register rtc nvmem\n"); -#if IS_REACHABLE(HWMON) +#if IS_REACHABLE(CONFIG_HWMON) if (max31335->chip->temp_reg) { hwmon = devm_hwmon_device_register_with_info(&client->dev, client->name, max31335, &max31335_chip_info, NULL); From a380a02ea3ddc69c1c1ccca3882748dee33ec3d3 Mon Sep 17 00:00:00 2001 From: John Keeping Date: Thu, 8 Jan 2026 18:47:48 +0000 Subject: [PATCH 03/19] rtc: pcf8563: use correct of_node for output clock When switching to regmap, the i2c_client pointer was removed from struct pcf8563 so this function switched to using the RTC device instead. But the RTC device is a child of the original I2C device and does not have an associated of_node. Reference the correct device's of_node to ensure that the output clock can be found when referenced by other devices and so that the override clock name is read correctly. Cc: stable@vger.kernel.org Fixes: 00f1bb9b8486b ("rtc: pcf8563: Switch to regmap") Signed-off-by: John Keeping Link: https://patch.msgid.link/20260108184749.3413348-1-jkeeping@inmusicbrands.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pcf8563.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 4e61011fb7a9..b281e9489df1 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -424,7 +424,7 @@ static const struct clk_ops pcf8563_clkout_ops = { static struct clk *pcf8563_clkout_register_clk(struct pcf8563 *pcf8563) { - struct device_node *node = pcf8563->rtc->dev.of_node; + struct device_node *node = pcf8563->rtc->dev.parent->of_node; struct clk_init_data init; struct clk *clk; int ret; From 1932db202c9326747c6046959284992ab4124bac Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 28 Jan 2026 10:55:32 +0100 Subject: [PATCH 04/19] rtc: amlogic-a4: Remove IRQF_ONESHOT Passing IRQF_ONESHOT ensures that the interrupt source is masked until the secondary (threaded) handler is done. If only a primary handler is used then the flag makes no sense because the interrupt can not fire (again) while its handler is running. The flag also disallows force-threading of the primary handler and the irq-core will warn about this. Remove IRQF_ONESHOT from irqflags. Fixes: c89ac9182ee29 ("rtc: support for the Amlogic on-chip RTC") Reviewed-by: Xianwei Zhao Signed-off-by: Sebastian Andrzej Siewior Link: https://patch.msgid.link/20260128095540.863589-13-bigeasy@linutronix.de Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-amlogic-a4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-amlogic-a4.c b/drivers/rtc/rtc-amlogic-a4.c index 123fb372fc9f..50938c35af36 100644 --- a/drivers/rtc/rtc-amlogic-a4.c +++ b/drivers/rtc/rtc-amlogic-a4.c @@ -369,7 +369,7 @@ static int aml_rtc_probe(struct platform_device *pdev) return PTR_ERR(rtc->rtc_dev); ret = devm_request_irq(dev, rtc->irq, aml_rtc_handler, - IRQF_ONESHOT, "aml-rtc alarm", rtc); + 0, "aml-rtc alarm", rtc); if (ret) { dev_err_probe(dev, ret, "IRQ%d request failed, ret = %d\n", rtc->irq, ret); From 2724fb4d429cbb724dcb6fa17953040918ebe3a2 Mon Sep 17 00:00:00 2001 From: Tomas Melin Date: Thu, 22 Jan 2026 13:53:45 +0000 Subject: [PATCH 05/19] rtc: zynqmp: correct frequency value Fix calibration value in case a clock reference is provided. The actual calibration value written into register is frequency - 1. Reviewed-by: Harini T Tested-by: Harini T Signed-off-by: Tomas Melin Acked-by: Michal Simek Link: https://patch.msgid.link/20260122-zynqmp-rtc-updates-v4-1-d4edb966b499@vaisala.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-zynqmp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c index 3baa2b481d9f..856bc1678e7d 100644 --- a/drivers/rtc/rtc-zynqmp.c +++ b/drivers/rtc/rtc-zynqmp.c @@ -345,7 +345,10 @@ static int xlnx_rtc_probe(struct platform_device *pdev) &xrtcdev->freq); if (ret) xrtcdev->freq = RTC_CALIB_DEF; + } else { + xrtcdev->freq--; } + ret = readl(xrtcdev->reg_base + RTC_CALIB_RD); if (!ret) writel(xrtcdev->freq, (xrtcdev->reg_base + RTC_CALIB_WR)); From 83b9e5eb043710190f6461729fa2e05320a6594d Mon Sep 17 00:00:00 2001 From: Tomas Melin Date: Thu, 22 Jan 2026 13:53:46 +0000 Subject: [PATCH 06/19] rtc: zynqmp: check calibration max value Enable check to not overflow the calibration max value. Reviewed-by: Harini T Tested-by: Harini T Signed-off-by: Tomas Melin Acked-by: Michal Simek Link: https://patch.msgid.link/20260122-zynqmp-rtc-updates-v4-2-d4edb966b499@vaisala.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-zynqmp.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c index 856bc1678e7d..caacce3725e2 100644 --- a/drivers/rtc/rtc-zynqmp.c +++ b/drivers/rtc/rtc-zynqmp.c @@ -349,6 +349,11 @@ static int xlnx_rtc_probe(struct platform_device *pdev) xrtcdev->freq--; } + if (xrtcdev->freq > RTC_TICK_MASK) { + dev_err(&pdev->dev, "Invalid RTC calibration value\n"); + return -EINVAL; + } + ret = readl(xrtcdev->reg_base + RTC_CALIB_RD); if (!ret) writel(xrtcdev->freq, (xrtcdev->reg_base + RTC_CALIB_WR)); From 0f9989443faec6ae8b8418ddf39f080c75a23c0d Mon Sep 17 00:00:00 2001 From: Tomas Melin Date: Thu, 22 Jan 2026 13:53:47 +0000 Subject: [PATCH 07/19] rtc: zynqmp: rework read_offset read_offset() was using static frequency for determining the tick offset. It was also using remainder from do_div() operation as tick_mult value which caused the offset to be incorrect. At the same time, rework function to improve readability. It is worth noting, that due to rounding errors, the offset readback will differ slightly for positive and negative calibration values. Reviewed-by: Harini T Tested-by: Harini T Signed-off-by: Tomas Melin Acked-by: Michal Simek Link: https://patch.msgid.link/20260122-zynqmp-rtc-updates-v4-3-d4edb966b499@vaisala.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-zynqmp.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c index caacce3725e2..c82f4d490fc7 100644 --- a/drivers/rtc/rtc-zynqmp.c +++ b/drivers/rtc/rtc-zynqmp.c @@ -43,7 +43,7 @@ #define RTC_MSEC 1000 #define RTC_FR_MASK 0xF0000 #define RTC_FR_MAX_TICKS 16 -#define RTC_PPB 1000000000LL +#define RTC_PPB 1000000000 #define RTC_MIN_OFFSET -32768000 #define RTC_MAX_OFFSET 32767000 @@ -178,21 +178,28 @@ static void xlnx_init_rtc(struct xlnx_rtc_dev *xrtcdev) static int xlnx_rtc_read_offset(struct device *dev, long *offset) { struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev); - unsigned long long rtc_ppb = RTC_PPB; - unsigned int tick_mult = do_div(rtc_ppb, xrtcdev->freq); - unsigned int calibval; + unsigned int calibval, fract_data, fract_part; + int freq = xrtcdev->freq; + int max_tick, tick_mult; long offset_val; + /* Tick to offset multiplier */ + tick_mult = DIV_ROUND_CLOSEST(RTC_PPB, freq); + calibval = readl(xrtcdev->reg_base + RTC_CALIB_RD); /* Offset with seconds ticks */ - offset_val = calibval & RTC_TICK_MASK; - offset_val = offset_val - RTC_CALIB_DEF; - offset_val = offset_val * tick_mult; + max_tick = calibval & RTC_TICK_MASK; + offset_val = max_tick - freq; + /* Convert to ppb */ + offset_val *= tick_mult; /* Offset with fractional ticks */ - if (calibval & RTC_FR_EN) - offset_val += ((calibval & RTC_FR_MASK) >> RTC_FR_DATSHIFT) - * (tick_mult / RTC_FR_MAX_TICKS); + if (calibval & RTC_FR_EN) { + fract_data = (calibval & RTC_FR_MASK) >> RTC_FR_DATSHIFT; + fract_part = DIV_ROUND_UP(tick_mult, RTC_FR_MAX_TICKS); + offset_val += (fract_part * fract_data); + } + *offset = offset_val; return 0; From 9f5af70268d679e710a65e5e1b4259789a848309 Mon Sep 17 00:00:00 2001 From: Tomas Melin Date: Thu, 22 Jan 2026 13:53:48 +0000 Subject: [PATCH 08/19] rtc: zynqmp: rework set_offset set_offset was using remainder of do_div as tick_mult which resulted in wrong offset. Calibration value also assumed builtin calibration default. Update fract_offset to correctly calculate the value for negative offset and replace the for loop with division. Tested-by: Harini T Signed-off-by: Tomas Melin Reviewed-by: Harini T Acked-by: Michal Simek Link: https://patch.msgid.link/20260122-zynqmp-rtc-updates-v4-4-d4edb966b499@vaisala.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-zynqmp.c | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c index c82f4d490fc7..f0f5dc63e254 100644 --- a/drivers/rtc/rtc-zynqmp.c +++ b/drivers/rtc/rtc-zynqmp.c @@ -208,13 +208,13 @@ static int xlnx_rtc_read_offset(struct device *dev, long *offset) static int xlnx_rtc_set_offset(struct device *dev, long offset) { struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev); - unsigned long long rtc_ppb = RTC_PPB; - unsigned int tick_mult = do_div(rtc_ppb, xrtcdev->freq); - unsigned char fract_tick = 0; + int max_tick, tick_mult, fract_offset, fract_part; + int freq = xrtcdev->freq; unsigned int calibval; - short int max_tick; - int fract_offset; + int fract_data = 0; + /* Tick to offset multiplier */ + tick_mult = DIV_ROUND_CLOSEST(RTC_PPB, freq); if (offset < RTC_MIN_OFFSET || offset > RTC_MAX_OFFSET) return -ERANGE; @@ -223,29 +223,22 @@ static int xlnx_rtc_set_offset(struct device *dev, long offset) /* Number fractional ticks for given offset */ if (fract_offset) { - if (fract_offset < 0) { - fract_offset = fract_offset + tick_mult; + fract_part = DIV_ROUND_UP(tick_mult, RTC_FR_MAX_TICKS); + fract_data = fract_offset / fract_part; + /* Subtract one from max_tick while adding fract_offset */ + if (fract_offset < 0 && fract_data) { max_tick--; - } - if (fract_offset > (tick_mult / RTC_FR_MAX_TICKS)) { - for (fract_tick = 1; fract_tick < 16; fract_tick++) { - if (fract_offset <= - (fract_tick * - (tick_mult / RTC_FR_MAX_TICKS))) - break; - } + fract_data += RTC_FR_MAX_TICKS; } } /* Zynqmp RTC uses second and fractional tick * counters for compensation */ - calibval = max_tick + RTC_CALIB_DEF; + calibval = max_tick + freq; - if (fract_tick) - calibval |= RTC_FR_EN; - - calibval |= (fract_tick << RTC_FR_DATSHIFT); + if (fract_data) + calibval |= (RTC_FR_EN | (fract_data << RTC_FR_DATSHIFT)); writel(calibval, (xrtcdev->reg_base + RTC_CALIB_WR)); From 2254383176fc9f15ce54eabc849b36c874efd3aa Mon Sep 17 00:00:00 2001 From: Tomas Melin Date: Thu, 22 Jan 2026 13:53:49 +0000 Subject: [PATCH 09/19] rtc: zynqmp: use dynamic max and min offset ranges Maximum and minimum offsets in ppb that can be handled are dependent on the rtc clock frequency and what can fit in the 16-bit register field. Reviewed-by: Harini T Tested-by: Harini T Signed-off-by: Tomas Melin Acked-by: Michal Simek Link: https://patch.msgid.link/20260122-zynqmp-rtc-updates-v4-5-d4edb966b499@vaisala.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-zynqmp.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c index f0f5dc63e254..2ae54804b87a 100644 --- a/drivers/rtc/rtc-zynqmp.c +++ b/drivers/rtc/rtc-zynqmp.c @@ -44,8 +44,6 @@ #define RTC_FR_MASK 0xF0000 #define RTC_FR_MAX_TICKS 16 #define RTC_PPB 1000000000 -#define RTC_MIN_OFFSET -32768000 -#define RTC_MAX_OFFSET 32767000 struct xlnx_rtc_dev { struct rtc_device *rtc; @@ -215,12 +213,13 @@ static int xlnx_rtc_set_offset(struct device *dev, long offset) /* Tick to offset multiplier */ tick_mult = DIV_ROUND_CLOSEST(RTC_PPB, freq); - if (offset < RTC_MIN_OFFSET || offset > RTC_MAX_OFFSET) - return -ERANGE; /* Number ticks for given offset */ max_tick = div_s64_rem(offset, tick_mult, &fract_offset); + if (freq + max_tick > RTC_TICK_MASK || (freq + max_tick < 1)) + return -ERANGE; + /* Number fractional ticks for given offset */ if (fract_offset) { fract_part = DIV_ROUND_UP(tick_mult, RTC_FR_MAX_TICKS); From 96a77ec577d4117f13e2527c9a377d6ba637f5c0 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Sun, 25 Jan 2026 15:42:58 +0200 Subject: [PATCH 10/19] dt-bindings: rtc: cpcap: convert to schema Convert RTC devicetree bindings for the Motorola CPCAP MFD from TXT to YAML format. This patch does not change any functionality; the bindings remain the same. Signed-off-by: Svyatoslav Ryhel Link: https://patch.msgid.link/20260125134302.45958-7-clamor95@gmail.com Signed-off-by: Alexandre Belloni --- .../devicetree/bindings/rtc/cpcap-rtc.txt | 18 ----------- .../bindings/rtc/motorola,cpcap-rtc.yaml | 32 +++++++++++++++++++ 2 files changed, 32 insertions(+), 18 deletions(-) delete mode 100644 Documentation/devicetree/bindings/rtc/cpcap-rtc.txt create mode 100644 Documentation/devicetree/bindings/rtc/motorola,cpcap-rtc.yaml diff --git a/Documentation/devicetree/bindings/rtc/cpcap-rtc.txt b/Documentation/devicetree/bindings/rtc/cpcap-rtc.txt deleted file mode 100644 index 45750ff3112d..000000000000 --- a/Documentation/devicetree/bindings/rtc/cpcap-rtc.txt +++ /dev/null @@ -1,18 +0,0 @@ -Motorola CPCAP PMIC RTC ------------------------ - -This module is part of the CPCAP. For more details about the whole -chip see Documentation/devicetree/bindings/mfd/motorola-cpcap.txt. - -Requires node properties: -- compatible: should contain "motorola,cpcap-rtc" -- interrupts: An interrupt specifier for alarm and 1 Hz irq - -Example: - -&cpcap { - cpcap_rtc: rtc { - compatible = "motorola,cpcap-rtc"; - interrupts = <39 IRQ_TYPE_NONE>, <26 IRQ_TYPE_NONE>; - }; -}; diff --git a/Documentation/devicetree/bindings/rtc/motorola,cpcap-rtc.yaml b/Documentation/devicetree/bindings/rtc/motorola,cpcap-rtc.yaml new file mode 100644 index 000000000000..bf2efd432a23 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/motorola,cpcap-rtc.yaml @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/rtc/motorola,cpcap-rtc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Motorola CPCAP PMIC RTC + +maintainers: + - Svyatoslav Ryhel + +description: + This module is part of the Motorola CPCAP MFD device. For more details + see Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml. The + RTC is represented as a sub-node of the PMIC node on the device tree. + +properties: + compatible: + const: motorola,cpcap-rtc + + interrupts: + items: + - description: alarm interrupt + - description: 1 Hz interrupt + +required: + - compatible + - interrupts + +additionalProperties: false + +... From f3ac75cfacc66f48523e730646dbbc2f19844799 Mon Sep 17 00:00:00 2001 From: Ovidiu Panait Date: Sun, 25 Jan 2026 19:27:03 +0000 Subject: [PATCH 11/19] dt-bindings: rtc: renesas,rz-rtca3: Add RZ/V2N support The Renesas RZ/V2N (r9a09g056) RTC is identical to the RZ/V2H (r9a09g057) variant. Add the compatible string for RZ/V2N and extend the existing RZ/V2H reset configuration to cover both variants. Signed-off-by: Ovidiu Panait Acked-by: Conor Dooley Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20260125192706.27099-4-ovidiu.panait.rb@renesas.com Signed-off-by: Alexandre Belloni --- Documentation/devicetree/bindings/rtc/renesas,rz-rtca3.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/rtc/renesas,rz-rtca3.yaml b/Documentation/devicetree/bindings/rtc/renesas,rz-rtca3.yaml index ccb1638c35b9..988bb9fa8143 100644 --- a/Documentation/devicetree/bindings/rtc/renesas,rz-rtca3.yaml +++ b/Documentation/devicetree/bindings/rtc/renesas,rz-rtca3.yaml @@ -14,6 +14,7 @@ properties: items: - enum: - renesas,r9a08g045-rtca3 # RZ/G3S + - renesas,r9a09g056-rtca3 # RZ/V2N - renesas,r9a09g057-rtca3 # RZ/V2H - const: renesas,rz-rtca3 @@ -82,7 +83,9 @@ allOf: properties: compatible: contains: - const: renesas,r9a09g057-rtca3 + enum: + - renesas,r9a09g056-rtca3 + - renesas,r9a09g057-rtca3 then: properties: resets: From da9934a6583adc40ac0c9cc21e7419617ad985fd Mon Sep 17 00:00:00 2001 From: Binbin Zhou Date: Sat, 17 Jan 2026 10:26:48 +0800 Subject: [PATCH 12/19] dt-bindings: rtc: loongson: Correct Loongson-1C interrupts property The `interrupts` property indicates an RTC alarm interrupt, which is required for RTCs that support the alarm feature, which is not supported by the Loongson-1C RTC. We exclude it for a more accurate description. Changing the `allowed` property is ABI-breaking behavior, but throughout the existing Loongson DTS{i}, the description of the RTC nodes conforms to the modified bingding rules. Thus, the existing Loongson DTS{i} will not be affected. Fixes: 487ef32caebe ("dt-bindings: rtc: Split loongson,ls2x-rtc into SoC-based compatibles") Reviewed-by: Huacai Chen Signed-off-by: Binbin Zhou Acked-by: Conor Dooley Link: https://patch.msgid.link/b6295c907410f6708115cba4df0959ee6629f8a5.1768616276.git.zhoubinbin@loongson.cn Signed-off-by: Alexandre Belloni --- .../devicetree/bindings/rtc/loongson,rtc.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Documentation/devicetree/bindings/rtc/loongson,rtc.yaml b/Documentation/devicetree/bindings/rtc/loongson,rtc.yaml index f89c1f660aee..fac90a18153e 100644 --- a/Documentation/devicetree/bindings/rtc/loongson,rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/loongson,rtc.yaml @@ -42,6 +42,17 @@ required: unevaluatedProperties: false +if: + properties: + compatible: + contains: + enum: + - loongson,ls1c-rtc + +then: + properties: + interrupts: false + examples: - | #include From 5d4899d4859f812290bf2fc458a517781fe6eeca Mon Sep 17 00:00:00 2001 From: Binbin Zhou Date: Sat, 17 Jan 2026 10:26:49 +0800 Subject: [PATCH 13/19] dt-bindings: rtc: loongson: Document Loongson-2K0300 compatible Add "loongson,ls2k0300-rtc" dedicated compatible to represent the RTC interface of the Loongson-2K0300 chip. Its hardware design is similar to that of the Loongson-1B, but it does not support the alarm feature. Reviewed-by: Huacai Chen Signed-off-by: Binbin Zhou Acked-by: Conor Dooley Link: https://patch.msgid.link/0c6a4fd221b5bf05f06cae9bb543a5bf7ea59f57.1768616276.git.zhoubinbin@loongson.cn Signed-off-by: Alexandre Belloni --- Documentation/devicetree/bindings/rtc/loongson,rtc.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/rtc/loongson,rtc.yaml b/Documentation/devicetree/bindings/rtc/loongson,rtc.yaml index fac90a18153e..aac91c79ffdb 100644 --- a/Documentation/devicetree/bindings/rtc/loongson,rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/loongson,rtc.yaml @@ -23,6 +23,7 @@ properties: - loongson,ls1b-rtc - loongson,ls1c-rtc - loongson,ls7a-rtc + - loongson,ls2k0300-rtc - loongson,ls2k1000-rtc - items: - enum: @@ -48,6 +49,7 @@ if: contains: enum: - loongson,ls1c-rtc + - loongson,ls2k0300-rtc then: properties: From 770a54accf80fa6b68df0753eb0c527a4ecf5402 Mon Sep 17 00:00:00 2001 From: Binbin Zhou Date: Sat, 17 Jan 2026 10:26:50 +0800 Subject: [PATCH 14/19] rtc: loongson: Add Loongson-2K0300 support The Loongson-2K0300's rtc hardware design is similar to that of the Loongson-1B, but it does not support the alarm feature. Introduce `LOONGSON_RTC_ALARM_WORKAROUND`, which indicates a chip that does not support the alarm feature, and rewrite the related logic in `loongson_rtc_alarm_setting()`. Reviewed-by: Huacai Chen Signed-off-by: Binbin Zhou Link: https://patch.msgid.link/abff68dda2fe6a6601a9e58b31e278d941297fce.1768616276.git.zhoubinbin@loongson.cn Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-loongson.c | 71 +++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 24 deletions(-) diff --git a/drivers/rtc/rtc-loongson.c b/drivers/rtc/rtc-loongson.c index 2ca7ffd5d7a9..066f0644d1c3 100644 --- a/drivers/rtc/rtc-loongson.c +++ b/drivers/rtc/rtc-loongson.c @@ -66,7 +66,8 @@ * According to the LS1C manual, RTC_CTRL and alarm-related registers are not defined. * Accessing the relevant registers will cause the system to hang. */ -#define LS1C_RTC_CTRL_WORKAROUND BIT(0) +#define LOONGSON_RTC_CTRL_WORKAROUND BIT(0) +#define LOONGSON_RTC_ALARM_WORKAROUND BIT(1) struct loongson_rtc_config { u32 pm_offset; /* Offset of PM domain, for RTC alarm wakeup */ @@ -89,7 +90,7 @@ static const struct loongson_rtc_config ls1b_rtc_config = { static const struct loongson_rtc_config ls1c_rtc_config = { .pm_offset = 0, - .flags = LS1C_RTC_CTRL_WORKAROUND, + .flags = LOONGSON_RTC_CTRL_WORKAROUND | LOONGSON_RTC_ALARM_WORKAROUND, }; static const struct loongson_rtc_config generic_rtc_config = { @@ -97,6 +98,11 @@ static const struct loongson_rtc_config generic_rtc_config = { .flags = 0, }; +static const struct loongson_rtc_config ls2k0300_rtc_config = { + .pm_offset = 0x0, + .flags = LOONGSON_RTC_ALARM_WORKAROUND, +}; + static const struct loongson_rtc_config ls2k1000_rtc_config = { .pm_offset = 0x800, .flags = 0, @@ -153,7 +159,7 @@ static int loongson_rtc_set_enabled(struct device *dev) { struct loongson_rtc_priv *priv = dev_get_drvdata(dev); - if (priv->config->flags & LS1C_RTC_CTRL_WORKAROUND) + if (priv->config->flags & LOONGSON_RTC_CTRL_WORKAROUND) return 0; /* Enable RTC TOY counters and crystal */ @@ -167,7 +173,7 @@ static bool loongson_rtc_get_enabled(struct device *dev) u32 ctrl_data; struct loongson_rtc_priv *priv = dev_get_drvdata(dev); - if (priv->config->flags & LS1C_RTC_CTRL_WORKAROUND) + if (priv->config->flags & LOONGSON_RTC_CTRL_WORKAROUND) return true; ret = regmap_read(priv->regmap, RTC_CTRL_REG, &ctrl_data); @@ -299,9 +305,41 @@ static const struct rtc_class_ops loongson_rtc_ops = { .alarm_irq_enable = loongson_rtc_alarm_irq_enable, }; +static int loongson_rtc_alarm_setting(struct platform_device *pdev, void __iomem *regs) +{ + int ret = 0, alarm_irq; + struct device *dev = &pdev->dev; + struct loongson_rtc_priv *priv = dev_get_drvdata(dev); + + if (priv->config->flags & LOONGSON_RTC_ALARM_WORKAROUND) { + /* Loongson-1C/Loongson-2K0300 RTC does not support alarm */ + clear_bit(RTC_FEATURE_ALARM, priv->rtcdev->features); + return 0; + } + + /* Get RTC alarm irq */ + alarm_irq = platform_get_irq(pdev, 0); + if (alarm_irq < 0) + return alarm_irq; + + ret = devm_request_irq(dev, alarm_irq, loongson_rtc_isr, 0, "loongson-alarm", + priv); + if (ret < 0) + return ret; + + priv->pm_base = regs - priv->config->pm_offset; + device_init_wakeup(dev, true); + + if (has_acpi_companion(dev)) + acpi_install_fixed_event_handler(ACPI_EVENT_RTC, + loongson_rtc_handler, priv); + + return ret; +} + static int loongson_rtc_probe(struct platform_device *pdev) { - int ret, alarm_irq; + int ret; void __iomem *regs; struct loongson_rtc_priv *priv; struct device *dev = &pdev->dev; @@ -330,25 +368,9 @@ static int loongson_rtc_probe(struct platform_device *pdev) return dev_err_probe(dev, PTR_ERR(priv->rtcdev), "devm_rtc_allocate_device failed\n"); - /* Get RTC alarm irq */ - alarm_irq = platform_get_irq(pdev, 0); - if (alarm_irq > 0) { - ret = devm_request_irq(dev, alarm_irq, loongson_rtc_isr, - 0, "loongson-alarm", priv); - if (ret < 0) - return dev_err_probe(dev, ret, "Unable to request irq %d\n", - alarm_irq); - - priv->pm_base = regs - priv->config->pm_offset; - device_init_wakeup(dev, true); - - if (has_acpi_companion(dev)) - acpi_install_fixed_event_handler(ACPI_EVENT_RTC, - loongson_rtc_handler, priv); - } else { - /* Loongson-1C RTC does not support alarm */ - clear_bit(RTC_FEATURE_ALARM, priv->rtcdev->features); - } + ret = loongson_rtc_alarm_setting(pdev, regs); + if (ret) + return ret; /* Loongson RTC does not support UIE */ clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, priv->rtcdev->features); @@ -379,6 +401,7 @@ static const struct of_device_id loongson_rtc_of_match[] = { { .compatible = "loongson,ls1b-rtc", .data = &ls1b_rtc_config }, { .compatible = "loongson,ls1c-rtc", .data = &ls1c_rtc_config }, { .compatible = "loongson,ls7a-rtc", .data = &generic_rtc_config }, + { .compatible = "loongson,ls2k0300-rtc", .data = &ls2k0300_rtc_config }, { .compatible = "loongson,ls2k1000-rtc", .data = &ls2k1000_rtc_config }, { /* sentinel */ } }; From 8eeb611b3d16241559bbf81ae5d938368c87818c Mon Sep 17 00:00:00 2001 From: Lorenz Brun Date: Tue, 23 Dec 2025 13:57:26 +0100 Subject: [PATCH 15/19] rtc: s35390a: implement nvmem support This RTC has one "free" register which can be used to store arbitrary data. Expose it as a nvmem resource in Linux. Signed-off-by: Lorenz Brun Link: https://patch.msgid.link/20251223125728.346073-1-lorenz@monogon.tech Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-s35390a.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index 07bd983b5692..a4678d7c6cf6 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c @@ -18,6 +18,7 @@ #define S35390A_CMD_TIME1 2 #define S35390A_CMD_TIME2 3 #define S35390A_CMD_INT2_REG1 5 +#define S35390A_CMD_FREE_REG 7 #define S35390A_BYTE_YEAR 0 #define S35390A_BYTE_MONTH 1 @@ -416,6 +417,23 @@ static const struct rtc_class_ops s35390a_rtc_ops = { .ioctl = s35390a_rtc_ioctl, }; +static int s35390a_nvmem_read(void *priv, unsigned int offset, void *val, + size_t bytes) +{ + struct s35390a *s35390a = priv; + + /* The offset is ignored because the NVMEM region is only 1 byte */ + return s35390a_get_reg(s35390a, S35390A_CMD_FREE_REG, val, bytes); +} + +static int s35390a_nvmem_write(void *priv, unsigned int offset, void *val, + size_t bytes) +{ + struct s35390a *s35390a = priv; + + return s35390a_set_reg(s35390a, S35390A_CMD_FREE_REG, val, bytes); +} + static int s35390a_probe(struct i2c_client *client) { int err, err_read; @@ -424,6 +442,15 @@ static int s35390a_probe(struct i2c_client *client) struct rtc_device *rtc; u8 buf, status1; struct device *dev = &client->dev; + struct nvmem_config nvmem_cfg = { + .name = "s35390a_nvram", + .type = NVMEM_TYPE_BATTERY_BACKED, + .word_size = 1, + .stride = 1, + .size = 1, + .reg_read = s35390a_nvmem_read, + .reg_write = s35390a_nvmem_write, + }; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) return -ENODEV; @@ -490,6 +517,11 @@ static int s35390a_probe(struct i2c_client *client) if (status1 & S35390A_FLAG_INT2) rtc_update_irq(rtc, 1, RTC_AF); + nvmem_cfg.priv = s35390a; + err = devm_rtc_nvmem_register(rtc, &nvmem_cfg); + if (err) + return err; + return devm_rtc_register_device(rtc); } From 81be22cd4ace020045cc6d31255c6f7c071eb7c0 Mon Sep 17 00:00:00 2001 From: "Anthony Pighin (Nokia)" Date: Tue, 25 Nov 2025 17:35:19 +0000 Subject: [PATCH 16/19] rtc: interface: Alarm race handling should not discard preceding error Commit 795cda8338ea ("rtc: interface: Fix long-standing race when setting alarm") should not discard any errors from the preceding validations. Prior to that commit, if the alarm feature was disabled, or the set_alarm failed, a meaningful error code would be returned to the caller for further action. After, more often than not, the __rtc_read_time will cause a success return code instead, misleading the caller. An example of this is when timer_enqueue is called for a rtc-abx080x device. Since that driver does not clear the alarm feature bit, but instead relies on the set_alarm operation to return invalid, the discard of the return code causes very different behaviour; i.e. hwclock: select() to /dev/rtc0 to wait for clock tick timed out Fixes: 795cda8338ea ("rtc: interface: Fix long-standing race when setting alarm") Signed-off-by: Anthony Pighin (Nokia) Reviewed-by: Esben Haabendal Tested-by: Nick Bowler Link: https://patch.msgid.link/BN0PR08MB6951415A751F236375A2945683D1A@BN0PR08MB6951.namprd08.prod.outlook.com Signed-off-by: Alexandre Belloni --- drivers/rtc/interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index b8b298efd9a9..1906f4884a83 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -457,7 +457,7 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) * are in, we can return -ETIME to signal that the timer has already * expired, which is true in both cases. */ - if ((scheduled - now) <= 1) { + if (!err && (scheduled - now) <= 1) { err = __rtc_read_time(rtc, &tm); if (err) return err; From d1f64cdfafdbd3fe220a59b85f13e125f49ce73e Mon Sep 17 00:00:00 2001 From: Rouven Czerwinski Date: Mon, 26 Jan 2026 11:11:26 +0100 Subject: [PATCH 17/19] rtc: optee: simplify OP-TEE context match Simplify the TEE implementor ID match by returning the boolean expression directly instead of going through an if/else. Signed-off-by: Rouven Czerwinski Link: https://patch.msgid.link/20260126-optee-simplify-context-match-v1-3-d4104e526cb6@linaro.org Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-optee.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/rtc/rtc-optee.c b/drivers/rtc/rtc-optee.c index 184c6d142801..2f18be3de684 100644 --- a/drivers/rtc/rtc-optee.c +++ b/drivers/rtc/rtc-optee.c @@ -541,10 +541,7 @@ static int optee_rtc_read_info(struct device *dev, struct rtc_device *rtc, static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data) { - if (ver->impl_id == TEE_IMPL_ID_OPTEE) - return 1; - else - return 0; + return (ver->impl_id == TEE_IMPL_ID_OPTEE); } static int optee_rtc_probe(struct device *dev) From 76e8919aef2dca25a07a0d6480e486ebe5e9ea79 Mon Sep 17 00:00:00 2001 From: Jinjie Ruan Date: Thu, 22 Jan 2026 17:00:31 +0800 Subject: [PATCH 18/19] rtc: class: Remove duplicate check for alarm In __devm_rtc_register_device(), the callee rtc_initialize_alarm() will check the alarm, there is no need to check in advance, so remove it. Signed-off-by: Jinjie Ruan Link: https://patch.msgid.link/20260122090031.3871746-1-ruanjinjie@huawei.com Signed-off-by: Alexandre Belloni --- drivers/rtc/class.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index b1a2be1f9e3b..84885ba6135c 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -410,7 +410,7 @@ int __devm_rtc_register_device(struct module *owner, struct rtc_device *rtc) /* Check to see if there is an ALARM already set in hw */ err = __rtc_read_alarm(rtc, &alrm); - if (!err && !rtc_valid_tm(&alrm.time)) + if (!err) rtc_initialize_alarm(rtc, &alrm); rtc_dev_prepare(rtc); From 969c3cca0f3b88682cd833cee4cf01b0915629a3 Mon Sep 17 00:00:00 2001 From: Andreas Gabriel-Platschek Date: Mon, 9 Feb 2026 06:34:39 +0100 Subject: [PATCH 19/19] rtc: ds1390: fix number of bytes read from RTC The spi_write_then_read() reads 8 bytes starting from DS1390_REG_SECONDS (== 0x01), so the last byte read would already be part of the alarm (Tenths and Hundredths of Seconds) feature. However 7 bytes are engouh -- seconds (0x01), minutes (0x02), hours (0x03), day (0x04), date (0x05), month/century (0x06) and year (0x07). Signed-off-by: Andreas Gabriel-Platschek Link: https://patch.msgid.link/20260209053439.313825-1-andi.platschek@gmail.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1390.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-ds1390.c b/drivers/rtc/rtc-ds1390.c index f46428ca77cc..f7afd6bdeb4a 100644 --- a/drivers/rtc/rtc-ds1390.c +++ b/drivers/rtc/rtc-ds1390.c @@ -134,7 +134,7 @@ static int ds1390_read_time(struct device *dev, struct rtc_time *dt) chip->txrx_buf[0] = DS1390_REG_SECONDS; /* do the i/o */ - status = spi_write_then_read(spi, chip->txrx_buf, 1, chip->txrx_buf, 8); + status = spi_write_then_read(spi, chip->txrx_buf, 1, chip->txrx_buf, 7); if (status != 0) return status;