From 94d4154792abf30ee6081d35beaeef035816e294 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 18 Jun 2024 16:18:49 +0200 Subject: [PATCH 01/16] rtc: tps6594: Fix memleak in probe struct rtc_device is allocated twice in probe(), once with devm_kzalloc(), and then with devm_rtc_allocate_device(). The allocation with devm_kzalloc() is lost and superfluous. Fixes: 9f67c1e63976 ("rtc: tps6594: Add driver for TPS6594 RTC") Signed-off-by: Richard Genoud Link: https://lore.kernel.org/r/20240618141851.1810000-2-richard.genoud@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-tps6594.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/rtc/rtc-tps6594.c b/drivers/rtc/rtc-tps6594.c index 838ae8562a35..bc8dc735aa23 100644 --- a/drivers/rtc/rtc-tps6594.c +++ b/drivers/rtc/rtc-tps6594.c @@ -360,10 +360,6 @@ static int tps6594_rtc_probe(struct platform_device *pdev) int irq; int ret; - rtc = devm_kzalloc(dev, sizeof(*rtc), GFP_KERNEL); - if (!rtc) - return -ENOMEM; - rtc = devm_rtc_allocate_device(dev); if (IS_ERR(rtc)) return PTR_ERR(rtc); From 29bf97586f189c404c39fe32925c8aea79efbb24 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 18 Jun 2024 16:18:50 +0200 Subject: [PATCH 02/16] rtc: tps6594: introduce private structure as drvdata This patch will prepare for the next one (power management support) by introducing struct tps6594_rtc. No functionnal change. Signed-off-by: Richard Genoud Link: https://lore.kernel.org/r/20240618141851.1810000-3-richard.genoud@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-tps6594.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/rtc/rtc-tps6594.c b/drivers/rtc/rtc-tps6594.c index bc8dc735aa23..06af177b2d78 100644 --- a/drivers/rtc/rtc-tps6594.c +++ b/drivers/rtc/rtc-tps6594.c @@ -42,6 +42,10 @@ // Multiplier for ppb conversions #define PPB_MULT NANO +struct tps6594_rtc { + struct rtc_device *rtc_dev; +}; + static int tps6594_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { @@ -325,11 +329,11 @@ static int tps6594_rtc_set_offset(struct device *dev, long offset) return tps6594_rtc_set_calibration(dev, calibration); } -static irqreturn_t tps6594_rtc_interrupt(int irq, void *rtc) +static irqreturn_t tps6594_rtc_interrupt(int irq, void *data) { - struct device *dev = rtc; + struct device *dev = data; struct tps6594 *tps = dev_get_drvdata(dev->parent); - struct rtc_device *rtc_dev = dev_get_drvdata(dev); + struct tps6594_rtc *rtc = dev_get_drvdata(dev); int ret; u32 rtc_reg; @@ -337,7 +341,7 @@ static irqreturn_t tps6594_rtc_interrupt(int irq, void *rtc) if (ret) return IRQ_NONE; - rtc_update_irq(rtc_dev, 1, RTC_IRQF | RTC_AF); + rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF); return IRQ_HANDLED; } @@ -356,13 +360,17 @@ static int tps6594_rtc_probe(struct platform_device *pdev) { struct tps6594 *tps = dev_get_drvdata(pdev->dev.parent); struct device *dev = &pdev->dev; - struct rtc_device *rtc; + struct tps6594_rtc *rtc; int irq; int ret; - rtc = devm_rtc_allocate_device(dev); - if (IS_ERR(rtc)) - return PTR_ERR(rtc); + rtc = devm_kzalloc(dev, sizeof(*rtc), GFP_KERNEL); + if (!rtc) + return -ENOMEM; + + rtc->rtc_dev = devm_rtc_allocate_device(dev); + if (IS_ERR(rtc->rtc_dev)) + return PTR_ERR(rtc->rtc_dev); // Enable crystal oscillator. ret = regmap_set_bits(tps->regmap, TPS6594_REG_RTC_CTRL_2, @@ -423,11 +431,11 @@ static int tps6594_rtc_probe(struct platform_device *pdev) return dev_err_probe(dev, ret, "Failed to init rtc as wakeup source\n"); - rtc->ops = &tps6594_rtc_ops; - rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; - rtc->range_max = RTC_TIMESTAMP_END_2099; + rtc->rtc_dev->ops = &tps6594_rtc_ops; + rtc->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_2000; + rtc->rtc_dev->range_max = RTC_TIMESTAMP_END_2099; - return devm_rtc_register_device(rtc); + return devm_rtc_register_device(rtc->rtc_dev); } static const struct platform_device_id tps6594_rtc_id_table[] = { From c88014c7aa5c4cd39c3a5f4830f6fb525c730693 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 18 Jun 2024 16:18:51 +0200 Subject: [PATCH 03/16] rtc: tps6594: Add power management support Add power management support to the driver. This allows a SoC to wake from suspend using the nINT provided by the RTC. It takes care of the case when the interrupt has not been caught because the kernel has not yet woke up. (This is the case when only edges interrupt are caught) Signed-off-by: Richard Genoud Link: https://lore.kernel.org/r/20240618141851.1810000-4-richard.genoud@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-tps6594.c | 47 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/drivers/rtc/rtc-tps6594.c b/drivers/rtc/rtc-tps6594.c index 06af177b2d78..e69667634137 100644 --- a/drivers/rtc/rtc-tps6594.c +++ b/drivers/rtc/rtc-tps6594.c @@ -44,6 +44,7 @@ struct tps6594_rtc { struct rtc_device *rtc_dev; + int irq; }; static int tps6594_rtc_alarm_irq_enable(struct device *dev, @@ -419,6 +420,8 @@ static int tps6594_rtc_probe(struct platform_device *pdev) if (irq < 0) return dev_err_probe(dev, irq, "Failed to get irq\n"); + rtc->irq = irq; + ret = devm_request_threaded_irq(dev, irq, NULL, tps6594_rtc_interrupt, IRQF_ONESHOT, TPS6594_IRQ_NAME_ALARM, dev); @@ -438,6 +441,49 @@ static int tps6594_rtc_probe(struct platform_device *pdev) return devm_rtc_register_device(rtc->rtc_dev); } +static int tps6594_rtc_resume(struct device *dev) +{ + struct tps6594 *tps = dev_get_drvdata(dev->parent); + struct tps6594_rtc *rtc = dev_get_drvdata(dev); + int ret; + + ret = regmap_test_bits(tps->regmap, TPS6594_REG_INT_STARTUP, + TPS6594_BIT_RTC_INT); + if (ret < 0) { + dev_err(dev, "failed to read REG_INT_STARTUP: %d\n", ret); + goto out; + } + + if (ret > 0) { + /* + * If the alarm bit is set, it means that the IRQ has been + * fired. But, the kernel may not have woke up yet when it + * happened. So, we have to clear it. + */ + ret = regmap_write(tps->regmap, TPS6594_REG_RTC_STATUS, + TPS6594_BIT_ALARM); + if (ret < 0) + dev_err(dev, "error clearing alarm bit: %d", ret); + + rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF); + } +out: + disable_irq_wake(rtc->irq); + + return 0; +} + +static int tps6594_rtc_suspend(struct device *dev) +{ + struct tps6594_rtc *rtc = dev_get_drvdata(dev); + + enable_irq_wake(rtc->irq); + + return 0; +} + +static DEFINE_SIMPLE_DEV_PM_OPS(tps6594_rtc_pm_ops, tps6594_rtc_suspend, tps6594_rtc_resume); + static const struct platform_device_id tps6594_rtc_id_table[] = { { "tps6594-rtc", }, {} @@ -448,6 +494,7 @@ static struct platform_driver tps6594_rtc_driver = { .probe = tps6594_rtc_probe, .driver = { .name = "tps6594-rtc", + .pm = pm_sleep_ptr(&tps6594_rtc_pm_ops), }, .id_table = tps6594_rtc_id_table, }; From 70f1ae5f0e7f44edf842444044615da7b59838c1 Mon Sep 17 00:00:00 2001 From: Joy Chakraborty Date: Wed, 12 Jun 2024 08:08:31 +0000 Subject: [PATCH 04/16] rtc: isl1208: Fix return value of nvmem callbacks Read/write callbacks registered with nvmem core expect 0 to be returned on success and a negative value to be returned on failure. isl1208_nvmem_read()/isl1208_nvmem_write() currently return the number of bytes read/written on success, fix to return 0 on success and negative on failure. Fixes: c3544f6f51ed ("rtc: isl1208: Add new style nvmem support to driver") Cc: stable@vger.kernel.org Signed-off-by: Joy Chakraborty Link: https://lore.kernel.org/r/20240612080831.1227131-1-joychakr@google.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-isl1208.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index e50c23ee1646..206f96b90f58 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c @@ -775,14 +775,13 @@ static int isl1208_nvmem_read(void *priv, unsigned int off, void *buf, { struct isl1208_state *isl1208 = priv; struct i2c_client *client = to_i2c_client(isl1208->rtc->dev.parent); - int ret; /* nvmem sanitizes offset/count for us, but count==0 is possible */ if (!count) return count; - ret = isl1208_i2c_read_regs(client, ISL1208_REG_USR1 + off, buf, + + return isl1208_i2c_read_regs(client, ISL1208_REG_USR1 + off, buf, count); - return ret == 0 ? count : ret; } static int isl1208_nvmem_write(void *priv, unsigned int off, void *buf, @@ -790,15 +789,13 @@ static int isl1208_nvmem_write(void *priv, unsigned int off, void *buf, { struct isl1208_state *isl1208 = priv; struct i2c_client *client = to_i2c_client(isl1208->rtc->dev.parent); - int ret; /* nvmem sanitizes off/count for us, but count==0 is possible */ if (!count) return count; - ret = isl1208_i2c_set_regs(client, ISL1208_REG_USR1 + off, buf, - count); - return ret == 0 ? count : ret; + return isl1208_i2c_set_regs(client, ISL1208_REG_USR1 + off, buf, + count); } static const struct nvmem_config isl1208_nvmem_config = { From 1c184baccf0d5e2ef4cc1562261d0e48508a1c2b Mon Sep 17 00:00:00 2001 From: Joy Chakraborty Date: Wed, 12 Jun 2024 08:36:35 +0000 Subject: [PATCH 05/16] rtc: cmos: Fix return value of nvmem callbacks Read/write callbacks registered with nvmem core expect 0 to be returned on success and a negative value to be returned on failure. cmos_nvram_read()/cmos_nvram_write() currently return the number of bytes read or written, fix to return 0 on success and -EIO incase number of bytes requested was not read or written. Fixes: 8b5b7958fd1c ("rtc: cmos: use generic nvmem") Cc: stable@vger.kernel.org Signed-off-by: Joy Chakraborty Reviewed-by: Dan Carpenter Link: https://lore.kernel.org/r/20240612083635.1253039-1-joychakr@google.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-cmos.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 7d99cd2c37a0..35dca2accbb8 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -643,11 +643,10 @@ static int cmos_nvram_read(void *priv, unsigned int off, void *val, size_t count) { unsigned char *buf = val; - int retval; off += NVRAM_OFFSET; spin_lock_irq(&rtc_lock); - for (retval = 0; count; count--, off++, retval++) { + for (; count; count--, off++) { if (off < 128) *buf++ = CMOS_READ(off); else if (can_bank2) @@ -657,7 +656,7 @@ static int cmos_nvram_read(void *priv, unsigned int off, void *val, } spin_unlock_irq(&rtc_lock); - return retval; + return count ? -EIO : 0; } static int cmos_nvram_write(void *priv, unsigned int off, void *val, @@ -665,7 +664,6 @@ static int cmos_nvram_write(void *priv, unsigned int off, void *val, { struct cmos_rtc *cmos = priv; unsigned char *buf = val; - int retval; /* NOTE: on at least PCs and Ataris, the boot firmware uses a * checksum on part of the NVRAM data. That's currently ignored @@ -674,7 +672,7 @@ static int cmos_nvram_write(void *priv, unsigned int off, void *val, */ off += NVRAM_OFFSET; spin_lock_irq(&rtc_lock); - for (retval = 0; count; count--, off++, retval++) { + for (; count; count--, off++) { /* don't trash RTC registers */ if (off == cmos->day_alrm || off == cmos->mon_alrm @@ -689,7 +687,7 @@ static int cmos_nvram_write(void *priv, unsigned int off, void *val, } spin_unlock_irq(&rtc_lock); - return retval; + return count ? -EIO : 0; } /*----------------------------------------------------------------*/ From fc82336b50e7652530bc32caec80be0f8792513b Mon Sep 17 00:00:00 2001 From: Joy Chakraborty Date: Thu, 13 Jun 2024 12:07:50 +0000 Subject: [PATCH 06/16] rtc: abx80x: Fix return value of nvmem callback on read Read callbacks registered with nvmem core expect 0 to be returned on success and a negative value to be returned on failure. abx80x_nvmem_xfer() on read calls i2c_smbus_read_i2c_block_data() which returns the number of bytes read on success as per its api description, this return value is handled as an error and returned to nvmem even on success. Fix to handle all possible values that would be returned by i2c_smbus_read_i2c_block_data(). Fixes: e90ff8ede777 ("rtc: abx80x: Add nvmem support") Cc: stable@vger.kernel.org Signed-off-by: Joy Chakraborty Reviewed-by: Dan Carpenter Reviewed-by: Sean Anderson Link: https://lore.kernel.org/r/20240613120750.1455209-1-joychakr@google.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-abx80x.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c index fde2b8054c2e..1298962402ff 100644 --- a/drivers/rtc/rtc-abx80x.c +++ b/drivers/rtc/rtc-abx80x.c @@ -705,14 +705,18 @@ static int abx80x_nvmem_xfer(struct abx80x_priv *priv, unsigned int offset, if (ret) return ret; - if (write) + if (write) { ret = i2c_smbus_write_i2c_block_data(priv->client, reg, len, val); - else + if (ret) + return ret; + } else { ret = i2c_smbus_read_i2c_block_data(priv->client, reg, len, val); - if (ret) - return ret; + if (ret <= 0) + return ret ? ret : -EIO; + len = ret; + } offset += len; val += len; From 86e9b5085d756aa05665248cc7eb503d5246a9d1 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Sat, 8 Jun 2024 22:52:03 -0700 Subject: [PATCH 07/16] rtc: add missing MODULE_DESCRIPTION() macro On x86, make allmodconfig && make W=1 C=1 reports: WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/rtc/lib_test.o WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/rtc/rtc-goldfish.o WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/rtc/rtc-omap.o WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/rtc/rtc-rc5t583.o WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/rtc/rtc-tps65910.o WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/rtc/rtc-twl.o Add the missing invocation of the MODULE_DESCRIPTION() macro to all files which have a MODULE_LICENSE(). This includes rtc-mpc5121.c, which does not produce a warning with the x86 allmodconfig since it is not built for x86, but it may cause this warning with Freescale PPC configurations. Signed-off-by: Jeff Johnson Link: https://lore.kernel.org/r/20240608-md-drivers-rtc-v1-1-5f44222adfae@quicinc.com Signed-off-by: Alexandre Belloni --- drivers/rtc/lib_test.c | 1 + drivers/rtc/rtc-goldfish.c | 1 + drivers/rtc/rtc-mpc5121.c | 1 + drivers/rtc/rtc-omap.c | 1 + drivers/rtc/rtc-rc5t583.c | 1 + drivers/rtc/rtc-tps65910.c | 1 + drivers/rtc/rtc-twl.c | 1 + 7 files changed, 7 insertions(+) diff --git a/drivers/rtc/lib_test.c b/drivers/rtc/lib_test.c index 3893a202e9ea..c30c759662e3 100644 --- a/drivers/rtc/lib_test.c +++ b/drivers/rtc/lib_test.c @@ -97,4 +97,5 @@ static struct kunit_suite rtc_lib_test_suite = { kunit_test_suite(rtc_lib_test_suite); +MODULE_DESCRIPTION("KUnit test for RTC lib functions"); MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-goldfish.c b/drivers/rtc/rtc-goldfish.c index 59c0f38cc08d..53ec7173c28e 100644 --- a/drivers/rtc/rtc-goldfish.c +++ b/drivers/rtc/rtc-goldfish.c @@ -203,4 +203,5 @@ static struct platform_driver goldfish_rtc = { module_platform_driver(goldfish_rtc); +MODULE_DESCRIPTION("Android Goldfish Real Time Clock driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index 28858fcaea8f..71eafe4fbc72 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c @@ -403,5 +403,6 @@ static struct platform_driver mpc5121_rtc_driver = { module_platform_driver(mpc5121_rtc_driver); +MODULE_DESCRIPTION("Freescale MPC5121 built-in RTC driver"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("John Rigby "); diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index c6155c48a4ac..e6b2a9c15b54 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c @@ -1027,4 +1027,5 @@ static struct platform_driver omap_rtc_driver = { module_platform_driver(omap_rtc_driver); MODULE_AUTHOR("George G. Davis (and others)"); +MODULE_DESCRIPTION("TI OMAP1, AM33xx, DA8xx/OMAP-L13x, AM43xx and DRA7xx RTC driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-rc5t583.c b/drivers/rtc/rtc-rc5t583.c index 6f4bf919827a..115c46f862f9 100644 --- a/drivers/rtc/rtc-rc5t583.c +++ b/drivers/rtc/rtc-rc5t583.c @@ -308,4 +308,5 @@ static struct platform_driver rc5t583_rtc_driver = { module_platform_driver(rc5t583_rtc_driver); MODULE_ALIAS("platform:rtc-rc5t583"); MODULE_AUTHOR("Venu Byravarasu "); +MODULE_DESCRIPTION("RICOH 5T583 RTC driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/rtc/rtc-tps65910.c b/drivers/rtc/rtc-tps65910.c index 411ff66c0468..2ea1bbfbbc2a 100644 --- a/drivers/rtc/rtc-tps65910.c +++ b/drivers/rtc/rtc-tps65910.c @@ -466,4 +466,5 @@ static struct platform_driver tps65910_rtc_driver = { module_platform_driver(tps65910_rtc_driver); MODULE_ALIAS("platform:tps65910-rtc"); MODULE_AUTHOR("Venu Byravarasu "); +MODULE_DESCRIPTION("TI TPS65910 RTC driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index 13f8ce08243c..2cfacdd37e09 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c @@ -685,4 +685,5 @@ static struct platform_driver twl4030rtc_driver = { module_platform_driver(twl4030rtc_driver); MODULE_AUTHOR("Texas Instruments, MontaVista Software"); +MODULE_DESCRIPTION("TI TWL4030/TWL5030/TWL6030/TPS659x0 RTC driver"); MODULE_LICENSE("GPL"); From 840ac611fbbec3a5dff37ee4fba6b2130eb6cc50 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Tue, 28 May 2024 14:43:59 -0400 Subject: [PATCH 08/16] dt-bindings: rtc: Convert rtc-fsl-ftm-alarm.txt to yaml format Convert dt-binding doc "rtc-fsl-ftm-alarm.txt" to yaml format. Change example's reg to 32bit address and length. Remove unrelated rcpm@1e34040 in example. Signed-off-by: Frank Li Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240528184359.2685109-1-Frank.Li@nxp.com Signed-off-by: Alexandre Belloni --- .../bindings/rtc/fsl,ls-ftm-alarm.yaml | 73 +++++++++++++++++++ .../bindings/rtc/rtc-fsl-ftm-alarm.txt | 36 --------- 2 files changed, 73 insertions(+), 36 deletions(-) create mode 100644 Documentation/devicetree/bindings/rtc/fsl,ls-ftm-alarm.yaml delete mode 100644 Documentation/devicetree/bindings/rtc/rtc-fsl-ftm-alarm.txt diff --git a/Documentation/devicetree/bindings/rtc/fsl,ls-ftm-alarm.yaml b/Documentation/devicetree/bindings/rtc/fsl,ls-ftm-alarm.yaml new file mode 100644 index 000000000000..388102ae30cd --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/fsl,ls-ftm-alarm.yaml @@ -0,0 +1,73 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/rtc/fsl,ls-ftm-alarm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Freescale FlexTimer Module (FTM) Alarm + +maintainers: + - Frank Li + +properties: + compatible: + enum: + - fsl,ls1012a-ftm-alarm + - fsl,ls1021a-ftm-alarm + - fsl,ls1028a-ftm-alarm + - fsl,ls1043a-ftm-alarm + - fsl,ls1046a-ftm-alarm + - fsl,ls1088a-ftm-alarm + - fsl,ls208xa-ftm-alarm + - fsl,lx2160a-ftm-alarm + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + fsl,rcpm-wakeup: + $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: phandle to rcpm node + - description: bit mask of IPPDEXPCR0 + - description: bit mask of IPPDEXPCR1 + - description: bit mask of IPPDEXPCR2 + - description: bit mask of IPPDEXPCR3 + - description: bit mask of IPPDEXPCR4 + - description: bit mask of IPPDEXPCR5 + - description: bit mask of IPPDEXPCR6 + minItems: 1 + description: + phandle to rcpm node, Please refer + Documentation/devicetree/bindings/soc/fsl/rcpm.txt + + big-endian: + $ref: /schemas/types.yaml#/definitions/flag + description: + If the host controller is big-endian mode, specify this property. + The default endian mode is little-endian. + +required: + - compatible + - reg + - interrupts + - fsl,rcpm-wakeup + +allOf: + - $ref: rtc.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + + rtc@2800000 { + compatible = "fsl,ls1088a-ftm-alarm"; + reg = <0x2800000 0x10000>; + fsl,rcpm-wakeup = <&rcpm 0x0 0x0 0x0 0x0 0x4000 0x0>; + interrupts = ; + }; diff --git a/Documentation/devicetree/bindings/rtc/rtc-fsl-ftm-alarm.txt b/Documentation/devicetree/bindings/rtc/rtc-fsl-ftm-alarm.txt deleted file mode 100644 index fffac74999da..000000000000 --- a/Documentation/devicetree/bindings/rtc/rtc-fsl-ftm-alarm.txt +++ /dev/null @@ -1,36 +0,0 @@ -Freescale FlexTimer Module (FTM) Alarm - -Required properties: -- compatible : Should be "fsl,-ftm-alarm", the - supported chips include - "fsl,ls1012a-ftm-alarm" - "fsl,ls1021a-ftm-alarm" - "fsl,ls1028a-ftm-alarm" - "fsl,ls1043a-ftm-alarm" - "fsl,ls1046a-ftm-alarm" - "fsl,ls1088a-ftm-alarm" - "fsl,ls208xa-ftm-alarm" - "fsl,lx2160a-ftm-alarm" -- reg : Specifies base physical address and size of the register sets for the - FlexTimer Module. -- interrupts : Should be the FlexTimer Module interrupt. -- fsl,rcpm-wakeup property and rcpm node : Please refer - Documentation/devicetree/bindings/soc/fsl/rcpm.txt - -Optional properties: -- big-endian: If the host controller is big-endian mode, specify this property. - The default endian mode is little-endian. - -Example: -rcpm: rcpm@1e34040 { - compatible = "fsl,ls1088a-rcpm", "fsl,qoriq-rcpm-2.1+"; - reg = <0x0 0x1e34040 0x0 0x18>; - #fsl,rcpm-wakeup-cells = <6>; -}; - -ftm_alarm0: timer@2800000 { - compatible = "fsl,ls1088a-ftm-alarm"; - reg = <0x0 0x2800000 0x0 0x10000>; - fsl,rcpm-wakeup = <&rcpm 0x0 0x0 0x0 0x0 0x4000 0x0>; - interrupts = <0 44 4>; -}; From 0dbd610c426ed695eef5d26584259d96b6250c76 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Tue, 18 Jun 2024 16:26:30 +0100 Subject: [PATCH 09/16] rtc: isl1208: Add a delay for clearing alarm As per the latest HW manual[1], the INT# output is pulled low after the alarm is triggered. After the INT# output is pulled low, it is low for at least 250ms, even if the correct action is taken to clear it. It is impossible to clear ALM if it is still active. The host must wait for the RTC to progress past the alarm time plus the 250ms delay before clearing ALM. [1]https://www.renesas.com/us/en/document/dst/raa215300-datasheet?r=1506351 Signed-off-by: Biju Das Link: https://lore.kernel.org/r/20240618152635.48956-2-biju.das.jz@bp.renesas.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-isl1208.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index 206f96b90f58..6877e2f3bde6 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -628,6 +629,18 @@ isl1208_rtc_interrupt(int irq, void *data) struct isl1208_state *isl1208 = i2c_get_clientdata(client); int handled = 0, sr, err; + if (!isl1208->config->has_tamper) { + /* + * The INT# output is pulled low 250ms after the alarm is + * triggered. After the INT# output is pulled low, it is low for + * at least 250ms, even if the correct action is taken to clear + * it. It is impossible to clear ALM if it is still active. The + * host must wait for the RTC to progress past the alarm time + * plus the 250ms delay before clearing ALM. + */ + msleep(250); + } + /* * I2C reads get NAK'ed if we read straight away after an interrupt? * Using a mdelay/msleep didn't seem to help either, so we work around From 43696b3a9e46cf622bfeb70856b9b1cfa5a9fb23 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Tue, 18 Jun 2024 16:26:31 +0100 Subject: [PATCH 10/16] rtc: isl1208: Update correct procedure for clearing alarm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per the latest HW manual[1], there is an internal delay(~250 microsec) from setting ALME = 0 to disabling the alarm function, so the user must add a short delay of greater than 250µs between setting ALME = 0 and clearing ALM. Currently setting of ALME = 0 is done after clearing the ALM, so just reverse the operation and add a delay of 275 microsec. [1]https://www.renesas.com/us/en/document/dst/raa215300-datasheet?r=1506351 Signed-off-by: Biju Das Link: https://lore.kernel.org/r/20240618152635.48956-3-biju.das.jz@bp.renesas.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-isl1208.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index 6877e2f3bde6..7b82e4a14b7a 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c @@ -663,6 +663,13 @@ isl1208_rtc_interrupt(int irq, void *data) rtc_update_irq(isl1208->rtc, 1, RTC_IRQF | RTC_AF); + /* Disable the alarm */ + err = isl1208_rtc_toggle_alarm(client, 0); + if (err) + return err; + + fsleep(275); + /* Clear the alarm */ sr &= ~ISL1208_REG_SR_ALM; sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, sr); @@ -671,11 +678,6 @@ isl1208_rtc_interrupt(int irq, void *data) __func__); else handled = 1; - - /* Disable the alarm */ - err = isl1208_rtc_toggle_alarm(client, 0); - if (err) - return err; } if (isl1208->config->has_tamper && (sr & ISL1208_REG_SR_EVT)) { From 35a34f09baed51216455740e01bd132cf60c71cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cs=C3=B3k=C3=A1s=2C=20Bence?= Date: Tue, 11 Jun 2024 09:24:08 +0200 Subject: [PATCH 11/16] rtc: ds1307: Detect oscillator fail on mcp794xx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch enables the detection of the oscillator failure on mcp794xx chips. Co-developed-by: Szentendrei, Tamás Signed-off-by: Szentendrei, Tamás Signed-off-by: Csókás, Bence Link: https://lore.kernel.org/r/20240611072411.671600-1-csokas.bence@prolan.hu Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 506b7d1c2397..bdb7b201a160 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -65,6 +65,7 @@ enum ds_type { # define DS1340_BIT_CENTURY_EN 0x80 /* in REG_HOUR */ # define DS1340_BIT_CENTURY 0x40 /* in REG_HOUR */ #define DS1307_REG_WDAY 0x03 /* 01-07 */ +# define MCP794XX_BIT_OSCRUN BIT(5) # define MCP794XX_BIT_VBATEN 0x08 #define DS1307_REG_MDAY 0x04 /* 01-31 */ #define DS1307_REG_MONTH 0x05 /* 01-12 */ @@ -242,6 +243,10 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t) regs[DS1307_REG_MIN] & M41T0_BIT_OF) { dev_warn_once(dev, "oscillator failed, set time!\n"); return -EINVAL; + } else if (ds1307->type == mcp794xx && + !(regs[DS1307_REG_WDAY] & MCP794XX_BIT_OSCRUN)) { + dev_warn_once(dev, "oscillator failed, set time!\n"); + return -EINVAL; } tmp = regs[DS1307_REG_SECS]; From 68f78c720da4088d254250867126c6ae5b68fa2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cs=C3=B3k=C3=A1s=2C=20Bence?= Date: Tue, 11 Jun 2024 09:24:09 +0200 Subject: [PATCH 12/16] rtc: ds1307: Clamp year to valid BCD (0-99) in `set_time()` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `tm_year` may go up to 299 if the device supports the century bit. Therefore, subtracting may not give us a valid 2-digit number, but modulo does. Co-developed-by: Szentendrei, Tamás Signed-off-by: Szentendrei, Tamás Signed-off-by: Csókás, Bence Link: https://lore.kernel.org/r/20240611072411.671600-2-csokas.bence@prolan.hu Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index bdb7b201a160..872e0b679be4 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -359,7 +359,7 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) regs[DS1307_REG_MONTH] = bin2bcd(t->tm_mon + 1); /* assume 20YY not 19YY */ - tmp = t->tm_year - 100; + tmp = t->tm_year % 100; regs[DS1307_REG_YEAR] = bin2bcd(tmp); if (chip->century_enable_bit) From 463927a8902a9f22c3633960119410f57d4c8920 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cs=C3=B3k=C3=A1s=2C=20Bence?= Date: Wed, 19 Jun 2024 16:04:52 +0200 Subject: [PATCH 13/16] rtc: interface: Add RTC offset to alarm after fix-up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `rtc_add_offset()` is called by `__rtc_read_time()` and `__rtc_read_alarm()` to add the RTC's offset to the raw read-outs from the device drivers. However, in the latter case, a fix-up algorithm is run if the RTC device does not report a full `struct rtc_time` alarm value. In that case, the offset was forgot to be added. Fixes: fd6792bb022e ("rtc: fix alarm read and set offset") Signed-off-by: Csókás, Bence Link: https://lore.kernel.org/r/20240619140451.2800578-1-csokas.bence@prolan.hu Signed-off-by: Alexandre Belloni --- drivers/rtc/interface.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 5faafb4aa55c..cca650b2e0b9 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -274,10 +274,9 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) return err; /* full-function RTCs won't have such missing fields */ - if (rtc_valid_tm(&alarm->time) == 0) { - rtc_add_offset(rtc, &alarm->time); - return 0; - } + err = rtc_valid_tm(&alarm->time); + if (!err) + goto done; /* get the "after" timestamp, to detect wrapped fields */ err = rtc_read_time(rtc, &now); @@ -379,6 +378,8 @@ done: if (err && alarm->enabled) dev_warn(&rtc->dev, "invalid alarm value: %ptR\n", &alarm->time); + else + rtc_add_offset(rtc, &alarm->time); return err; } From a47d377e22c4a896a87a18db33f26cc6d5cc9771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Wed, 15 May 2024 21:43:37 +0200 Subject: [PATCH 14/16] rtc: Drop explicit initialization of struct i2c_device_id::driver_data to 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These drivers don't use the driver_data member of struct i2c_device_id, so don't explicitly initialize this member. This prepares putting driver_data in an anonymous union which requires either no initialization or named designators. But it's also a nice cleanup on its own. While add it, also remove a comma after the sentinel entry in rtc-hym8563. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20240515194336.58342-2-u.kleine-koenig@pengutronix.de Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ab-b5ze-s3.c | 2 +- drivers/rtc/rtc-ab-eoz9.c | 2 +- drivers/rtc/rtc-bq32k.c | 2 +- drivers/rtc/rtc-ds1374.c | 2 +- drivers/rtc/rtc-ds1672.c | 2 +- drivers/rtc/rtc-ds3232.c | 2 +- drivers/rtc/rtc-em3027.c | 2 +- drivers/rtc/rtc-fm3130.c | 2 +- drivers/rtc/rtc-hym8563.c | 4 ++-- drivers/rtc/rtc-isl12022.c | 2 +- drivers/rtc/rtc-max31335.c | 2 +- drivers/rtc/rtc-max6900.c | 2 +- drivers/rtc/rtc-nct3018y.c | 2 +- drivers/rtc/rtc-pcf8523.c | 2 +- drivers/rtc/rtc-pcf8563.c | 6 +++--- drivers/rtc/rtc-pcf8583.c | 2 +- drivers/rtc/rtc-rv3029c2.c | 4 ++-- drivers/rtc/rtc-rx6110.c | 2 +- drivers/rtc/rtc-rx8010.c | 2 +- drivers/rtc/rtc-rx8581.c | 2 +- drivers/rtc/rtc-s35390a.c | 2 +- drivers/rtc/rtc-sd3078.c | 2 +- drivers/rtc/rtc-x1205.c | 2 +- 23 files changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/rtc/rtc-ab-b5ze-s3.c b/drivers/rtc/rtc-ab-b5ze-s3.c index 100062001831..684f9898d768 100644 --- a/drivers/rtc/rtc-ab-b5ze-s3.c +++ b/drivers/rtc/rtc-ab-b5ze-s3.c @@ -933,7 +933,7 @@ MODULE_DEVICE_TABLE(of, abb5zes3_dt_match); #endif static const struct i2c_device_id abb5zes3_id[] = { - { "abb5zes3", 0 }, + { "abb5zes3" }, { } }; MODULE_DEVICE_TABLE(i2c, abb5zes3_id); diff --git a/drivers/rtc/rtc-ab-eoz9.c b/drivers/rtc/rtc-ab-eoz9.c index 04e1b8e93bc1..02f7d0711287 100644 --- a/drivers/rtc/rtc-ab-eoz9.c +++ b/drivers/rtc/rtc-ab-eoz9.c @@ -575,7 +575,7 @@ MODULE_DEVICE_TABLE(of, abeoz9_dt_match); #endif static const struct i2c_device_id abeoz9_id[] = { - { "abeoz9", 0 }, + { "abeoz9" }, { } }; diff --git a/drivers/rtc/rtc-bq32k.c b/drivers/rtc/rtc-bq32k.c index 591e42391747..7ad34539be4d 100644 --- a/drivers/rtc/rtc-bq32k.c +++ b/drivers/rtc/rtc-bq32k.c @@ -304,7 +304,7 @@ static void bq32k_remove(struct i2c_client *client) } static const struct i2c_device_id bq32k_id[] = { - { "bq32000", 0 }, + { "bq32000" }, { } }; MODULE_DEVICE_TABLE(i2c, bq32k_id); diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index 4a5005cb23f5..c2359eb86bc9 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c @@ -52,7 +52,7 @@ #define DS1374_REG_TCR 0x09 /* Trickle Charge */ static const struct i2c_device_id ds1374_id[] = { - { "ds1374", 0 }, + { "ds1374" }, { } }; MODULE_DEVICE_TABLE(i2c, ds1374_id); diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c index 641799f30baa..6e5314215d00 100644 --- a/drivers/rtc/rtc-ds1672.c +++ b/drivers/rtc/rtc-ds1672.c @@ -133,7 +133,7 @@ static int ds1672_probe(struct i2c_client *client) } static const struct i2c_device_id ds1672_id[] = { - { "ds1672", 0 }, + { "ds1672" }, { } }; MODULE_DEVICE_TABLE(i2c, ds1672_id); diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index 1485a6ae51e6..dd37b055693c 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c @@ -586,7 +586,7 @@ static int ds3232_i2c_probe(struct i2c_client *client) } static const struct i2c_device_id ds3232_id[] = { - { "ds3232", 0 }, + { "ds3232" }, { } }; MODULE_DEVICE_TABLE(i2c, ds3232_id); diff --git a/drivers/rtc/rtc-em3027.c b/drivers/rtc/rtc-em3027.c index fc772eae5da5..dc1ccbc65dcb 100644 --- a/drivers/rtc/rtc-em3027.c +++ b/drivers/rtc/rtc-em3027.c @@ -129,7 +129,7 @@ static int em3027_probe(struct i2c_client *client) } static const struct i2c_device_id em3027_id[] = { - { "em3027", 0 }, + { "em3027" }, { } }; MODULE_DEVICE_TABLE(i2c, em3027_id); diff --git a/drivers/rtc/rtc-fm3130.c b/drivers/rtc/rtc-fm3130.c index 400ce4ad0c49..f82728ebac0c 100644 --- a/drivers/rtc/rtc-fm3130.c +++ b/drivers/rtc/rtc-fm3130.c @@ -53,7 +53,7 @@ struct fm3130 { int data_valid; }; static const struct i2c_device_id fm3130_id[] = { - { "fm3130", 0 }, + { "fm3130" }, { } }; MODULE_DEVICE_TABLE(i2c, fm3130_id); diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c index b018535c842b..63f11ea3589d 100644 --- a/drivers/rtc/rtc-hym8563.c +++ b/drivers/rtc/rtc-hym8563.c @@ -559,8 +559,8 @@ static int hym8563_probe(struct i2c_client *client) } static const struct i2c_device_id hym8563_id[] = { - { "hym8563", 0 }, - {}, + { "hym8563" }, + {} }; MODULE_DEVICE_TABLE(i2c, hym8563_id); diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c index 4eef7afcc8bc..6fa9a68af9d9 100644 --- a/drivers/rtc/rtc-isl12022.c +++ b/drivers/rtc/rtc-isl12022.c @@ -366,7 +366,7 @@ static const struct of_device_id isl12022_dt_match[] = { MODULE_DEVICE_TABLE(of, isl12022_dt_match); static const struct i2c_device_id isl12022_id[] = { - { "isl12022", 0 }, + { "isl12022" }, { } }; MODULE_DEVICE_TABLE(i2c, isl12022_id); diff --git a/drivers/rtc/rtc-max31335.c b/drivers/rtc/rtc-max31335.c index a2441e5c2c74..9a456f537d3b 100644 --- a/drivers/rtc/rtc-max31335.c +++ b/drivers/rtc/rtc-max31335.c @@ -669,7 +669,7 @@ static int max31335_probe(struct i2c_client *client) } static const struct i2c_device_id max31335_id[] = { - { "max31335", 0 }, + { "max31335" }, { } }; diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c index 31b910e4d91a..7be31fce5bc7 100644 --- a/drivers/rtc/rtc-max6900.c +++ b/drivers/rtc/rtc-max6900.c @@ -215,7 +215,7 @@ static int max6900_probe(struct i2c_client *client) } static const struct i2c_device_id max6900_id[] = { - { "max6900", 0 }, + { "max6900" }, { } }; MODULE_DEVICE_TABLE(i2c, max6900_id); diff --git a/drivers/rtc/rtc-nct3018y.c b/drivers/rtc/rtc-nct3018y.c index 7a8b4de893b8..76c5f464b2da 100644 --- a/drivers/rtc/rtc-nct3018y.c +++ b/drivers/rtc/rtc-nct3018y.c @@ -567,7 +567,7 @@ static int nct3018y_probe(struct i2c_client *client) } static const struct i2c_device_id nct3018y_id[] = { - { "nct3018y", 0 }, + { "nct3018y" }, { } }; MODULE_DEVICE_TABLE(i2c, nct3018y_id); diff --git a/drivers/rtc/rtc-pcf8523.c b/drivers/rtc/rtc-pcf8523.c index 98b77f790b0c..2c63c0ffd05a 100644 --- a/drivers/rtc/rtc-pcf8523.c +++ b/drivers/rtc/rtc-pcf8523.c @@ -495,7 +495,7 @@ static int pcf8523_probe(struct i2c_client *client) } static const struct i2c_device_id pcf8523_id[] = { - { "pcf8523", 0 }, + { "pcf8523" }, { } }; MODULE_DEVICE_TABLE(i2c, pcf8523_id); diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 1949d7473310..647d52f1f5c5 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -594,9 +594,9 @@ static int pcf8563_probe(struct i2c_client *client) } static const struct i2c_device_id pcf8563_id[] = { - { "pcf8563", 0 }, - { "rtc8564", 0 }, - { "pca8565", 0 }, + { "pcf8563" }, + { "rtc8564" }, + { "pca8565" }, { } }; MODULE_DEVICE_TABLE(i2c, pcf8563_id); diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c index a7e0fc360b6a..652b9dfa7566 100644 --- a/drivers/rtc/rtc-pcf8583.c +++ b/drivers/rtc/rtc-pcf8583.c @@ -297,7 +297,7 @@ static int pcf8583_probe(struct i2c_client *client) } static const struct i2c_device_id pcf8583_id[] = { - { "pcf8583", 0 }, + { "pcf8583" }, { } }; MODULE_DEVICE_TABLE(i2c, pcf8583_id); diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c index 4a81feeb00ff..83331d1fcab0 100644 --- a/drivers/rtc/rtc-rv3029c2.c +++ b/drivers/rtc/rtc-rv3029c2.c @@ -807,8 +807,8 @@ static int rv3029_i2c_probe(struct i2c_client *client) } static const struct i2c_device_id rv3029_id[] = { - { "rv3029", 0 }, - { "rv3029c2", 0 }, + { "rv3029" }, + { "rv3029c2" }, { } }; MODULE_DEVICE_TABLE(i2c, rv3029_id); diff --git a/drivers/rtc/rtc-rx6110.c b/drivers/rtc/rtc-rx6110.c index af6dd6ccbe3b..7c423d672adb 100644 --- a/drivers/rtc/rtc-rx6110.c +++ b/drivers/rtc/rtc-rx6110.c @@ -451,7 +451,7 @@ static const struct acpi_device_id rx6110_i2c_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, rx6110_i2c_acpi_match); static const struct i2c_device_id rx6110_i2c_id[] = { - { "rx6110", 0 }, + { "rx6110" }, { } }; MODULE_DEVICE_TABLE(i2c, rx6110_i2c_id); diff --git a/drivers/rtc/rtc-rx8010.c b/drivers/rtc/rtc-rx8010.c index f44e212c07de..2b6198d1cf81 100644 --- a/drivers/rtc/rtc-rx8010.c +++ b/drivers/rtc/rtc-rx8010.c @@ -50,7 +50,7 @@ #define RX8010_ALARM_AE BIT(7) static const struct i2c_device_id rx8010_id[] = { - { "rx8010", 0 }, + { "rx8010" }, { } }; MODULE_DEVICE_TABLE(i2c, rx8010_id); diff --git a/drivers/rtc/rtc-rx8581.c b/drivers/rtc/rtc-rx8581.c index 48efd61a114d..b18c12887bdc 100644 --- a/drivers/rtc/rtc-rx8581.c +++ b/drivers/rtc/rtc-rx8581.c @@ -307,7 +307,7 @@ static int rx8581_probe(struct i2c_client *client) } static const struct i2c_device_id rx8581_id[] = { - { "rx8581", 0 }, + { "rx8581" }, { } }; MODULE_DEVICE_TABLE(i2c, rx8581_id); diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index 90a3028ac574..2d6b655a4b25 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c @@ -50,7 +50,7 @@ #define S35390A_INT2_MODE_PMIN (BIT(3) | BIT(2)) /* INT2FE | INT2ME */ static const struct i2c_device_id s35390a_id[] = { - { "s35390a", 0 }, + { "s35390a" }, { } }; MODULE_DEVICE_TABLE(i2c, s35390a_id); diff --git a/drivers/rtc/rtc-sd3078.c b/drivers/rtc/rtc-sd3078.c index 7760394ccd2d..fe27b54beaad 100644 --- a/drivers/rtc/rtc-sd3078.c +++ b/drivers/rtc/rtc-sd3078.c @@ -201,7 +201,7 @@ static int sd3078_probe(struct i2c_client *client) } static const struct i2c_device_id sd3078_id[] = { - {"sd3078", 0}, + { "sd3078" }, { } }; MODULE_DEVICE_TABLE(i2c, sd3078_id); diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index 807f953ae0ae..4bcd7ca32f27 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c @@ -663,7 +663,7 @@ static void x1205_remove(struct i2c_client *client) } static const struct i2c_device_id x1205_id[] = { - { "x1205", 0 }, + { "x1205" }, { } }; MODULE_DEVICE_TABLE(i2c, x1205_id); From 1746a61a0248f93fee11b9ab44c71720d45d713b Mon Sep 17 00:00:00 2001 From: Valentin Caron Date: Mon, 8 Jul 2024 17:34:33 +0200 Subject: [PATCH 15/16] dt-bindings: rtc: stm32: introduce new st,stm32mp25-rtc compatible Introduce new st,stm32mp25-rtc compatible. It is based on st,stm32mp1-rtc. Difference is that stm32mp25 soc implements a triple protection on RTC registers: - Secure bit based protection - Privileged context based protection - Compartment ID filtering based protection This driver will now check theses configurations before probing to avoid exceptions and fake reads on register. Link: https://www.st.com/resource/en/reference_manual/rm0457-stm32mp25xx-advanced-armbased-3264bit-mpus-stmicroelectronics.pdf#page=4081 Signed-off-by: Valentin Caron Reviewed-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20240708153434.416287-2-valentin.caron@foss.st.com Signed-off-by: Alexandre Belloni --- Documentation/devicetree/bindings/rtc/st,stm32-rtc.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.yaml b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.yaml index 4703083d1f11..7a0fab721cf1 100644 --- a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.yaml @@ -15,6 +15,7 @@ properties: - st,stm32-rtc - st,stm32h7-rtc - st,stm32mp1-rtc + - st,stm32mp25-rtc reg: maxItems: 1 @@ -90,7 +91,9 @@ allOf: properties: compatible: contains: - const: st,stm32mp1-rtc + enum: + - st,stm32mp1-rtc + - st,stm32mp25-rtc then: properties: From efa9c5be2caecae7dfa4f29c6ab3d4a2f341eb15 Mon Sep 17 00:00:00 2001 From: Valentin Caron Date: Mon, 8 Jul 2024 17:34:34 +0200 Subject: [PATCH 16/16] rtc: stm32: add new st,stm32mp25-rtc compatible and check RIF configuration Introduce new st,stm32mp25-rtc compatible. It is based on st,stm32mp1-rtc. Difference is that stm32mp25 soc implements a triple protection on RTC registers: - Secure bit based protection - Privileged context based protection - Compartment ID filtering based protection This driver will now check theses configurations before probing to avoid exceptions and fake reads on register. At this time, driver needs only to check two resources: INIT and ALARM_A. Other resources are not used. Resource isolation framework (RIF) is a comprehensive set of hardware blocks designed to enforce and manage isolation of STM32 hardware resources, like memory and peripherals. Link: https://www.st.com/resource/en/reference_manual/rm0457-stm32mp25xx-advanced-armbased-3264bit-mpus-stmicroelectronics.pdf#page=4081 Signed-off-by: Valentin Caron Link: https://lore.kernel.org/r/20240708153434.416287-3-valentin.caron@foss.st.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-stm32.c | 78 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c index 76753c71d92e..98b07969609d 100644 --- a/drivers/rtc/rtc-stm32.c +++ b/drivers/rtc/rtc-stm32.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -83,6 +84,18 @@ #define STM32_RTC_VERR_MAJREV_SHIFT 4 #define STM32_RTC_VERR_MAJREV GENMASK(7, 4) +/* STM32_RTC_SECCFGR bit fields */ +#define STM32_RTC_SECCFGR 0x20 +#define STM32_RTC_SECCFGR_ALRA_SEC BIT(0) +#define STM32_RTC_SECCFGR_INIT_SEC BIT(14) +#define STM32_RTC_SECCFGR_SEC BIT(15) + +/* STM32_RTC_RXCIDCFGR bit fields */ +#define STM32_RTC_RXCIDCFGR(x) (0x80 + 0x4 * (x)) +#define STM32_RTC_RXCIDCFGR_CFEN BIT(0) +#define STM32_RTC_RXCIDCFGR_CID GENMASK(6, 4) +#define STM32_RTC_RXCIDCFGR_CID1 1 + /* STM32_RTC_WPR key constants */ #define RTC_WPR_1ST_KEY 0xCA #define RTC_WPR_2ND_KEY 0x53 @@ -120,6 +133,7 @@ struct stm32_rtc_data { bool has_pclk; bool need_dbp; bool need_accuracy; + bool rif_protected; }; struct stm32_rtc { @@ -134,6 +148,14 @@ struct stm32_rtc { int irq_alarm; }; +struct stm32_rtc_rif_resource { + unsigned int num; + u32 bit; +}; + +static const struct stm32_rtc_rif_resource STM32_RTC_RES_ALRA = {0, STM32_RTC_SECCFGR_ALRA_SEC}; +static const struct stm32_rtc_rif_resource STM32_RTC_RES_INIT = {5, STM32_RTC_SECCFGR_INIT_SEC}; + static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc) { const struct stm32_rtc_registers *regs = &rtc->data->regs; @@ -553,6 +575,7 @@ static const struct stm32_rtc_data stm32_rtc_data = { .has_pclk = false, .need_dbp = true, .need_accuracy = false, + .rif_protected = false, .regs = { .tr = 0x00, .dr = 0x04, @@ -575,6 +598,7 @@ static const struct stm32_rtc_data stm32h7_rtc_data = { .has_pclk = true, .need_dbp = true, .need_accuracy = false, + .rif_protected = false, .regs = { .tr = 0x00, .dr = 0x04, @@ -606,6 +630,7 @@ static const struct stm32_rtc_data stm32mp1_data = { .has_pclk = true, .need_dbp = false, .need_accuracy = true, + .rif_protected = false, .regs = { .tr = 0x00, .dr = 0x04, @@ -624,14 +649,57 @@ static const struct stm32_rtc_data stm32mp1_data = { .clear_events = stm32mp1_rtc_clear_events, }; +static const struct stm32_rtc_data stm32mp25_data = { + .has_pclk = true, + .need_dbp = false, + .need_accuracy = true, + .rif_protected = true, + .regs = { + .tr = 0x00, + .dr = 0x04, + .cr = 0x18, + .isr = 0x0C, /* named RTC_ICSR on stm32mp25 */ + .prer = 0x10, + .alrmar = 0x40, + .wpr = 0x24, + .sr = 0x50, + .scr = 0x5C, + .verr = 0x3F4, + }, + .events = { + .alra = STM32_RTC_SR_ALRA, + }, + .clear_events = stm32mp1_rtc_clear_events, +}; + static const struct of_device_id stm32_rtc_of_match[] = { { .compatible = "st,stm32-rtc", .data = &stm32_rtc_data }, { .compatible = "st,stm32h7-rtc", .data = &stm32h7_rtc_data }, { .compatible = "st,stm32mp1-rtc", .data = &stm32mp1_data }, + { .compatible = "st,stm32mp25-rtc", .data = &stm32mp25_data }, {} }; MODULE_DEVICE_TABLE(of, stm32_rtc_of_match); +static int stm32_rtc_check_rif(struct stm32_rtc *stm32_rtc, + struct stm32_rtc_rif_resource res) +{ + u32 rxcidcfgr = readl_relaxed(stm32_rtc->base + STM32_RTC_RXCIDCFGR(res.num)); + u32 seccfgr; + + /* Check if RTC available for our CID */ + if ((rxcidcfgr & STM32_RTC_RXCIDCFGR_CFEN) && + (FIELD_GET(STM32_RTC_RXCIDCFGR_CID, rxcidcfgr) != STM32_RTC_RXCIDCFGR_CID1)) + return -EACCES; + + /* Check if RTC available for non secure world */ + seccfgr = readl_relaxed(stm32_rtc->base + STM32_RTC_SECCFGR); + if ((seccfgr & STM32_RTC_SECCFGR_SEC) | (seccfgr & res.bit)) + return -EACCES; + + return 0; +} + static int stm32_rtc_init(struct platform_device *pdev, struct stm32_rtc *rtc) { @@ -787,6 +855,16 @@ static int stm32_rtc_probe(struct platform_device *pdev) regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, rtc->dbp_mask); + if (rtc->data->rif_protected) { + ret = stm32_rtc_check_rif(rtc, STM32_RTC_RES_INIT); + if (!ret) + ret = stm32_rtc_check_rif(rtc, STM32_RTC_RES_ALRA); + if (ret) { + dev_err(&pdev->dev, "Failed to probe RTC due to RIF configuration\n"); + goto err; + } + } + /* * After a system reset, RTC_ISR.INITS flag can be read to check if * the calendar has been initialized or not. INITS flag is reset by a