From 06ce29264f1d46f00fdb46b0c2d9fb060ce72368 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Wed, 3 Sep 2025 15:11:27 -0400 Subject: dt-bindings: rtc: pcf85063: remove quartz-load-femtofarads restriction for nxp,pcf85063 Original TXT binding doc have not limitition about quartz-load-femtofarads, which only allow 7000 for nxp,pcf85063. So remove it to fix below CHECK_DTBS warnings: arch/arm/boot/dts/nxp/imx/imx6dl-skov-revc-lt2.dtb: rtc@51 (nxp,pcf85063): quartz-load-femtofarads:0: 7000 was expected from schema $id: http://devicetree.org/schemas/rtc/nxp,pcf85063.yaml# Signed-off-by: Frank Li Acked-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20250903191128.439164-1-Frank.Li@nxp.com Signed-off-by: Alexandre Belloni --- Documentation/devicetree/bindings/rtc/nxp,pcf85063.yaml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/Documentation/devicetree/bindings/rtc/nxp,pcf85063.yaml b/Documentation/devicetree/bindings/rtc/nxp,pcf85063.yaml index 1e6277e524c2..f7013cd8fc20 100644 --- a/Documentation/devicetree/bindings/rtc/nxp,pcf85063.yaml +++ b/Documentation/devicetree/bindings/rtc/nxp,pcf85063.yaml @@ -62,16 +62,6 @@ allOf: then: properties: quartz-load-femtofarads: false - - if: - properties: - compatible: - contains: - enum: - - nxp,pcf85063 - then: - properties: - quartz-load-femtofarads: - const: 7000 - if: properties: compatible: -- cgit v1.2.3 From 0dbb84b5c447ddf2681ed0248a6fb7c9fc3fdb6c Mon Sep 17 00:00:00 2001 From: Frank Li Date: Wed, 27 Aug 2025 15:33:55 -0400 Subject: dt-bindings: rtc: trivial-rtc: add dallas,m41t00 Add compatible string dallas,m41t00 for dallas m41t00 RTC. Signed-off-by: Frank Li Acked-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20250827193356.78368-1-Frank.Li@nxp.com Signed-off-by: Alexandre Belloni --- Documentation/devicetree/bindings/rtc/trivial-rtc.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml index 5e0c7cd25cc6..587b7cd5806c 100644 --- a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml @@ -38,6 +38,8 @@ properties: - dallas,ds1672 # Extremely Accurate I²C RTC with Integrated Crystal and SRAM - dallas,ds3232 + # Dallas m41t00 Real-time Clock + - dallas,m41t00 # SD2405AL Real-Time Clock - dfrobot,sd2405al # EM Microelectronic EM3027 RTC -- cgit v1.2.3 From d06b24f805b5c86c83f4182f32ed1cdd7c690171 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sat, 30 Aug 2025 15:00:25 +0200 Subject: rtc: s3c: Drop unused defines Drop defines for S3C2416 and S3C2443 SoCs which are not used anywhere. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250830130024.142815-4-krzysztof.kozlowski@linaro.org Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-s3c.h | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/drivers/rtc/rtc-s3c.h b/drivers/rtc/rtc-s3c.h index 3552914aa611..44e9d6c9428f 100644 --- a/drivers/rtc/rtc-s3c.h +++ b/drivers/rtc/rtc-s3c.h @@ -24,22 +24,6 @@ #define S3C2410_TICNT S3C2410_RTCREG(0x44) #define S3C2410_TICNT_ENABLE (1 << 7) -/* S3C2443: tick count is 15 bit wide - * TICNT[6:0] contains upper 7 bits - * TICNT1[7:0] contains lower 8 bits - */ -#define S3C2443_TICNT_PART(x) ((x & 0x7f00) >> 8) -#define S3C2443_TICNT1 S3C2410_RTCREG(0x4C) -#define S3C2443_TICNT1_PART(x) (x & 0xff) - -/* S3C2416: tick count is 32 bit wide - * TICNT[6:0] contains bits [14:8] - * TICNT1[7:0] contains lower 8 bits - * TICNT2[16:0] contains upper 17 bits - */ -#define S3C2416_TICNT2 S3C2410_RTCREG(0x48) -#define S3C2416_TICNT2_PART(x) ((x & 0xffff8000) >> 15) - #define S3C2410_RTCALM S3C2410_RTCREG(0x50) #define S3C2410_RTCALM_ALMEN (1 << 6) #define S3C2410_RTCALM_YEAREN (1 << 5) -- cgit v1.2.3 From 9693342805748bcf0c02b16ac0a0aa852688dea9 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sat, 30 Aug 2025 15:00:26 +0200 Subject: rtc: s3c: Drop support for S3C2410 Samsung S3C24xx family of SoCs was removed the Linux kernel in the commit 61b7f8920b17 ("ARM: s3c: remove all s3c24xx support"), in January 2023. There are no in-kernel users of remaining S3C24xx compatibles. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250830130024.142815-5-krzysztof.kozlowski@linaro.org Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-s3c.c | 49 ++----------------------------------------------- drivers/rtc/rtc-s3c.h | 3 --- 2 files changed, 2 insertions(+), 50 deletions(-) diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 79b2a16f15ad..291c0ccb0acd 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -331,7 +331,7 @@ static const struct rtc_class_ops s3c_rtcops = { .alarm_irq_enable = s3c_rtc_setaie, }; -static void s3c24xx_rtc_enable(struct s3c_rtc *info) +static void s3c6410_rtc_enable(struct s3c_rtc *info) { unsigned int con, tmp; @@ -361,19 +361,6 @@ static void s3c24xx_rtc_enable(struct s3c_rtc *info) } } -static void s3c24xx_rtc_disable(struct s3c_rtc *info) -{ - unsigned int con; - - con = readw(info->base + S3C2410_RTCCON); - con &= ~S3C2410_RTCCON_RTCEN; - writew(con, info->base + S3C2410_RTCCON); - - con = readb(info->base + S3C2410_TICNT); - con &= ~S3C2410_TICNT_ENABLE; - writeb(con, info->base + S3C2410_TICNT); -} - static void s3c6410_rtc_disable(struct s3c_rtc *info) { unsigned int con; @@ -538,53 +525,21 @@ static int s3c_rtc_resume(struct device *dev) #endif static SIMPLE_DEV_PM_OPS(s3c_rtc_pm_ops, s3c_rtc_suspend, s3c_rtc_resume); -static void s3c24xx_rtc_irq(struct s3c_rtc *info, int mask) -{ - rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF); -} - static void s3c6410_rtc_irq(struct s3c_rtc *info, int mask) { rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF); writeb(mask, info->base + S3C2410_INTP); } -static const struct s3c_rtc_data s3c2410_rtc_data = { - .irq_handler = s3c24xx_rtc_irq, - .enable = s3c24xx_rtc_enable, - .disable = s3c24xx_rtc_disable, -}; - -static const struct s3c_rtc_data s3c2416_rtc_data = { - .irq_handler = s3c24xx_rtc_irq, - .enable = s3c24xx_rtc_enable, - .disable = s3c24xx_rtc_disable, -}; - -static const struct s3c_rtc_data s3c2443_rtc_data = { - .irq_handler = s3c24xx_rtc_irq, - .enable = s3c24xx_rtc_enable, - .disable = s3c24xx_rtc_disable, -}; - static const struct s3c_rtc_data s3c6410_rtc_data = { .needs_src_clk = true, .irq_handler = s3c6410_rtc_irq, - .enable = s3c24xx_rtc_enable, + .enable = s3c6410_rtc_enable, .disable = s3c6410_rtc_disable, }; static const __maybe_unused struct of_device_id s3c_rtc_dt_match[] = { { - .compatible = "samsung,s3c2410-rtc", - .data = &s3c2410_rtc_data, - }, { - .compatible = "samsung,s3c2416-rtc", - .data = &s3c2416_rtc_data, - }, { - .compatible = "samsung,s3c2443-rtc", - .data = &s3c2443_rtc_data, - }, { .compatible = "samsung,s3c6410-rtc", .data = &s3c6410_rtc_data, }, { diff --git a/drivers/rtc/rtc-s3c.h b/drivers/rtc/rtc-s3c.h index 44e9d6c9428f..11d7a1255ce4 100644 --- a/drivers/rtc/rtc-s3c.h +++ b/drivers/rtc/rtc-s3c.h @@ -21,9 +21,6 @@ #define S3C2443_RTCCON_TICSEL (1 << 4) #define S3C64XX_RTCCON_TICEN (1 << 8) -#define S3C2410_TICNT S3C2410_RTCREG(0x44) -#define S3C2410_TICNT_ENABLE (1 << 7) - #define S3C2410_RTCALM S3C2410_RTCREG(0x50) #define S3C2410_RTCALM_ALMEN (1 << 6) #define S3C2410_RTCALM_YEAREN (1 << 5) -- cgit v1.2.3 From bf7ab18cd741ae82ee8d8e356f73ce3003f6b2fc Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sat, 30 Aug 2025 15:00:27 +0200 Subject: dt-bindings: rtc: s3c: Drop S3C2410 Samsung S3C24xx family of SoCs was removed the Linux kernel in the commit 61b7f8920b17 ("ARM: s3c: remove all s3c24xx support"), in January 2023. There are no in-kernel users of remaining S3C24xx compatibles. Signed-off-by: Krzysztof Kozlowski Acked-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20250830130024.142815-6-krzysztof.kozlowski@linaro.org Signed-off-by: Alexandre Belloni --- Documentation/devicetree/bindings/rtc/s3c-rtc.yaml | 40 ++-------------------- 1 file changed, 3 insertions(+), 37 deletions(-) diff --git a/Documentation/devicetree/bindings/rtc/s3c-rtc.yaml b/Documentation/devicetree/bindings/rtc/s3c-rtc.yaml index bf4e11d6dffb..338874e7ed7f 100644 --- a/Documentation/devicetree/bindings/rtc/s3c-rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/s3c-rtc.yaml @@ -13,9 +13,6 @@ properties: compatible: oneOf: - enum: - - samsung,s3c2410-rtc - - samsung,s3c2416-rtc - - samsung,s3c2443-rtc - samsung,s3c6410-rtc - items: - enum: @@ -29,19 +26,12 @@ properties: maxItems: 1 clocks: - description: - Must contain a list of phandle and clock specifier for the rtc - clock and in the case of a s3c6410 compatible controller, also - a source clock. - minItems: 1 maxItems: 2 clock-names: - description: - Must contain "rtc" and for a s3c6410 compatible controller - also "rtc_src". - minItems: 1 - maxItems: 2 + items: + - const: rtc + - const: rtc_src interrupts: description: @@ -54,30 +44,6 @@ properties: allOf: - $ref: rtc.yaml# - - if: - properties: - compatible: - contains: - enum: - - samsung,s3c6410-rtc - - samsung,exynos3250-rtc - then: - properties: - clocks: - minItems: 2 - maxItems: 2 - clock-names: - items: - - const: rtc - - const: rtc_src - else: - properties: - clocks: - minItems: 1 - maxItems: 1 - clock-names: - items: - - const: rtc unevaluatedProperties: false -- cgit v1.2.3 From a6f1a4f05970664004a9370459c6799c1b2f2dcf Mon Sep 17 00:00:00 2001 From: Josua Mayer Date: Mon, 25 Aug 2025 19:54:09 +0200 Subject: rtc: pcf2127: clear minute/second interrupt PCF2127 can generate interrupt every full second or minute configured from control and status register 1, bits MI (1) and SI (0). On interrupt control register 2 bit MSF (7) is set and must be cleared to continue normal operation. While the driver never enables this interrupt on its own, users or firmware may do so - e.g. as an easy way to test the interrupt. Add preprocessor definition for MSF bit and include it in the irq bitmask to ensure minute and second interrupts are cleared when fired. This fixes an issue where the rtc enters a test mode and becomes unresponsive after a second interrupt has fired and is not cleared in time. In this state register writes to control registers have no effect and the interrupt line is kept asserted [1]: [1] userspace commands to put rtc into unresponsive state: $ i2cget -f -y 2 0x51 0x00 0x04 $ i2cset -f -y 2 0x51 0x00 0x05 # set bit 0 SI $ i2cget -f -y 2 0x51 0x00 0x84 # bit 8 EXT_TEST set $ i2cset -f -y 2 0x51 0x00 0x05 # try overwrite control register $ i2cget -f -y 2 0x51 0x00 0x84 # no change Signed-off-by: Josua Mayer Reviewed-by: Bruno Thomsen Link: https://lore.kernel.org/r/20250825-rtc-irq-v1-1-0133319406a7@solid-run.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pcf2127.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index 2e1ac0c42e93..3ba1de30e89c 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c @@ -42,6 +42,7 @@ #define PCF2127_BIT_CTRL2_AF BIT(4) #define PCF2127_BIT_CTRL2_TSF2 BIT(5) #define PCF2127_BIT_CTRL2_WDTF BIT(6) +#define PCF2127_BIT_CTRL2_MSF BIT(7) /* Control register 3 */ #define PCF2127_REG_CTRL3 0x02 #define PCF2127_BIT_CTRL3_BLIE BIT(0) @@ -96,7 +97,8 @@ #define PCF2127_CTRL2_IRQ_MASK ( \ PCF2127_BIT_CTRL2_AF | \ PCF2127_BIT_CTRL2_WDTF | \ - PCF2127_BIT_CTRL2_TSF2) + PCF2127_BIT_CTRL2_TSF2 | \ + PCF2127_BIT_CTRL2_MSF) #define PCF2127_MAX_TS_SUPPORTED 4 -- cgit v1.2.3 From 18a3510bc87d48deec0abb72bc9e0b2f8393ff0b Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 14 Jul 2025 08:08:45 +0200 Subject: rtc: efi: Remove wakeup functionality The EFI rtc driver is used by non-x86 architectures only, and exposes the get/set wakeup time functionality provided by the underlying platform. This is usually broken on most platforms, and not widely used to begin with [if at all], so let's just remove it. Signed-off-by: Ard Biesheuvel Tested-by: Feng Tang Link: https://lore.kernel.org/r/20250714060843.4029171-6-ardb+git@google.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-efi.c | 76 ++------------------------------------------------- 1 file changed, 2 insertions(+), 74 deletions(-) diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c index fa8bf82df948..b4f44999ef0f 100644 --- a/drivers/rtc/rtc-efi.c +++ b/drivers/rtc/rtc-efi.c @@ -112,48 +112,6 @@ convert_from_efi_time(efi_time_t *eft, struct rtc_time *wtime) return true; } -static int efi_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) -{ - efi_time_t eft; - efi_status_t status; - - /* - * As of EFI v1.10, this call always returns an unsupported status - */ - status = efi.get_wakeup_time((efi_bool_t *)&wkalrm->enabled, - (efi_bool_t *)&wkalrm->pending, &eft); - - if (status != EFI_SUCCESS) - return -EINVAL; - - if (!convert_from_efi_time(&eft, &wkalrm->time)) - return -EIO; - - return rtc_valid_tm(&wkalrm->time); -} - -static int efi_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) -{ - efi_time_t eft; - efi_status_t status; - - convert_to_efi_time(&wkalrm->time, &eft); - - /* - * XXX Fixme: - * As of EFI 0.92 with the firmware I have on my - * machine this call does not seem to work quite - * right - * - * As of v1.10, this call always returns an unsupported status - */ - status = efi.set_wakeup_time((efi_bool_t)wkalrm->enabled, &eft); - - dev_warn(dev, "write status is %d\n", (int)status); - - return status == EFI_SUCCESS ? 0 : -EINVAL; -} - static int efi_read_time(struct device *dev, struct rtc_time *tm) { efi_status_t status; @@ -188,17 +146,13 @@ static int efi_set_time(struct device *dev, struct rtc_time *tm) static int efi_procfs(struct device *dev, struct seq_file *seq) { - efi_time_t eft, alm; + efi_time_t eft; efi_time_cap_t cap; - efi_bool_t enabled, pending; - struct rtc_device *rtc = dev_get_drvdata(dev); memset(&eft, 0, sizeof(eft)); - memset(&alm, 0, sizeof(alm)); memset(&cap, 0, sizeof(cap)); efi.get_time(&eft, &cap); - efi.get_wakeup_time(&enabled, &pending, &alm); seq_printf(seq, "Time\t\t: %u:%u:%u.%09u\n" @@ -214,26 +168,6 @@ static int efi_procfs(struct device *dev, struct seq_file *seq) /* XXX fixme: convert to string? */ seq_printf(seq, "Timezone\t: %u\n", eft.timezone); - if (test_bit(RTC_FEATURE_ALARM, rtc->features)) { - seq_printf(seq, - "Alarm Time\t: %u:%u:%u.%09u\n" - "Alarm Date\t: %u-%u-%u\n" - "Alarm Daylight\t: %u\n" - "Enabled\t\t: %s\n" - "Pending\t\t: %s\n", - alm.hour, alm.minute, alm.second, alm.nanosecond, - alm.year, alm.month, alm.day, - alm.daylight, - enabled == 1 ? "yes" : "no", - pending == 1 ? "yes" : "no"); - - if (alm.timezone == EFI_UNSPECIFIED_TIMEZONE) - seq_puts(seq, "Timezone\t: unspecified\n"); - else - /* XXX fixme: convert to string? */ - seq_printf(seq, "Timezone\t: %u\n", alm.timezone); - } - /* * now prints the capabilities */ @@ -249,8 +183,6 @@ static int efi_procfs(struct device *dev, struct seq_file *seq) static const struct rtc_class_ops efi_rtc_ops = { .read_time = efi_read_time, .set_time = efi_set_time, - .read_alarm = efi_read_alarm, - .set_alarm = efi_set_alarm, .proc = efi_procfs, }; @@ -271,11 +203,7 @@ static int __init efi_rtc_probe(struct platform_device *dev) platform_set_drvdata(dev, rtc); rtc->ops = &efi_rtc_ops; - clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features); - if (efi_rt_services_supported(EFI_RT_SUPPORTED_WAKEUP_SERVICES)) - set_bit(RTC_FEATURE_ALARM_WAKEUP_ONLY, rtc->features); - else - clear_bit(RTC_FEATURE_ALARM, rtc->features); + clear_bit(RTC_FEATURE_ALARM, rtc->features); device_init_wakeup(&dev->dev, true); -- cgit v1.2.3 From 84454c4e504b1fe86f77a898190d63b4193ca25d Mon Sep 17 00:00:00 2001 From: "Rob Herring (Arm)" Date: Thu, 7 Aug 2025 16:44:13 -0500 Subject: dt-bindings: rtc: Drop isil,isl12057.txt The "isil,isl12057" compatible is already supported by rtc-ds1307.yaml, so remove the old text binding. Signed-off-by: Rob Herring (Arm) Acked-by: Conor Dooley Link: https://lore.kernel.org/r/20250807214414.4172910-1-robh@kernel.org Signed-off-by: Alexandre Belloni --- .../devicetree/bindings/rtc/isil,isl12057.txt | 74 ---------------------- 1 file changed, 74 deletions(-) delete mode 100644 Documentation/devicetree/bindings/rtc/isil,isl12057.txt diff --git a/Documentation/devicetree/bindings/rtc/isil,isl12057.txt b/Documentation/devicetree/bindings/rtc/isil,isl12057.txt deleted file mode 100644 index ff7c43555199..000000000000 --- a/Documentation/devicetree/bindings/rtc/isil,isl12057.txt +++ /dev/null @@ -1,74 +0,0 @@ -Intersil ISL12057 I2C RTC/Alarm chip - -ISL12057 is a trivial I2C device (it has simple device tree bindings, -consisting of a compatible field, an address and possibly an interrupt -line). - -Nonetheless, it also supports an option boolean property -("wakeup-source") to handle the specific use-case found -on at least three in-tree users of the chip (NETGEAR ReadyNAS 102, 104 -and 2120 ARM-based NAS); On those devices, the IRQ#2 pin of the chip -(associated with the alarm supported by the driver) is not connected -to the SoC but to a PMIC. It allows the device to be powered up when -RTC alarm rings. In order to mark the device has a wakeup source and -get access to the 'wakealarm' sysfs entry, this specific property can -be set when the IRQ#2 pin of the chip is not connected to the SoC but -can wake up the device. - -Required properties supported by the device: - - - "compatible": must be "isil,isl12057" - - "reg": I2C bus address of the device - -Optional properties: - - - "wakeup-source": mark the chip as a wakeup source, independently of - the availability of an IRQ line connected to the SoC. - - -Example isl12057 node without IRQ#2 pin connected (no alarm support): - - isl12057: isl12057@68 { - compatible = "isil,isl12057"; - reg = <0x68>; - }; - - -Example isl12057 node with IRQ#2 pin connected to main SoC via MPP6 (note -that the pinctrl-related properties below are given for completeness and -may not be required or may be different depending on your system or -SoC, and the main function of the MPP used as IRQ line, i.e. -"interrupt-parent" and "interrupts" are usually sufficient): - - pinctrl { - ... - - rtc_alarm_pin: rtc_alarm_pin { - marvell,pins = "mpp6"; - marvell,function = "gpio"; - }; - - ... - - }; - - ... - - isl12057: isl12057@68 { - compatible = "isil,isl12057"; - reg = <0x68>; - pinctrl-0 = <&rtc_alarm_pin>; - pinctrl-names = "default"; - interrupt-parent = <&gpio0>; - interrupts = <6 IRQ_TYPE_EDGE_FALLING>; - }; - - -Example isl12057 node without IRQ#2 pin connected to the SoC but to a -PMIC, allowing the device to be started based on configured alarm: - - isl12057: isl12057@68 { - compatible = "isil,isl12057"; - reg = <0x68>; - wakeup-source; - }; -- cgit v1.2.3 From f0ea5f6e75f6b8bbe5d393720bfaf804d04e383f Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 13 Aug 2025 18:15:03 +0200 Subject: rtc: remove unneeded 'fast_io' parameter in regmap_config When using MMIO with regmap, fast_io is implied. No need to set it again. Signed-off-by: Wolfram Sang Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20250813161517.4746-18-wsa+renesas@sang-engineering.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-meson.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/rtc/rtc-meson.c b/drivers/rtc/rtc-meson.c index 47e9ebf58ffc..21eceb9e2e13 100644 --- a/drivers/rtc/rtc-meson.c +++ b/drivers/rtc/rtc-meson.c @@ -72,7 +72,6 @@ static const struct regmap_config meson_rtc_peripheral_regmap_config = { .val_bits = 32, .reg_stride = 4, .max_register = RTC_REG4, - .fast_io = true, }; /* RTC front-end serialiser controls */ -- cgit v1.2.3 From f2e44e5fb2de9a464b4fc94d8de071da7ebfda15 Mon Sep 17 00:00:00 2001 From: "Rob Herring (Arm)" Date: Thu, 21 Aug 2025 16:57:01 -0500 Subject: dt-bindings: rtc: Fix Xicor X1205 vendor prefix The vendor for the Xircom X1205 RTC is not Xircom, but Xicor which was acquired by Intersil. Signed-off-by: Rob Herring (Arm) Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20250821215703.869628-1-robh@kernel.org Signed-off-by: Alexandre Belloni --- Documentation/devicetree/bindings/rtc/trivial-rtc.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml index 587b7cd5806c..b47822370d6f 100644 --- a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml @@ -85,8 +85,8 @@ properties: - via,vt8500-rtc # I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC - whwave,sd3078 - # Xircom X1205 I2C RTC - - xircom,x1205 + # Xicor/Intersil X1205 I2C RTC + - xicor,x1205 reg: maxItems: 1 -- cgit v1.2.3 From 606d19ee37de3a72f1b6e95a4ea544f6f20dbb46 Mon Sep 17 00:00:00 2001 From: "Rob Herring (Arm)" Date: Thu, 21 Aug 2025 16:57:02 -0500 Subject: rtc: x1205: Fix Xicor X1205 vendor prefix The vendor for the X1205 RTC is not Xircom, but Xicor which was acquired by Intersil. Since the I2C subsystem drops the vendor prefix for driver matching, the vendor prefix hasn't mattered. Fixes: 6875404fdb44 ("rtc: x1205: Add DT probing support") Signed-off-by: Rob Herring (Arm) Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20250821215703.869628-2-robh@kernel.org Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-x1205.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index 4bcd7ca32f27..b8a0fccef14e 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c @@ -669,7 +669,7 @@ static const struct i2c_device_id x1205_id[] = { MODULE_DEVICE_TABLE(i2c, x1205_id); static const struct of_device_id x1205_dt_ids[] = { - { .compatible = "xircom,x1205", }, + { .compatible = "xicor,x1205", }, {}, }; MODULE_DEVICE_TABLE(of, x1205_dt_ids); -- cgit v1.2.3 From a531350d2fe58f7fc4516e555f22391dee94efd9 Mon Sep 17 00:00:00 2001 From: Clément Le Goffic Date: Tue, 15 Jul 2025 16:07:13 +0200 Subject: rtc: optee: fix memory leak on driver removal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix a memory leak in case of driver removal. Free the shared memory used for arguments exchanges between kernel and OP-TEE RTC PTA. Fixes: 81c2f059ab90 ("rtc: optee: add RTC driver for OP-TEE RTC PTA") Signed-off-by: Clément Le Goffic Link: https://lore.kernel.org/r/20250715-upstream-optee-rtc-v1-1-e0fdf8aae545@foss.st.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-optee.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/rtc/rtc-optee.c b/drivers/rtc/rtc-optee.c index 9f8b5d4a8f6b..6b77c122fdc1 100644 --- a/drivers/rtc/rtc-optee.c +++ b/drivers/rtc/rtc-optee.c @@ -320,6 +320,7 @@ static int optee_rtc_remove(struct device *dev) { struct optee_rtc *priv = dev_get_drvdata(dev); + tee_shm_free(priv->shm); tee_client_close_session(priv->ctx, priv->session_id); tee_client_close_context(priv->ctx); -- cgit v1.2.3 From 44fee00f2139894b2ae4433f0661d70134b511c0 Mon Sep 17 00:00:00 2001 From: Clément Le Goffic Date: Tue, 15 Jul 2025 16:07:14 +0200 Subject: rtc: optee: remove unnecessary memory operations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove memcpy by using directly the shared memory. Remove memset be initialize variable to 0 on stack. Signed-off-by: Clément Le Goffic Link: https://lore.kernel.org/r/20250715-upstream-optee-rtc-v1-2-e0fdf8aae545@foss.st.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-optee.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/drivers/rtc/rtc-optee.c b/drivers/rtc/rtc-optee.c index 6b77c122fdc1..b65953eb7ca1 100644 --- a/drivers/rtc/rtc-optee.c +++ b/drivers/rtc/rtc-optee.c @@ -97,18 +97,9 @@ static int optee_rtc_settime(struct device *dev, struct rtc_time *tm) struct optee_rtc *priv = dev_get_drvdata(dev); struct tee_ioctl_invoke_arg inv_arg = {0}; struct tee_param param[4] = {0}; - struct optee_rtc_time optee_tm; - void *rtc_data; + struct optee_rtc_time *optee_tm; int ret; - optee_tm.tm_sec = tm->tm_sec; - optee_tm.tm_min = tm->tm_min; - optee_tm.tm_hour = tm->tm_hour; - optee_tm.tm_mday = tm->tm_mday; - optee_tm.tm_mon = tm->tm_mon; - optee_tm.tm_year = tm->tm_year + 1900; - optee_tm.tm_wday = tm->tm_wday; - inv_arg.func = TA_CMD_RTC_SET_TIME; inv_arg.session = priv->session_id; inv_arg.num_params = 4; @@ -117,11 +108,17 @@ static int optee_rtc_settime(struct device *dev, struct rtc_time *tm) param[0].u.memref.shm = priv->shm; param[0].u.memref.size = sizeof(struct optee_rtc_time); - rtc_data = tee_shm_get_va(priv->shm, 0); - if (IS_ERR(rtc_data)) - return PTR_ERR(rtc_data); + optee_tm = tee_shm_get_va(priv->shm, 0); + if (IS_ERR(optee_tm)) + return PTR_ERR(optee_tm); - memcpy(rtc_data, &optee_tm, sizeof(struct optee_rtc_time)); + optee_tm->tm_min = tm->tm_min; + optee_tm->tm_sec = tm->tm_sec; + optee_tm->tm_hour = tm->tm_hour; + optee_tm->tm_mday = tm->tm_mday; + optee_tm->tm_mon = tm->tm_mon; + optee_tm->tm_year = tm->tm_year + 1900; + optee_tm->tm_wday = tm->tm_wday; ret = tee_client_invoke_func(priv->ctx, &inv_arg, param); if (ret < 0 || inv_arg.ret != 0) @@ -241,14 +238,12 @@ static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data) static int optee_rtc_probe(struct device *dev) { struct tee_client_device *rtc_device = to_tee_client_device(dev); - struct tee_ioctl_open_session_arg sess_arg; + struct tee_ioctl_open_session_arg sess_arg = {0}; struct optee_rtc *priv; struct rtc_device *rtc; struct tee_shm *shm; int ret, err; - memset(&sess_arg, 0, sizeof(sess_arg)); - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; -- cgit v1.2.3 From 6266aea864fa5484f6e8313f913a69e794765fab Mon Sep 17 00:00:00 2001 From: Clément Le Goffic Date: Tue, 15 Jul 2025 16:07:15 +0200 Subject: rtc: optee: add alarm related rtc ops to optee rtc driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add read_alarm and set_alarm ops from the rtc framework. The support of an alarm is handled by a kernel thread waiting in OP-TEE for an asynchronous notification that comes in the interrupt handler of the alarm interruption on OP-TEE secure world. Once the notification arrives, the kernel thread previously suspended is rescheduled (this is handled by the OP-TEE kernel driver) and comes back with the alarm information to the kernel. A second session is therefore needed to enable/disable/cancel a waiting alarm event as the kernel thread stopped in OP-TEE takes a form of mutex on the session and so no one can use this session in parallel. Signed-off-by: Clément Le Goffic Link: https://lore.kernel.org/r/20250715-upstream-optee-rtc-v1-3-e0fdf8aae545@foss.st.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-optee.c | 434 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 413 insertions(+), 21 deletions(-) diff --git a/drivers/rtc/rtc-optee.c b/drivers/rtc/rtc-optee.c index b65953eb7ca1..27db403e3047 100644 --- a/drivers/rtc/rtc-optee.c +++ b/drivers/rtc/rtc-optee.c @@ -5,19 +5,104 @@ #include #include +#include #include #include #include -#define RTC_INFO_VERSION 0x1 +#define RTC_INFO_VERSION 0x1 -#define TA_CMD_RTC_GET_INFO 0x0 -#define TA_CMD_RTC_GET_TIME 0x1 -#define TA_CMD_RTC_SET_TIME 0x2 -#define TA_CMD_RTC_GET_OFFSET 0x3 -#define TA_CMD_RTC_SET_OFFSET 0x4 +#define TA_RTC_FEATURE_CORRECTION BIT(0) +#define TA_RTC_FEATURE_ALARM BIT(1) +#define TA_RTC_FEATURE_WAKEUP_ALARM BIT(2) -#define TA_RTC_FEATURE_CORRECTION BIT(0) +enum rtc_optee_pta_cmd { + /* PTA_CMD_RTC_GET_INFO - Get RTC information + * + * [out] memref[0] RTC buffer memory reference containing a struct pta_rtc_info + */ + PTA_CMD_RTC_GET_INF = 0x0, + + /* + * PTA_CMD_RTC_GET_TIME - Get time from RTC + * + * [out] memref[0] RTC buffer memory reference containing a struct pta_rtc_time + */ + PTA_CMD_RTC_GET_TIME = 0x1, + + /* + * PTA_CMD_RTC_SET_TIME - Set time from RTC + * + * [in] memref[0] RTC buffer memory reference containing a struct pta_rtc_time to be + * used as RTC time + */ + PTA_CMD_RTC_SET_TIME = 0x2, + + /* + * PTA_CMD_RTC_GET_OFFSET - Get RTC offset + * + * [out] value[0].a RTC offset (signed 32bit value) + */ + PTA_CMD_RTC_GET_OFFSET = 0x3, + + /* + * PTA_CMD_RTC_SET_OFFSET - Set RTC offset + * + * [in] value[0].a RTC offset to be set (signed 32bit value) + */ + PTA_CMD_RTC_SET_OFFSET = 0x4, + + /* + * PTA_CMD_RTC_READ_ALARM - Read RTC alarm + * + * [out] memref[0] RTC buffer memory reference containing a struct pta_rtc_alarm + */ + PTA_CMD_RTC_READ_ALARM = 0x5, + + /* + * PTA_CMD_RTC_SET_ALARM - Set RTC alarm + * + * [in] memref[0] RTC buffer memory reference containing a struct pta_rtc_alarm to be + * used as RTC alarm + */ + PTA_CMD_RTC_SET_ALARM = 0x6, + + /* + * PTA_CMD_RTC_ENABLE_ALARM - Enable Alarm + * + * [in] value[0].a RTC IRQ flag (uint32_t), 0 to disable the alarm, 1 to enable + */ + PTA_CMD_RTC_ENABLE_ALARM = 0x7, + + /* + * PTA_CMD_RTC_WAIT_ALARM - Get alarm event + * + * [out] value[0].a RTC wait alarm return status (uint32_t): + * - 0: No alarm event + * - 1: Alarm event occurred + * - 2: Alarm event canceled + */ + PTA_CMD_RTC_WAIT_ALARM = 0x8, + + /* + * PTA_CMD_RTC_CANCEL_WAIT - Cancel wait for alarm event + */ + PTA_CMD_RTC_CANCEL_WAIT = 0x9, + + /* + * PTA_CMD_RTC_SET_WAKE_ALARM_STATUS - Set RTC wake alarm status flag + * + * [in] value[0].a RTC IRQ wake alarm flag (uint32_t), 0 to disable the wake up + * capability, 1 to enable. + */ + PTA_CMD_RTC_SET_WAKE_ALARM_STATUS = 0xA, +}; + +enum rtc_wait_alarm_status { + WAIT_ALARM_RESET = 0x0, + WAIT_ALARM_ALARM_OCCURRED = 0x1, + WAIT_ALARM_CANCELED = 0x2, +}; struct optee_rtc_time { u32 tm_sec; @@ -29,6 +114,12 @@ struct optee_rtc_time { u32 tm_wday; }; +struct optee_rtc_alarm { + u8 enabled; + u8 pending; + struct optee_rtc_time time; +}; + struct optee_rtc_info { u64 version; u64 features; @@ -41,15 +132,21 @@ struct optee_rtc_info { * @dev: OP-TEE based RTC device. * @ctx: OP-TEE context handler. * @session_id: RTC TA session identifier. + * @session2_id: RTC wait alarm session identifier. * @shm: Memory pool shared with RTC device. * @features: Bitfield of RTC features + * @alarm_task: RTC wait alamr task. + * @rtc: RTC device. */ struct optee_rtc { struct device *dev; struct tee_context *ctx; u32 session_id; + u32 session2_id; struct tee_shm *shm; u64 features; + struct task_struct *alarm_task; + struct rtc_device *rtc; }; static int optee_rtc_readtime(struct device *dev, struct rtc_time *tm) @@ -60,7 +157,7 @@ static int optee_rtc_readtime(struct device *dev, struct rtc_time *tm) struct tee_param param[4] = {0}; int ret; - inv_arg.func = TA_CMD_RTC_GET_TIME; + inv_arg.func = PTA_CMD_RTC_GET_TIME; inv_arg.session = priv->session_id; inv_arg.num_params = 4; @@ -100,7 +197,7 @@ static int optee_rtc_settime(struct device *dev, struct rtc_time *tm) struct optee_rtc_time *optee_tm; int ret; - inv_arg.func = TA_CMD_RTC_SET_TIME; + inv_arg.func = PTA_CMD_RTC_SET_TIME; inv_arg.session = priv->session_id; inv_arg.num_params = 4; @@ -137,7 +234,7 @@ static int optee_rtc_readoffset(struct device *dev, long *offset) if (!(priv->features & TA_RTC_FEATURE_CORRECTION)) return -EOPNOTSUPP; - inv_arg.func = TA_CMD_RTC_GET_OFFSET; + inv_arg.func = PTA_CMD_RTC_GET_OFFSET; inv_arg.session = priv->session_id; inv_arg.num_params = 4; @@ -162,7 +259,7 @@ static int optee_rtc_setoffset(struct device *dev, long offset) if (!(priv->features & TA_RTC_FEATURE_CORRECTION)) return -EOPNOTSUPP; - inv_arg.func = TA_CMD_RTC_SET_OFFSET; + inv_arg.func = PTA_CMD_RTC_SET_OFFSET; inv_arg.session = priv->session_id; inv_arg.num_params = 4; @@ -176,13 +273,228 @@ static int optee_rtc_setoffset(struct device *dev, long offset) return 0; } +static int optee_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) +{ + struct optee_rtc *priv = dev_get_drvdata(dev); + struct tee_ioctl_invoke_arg inv_arg = {0}; + struct optee_rtc_alarm *optee_alarm; + struct tee_param param[1] = {0}; + int ret; + + if (!(priv->features & TA_RTC_FEATURE_ALARM)) + return -EOPNOTSUPP; + + inv_arg.func = PTA_CMD_RTC_READ_ALARM; + inv_arg.session = priv->session_id; + inv_arg.num_params = 1; + + /* Fill invoke cmd params */ + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT; + param[0].u.memref.shm = priv->shm; + param[0].u.memref.size = sizeof(struct optee_rtc_alarm); + + ret = tee_client_invoke_func(priv->ctx, &inv_arg, param); + if (ret < 0 || inv_arg.ret != 0) + return ret ? ret : -EPROTO; + + optee_alarm = tee_shm_get_va(priv->shm, 0); + if (IS_ERR(optee_alarm)) + return PTR_ERR(alarm); + + if (param[0].u.memref.size != sizeof(*optee_alarm)) + return -EPROTO; + + alarm->enabled = optee_alarm->enabled; + alarm->pending = optee_alarm->pending; + alarm->time.tm_sec = optee_alarm->time.tm_sec; + alarm->time.tm_min = optee_alarm->time.tm_min; + alarm->time.tm_hour = optee_alarm->time.tm_hour; + alarm->time.tm_mday = optee_alarm->time.tm_mday; + alarm->time.tm_mon = optee_alarm->time.tm_mon; + alarm->time.tm_year = optee_alarm->time.tm_year - 1900; + alarm->time.tm_wday = optee_alarm->time.tm_wday; + alarm->time.tm_yday = rtc_year_days(alarm->time.tm_mday, + alarm->time.tm_mon, + alarm->time.tm_year); + + return 0; +} + +static int optee_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) +{ + struct optee_rtc *priv = dev_get_drvdata(dev); + struct tee_ioctl_invoke_arg inv_arg = {0}; + struct optee_rtc_alarm *optee_alarm; + struct tee_param param[1] = {0}; + int ret; + + if (!(priv->features & TA_RTC_FEATURE_ALARM)) + return -EOPNOTSUPP; + + inv_arg.func = PTA_CMD_RTC_SET_ALARM; + inv_arg.session = priv->session_id; + inv_arg.num_params = 1; + + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT; + param[0].u.memref.shm = priv->shm; + param[0].u.memref.size = sizeof(struct optee_rtc_alarm); + + optee_alarm = tee_shm_get_va(priv->shm, 0); + if (IS_ERR(optee_alarm)) + return PTR_ERR(optee_alarm); + + optee_alarm->enabled = alarm->enabled; + optee_alarm->pending = alarm->pending; + optee_alarm->time.tm_sec = alarm->time.tm_sec; + optee_alarm->time.tm_min = alarm->time.tm_min; + optee_alarm->time.tm_hour = alarm->time.tm_hour; + optee_alarm->time.tm_mday = alarm->time.tm_mday; + optee_alarm->time.tm_mon = alarm->time.tm_mon; + optee_alarm->time.tm_year = alarm->time.tm_year + 1900; + optee_alarm->time.tm_wday = alarm->time.tm_wday; + + ret = tee_client_invoke_func(priv->ctx, &inv_arg, param); + if (ret < 0 || inv_arg.ret != 0) + return ret ? ret : -EPROTO; + + return 0; +} + +static int optee_rtc_enable_alarm(struct device *dev, unsigned int enabled) +{ + struct optee_rtc *priv = dev_get_drvdata(dev); + struct tee_ioctl_invoke_arg inv_arg = {0}; + struct tee_param param[1] = {0}; + int ret; + + if (!(priv->features & TA_RTC_FEATURE_ALARM)) + return -EOPNOTSUPP; + + inv_arg.func = PTA_CMD_RTC_ENABLE_ALARM; + inv_arg.session = priv->session_id; + inv_arg.num_params = 1; + + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; + param[0].u.value.a = (bool)enabled; + + ret = tee_client_invoke_func(priv->ctx, &inv_arg, param); + if (ret < 0 || inv_arg.ret != 0) + return ret ? ret : -EPROTO; + + return 0; +} + static const struct rtc_class_ops optee_rtc_ops = { - .read_time = optee_rtc_readtime, - .set_time = optee_rtc_settime, - .set_offset = optee_rtc_setoffset, - .read_offset = optee_rtc_readoffset, + .read_time = optee_rtc_readtime, + .set_time = optee_rtc_settime, + .set_offset = optee_rtc_setoffset, + .read_offset = optee_rtc_readoffset, + .read_alarm = optee_rtc_read_alarm, + .set_alarm = optee_rtc_set_alarm, + .alarm_irq_enable = optee_rtc_enable_alarm, }; +static int optee_rtc_wait_alarm(struct device *dev, int *return_status) +{ + struct optee_rtc *priv = dev_get_drvdata(dev); + struct tee_ioctl_invoke_arg inv_arg = {0}; + struct tee_param param[1] = {0}; + int ret; + + if (!(priv->features & TA_RTC_FEATURE_ALARM)) + return -EOPNOTSUPP; + + inv_arg.func = PTA_CMD_RTC_WAIT_ALARM; + inv_arg.session = priv->session2_id; + inv_arg.num_params = 1; + + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT; + + ret = tee_client_invoke_func(priv->ctx, &inv_arg, param); + if (ret < 0 || inv_arg.ret != 0) + return ret ? ret : -EPROTO; + + *return_status = param[0].u.value.a; + + return 0; +} + +static int optee_rtc_cancel_wait_alarm(struct device *dev) +{ + struct optee_rtc *priv = dev_get_drvdata(dev); + struct tee_ioctl_invoke_arg inv_arg = {0}; + struct tee_param param[1] = {0}; + int ret; + + if (!(priv->features & TA_RTC_FEATURE_ALARM)) + return -EOPNOTSUPP; + + inv_arg.func = PTA_CMD_RTC_CANCEL_WAIT; + inv_arg.session = priv->session_id; + inv_arg.num_params = 0; + + ret = tee_client_invoke_func(priv->ctx, &inv_arg, param); + if (ret < 0 || inv_arg.ret != 0) + return ret ? ret : -EPROTO; + + return 0; +} + +static int optee_rtc_set_alarm_wake_status(struct device *dev, bool status) +{ + struct optee_rtc *priv = dev_get_drvdata(dev); + struct tee_ioctl_invoke_arg inv_arg = {0}; + struct tee_param param[1] = {0}; + int ret; + + if (!(priv->features & TA_RTC_FEATURE_ALARM)) + return -EOPNOTSUPP; + + inv_arg.func = PTA_CMD_RTC_SET_WAKE_ALARM_STATUS; + inv_arg.session = priv->session_id; + inv_arg.num_params = 1; + + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; + param[0].u.value.a = status; + + ret = tee_client_invoke_func(priv->ctx, &inv_arg, param); + + if (ret < 0 || inv_arg.ret != 0) + return ret ? ret : -EPROTO; + + return 0; +} + +static int optee_rtc_handle_alarm_event(void *data) +{ + struct optee_rtc *priv = (struct optee_rtc *)data; + int wait_alarm_return_status = 0; + int ret; + + while (!kthread_should_stop()) { + ret = optee_rtc_wait_alarm(priv->dev, &wait_alarm_return_status); + if (ret) { + dev_err(priv->dev, "Failed to wait for alarm: %d\n", ret); + return ret; + } + switch (wait_alarm_return_status) { + case WAIT_ALARM_ALARM_OCCURRED: + dev_dbg(priv->dev, "Alarm occurred\n"); + rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_AF); + break; + case WAIT_ALARM_CANCELED: + dev_dbg(priv->dev, "Alarm canceled\n"); + break; + default: + dev_warn(priv->dev, "Unknown return status: %d\n", + wait_alarm_return_status); + break; + } + } + + return 0; +} + static int optee_rtc_read_info(struct device *dev, struct rtc_device *rtc, u64 *features) { @@ -193,7 +505,7 @@ static int optee_rtc_read_info(struct device *dev, struct rtc_device *rtc, struct optee_rtc_time *tm; int ret; - inv_arg.func = TA_CMD_RTC_GET_INFO; + inv_arg.func = PTA_CMD_RTC_GET_INF; inv_arg.session = priv->session_id; inv_arg.num_params = 4; @@ -238,6 +550,7 @@ static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data) static int optee_rtc_probe(struct device *dev) { struct tee_client_device *rtc_device = to_tee_client_device(dev); + struct tee_ioctl_open_session_arg sess2_arg = {0}; struct tee_ioctl_open_session_arg sess_arg = {0}; struct optee_rtc *priv; struct rtc_device *rtc; @@ -252,12 +565,14 @@ static int optee_rtc_probe(struct device *dev) if (IS_ERR(rtc)) return PTR_ERR(rtc); + priv->rtc = rtc; + /* Open context with TEE driver */ priv->ctx = tee_client_open_context(NULL, optee_ctx_match, NULL, NULL); if (IS_ERR(priv->ctx)) return -ENODEV; - /* Open session with rtc Trusted App */ + /* Open first session with rtc Pseudo Trusted App */ export_uuid(sess_arg.uuid, &rtc_device->id.uuid); sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL; @@ -269,6 +584,11 @@ static int optee_rtc_probe(struct device *dev) } priv->session_id = sess_arg.session; + /* + * Shared memory is used for passing an instance of either struct optee_rtc_info, + * struct optee_rtc_time or struct optee_rtc_alarm to OP-TEE service. + * The former is by definition large enough to cover both parameter cases. + */ shm = tee_shm_alloc_kernel_buf(priv->ctx, sizeof(struct optee_rtc_info)); if (IS_ERR(shm)) { dev_err(priv->dev, "tee_shm_alloc_kernel_buf failed\n"); @@ -288,19 +608,69 @@ static int optee_rtc_probe(struct device *dev) goto out_shm; } + /* Handle feature's related setup before registering to rtc framework */ + if (priv->features & TA_RTC_FEATURE_ALARM) { + priv->alarm_task = kthread_create(optee_rtc_handle_alarm_event, + priv, "rtc_alarm_evt"); + if (IS_ERR(priv->alarm_task)) { + dev_err(dev, "Failed to create alarm thread\n"); + goto out_shm; + } + + /* + * In case of supported alarm feature on optee side, we create a kthread + * that will, in a new optee session, call a PTA interface "rtc_wait_alarm". + * This call return in case of alarm and in case of canceled alarm. + * The new optee session is therefore only needed in this case as we cannot + * use the same session for parallel calls to optee PTA. + * Hence one session is reserved to wait for alarms and the other to make + * standard calls to RTC PTA. + */ + + /* Open second session with rtc Trusted App */ + export_uuid(sess2_arg.uuid, &rtc_device->id.uuid); + sess2_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL; + + ret = tee_client_open_session(priv->ctx, &sess2_arg, NULL); + if (ret < 0 || sess2_arg.ret != 0) { + dev_err(dev, "tee_client_open_session failed, err: %x\n", sess2_arg.ret); + err = -EINVAL; + goto out_thrd; + } + priv->session2_id = sess2_arg.session; + + if (priv->features & TA_RTC_FEATURE_WAKEUP_ALARM) + device_init_wakeup(dev, true); + } + err = devm_rtc_register_device(rtc); if (err) - goto out_shm; + goto out_wk; /* - * We must clear this bit after registering because rtc_register_device - * will set it if it sees that .set_offset is provided. + * We must clear those bits after registering because registering a rtc_device + * will set them if it sees that .set_offset and .set_alarm are provided. */ if (!(priv->features & TA_RTC_FEATURE_CORRECTION)) clear_bit(RTC_FEATURE_CORRECTION, rtc->features); + if (!(priv->features & TA_RTC_FEATURE_ALARM)) + clear_bit(RTC_FEATURE_ALARM, rtc->features); - return 0; + /* Start the thread after the rtc is setup */ + if (priv->alarm_task) { + wake_up_process(priv->alarm_task); + dev_dbg(dev, "Wait alarm thread successfully started\n"); + } + return 0; +out_wk: + if (priv->features & TA_RTC_FEATURE_ALARM) { + device_init_wakeup(dev, false); + tee_client_close_session(priv->ctx, priv->session2_id); + } +out_thrd: + if (priv->features & TA_RTC_FEATURE_ALARM) + kthread_stop(priv->alarm_task); out_shm: tee_shm_free(priv->shm); out_sess: @@ -315,6 +685,13 @@ static int optee_rtc_remove(struct device *dev) { struct optee_rtc *priv = dev_get_drvdata(dev); + if (priv->features & TA_RTC_FEATURE_ALARM) { + optee_rtc_cancel_wait_alarm(dev); + kthread_stop(priv->alarm_task); + device_init_wakeup(dev, false); + tee_client_close_session(priv->ctx, priv->session2_id); + } + tee_shm_free(priv->shm); tee_client_close_session(priv->ctx, priv->session_id); tee_client_close_context(priv->ctx); @@ -322,6 +699,20 @@ static int optee_rtc_remove(struct device *dev) return 0; } +static int optee_rtc_suspend(struct device *dev) +{ + int res = optee_rtc_set_alarm_wake_status(dev, device_may_wakeup(dev)); + + if (res) { + dev_err(dev, "Unable to transmit wakeup information to optee rtc\n"); + return res; + } + + return 0; +} + +DEFINE_SIMPLE_DEV_PM_OPS(optee_rtc_pm_ops, optee_rtc_suspend, NULL); + static const struct tee_client_device_id optee_rtc_id_table[] = { {UUID_INIT(0xf389f8c8, 0x845f, 0x496c, 0x8b, 0xbe, 0xd6, 0x4b, 0xd2, 0x4c, 0x92, 0xfd)}, @@ -337,6 +728,7 @@ static struct tee_client_driver optee_rtc_driver = { .bus = &tee_bus_type, .probe = optee_rtc_probe, .remove = optee_rtc_remove, + .pm = pm_sleep_ptr(&optee_rtc_pm_ops), }, }; -- cgit v1.2.3 From a6de182daa2b1a627d88a594526a0db4ac1e396e Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Mon, 25 Aug 2025 12:20:53 -0500 Subject: rtc: spacemit: support the SpacemiT P1 RTC Add support for the RTC found in the SpacemiT P1 PMIC. Initially only setting and reading the time are supported. The PMIC is implemented as a multi-function device. This RTC is probed based on this driver being named in a MFD cell in the simple MFD I2C driver. Signed-off-by: Alex Elder Acked-by: Alexandre Belloni Link: https://lore.kernel.org/r/20250825172057.163883-5-elder@riscstar.com Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 10 +++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-spacemit-p1.c | 167 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 178 insertions(+) create mode 100644 drivers/rtc/rtc-spacemit-p1.c diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 64f6e9756aff..31d355b103d4 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -406,6 +406,16 @@ config RTC_DRV_MAX77686 This driver can also be built as a module. If so, the module will be called rtc-max77686. +config RTC_DRV_SPACEMIT_P1 + tristate "SpacemiT P1 RTC" + depends on ARCH_SPACEMIT || COMPILE_TEST + select MFD_SPACEMIT_P1 + default ARCH_SPACEMIT + help + Enable support for the RTC function in the SpacemiT P1 PMIC. + This driver can also be built as a module, which will be called + "spacemit-p1-rtc". + config RTC_DRV_NCT3018Y tristate "Nuvoton NCT3018Y" depends on OF diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 789bddfea99d..f41fdb4fabae 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -171,6 +171,7 @@ obj-$(CONFIG_RTC_DRV_SD2405AL) += rtc-sd2405al.o obj-$(CONFIG_RTC_DRV_SD3078) += rtc-sd3078.o obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o obj-$(CONFIG_RTC_DRV_SNVS) += rtc-snvs.o +obj-$(CONFIG_RTC_DRV_SPACEMIT_P1) += rtc-spacemit-p1.o obj-$(CONFIG_RTC_DRV_SPEAR) += rtc-spear.o obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o diff --git a/drivers/rtc/rtc-spacemit-p1.c b/drivers/rtc/rtc-spacemit-p1.c new file mode 100644 index 000000000000..43ab62494bb4 --- /dev/null +++ b/drivers/rtc/rtc-spacemit-p1.c @@ -0,0 +1,167 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for the RTC found in the SpacemiT P1 PMIC + * + * Copyright (C) 2025 by RISCstar Solutions Corporation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include + +#define MOD_NAME "spacemit-p1-rtc" + +/* + * Six consecutive 1-byte registers hold the seconds, minutes, hours, + * day-of-month, month, and year (respectively). + * + * The range of values in these registers is: + * seconds 0-59 + * minutes 0-59 + * hours 0-59 + * day 0-30 (struct tm is 1-31) + * month 0-11 + * year years since 2000 (struct tm is since 1900) + * + * Note that the day and month must be converted after reading and + * before writing. + */ +#define RTC_TIME 0x0d /* Offset of the seconds register */ + +#define RTC_CTRL 0x1d +#define RTC_EN BIT(2) + +/* Number of attempts to read a consistent time stamp before giving up */ +#define RTC_READ_TRIES 20 /* At least 1 */ + +struct p1_rtc { + struct regmap *regmap; + struct rtc_device *rtc; +}; + +/* + * The P1 hardware documentation states that the register values are + * latched to ensure a consistent time snapshot within the registers, + * but these are in fact unstable due to a bug in the hardware design. + * So we loop until we get two identical readings. + */ +static int p1_rtc_read_time(struct device *dev, struct rtc_time *t) +{ + struct p1_rtc *p1 = dev_get_drvdata(dev); + struct regmap *regmap = p1->regmap; + u32 count = RTC_READ_TRIES; + u8 seconds; + u8 time[6]; + int ret; + + if (!regmap_test_bits(regmap, RTC_CTRL, RTC_EN)) + return -EINVAL; /* RTC is disabled */ + + ret = regmap_bulk_read(regmap, RTC_TIME, time, sizeof(time)); + if (ret) + return ret; + + do { + seconds = time[0]; + ret = regmap_bulk_read(regmap, RTC_TIME, time, sizeof(time)); + if (ret) + return ret; + } while (time[0] != seconds && --count); + + if (!count) + return -EIO; /* Unable to get a consistent result */ + + t->tm_sec = time[0] & GENMASK(5, 0); + t->tm_min = time[1] & GENMASK(5, 0); + t->tm_hour = time[2] & GENMASK(4, 0); + t->tm_mday = (time[3] & GENMASK(4, 0)) + 1; + t->tm_mon = time[4] & GENMASK(3, 0); + t->tm_year = (time[5] & GENMASK(5, 0)) + 100; + + return 0; +} + +/* + * The P1 hardware documentation states that values in the registers are + * latched so when written they represent a consistent time snapshot. + * Nevertheless, this is not guaranteed by the implementation, so we must + * disable the RTC while updating it. + */ +static int p1_rtc_set_time(struct device *dev, struct rtc_time *t) +{ + struct p1_rtc *p1 = dev_get_drvdata(dev); + struct regmap *regmap = p1->regmap; + u8 time[6]; + int ret; + + time[0] = t->tm_sec; + time[1] = t->tm_min; + time[2] = t->tm_hour; + time[3] = t->tm_mday - 1; + time[4] = t->tm_mon; + time[5] = t->tm_year - 100; + + /* Disable the RTC to update; re-enable again when done */ + ret = regmap_clear_bits(regmap, RTC_CTRL, RTC_EN); + if (ret) + return ret; + + /* If something goes wrong, leave the RTC disabled */ + ret = regmap_bulk_write(regmap, RTC_TIME, time, sizeof(time)); + if (ret) + return ret; + + return regmap_set_bits(regmap, RTC_CTRL, RTC_EN); +} + +static const struct rtc_class_ops p1_rtc_class_ops = { + .read_time = p1_rtc_read_time, + .set_time = p1_rtc_set_time, +}; + +static int p1_rtc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct rtc_device *rtc; + struct p1_rtc *p1; + + p1 = devm_kzalloc(dev, sizeof(*p1), GFP_KERNEL); + if (!p1) + return -ENOMEM; + dev_set_drvdata(dev, p1); + + p1->regmap = dev_get_regmap(dev->parent, NULL); + if (!p1->regmap) + return dev_err_probe(dev, -ENODEV, "failed to get regmap\n"); + + rtc = devm_rtc_allocate_device(dev); + if (IS_ERR(rtc)) + return dev_err_probe(dev, PTR_ERR(rtc), + "error allocating device\n"); + p1->rtc = rtc; + + rtc->ops = &p1_rtc_class_ops; + rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; + rtc->range_max = RTC_TIMESTAMP_END_2063; + + clear_bit(RTC_FEATURE_ALARM, rtc->features); + clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features); + + return devm_rtc_register_device(rtc); +} + +static struct platform_driver p1_rtc_driver = { + .probe = p1_rtc_probe, + .driver = { + .name = MOD_NAME, + }, +}; + +module_platform_driver(p1_rtc_driver); + +MODULE_DESCRIPTION("SpacemiT P1 RTC driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" MOD_NAME); -- cgit v1.2.3 From a6b4f791cdc56655b2dee8ac793f5b28dc4e542d Mon Sep 17 00:00:00 2001 From: "Rob Herring (Arm)" Date: Wed, 24 Sep 2025 17:28:46 -0500 Subject: dt-bindings: rtc: Convert apm,xgene-rtc to DT schema Convert the APM XGene RTC binding to DT schema format. It's a straight-forward conversion. Signed-off-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20250924222848.2949235-1-robh@kernel.org Signed-off-by: Alexandre Belloni --- .../devicetree/bindings/rtc/apm,xgene-rtc.yaml | 45 ++++++++++++++++++++++ .../devicetree/bindings/rtc/xgene-rtc.txt | 28 -------------- 2 files changed, 45 insertions(+), 28 deletions(-) create mode 100644 Documentation/devicetree/bindings/rtc/apm,xgene-rtc.yaml delete mode 100644 Documentation/devicetree/bindings/rtc/xgene-rtc.txt diff --git a/Documentation/devicetree/bindings/rtc/apm,xgene-rtc.yaml b/Documentation/devicetree/bindings/rtc/apm,xgene-rtc.yaml new file mode 100644 index 000000000000..b8f46536fd5a --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/apm,xgene-rtc.yaml @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/rtc/apm,xgene-rtc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: APM X-Gene Real Time Clock + +maintainers: + - Khuong Dinh + +properties: + compatible: + const: apm,xgene-rtc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + '#clock-cells': + const: 1 + + clocks: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - '#clock-cells' + - clocks + +additionalProperties: false + +examples: + - | + rtc@10510000 { + compatible = "apm,xgene-rtc"; + reg = <0x10510000 0x400>; + interrupts = <0x0 0x46 0x4>; + #clock-cells = <1>; + clocks = <&rtcclk 0>; + }; diff --git a/Documentation/devicetree/bindings/rtc/xgene-rtc.txt b/Documentation/devicetree/bindings/rtc/xgene-rtc.txt deleted file mode 100644 index fd195c358446..000000000000 --- a/Documentation/devicetree/bindings/rtc/xgene-rtc.txt +++ /dev/null @@ -1,28 +0,0 @@ -* APM X-Gene Real Time Clock - -RTC controller for the APM X-Gene Real Time Clock - -Required properties: -- compatible : Should be "apm,xgene-rtc" -- reg: physical base address of the controller and length of memory mapped - region. -- interrupts: IRQ line for the RTC. -- #clock-cells: Should be 1. -- clocks: Reference to the clock entry. - -Example: - -rtcclk: rtcclk { - compatible = "fixed-clock"; - #clock-cells = <1>; - clock-frequency = <100000000>; - clock-output-names = "rtcclk"; -}; - -rtc: rtc@10510000 { - compatible = "apm,xgene-rtc"; - reg = <0x0 0x10510000 0x0 0x400>; - interrupts = <0x0 0x46 0x4>; - #clock-cells = <1>; - clocks = <&rtcclk 0>; -}; -- cgit v1.2.3 From 8bbd727453b497722b3e31b5d634c35faa953fbd Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 18 Sep 2025 12:49:31 +0300 Subject: rtc: optee: fix error code in probe() Return an error code if kthread_create() fails. Currently the code returns success. Fixes: 6266aea864fa ("rtc: optee: add alarm related rtc ops to optee rtc driver") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/21f1a18008f1bbc8f70d0bd5c05b72fbf5fc9c7d.1758182509.git.dan.carpenter@linaro.org Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-optee.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/rtc/rtc-optee.c b/drivers/rtc/rtc-optee.c index 27db403e3047..7b44d7723cae 100644 --- a/drivers/rtc/rtc-optee.c +++ b/drivers/rtc/rtc-optee.c @@ -614,6 +614,7 @@ static int optee_rtc_probe(struct device *dev) priv, "rtc_alarm_evt"); if (IS_ERR(priv->alarm_task)) { dev_err(dev, "Failed to create alarm thread\n"); + err = PTR_ERR(priv->alarm_task); goto out_shm; } -- cgit v1.2.3 From eb7392a019642f0ef5b9acd5e56a3f051d64a5ef Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 18 Sep 2025 12:49:48 +0300 Subject: rtc: optee: Fix error code in optee_rtc_read_alarm() Return "optee_alarm" instead of "alarm". The "alarm" pointer is a valid pointer and not an error pointer. Fixes: 6266aea864fa ("rtc: optee: add alarm related rtc ops to optee rtc driver") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/9e3718fe1128964907619ad325c0c5f5c1354ace.1758182509.git.dan.carpenter@linaro.org Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-optee.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-optee.c b/drivers/rtc/rtc-optee.c index 7b44d7723cae..3d5662aa1bd8 100644 --- a/drivers/rtc/rtc-optee.c +++ b/drivers/rtc/rtc-optee.c @@ -299,7 +299,7 @@ static int optee_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) optee_alarm = tee_shm_get_va(priv->shm, 0); if (IS_ERR(optee_alarm)) - return PTR_ERR(alarm); + return PTR_ERR(optee_alarm); if (param[0].u.memref.size != sizeof(*optee_alarm)) return -EPROTO; -- cgit v1.2.3 From b650cf9108efea71e51f1287f2e5ccd2144979af Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sun, 5 Oct 2025 22:19:24 +0200 Subject: rtc: optee: make optee_rtc_pm_ops static Fix sparse warningg: drivers/rtc/rtc-optee.c:714:1: sparse: sparse: symbol 'optee_rtc_pm_ops' was not declared. Should it be static? Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202509230549.L26lw7UZ-lkp@intel.com/ Link: https://lore.kernel.org/r/20251005201925.3757345-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-optee.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-optee.c b/drivers/rtc/rtc-optee.c index 3d5662aa1bd8..184c6d142801 100644 --- a/drivers/rtc/rtc-optee.c +++ b/drivers/rtc/rtc-optee.c @@ -712,7 +712,7 @@ static int optee_rtc_suspend(struct device *dev) return 0; } -DEFINE_SIMPLE_DEV_PM_OPS(optee_rtc_pm_ops, optee_rtc_suspend, NULL); +static DEFINE_SIMPLE_DEV_PM_OPS(optee_rtc_pm_ops, optee_rtc_suspend, NULL); static const struct tee_client_device_id optee_rtc_id_table[] = { {UUID_INIT(0xf389f8c8, 0x845f, 0x496c, -- cgit v1.2.3 From a5a19e80b235ed2c456dbab59c85ca43e87e01bf Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sun, 5 Oct 2025 22:30:48 +0200 Subject: rtc: Kconfig: move symbols to proper section There is only one HID RTC, the following symbols are for on-SoC RTCs Link: https://lore.kernel.org/r/20251005203048.3759240-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 31d355b103d4..17531bfe3dea 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -2044,20 +2044,6 @@ config RTC_DRV_RENESAS_RTCA3 This driver can also be built as a module, if so, the module will be called "rtc-rtca3". -comment "HID Sensor RTC drivers" - -config RTC_DRV_HID_SENSOR_TIME - tristate "HID Sensor Time" - depends on USB_HID - depends on HID_SENSOR_HUB && IIO - select HID_SENSOR_IIO_COMMON - help - Say yes here to build support for the HID Sensors of type Time. - This drivers makes such sensors available as RTCs. - - If this driver is compiled as a module, it will be named - rtc-hid-sensor-time. - config RTC_DRV_GOLDFISH tristate "Goldfish Real Time Clock" depends on HAS_IOMEM @@ -2132,4 +2118,18 @@ config RTC_DRV_S32G This RTC module can be used as a wakeup source. Please note that it is not battery-powered. +comment "HID Sensor RTC drivers" + +config RTC_DRV_HID_SENSOR_TIME + tristate "HID Sensor Time" + depends on USB_HID + depends on HID_SENSOR_HUB && IIO + select HID_SENSOR_IIO_COMMON + help + Say yes here to build support for the HID Sensors of type Time. + This drivers makes such sensors available as RTCs. + + If this driver is compiled as a module, it will be named + rtc-hid-sensor-time. + endif # RTC_CLASS -- cgit v1.2.3 From 75b002a38d4f740d51f0e09dcd778541f61a2797 Mon Sep 17 00:00:00 2001 From: Tóth János Date: Mon, 7 Apr 2025 13:48:49 +0200 Subject: rtc: sd2405al: Add I2C address. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is common to include the I2C address of the device in the source file. Signed-off-by: Tóth János Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-sd2405al.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-sd2405al.c b/drivers/rtc/rtc-sd2405al.c index 00c3033e8079..708ea5d964de 100644 --- a/drivers/rtc/rtc-sd2405al.c +++ b/drivers/rtc/rtc-sd2405al.c @@ -5,7 +5,9 @@ * Datasheet: * https://image.dfrobot.com/image/data/TOY0021/SD2405AL%20datasheet%20(Angelo%20v0.1).pdf * - * Copyright (C) 2024 Tóth János + * I2C slave address: 0x32 + * + * Copyright (C) 2024-2025 Tóth János */ #include -- cgit v1.2.3 From f38bdd730914be1fcd63240af89a2dc802148c8a Mon Sep 17 00:00:00 2001 From: Xianwei Zhao Date: Tue, 22 Jul 2025 19:30:48 +0800 Subject: rtc: amlogic-a4: Optimize global variables Convert a global variable into a local one of aml_rtc_probe(). Signed-off-by: Xianwei Zhao Link: https://lore.kernel.org/r/20250722-rtc-regmap-v2-1-58bc17187a11@amlogic.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-amlogic-a4.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/rtc/rtc-amlogic-a4.c b/drivers/rtc/rtc-amlogic-a4.c index 09d78c2cc691..1928b29c1045 100644 --- a/drivers/rtc/rtc-amlogic-a4.c +++ b/drivers/rtc/rtc-amlogic-a4.c @@ -72,13 +72,6 @@ struct aml_rtc_data { const struct aml_rtc_config *config; }; -static const struct regmap_config aml_rtc_regmap_config = { - .reg_bits = 32, - .val_bits = 32, - .reg_stride = 4, - .max_register = RTC_REAL_TIME, -}; - static inline u32 gray_to_binary(u32 gray) { u32 bcd = gray; @@ -328,6 +321,13 @@ static int aml_rtc_probe(struct platform_device *pdev) void __iomem *base; int ret = 0; + const struct regmap_config aml_rtc_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = RTC_REAL_TIME, + }; + rtc = devm_kzalloc(dev, sizeof(*rtc), GFP_KERNEL); if (!rtc) return -ENOMEM; -- cgit v1.2.3 From e22f4d1321e0055065f274e20bf6d1dbf4b500f5 Mon Sep 17 00:00:00 2001 From: Harini T Date: Wed, 30 Jul 2025 19:51:10 +0530 Subject: rtc: zynqmp: Restore alarm functionality after kexec transition During kexec reboots, RTC alarms that are fired during the kernel transition experience delayed execution. The new kernel would eventually honor these alarms, but the interrupt handlers would only execute after the driver probe is completed rather than at the intended alarm time. This is because pending alarm interrupt status from the previous kernel is not properly cleared during driver initialization, causing timing discrepancies in alarm delivery. To ensure precise alarm timing across kexec transitions, enhance the probe function to: 1. Clear any pending alarm interrupt status from previous boot. 2. Detect existing valid alarms and preserve their state. 3. Re-enable alarm interrupts for future alarms. Signed-off-by: Harini T Link: https://lore.kernel.org/r/20250730142110.2354507-1-harini.t@amd.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-zynqmp.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c index f39102b66eac..3baa2b481d9f 100644 --- a/drivers/rtc/rtc-zynqmp.c +++ b/drivers/rtc/rtc-zynqmp.c @@ -277,6 +277,10 @@ static irqreturn_t xlnx_rtc_interrupt(int irq, void *id) static int xlnx_rtc_probe(struct platform_device *pdev) { struct xlnx_rtc_dev *xrtcdev; + bool is_alarm_set = false; + u32 pending_alrm_irq; + u32 current_time; + u32 alarm_time; int ret; xrtcdev = devm_kzalloc(&pdev->dev, sizeof(*xrtcdev), GFP_KERNEL); @@ -296,6 +300,17 @@ static int xlnx_rtc_probe(struct platform_device *pdev) if (IS_ERR(xrtcdev->reg_base)) return PTR_ERR(xrtcdev->reg_base); + /* Clear any pending alarm interrupts from previous kernel/boot */ + pending_alrm_irq = readl(xrtcdev->reg_base + RTC_INT_STS) & RTC_INT_ALRM; + if (pending_alrm_irq) + writel(pending_alrm_irq, xrtcdev->reg_base + RTC_INT_STS); + + /* Check if a valid alarm is already set from previous kernel/boot */ + alarm_time = readl(xrtcdev->reg_base + RTC_ALRM); + current_time = readl(xrtcdev->reg_base + RTC_CUR_TM); + if (alarm_time > current_time && alarm_time != 0) + is_alarm_set = true; + xrtcdev->alarm_irq = platform_get_irq_byname(pdev, "alarm"); if (xrtcdev->alarm_irq < 0) return xrtcdev->alarm_irq; @@ -337,6 +352,10 @@ static int xlnx_rtc_probe(struct platform_device *pdev) xlnx_init_rtc(xrtcdev); + /* Re-enable alarm interrupt if a valid alarm was found */ + if (is_alarm_set) + writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_EN); + device_init_wakeup(&pdev->dev, true); return devm_rtc_register_device(xrtcdev->rtc); -- cgit v1.2.3 From 87064da2db7be537a7da20a25c18ba912c4db9e1 Mon Sep 17 00:00:00 2001 From: Bruno Thomsen Date: Tue, 2 Sep 2025 20:22:35 +0200 Subject: rtc: pcf2127: fix watchdog interrupt mask on pcf2131 When using interrupt pin (INT A) as watchdog output all other interrupt sources need to be disabled to avoid additional resets. Resulting INT_A_MASK1 value is 55 (0x37). Signed-off-by: Bruno Thomsen Link: https://lore.kernel.org/r/20250902182235.6825-1-bruno.thomsen@gmail.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pcf2127.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index 3ba1de30e89c..bb4fe81d3d62 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c @@ -608,6 +608,21 @@ static int pcf2127_watchdog_init(struct device *dev, struct pcf2127 *pcf2127) set_bit(WDOG_HW_RUNNING, &pcf2127->wdd.status); } + /* + * When using interrupt pin (INT A) as watchdog output, only allow + * watchdog interrupt (PCF2131_BIT_INT_WD_CD) and disable (mask) all + * other interrupts. + */ + if (pcf2127->cfg->type == PCF2131) { + ret = regmap_write(pcf2127->regmap, + PCF2131_REG_INT_A_MASK1, + PCF2131_BIT_INT_BLIE | + PCF2131_BIT_INT_BIE | + PCF2131_BIT_INT_AIE | + PCF2131_BIT_INT_SI | + PCF2131_BIT_INT_MI); + } + return devm_watchdog_register_device(dev, &pcf2127->wdd); } -- cgit v1.2.3 From 795cda8338eab036013314dbc0b04aae728880ab Mon Sep 17 00:00:00 2001 From: Esben Haabendal Date: Fri, 16 May 2025 09:23:35 +0200 Subject: rtc: interface: Fix long-standing race when setting alarm As described in the old comment dating back to commit 6610e0893b8b ("RTC: Rework RTC code to use timerqueue for events") from 2010, we have been living with a race window when setting alarm with an expiry in the near future (i.e. next second). With 1 second resolution, it can happen that the second ticks after the check for the timer having expired, but before the alarm is actually set. When this happen, no alarm IRQ is generated, at least not with some RTC chips (isl12022 is an example of this). With UIE RTC timer being implemented on top of alarm irq, being re-armed every second, UIE will occasionally fail to work, as an alarm irq lost due to this race will stop the re-arming loop. For now, I have limited the additional expiry check to only be done for alarms set to next seconds. I expect it should be good enough, although I don't know if we can now for sure that systems with loads could end up causing the same problems for alarms set 2 seconds or even longer in the future. I haven't been able to reproduce the problem with this check in place. Cc: stable@vger.kernel.org Signed-off-by: Esben Haabendal Link: https://lore.kernel.org/r/20250516-rtc-uie-irq-fixes-v2-1-3de8e530a39e@geanix.com Signed-off-by: Alexandre Belloni --- drivers/rtc/interface.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index dc741ba29fa3..6fafe2a4ae4f 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -443,6 +443,29 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) else err = rtc->ops->set_alarm(rtc->dev.parent, alarm); + /* + * Check for potential race described above. If the waiting for next + * second, and the second just ticked since the check above, either + * + * 1) It ticked after the alarm was set, and an alarm irq should be + * generated. + * + * 2) It ticked before the alarm was set, and alarm irq most likely will + * not be generated. + * + * While we cannot easily check for which of these two scenarios we + * are in, we can return -ETIME to signal that the timer has already + * expired, which is true in both cases. + */ + if ((scheduled - now) <= 1) { + err = __rtc_read_time(rtc, &tm); + if (err) + return err; + now = rtc_tm_to_time64(&tm); + if (scheduled <= now) + return -ETIME; + } + trace_rtc_set_alarm(rtc_tm_to_time64(&alarm->time), err); return err; } -- cgit v1.2.3 From 9ffe06b6ccd7a8eaa31d31625db009ea26a22a3c Mon Sep 17 00:00:00 2001 From: Esben Haabendal Date: Fri, 16 May 2025 09:23:36 +0200 Subject: rtc: isl12022: Fix initial enable_irq/disable_irq balance Interrupts are automatically enabled when requested, so we need to initialize irq_enabled accordingly to avoid causing an unbalanced enable warning. Fixes: c62d658e5253 ("rtc: isl12022: Add alarm support") Signed-off-by: Esben Haabendal Link: https://lore.kernel.org/r/20250516-rtc-uie-irq-fixes-v2-2-3de8e530a39e@geanix.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-isl12022.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c index 9b44839a7402..5fc52dc64213 100644 --- a/drivers/rtc/rtc-isl12022.c +++ b/drivers/rtc/rtc-isl12022.c @@ -413,6 +413,7 @@ static int isl12022_setup_irq(struct device *dev, int irq) if (ret) return ret; + isl12022->irq_enabled = true; ret = devm_request_threaded_irq(dev, irq, NULL, isl12022_rtc_interrupt, IRQF_SHARED | IRQF_ONESHOT, -- cgit v1.2.3 From e0762fd26ad68f0232979e742e080d73a1388ead Mon Sep 17 00:00:00 2001 From: Esben Haabendal Date: Fri, 16 May 2025 09:23:37 +0200 Subject: rtc: cpcap: Fix initial enable_irq/disable_irq balance Interrupts are automatically enabled when requested, so we need to initialize alarm_enabled accordingly to avoid causing an unbalanced enable warning. Signed-off-by: Esben Haabendal Link: https://lore.kernel.org/r/20250516-rtc-uie-irq-fixes-v2-3-3de8e530a39e@geanix.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-cpcap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/rtc/rtc-cpcap.c b/drivers/rtc/rtc-cpcap.c index c170345ac076..8b6b35716f53 100644 --- a/drivers/rtc/rtc-cpcap.c +++ b/drivers/rtc/rtc-cpcap.c @@ -268,6 +268,7 @@ static int cpcap_rtc_probe(struct platform_device *pdev) return err; rtc->alarm_irq = platform_get_irq(pdev, 0); + rtc->alarm_enabled = true; err = devm_request_threaded_irq(dev, rtc->alarm_irq, NULL, cpcap_rtc_alarm_irq, IRQF_TRIGGER_NONE | IRQF_ONESHOT, -- cgit v1.2.3 From 1502fe0e97be01d18f2b30fd7fe29bb39def0e7d Mon Sep 17 00:00:00 2001 From: Esben Haabendal Date: Fri, 16 May 2025 09:23:38 +0200 Subject: rtc: tps6586x: Fix initial enable_irq/disable_irq balance Interrupts are automatically enabled when requested, so we need to initialize irq_en accordingly to avoid causing an unbalanced enable warning. Signed-off-by: Esben Haabendal Link: https://lore.kernel.org/r/20250516-rtc-uie-irq-fixes-v2-4-3de8e530a39e@geanix.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-tps6586x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/rtc/rtc-tps6586x.c b/drivers/rtc/rtc-tps6586x.c index 54c8429b16bf..76ecf7b798f0 100644 --- a/drivers/rtc/rtc-tps6586x.c +++ b/drivers/rtc/rtc-tps6586x.c @@ -258,6 +258,7 @@ static int tps6586x_rtc_probe(struct platform_device *pdev) irq_set_status_flags(rtc->irq, IRQ_NOAUTOEN); + rtc->irq_en = true; ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL, tps6586x_rtc_irq, IRQF_ONESHOT, -- cgit v1.2.3 From 9db26d5855d0374d4652487bfb5aacf40821c469 Mon Sep 17 00:00:00 2001 From: Esben Haabendal Date: Fri, 16 May 2025 09:23:39 +0200 Subject: rtc: interface: Ensure alarm irq is enabled when UIE is enabled When setting a normal alarm, user-space is responsible for using RTC_AIE_ON/RTC_AIE_OFF to control if alarm irq should be enabled. But when RTC_UIE_ON is used, interrupts must be enabled so that the requested irq events are generated. When RTC_UIE_OFF is used, alarm irq is disabled if there are no other alarms queued, so this commit brings symmetry to that. Signed-off-by: Esben Haabendal Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20250516-rtc-uie-irq-fixes-v2-5-3de8e530a39e@geanix.com Signed-off-by: Alexandre Belloni --- drivers/rtc/interface.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 6fafe2a4ae4f..b8b298efd9a9 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -617,6 +617,10 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) rtc->uie_rtctimer.node.expires = ktime_add(now, onesec); rtc->uie_rtctimer.period = ktime_set(1, 0); err = rtc_timer_enqueue(rtc, &rtc->uie_rtctimer); + if (!err && rtc->ops && rtc->ops->alarm_irq_enable) + err = rtc->ops->alarm_irq_enable(rtc->dev.parent, 1); + if (err) + goto out; } else { rtc_timer_remove(rtc, &rtc->uie_rtctimer); } -- cgit v1.2.3