summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-08-28 09:53:43 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-08-28 09:53:43 -0700
commit275bc4eedf2c6081200998954efcb5eb90413a41 (patch)
treef8f0b71a819301d7283fff7cc21f1f9e44170d6f
parentafe0579334f622c803f2864f22c04c20c320bd80 (diff)
parentafce9701d6423a63194a349d2f1e34c50ce76482 (diff)
Merge tag 'rtc-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
Pull RTC updates from Alexandre Belloni: "The RZN1 driver got a fairly comprehensive cleanup. More DT binding are converted to DT schema, leaving only 5 remaining files to convert. Subsystem: - patchwork project is moving to kernel.org - fully initialize clk_init_data - add missing MODULE_DEVICE_TABLE() - DT bindings conversions to DT schema Drivers: - ds1307: fix WADA bit for alarms on RX8130 - rzn1: add support for RZ/T2H and RZ/N2H, many fixes" * tag 'rtc-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (42 commits) MAINTAINERS: update rtc subsystem patchwork location rtc: msc313: Select by default on MSTARV7 rtc: microcrystal: Make sure clk_init_data is fully initialized rtc: philips: Make sure clk_init_data is fully initialized rtc: nct3018y: Make sure clk_init_data is fully initialized rtc: m41t80: Make sure clk_init_data is fully initialized rtc: hym8563: Make sure clk_init_data is fully initialized rtc: rzn1: Add support for Renesas RZ/T2H and RZ/N2H SoCs rtc: rzn1: Drop trailing comma from OF match table sentinel rtc: rzn1: Add OF match data to gate SUBU register access rtc: rzn1: use FIELD_PREP/FIELD_GET and GENMASK for register access rtc: rzn1: Consistently use dev_err_probe() rtc: rzn1: Use temporary variable for struct device rtc: rzn1: Dynamically calculate synchronization delay based on clock rate rtc: rzn1: Replace remove callback with devm_add_action_or_reset() rtc: rzn1: Use pm_runtime_put_sync() rtc: Kconfig: Broaden RTC_DRV_RZN1 dependency to ARCH_RENESAS rtc: rzn1: Fix malformed MODULE_AUTHOR string rtc: rzn1: Disable alarm interrupt before reprogramming alarm registers rtc: rzn1: Fix alarm range check truncation on 32-bit systems ...
-rw-r--r--Documentation/devicetree/bindings/rtc/microchip,pic32-rtc.txt21
-rw-r--r--Documentation/devicetree/bindings/rtc/microchip,pic32mzda-rtc.yaml50
-rw-r--r--Documentation/devicetree/bindings/rtc/renesas,rzn1-rtc.yaml35
-rw-r--r--Documentation/devicetree/bindings/rtc/rtc-cmos.txt27
-rw-r--r--Documentation/devicetree/bindings/rtc/rtc-cmos.yaml63
-rw-r--r--Documentation/devicetree/bindings/rtc/rtc-omap.txt53
-rw-r--r--Documentation/devicetree/bindings/rtc/rtc-palmas.txt32
-rw-r--r--Documentation/devicetree/bindings/rtc/ti,omap-rtc.yaml140
-rw-r--r--Documentation/devicetree/bindings/rtc/ti,palmas-rtc.yaml57
-rw-r--r--MAINTAINERS2
-rw-r--r--drivers/rtc/Kconfig8
-rw-r--r--drivers/rtc/rtc-ab-eoz9.c1
-rw-r--r--drivers/rtc/rtc-brcmstb-waketimer.c1
-rw-r--r--drivers/rtc/rtc-ds1307.c2
-rw-r--r--drivers/rtc/rtc-ds1343.c4
-rw-r--r--drivers/rtc/rtc-gamecube.c4
-rw-r--r--drivers/rtc/rtc-hym8563.c2
-rw-r--r--drivers/rtc/rtc-m41t80.c2
-rw-r--r--drivers/rtc/rtc-mv.c41
-rw-r--r--drivers/rtc/rtc-nct3018y.c2
-rw-r--r--drivers/rtc/rtc-pcf2127.c7
-rw-r--r--drivers/rtc/rtc-pcf85063.c2
-rw-r--r--drivers/rtc/rtc-pcf85363.c17
-rw-r--r--drivers/rtc/rtc-pcf8563.c6
-rw-r--r--drivers/rtc/rtc-rv3028.c2
-rw-r--r--drivers/rtc/rtc-rv3032.c2
-rw-r--r--drivers/rtc/rtc-rzn1.c197
-rw-r--r--drivers/rtc/rtc-s32g.c1
-rw-r--r--drivers/rtc/rtc-spacemit-p1.c5
-rw-r--r--drivers/rtc/rtc-st-lpc.c9
-rw-r--r--drivers/rtc/rtc-zynqmp.c7
31 files changed, 507 insertions, 295 deletions
diff --git a/Documentation/devicetree/bindings/rtc/microchip,pic32-rtc.txt b/Documentation/devicetree/bindings/rtc/microchip,pic32-rtc.txt
deleted file mode 100644
index 180b7144bfcc..000000000000
--- a/Documentation/devicetree/bindings/rtc/microchip,pic32-rtc.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-* Microchip PIC32 Real Time Clock and Calendar
-
-The RTCC keeps time in hours, minutes, and seconds, and one half second. It
-provides a calendar in weekday, date, month, and year. It also provides a
-configurable alarm.
-
-Required properties:
-- compatible: should be: "microchip,pic32mzda-rtc"
-- reg: physical base address of the controller and length of memory mapped
- region.
-- interrupts: RTC alarm/event interrupt
-- clocks: clock phandle
-
-Example:
-
- rtc: rtc@1f8c0000 {
- compatible = "microchip,pic32mzda-rtc";
- reg = <0x1f8c0000 0x60>;
- interrupts = <166 IRQ_TYPE_EDGE_RISING>;
- clocks = <&PBCLK6>;
- };
diff --git a/Documentation/devicetree/bindings/rtc/microchip,pic32mzda-rtc.yaml b/Documentation/devicetree/bindings/rtc/microchip,pic32mzda-rtc.yaml
new file mode 100644
index 000000000000..481ee28c06e3
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/microchip,pic32mzda-rtc.yaml
@@ -0,0 +1,50 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/rtc/microchip,pic32mzda-rtc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip PIC32 Real Time Clock and Calendar
+
+maintainers:
+ - Alexandre Belloni <alexandre.belloni@bootlin.com>
+
+description: |
+ The Microchip PIC32 Real Time Clock and Calendar (RTCC) keeps time in hours,
+ minutes, seconds, and one half second. It also provides a calendar with
+ weekday, date, month, and year, along with a configurable alarm.
+
+allOf:
+ - $ref: rtc.yaml#
+
+properties:
+ compatible:
+ const: microchip,pic32mzda-rtc
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ rtc@1f8c0000 {
+ compatible = "microchip,pic32mzda-rtc";
+ reg = <0x1f8c0000 0x60>;
+ interrupts = <166 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&PBCLK6>;
+ };
diff --git a/Documentation/devicetree/bindings/rtc/renesas,rzn1-rtc.yaml b/Documentation/devicetree/bindings/rtc/renesas,rzn1-rtc.yaml
index 1860f0e4c31a..ea7b039a91e7 100644
--- a/Documentation/devicetree/bindings/rtc/renesas,rzn1-rtc.yaml
+++ b/Documentation/devicetree/bindings/rtc/renesas,rzn1-rtc.yaml
@@ -9,15 +9,19 @@ title: Renesas RZ/N1 SoCs Real-Time Clock
maintainers:
- Miquel Raynal <miquel.raynal@bootlin.com>
-allOf:
- - $ref: rtc.yaml#
-
properties:
compatible:
- items:
- - enum:
- - renesas,r9a06g032-rtc
- - const: renesas,rzn1-rtc
+ oneOf:
+ - items:
+ - enum:
+ - renesas,r9a06g032-rtc
+ - const: renesas,rzn1-rtc
+
+ - const: renesas,r9a09g077-rtc
+
+ - items:
+ - const: renesas,r9a09g087-rtc
+ - const: renesas,r9a09g077-rtc
reg:
maxItems: 1
@@ -54,6 +58,23 @@ required:
- clock-names
- power-domains
+allOf:
+ - $ref: rtc.yaml#
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - renesas,r9a09g077-rtc
+ - renesas,r9a09g087-rtc
+ then:
+ properties:
+ clocks:
+ minItems: 2
+ clock-names:
+ minItems: 2
+
unevaluatedProperties: false
examples:
diff --git a/Documentation/devicetree/bindings/rtc/rtc-cmos.txt b/Documentation/devicetree/bindings/rtc/rtc-cmos.txt
deleted file mode 100644
index 7d7b5f6bda65..000000000000
--- a/Documentation/devicetree/bindings/rtc/rtc-cmos.txt
+++ /dev/null
@@ -1,27 +0,0 @@
- Motorola mc146818 compatible RTC
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Required properties:
- - compatible : "motorola,mc146818"
- - reg : should contain registers location and length.
-
-Optional properties:
- - interrupts : should contain interrupt.
- - ctrl-reg : Contains the initial value of the control register also
- called "Register B".
- - freq-reg : Contains the initial value of the frequency register also
- called "Register A".
-
-"Register A" and "B" are usually initialized by the firmware (BIOS for
-instance). If this is not done, it can be performed by the driver.
-
-ISA Example:
-
- rtc@70 {
- compatible = "motorola,mc146818";
- interrupts = <8 3>;
- interrupt-parent = <&ioapic1>;
- ctrl-reg = <2>;
- freq-reg = <0x26>;
- reg = <1 0x70 2>;
- };
diff --git a/Documentation/devicetree/bindings/rtc/rtc-cmos.yaml b/Documentation/devicetree/bindings/rtc/rtc-cmos.yaml
new file mode 100644
index 000000000000..e37927e9916c
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/rtc-cmos.yaml
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/rtc/rtc-cmos.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Motorola mc146818 compatible RTC
+
+maintainers:
+ - Alexandre Belloni <alexandre.belloni@bootlin.com>
+
+properties:
+ compatible:
+ oneOf:
+ - const: motorola,mc146818
+
+ - items:
+ - const: intel,ce4100-rtc
+ - const: motorola,mc146818
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ ctrl-reg:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ Initial value of the control register
+ (also known as Register B).
+
+ freq-reg:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ Initial value of the frequency register
+ (also known as Register A).
+
+required:
+ - compatible
+ - reg
+
+allOf:
+ - $ref: rtc.yaml#
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ bus {
+ #address-cells = <2>;
+ #size-cells = <1>;
+
+ rtc@1,70 {
+ compatible = "motorola,mc146818";
+ reg = <0x1 0x70 0x2>;
+
+ interrupts = <8 3>;
+
+ ctrl-reg = <2>;
+ freq-reg = <0x26>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/rtc/rtc-omap.txt b/Documentation/devicetree/bindings/rtc/rtc-omap.txt
deleted file mode 100644
index 062ebb14cecf..000000000000
--- a/Documentation/devicetree/bindings/rtc/rtc-omap.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-TI Real Time Clock
-
-Required properties:
-- compatible:
- - "ti,da830-rtc" - for RTC IP used similar to that on DA8xx SoC family.
- - "ti,am3352-rtc" - for RTC IP used similar to that on AM335x SoC family.
- This RTC IP has special WAKE-EN Register to enable
- Wakeup generation for event Alarm. It can also be
- used to control an external PMIC via the
- pmic_power_en pin.
- - "ti,am4372-rtc" - for RTC IP used similar to that on AM437X SoC family.
-- reg: Address range of rtc register set
-- interrupts: rtc timer, alarm interrupts in order
-
-Optional properties:
-- system-power-controller: whether the rtc is controlling the system power
- through pmic_power_en
-- clocks: Any internal or external clocks feeding in to rtc
-- clock-names: Corresponding names of the clocks
-- pinctrl-0: a phandle pointing to the pin settings for the device
-- pinctrl-names: should be "default"
-
-Optional subnodes:
-- generic pinctrl node
-
-Required pinctrl subnodes properties:
-- pins - Names of ext_wakeup pins to configure
-
-Optional pinctrl subnodes properties:
-- input-enable - Enables ext_wakeup
-- ti,active-high - Set input active high (by default active low)
-
-Example:
-
-rtc@1c23000 {
- compatible = "ti,da830-rtc";
- reg = <0x23000 0x1000>;
- interrupts = <19
- 19>;
- interrupt-parent = <&intc>;
- system-power-controller;
- clocks = <&clk_32k_rtc>, <&clk_32768_ck>;
- clock-names = "ext-clk", "int-clk";
-
- pinctrl-0 = <&ext_wakeup>;
- pinctrl-names = "default";
-
- ext_wakeup: ext-wakeup {
- pins = "ext_wakeup0";
- input-enable;
- ti,active-high;
- };
-};
diff --git a/Documentation/devicetree/bindings/rtc/rtc-palmas.txt b/Documentation/devicetree/bindings/rtc/rtc-palmas.txt
deleted file mode 100644
index c6cf37758a77..000000000000
--- a/Documentation/devicetree/bindings/rtc/rtc-palmas.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-Palmas RTC controller bindings
-
-Required properties:
-- compatible:
- - "ti,palmas-rtc" for palma series of the RTC controller
-- interrupts: Interrupt number of RTC submodule on device.
-
-Optional properties:
-
-- ti,backup-battery-chargeable: The Palmas series device like TPS65913 or
- TPS80036 supports the backup battery for powering the RTC when main
- battery is removed or in very low power state. The backup battery
- can be chargeable or non-chargeable. This flag will tells whether
- battery is chargeable or not. If charging battery then driver can
- enable the charging.
-- ti,backup-battery-charge-high-current: Enable high current charging in
- backup battery. Device supports the < 100uA and > 100uA charging.
- The high current will be > 100uA. Absence of this property will
- charge battery to lower current i.e. < 100uA.
-
-Example:
- palmas: tps65913@58 {
- ...
- palmas_rtc: rtc {
- compatible = "ti,palmas-rtc";
- interrupt-parent = <&palmas>;
- interrupts = <8 0>;
- ti,backup-battery-chargeable;
- ti,backup-battery-charge-high-current;
- };
- ...
- };
diff --git a/Documentation/devicetree/bindings/rtc/ti,omap-rtc.yaml b/Documentation/devicetree/bindings/rtc/ti,omap-rtc.yaml
new file mode 100644
index 000000000000..02b3c23cf435
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/ti,omap-rtc.yaml
@@ -0,0 +1,140 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/rtc/ti,omap-rtc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments OMAP Real Time Clock
+
+maintainers:
+ - Keerthy <j-keerthy@ti.com>
+ - Afzal Mohammed <afzal@ti.com>
+
+description:
+ The OMAP RTC is a year/month/day/hours/minutes/seconds BCD clock with
+ century-range alarm matching, driven by the 32kHz clock.
+
+properties:
+ compatible:
+ oneOf:
+ - const: ti,da830-rtc
+ - items:
+ - const: ti,am3352-rtc
+ - const: ti,da830-rtc
+ - items:
+ - const: ti,am4372-rtc
+ - const: ti,am3352-rtc
+ - const: ti,da830-rtc
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ minItems: 2
+ maxItems: 2
+
+ system-power-controller:
+ type: boolean
+ description:
+ Indicates that this RTC controls system power via the pmic_power_en pin.
+
+ clocks:
+ minItems: 1
+ maxItems: 2
+
+ clock-names:
+ minItems: 1
+ items:
+ - enum: [ext-clk, int-clk]
+ - const: int-clk
+
+ pinctrl-0:
+ description:
+ Phandle to pin configuration for the external wakeup pins.
+
+ pinctrl-names:
+ minItems: 1
+
+ ti,hwmods:
+ $ref: /schemas/types.yaml#/definitions/string
+ description:
+ Name of the hwmod associated with the RTC.
+ const: rtc
+ deprecated: true
+
+patternProperties:
+ "^ext-wakeup(-[0-9]+)?$":
+ type: object
+
+ description:
+ Child node describing external wakeup pin configuration.
+
+ properties:
+ pins:
+ pattern: '^ext_wakeup[0-3]$'
+
+ input-enable:
+ type: boolean
+ description:
+ Enables the external wakeup input on the selected pin.
+
+ ti,active-high:
+ type: boolean
+ description:
+ Sets the wakeup input polarity to active high. By default the
+ input is active low.
+
+ required:
+ - pins
+
+ additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - interrupts
+
+allOf:
+ - $ref: rtc.yaml#
+ - if:
+ not:
+ properties:
+ compatible:
+ contains:
+ const: ti,am3352-rtc
+ then:
+ properties:
+ system-power-controller: false
+ patternProperties:
+ "^ext-wakeup(-[0-9]+)?$": false
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ rtc@23000 {
+ compatible = "ti,da830-rtc";
+ reg = <0x23000 0x1000>;
+ interrupts = <19>, <19>;
+ clocks = <&clk_32768_ck>;
+ clock-names = "int-clk";
+ };
+
+ - |
+ rtc@0 {
+ compatible = "ti,am3352-rtc", "ti,da830-rtc";
+ reg = <0x0 0x1000>;
+ interrupts = <75>, <76>;
+ system-power-controller;
+ clocks = <&clk_32k_rtc>, <&clk_32768_ck>;
+ clock-names = "ext-clk", "int-clk";
+
+ pinctrl-0 = <&ext_wakeup>;
+ pinctrl-names = "default";
+
+ ext-wakeup {
+ pins = "ext_wakeup0";
+ input-enable;
+ ti,active-high;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/rtc/ti,palmas-rtc.yaml b/Documentation/devicetree/bindings/rtc/ti,palmas-rtc.yaml
new file mode 100644
index 000000000000..ac64f0589c84
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/ti,palmas-rtc.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/rtc/ti,palmas-rtc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments Palmas RTC
+
+maintainers:
+ - Eduard Bostina <egbostina@gmail.com>
+
+allOf:
+ - $ref: /schemas/rtc/rtc.yaml#
+
+properties:
+ compatible:
+ const: ti,palmas-rtc
+
+ interrupts:
+ maxItems: 1
+
+ wakeup-source: true
+
+ ti,backup-battery-chargeable:
+ type: boolean
+ description:
+ The backup battery can be chargeable or non-chargeable. This flag
+ indicates whether the battery is chargeable. If present, the driver
+ can enable charging.
+
+ ti,backup-battery-charge-high-current:
+ type: boolean
+ description:
+ Enable high current charging in the backup battery.
+ Device supports the < 100uA and > 100uA charging. The high current will
+ be > 100uA. Absence of this property will charge battery to lower
+ current i.e. < 100uA.
+
+required:
+ - compatible
+ - interrupts
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ pmic {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rtc {
+ compatible = "ti,palmas-rtc";
+ interrupts = <8 0>;
+ ti,backup-battery-chargeable;
+ ti,backup-battery-charge-high-current;
+ };
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index 0b42e898f4d8..00fb76bf93c2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22949,7 +22949,7 @@ REAL TIME CLOCK (RTC) SUBSYSTEM
M: Alexandre Belloni <alexandre.belloni@bootlin.com>
L: linux-rtc@vger.kernel.org
S: Maintained
-Q: http://patchwork.ozlabs.org/project/rtc-linux/list/
+Q: https://patchwork.kernel.org/project/linux-rtc/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git
F: Documentation/admin-guide/rtc.rst
F: Documentation/devicetree/bindings/rtc/
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 01def8231873..05b9233b9418 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1635,10 +1635,11 @@ config RTC_DRV_RS5C313
config RTC_DRV_RZN1
tristate "Renesas RZ/N1 RTC"
- depends on ARCH_RZN1 || COMPILE_TEST
+ depends on ARCH_RENESAS || COMPILE_TEST
depends on OF && HAS_IOMEM
help
- If you say yes here you get support for the Renesas RZ/N1 RTC.
+ If you say yes here you get support for the RTC initially found on
+ Renesas RZ/N1 SoCs.
config RTC_DRV_GENERIC
tristate "Generic RTC support"
@@ -2106,7 +2107,8 @@ config RTC_DRV_MACSMC
config RTC_DRV_MSC313
tristate "MStar MSC313 RTC"
- depends on ARCH_MSTARV7 || COMPILE_TEST
+ depends on ARCH_MSTARV7 || COMPILE_TEST
+ default ARCH_MSTARV7
help
If you say yes here you get support for the Mstar MSC313e On-Chip
Real Time Clock.
diff --git a/drivers/rtc/rtc-ab-eoz9.c b/drivers/rtc/rtc-ab-eoz9.c
index b75f4f665076..eb6d267c2ec3 100644
--- a/drivers/rtc/rtc-ab-eoz9.c
+++ b/drivers/rtc/rtc-ab-eoz9.c
@@ -549,6 +549,7 @@ static const struct i2c_device_id abeoz9_id[] = {
{ .name = "abeoz9" },
{ }
};
+MODULE_DEVICE_TABLE(i2c, abeoz9_id);
static struct i2c_driver abeoz9_driver = {
.driver = {
diff --git a/drivers/rtc/rtc-brcmstb-waketimer.c b/drivers/rtc/rtc-brcmstb-waketimer.c
index fb47c32ab5ff..55c15aad42cf 100644
--- a/drivers/rtc/rtc-brcmstb-waketimer.c
+++ b/drivers/rtc/rtc-brcmstb-waketimer.c
@@ -413,6 +413,7 @@ static const __maybe_unused struct of_device_id brcmstb_waketmr_of_match[] = {
{ .compatible = "brcm,brcmstb-waketimer" },
{ /* sentinel */ },
};
+MODULE_DEVICE_TABLE(of, brcmstb_waketmr_of_match);
static struct platform_driver brcmstb_waketmr_driver = {
.probe = brcmstb_waketmr_probe,
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index fd3858b6569e..522f7eef3b4a 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -661,7 +661,7 @@ static int rx8130_set_alarm(struct device *dev, struct rtc_wkalrm *t)
if (ret < 0)
return ret;
- ctl[0] &= RX8130_REG_EXTENSION_WADA;
+ ctl[0] |= RX8130_REG_EXTENSION_WADA;
ctl[1] &= ~RX8130_REG_FLAG_AF;
ctl[2] &= ~RX8130_REG_CONTROL0_AIE;
diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c
index aa9500791b7e..54f6af7886a8 100644
--- a/drivers/rtc/rtc-ds1343.c
+++ b/drivers/rtc/rtc-ds1343.c
@@ -120,7 +120,7 @@ static ssize_t ds1343_store_glitchfilter(struct device *dev,
return count;
}
-static DEVICE_ATTR(glitch_filter, S_IRUGO | S_IWUSR, ds1343_show_glitchfilter,
+static DEVICE_ATTR(glitch_filter, 0644, ds1343_show_glitchfilter,
ds1343_store_glitchfilter);
static int ds1343_nvram_write(void *priv, unsigned int off, void *val,
@@ -183,7 +183,7 @@ static ssize_t ds1343_show_tricklecharger(struct device *dev,
return sprintf(buf, "%s %s\n", diodes, resistors);
}
-static DEVICE_ATTR(trickle_charger, S_IRUGO, ds1343_show_tricklecharger, NULL);
+static DEVICE_ATTR(trickle_charger, 0444, ds1343_show_tricklecharger, NULL);
static struct attribute *ds1343_attrs[] = {
&dev_attr_glitch_filter.attr,
diff --git a/drivers/rtc/rtc-gamecube.c b/drivers/rtc/rtc-gamecube.c
index 045d5d45ab4b..889028cecf4a 100644
--- a/drivers/rtc/rtc-gamecube.c
+++ b/drivers/rtc/rtc-gamecube.c
@@ -355,9 +355,7 @@ static int gamecube_rtc_probe(struct platform_device *pdev)
rtc->range_max = U32_MAX;
rtc->ops = &gamecube_rtc_ops;
- devm_rtc_register_device(rtc);
-
- return 0;
+ return devm_rtc_register_device(rtc);
}
static const struct of_device_id gamecube_rtc_of_match[] = {
diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c
index 3156aa5f2d9f..1d52cc3def02 100644
--- a/drivers/rtc/rtc-hym8563.c
+++ b/drivers/rtc/rtc-hym8563.c
@@ -376,8 +376,8 @@ static struct clk *hym8563_clkout_register_clk(struct hym8563 *hym8563)
{
struct i2c_client *client = hym8563->client;
struct device_node *node = client->dev.of_node;
+ struct clk_init_data init = {};
struct clk *clk;
- struct clk_init_data init;
int ret;
ret = i2c_smbus_write_byte_data(client, HYM8563_CLKOUT,
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 3c8c379392c1..ec86ca3f2c4c 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -574,8 +574,8 @@ static struct clk *m41t80_sqw_register_clk(struct m41t80_data *m41t80)
struct i2c_client *client = m41t80->client;
struct device_node *node = client->dev.of_node;
struct device_node *fixed_clock;
+ struct clk_init_data init = {};
struct clk *clk;
- struct clk_init_data init;
int ret;
fixed_clock = of_get_child_by_name(node, "clock");
diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c
index f88976fd6d5d..db64c459ee19 100644
--- a/drivers/rtc/rtc-mv.c
+++ b/drivers/rtc/rtc-mv.c
@@ -219,17 +219,15 @@ static int __init mv_rtc_probe(struct platform_device *pdev)
if (IS_ERR(pdata->ioaddr))
return PTR_ERR(pdata->ioaddr);
- pdata->clk = devm_clk_get(&pdev->dev, NULL);
- /* Not all SoCs require a clock.*/
- if (!IS_ERR(pdata->clk))
- clk_prepare_enable(pdata->clk);
+ pdata->clk = devm_clk_get_optional_prepared(&pdev->dev, NULL);
+ if (IS_ERR(pdata->clk))
+ return PTR_ERR(pdata->clk);
/* make sure the 24 hour mode is enabled */
rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS);
if (rtc_time & RTC_HOURS_12H_MODE) {
dev_err(&pdev->dev, "12 Hour mode is enabled but not supported.\n");
- ret = -EINVAL;
- goto out;
+ return -EINVAL;
}
/* make sure it is actually functional */
@@ -238,8 +236,7 @@ static int __init mv_rtc_probe(struct platform_device *pdev)
rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS);
if (rtc_time == 0x01000000) {
dev_err(&pdev->dev, "internal RTC not ticking\n");
- ret = -ENODEV;
- goto out;
+ return -ENODEV;
}
}
@@ -249,8 +246,7 @@ static int __init mv_rtc_probe(struct platform_device *pdev)
pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(pdata->rtc)) {
- ret = PTR_ERR(pdata->rtc);
- goto out;
+ return PTR_ERR(pdata->rtc);
}
if (pdata->irq >= 0) {
@@ -264,7 +260,7 @@ static int __init mv_rtc_probe(struct platform_device *pdev)
}
if (pdata->irq >= 0)
- device_init_wakeup(&pdev->dev, true);
+ devm_device_init_wakeup(&pdev->dev);
else
clear_bit(RTC_FEATURE_ALARM, pdata->rtc->features);
@@ -275,24 +271,10 @@ static int __init mv_rtc_probe(struct platform_device *pdev)
ret = devm_rtc_register_device(pdata->rtc);
if (!ret)
return 0;
-out:
- if (!IS_ERR(pdata->clk))
- clk_disable_unprepare(pdata->clk);
return ret;
}
-static void __exit mv_rtc_remove(struct platform_device *pdev)
-{
- struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
-
- if (pdata->irq >= 0)
- device_init_wakeup(&pdev->dev, false);
-
- if (!IS_ERR(pdata->clk))
- clk_disable_unprepare(pdata->clk);
-}
-
#ifdef CONFIG_OF
static const struct of_device_id rtc_mv_of_match_table[] = {
{ .compatible = "marvell,orion-rtc", },
@@ -323,14 +305,7 @@ static int mv_rtc_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(mv_rtc_pm_ops, mv_rtc_suspend, mv_rtc_resume);
-/*
- * mv_rtc_remove() lives in .exit.text. For drivers registered via
- * module_platform_driver_probe() this is ok because they cannot get unbound at
- * runtime. So mark the driver struct with __refdata to prevent modpost
- * triggering a section mismatch warning.
- */
-static struct platform_driver mv_rtc_driver __refdata = {
- .remove = __exit_p(mv_rtc_remove),
+static struct platform_driver mv_rtc_driver = {
.driver = {
.name = "rtc-mv",
.of_match_table = of_match_ptr(rtc_mv_of_match_table),
diff --git a/drivers/rtc/rtc-nct3018y.c b/drivers/rtc/rtc-nct3018y.c
index 700a395fad3a..2f7ad57057a4 100644
--- a/drivers/rtc/rtc-nct3018y.c
+++ b/drivers/rtc/rtc-nct3018y.c
@@ -459,8 +459,8 @@ static struct clk *nct3018y_clkout_register_clk(struct nct3018y *nct3018y)
{
struct i2c_client *client = nct3018y->client;
struct device_node *node = client->dev.of_node;
+ struct clk_init_data init = {};
struct clk *clk;
- struct clk_init_data init;
init.name = "nct3018y-clkout";
init.ops = &nct3018y_clkout_ops;
diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c
index 1995e9f2756d..ff2023908f5a 100644
--- a/drivers/rtc/rtc-pcf2127.c
+++ b/drivers/rtc/rtc-pcf2127.c
@@ -1184,12 +1184,7 @@ static int pcf2127_configure_interrupt_pins(struct device *dev)
if (ret)
return ret;
- ret = regmap_write(pcf2127->regmap,
- PCF2131_REG_INT_A_MASK2, 0);
- if (ret)
- return ret;
-
- return ret;
+ return regmap_write(pcf2127->regmap, PCF2131_REG_INT_A_MASK2, 0);
}
static int pcf2127_probe(struct device *dev, struct regmap *regmap,
diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c
index 01e209d88f5f..8cb9ffc73f6d 100644
--- a/drivers/rtc/rtc-pcf85063.c
+++ b/drivers/rtc/rtc-pcf85063.c
@@ -498,7 +498,7 @@ static const struct clk_ops pcf85063_clkout_ops = {
static struct clk *pcf85063_clkout_register_clk(struct pcf85063 *pcf85063)
{
struct clk *clk;
- struct clk_init_data init;
+ struct clk_init_data init = {};
struct device_node *node = pcf85063->rtc->dev.parent->of_node;
struct device_node *fixed_clock;
diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c
index 540042b9eec8..ccc7834e5759 100644
--- a/drivers/rtc/rtc-pcf85363.c
+++ b/drivers/rtc/rtc-pcf85363.c
@@ -426,8 +426,8 @@ static int pcf85363_probe(struct i2c_client *client)
err = pcf85363_load_capacitance(pcf85363, client->dev.of_node);
if (err < 0)
- dev_warn(&client->dev, "failed to set xtal load capacitance: %d",
- err);
+ return dev_err_probe(&client->dev, err,
+ "failed to set xtal load capacitance\n");
pcf85363->rtc->ops = &rtc_ops;
pcf85363->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
@@ -436,9 +436,16 @@ static int pcf85363_probe(struct i2c_client *client)
wakeup_source = device_property_read_bool(&client->dev,
"wakeup-source");
if (client->irq > 0 || wakeup_source) {
- regmap_write(pcf85363->regmap, CTRL_FLAGS, 0);
- regmap_update_bits(pcf85363->regmap, CTRL_PIN_IO,
- PIN_IO_INTAPM, PIN_IO_INTA_OUT);
+ err = regmap_write(pcf85363->regmap, CTRL_FLAGS, 0);
+ if (err)
+ return dev_err_probe(&client->dev, err,
+ "failed to clear flags\n");
+
+ err = regmap_update_bits(pcf85363->regmap, CTRL_PIN_IO,
+ PIN_IO_INTAPM, PIN_IO_INTA_OUT);
+ if (err)
+ return dev_err_probe(&client->dev, err,
+ "failed to set interrupt pin mode\n");
}
if (client->irq > 0) {
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
index 81d13733b1e9..7eebdb058067 100644
--- a/drivers/rtc/rtc-pcf8563.c
+++ b/drivers/rtc/rtc-pcf8563.c
@@ -425,7 +425,7 @@ static const struct clk_ops pcf8563_clkout_ops = {
static struct clk *pcf8563_clkout_register_clk(struct pcf8563 *pcf8563)
{
struct device_node *node = pcf8563->rtc->dev.parent->of_node;
- struct clk_init_data init;
+ struct clk_init_data init = {};
struct clk *clk;
int ret;
@@ -449,7 +449,9 @@ static struct clk *pcf8563_clkout_register_clk(struct pcf8563 *pcf8563)
clk = devm_clk_register(&pcf8563->rtc->dev, &pcf8563->clkout_hw);
if (!IS_ERR(clk))
- of_clk_add_provider(node, of_clk_src_simple_get, clk);
+ devm_of_clk_add_hw_provider(pcf8563->rtc->dev.parent,
+ of_clk_hw_simple_get,
+ &pcf8563->clkout_hw);
return clk;
}
diff --git a/drivers/rtc/rtc-rv3028.c b/drivers/rtc/rtc-rv3028.c
index d96f6bb68850..d25e33d0835e 100644
--- a/drivers/rtc/rtc-rv3028.c
+++ b/drivers/rtc/rtc-rv3028.c
@@ -816,7 +816,7 @@ static int rv3028_clkout_register_clk(struct rv3028_data *rv3028,
{
int ret;
struct clk *clk;
- struct clk_init_data init;
+ struct clk_init_data init = {};
struct device_node *node = client->dev.of_node;
ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS,
diff --git a/drivers/rtc/rtc-rv3032.c b/drivers/rtc/rtc-rv3032.c
index 6bafdec637ae..687faaef42b2 100644
--- a/drivers/rtc/rtc-rv3032.c
+++ b/drivers/rtc/rtc-rv3032.c
@@ -752,7 +752,7 @@ static int rv3032_clkout_register_clk(struct rv3032_data *rv3032,
{
int ret;
struct clk *clk;
- struct clk_init_data init;
+ struct clk_init_data init = {};
struct device_node *node = client->dev.of_node;
ret = regmap_update_bits(rv3032->regmap, RV3032_TLSB, RV3032_TLSB_CLKF, 0);
diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
index 305f10a8a85b..b9d69ebdd224 100644
--- a/drivers/rtc/rtc-rzn1.c
+++ b/drivers/rtc/rtc-rzn1.c
@@ -12,10 +12,13 @@
*/
#include <linux/bcd.h>
+#include <linux/bitfield.h>
+#include <linux/bits.h>
#include <linux/clk.h>
#include <linux/init.h>
#include <linux/iopoll.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/rtc.h>
@@ -38,14 +41,18 @@
#define RZN1_RTC_CTL2_STOPPED (RZN1_RTC_CTL2_WAIT | RZN1_RTC_CTL2_WST)
#define RZN1_RTC_TIME 0x30
-#define RZN1_RTC_TIME_MIN_SHIFT 8
-#define RZN1_RTC_TIME_HOUR_SHIFT 16
+#define RZN1_RTC_TIME_SEC GENMASK(7, 0)
+#define RZN1_RTC_TIME_MIN GENMASK(15, 8)
+#define RZN1_RTC_TIME_HOUR GENMASK(23, 16)
+
#define RZN1_RTC_CAL 0x34
-#define RZN1_RTC_CAL_DAY_SHIFT 8
-#define RZN1_RTC_CAL_MON_SHIFT 16
-#define RZN1_RTC_CAL_YEAR_SHIFT 24
+#define RZN1_RTC_CAL_WDAY GENMASK(7, 0)
+#define RZN1_RTC_CAL_DAY GENMASK(15, 8)
+#define RZN1_RTC_CAL_MON GENMASK(23, 16)
+#define RZN1_RTC_CAL_YEAR GENMASK(31, 24)
#define RZN1_RTC_SUBU 0x38
+#define RZN1_RTC_SUBU_RTCA0FX GENMASK(5, 0)
#define RZN1_RTC_SUBU_DEV BIT(7)
#define RZN1_RTC_SUBU_DECR BIT(6)
@@ -59,6 +66,10 @@
#define RZN1_RTC_TIMEC 0x68
#define RZN1_RTC_CALC 0x6c
+struct rzn1_rtc_data {
+ bool has_subu;
+};
+
struct rzn1_rtc {
struct rtc_device *rtcdev;
void __iomem *base;
@@ -69,6 +80,7 @@ struct rzn1_rtc {
*/
spinlock_t ctl1_access_lock;
struct rtc_time tm_alarm;
+ unsigned long sync_time;
};
static void rzn1_rtc_get_time_snapshot(struct rzn1_rtc *rtc, struct rtc_time *tm)
@@ -76,15 +88,15 @@ static void rzn1_rtc_get_time_snapshot(struct rzn1_rtc *rtc, struct rtc_time *tm
u32 val;
val = readl(rtc->base + RZN1_RTC_TIMEC);
- tm->tm_sec = bcd2bin(val);
- tm->tm_min = bcd2bin(val >> RZN1_RTC_TIME_MIN_SHIFT);
- tm->tm_hour = bcd2bin(val >> RZN1_RTC_TIME_HOUR_SHIFT);
+ tm->tm_sec = bcd2bin(FIELD_GET(RZN1_RTC_TIME_SEC, val));
+ tm->tm_min = bcd2bin(FIELD_GET(RZN1_RTC_TIME_MIN, val));
+ tm->tm_hour = bcd2bin(FIELD_GET(RZN1_RTC_TIME_HOUR, val));
val = readl(rtc->base + RZN1_RTC_CALC);
- tm->tm_wday = val & 0x0f;
- tm->tm_mday = bcd2bin(val >> RZN1_RTC_CAL_DAY_SHIFT);
- tm->tm_mon = bcd2bin(val >> RZN1_RTC_CAL_MON_SHIFT) - 1;
- tm->tm_year = bcd2bin(val >> RZN1_RTC_CAL_YEAR_SHIFT) + 100;
+ tm->tm_wday = FIELD_GET(RZN1_RTC_CAL_WDAY, val);
+ tm->tm_mday = bcd2bin(FIELD_GET(RZN1_RTC_CAL_DAY, val));
+ tm->tm_mon = bcd2bin(FIELD_GET(RZN1_RTC_CAL_MON, val)) - 1;
+ tm->tm_year = bcd2bin(FIELD_GET(RZN1_RTC_CAL_YEAR, val)) + 100;
}
static int rzn1_rtc_read_time(struct device *dev, struct rtc_time *tm)
@@ -119,23 +131,23 @@ static int rzn1_rtc_set_time(struct device *dev, struct rtc_time *tm)
/* Hold the counter if it was counting up */
writel(RZN1_RTC_CTL2_WAIT, rtc->base + RZN1_RTC_CTL2);
- /* Wait for the counter to stop: two 32k clock cycles */
- usleep_range(61, 100);
+ /* Wait 2-4 RTC_PCLK clock cycles for the counter to stop */
+ usleep_range(rtc->sync_time, rtc->sync_time * 2);
ret = readl_poll_timeout(rtc->base + RZN1_RTC_CTL2, val,
val & RZN1_RTC_CTL2_WST, 0, 100);
if (ret)
return ret;
}
- val = bin2bcd(tm->tm_sec);
- val |= bin2bcd(tm->tm_min) << RZN1_RTC_TIME_MIN_SHIFT;
- val |= bin2bcd(tm->tm_hour) << RZN1_RTC_TIME_HOUR_SHIFT;
+ val = FIELD_PREP(RZN1_RTC_TIME_SEC, bin2bcd(tm->tm_sec)) |
+ FIELD_PREP(RZN1_RTC_TIME_MIN, bin2bcd(tm->tm_min)) |
+ FIELD_PREP(RZN1_RTC_TIME_HOUR, bin2bcd(tm->tm_hour));
writel(val, rtc->base + RZN1_RTC_TIME);
- val = tm->tm_wday;
- val |= bin2bcd(tm->tm_mday) << RZN1_RTC_CAL_DAY_SHIFT;
- val |= bin2bcd(tm->tm_mon + 1) << RZN1_RTC_CAL_MON_SHIFT;
- val |= bin2bcd(tm->tm_year - 100) << RZN1_RTC_CAL_YEAR_SHIFT;
+ val = FIELD_PREP(RZN1_RTC_CAL_WDAY, tm->tm_wday) |
+ FIELD_PREP(RZN1_RTC_CAL_DAY, bin2bcd(tm->tm_mday)) |
+ FIELD_PREP(RZN1_RTC_CAL_MON, bin2bcd(tm->tm_mon + 1)) |
+ FIELD_PREP(RZN1_RTC_CAL_YEAR, bin2bcd(tm->tm_year - 100));
writel(val, rtc->base + RZN1_RTC_CAL);
writel(0, rtc->base + RZN1_RTC_CTL2);
@@ -234,13 +246,24 @@ static int rzn1_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
if (ret)
return ret;
+ ctl1 = readl(rtc->base + RZN1_RTC_CTL1);
+ alrm->enabled = !!(ctl1 & (RZN1_RTC_CTL1_ALME | RZN1_RTC_CTL1_1SE));
+
min = readl(rtc->base + RZN1_RTC_ALM);
hour = readl(rtc->base + RZN1_RTC_ALH);
- wday = readl(rtc->base + RZN1_RTC_ALW);
tm->tm_sec = 0;
tm->tm_min = bcd2bin(min);
tm->tm_hour = bcd2bin(hour);
+
+ /*
+ * If wday is zero, no bit is set in RZN1_RTC_ALW. This is the
+ * register's power-on reset value.
+ */
+ wday = readl(rtc->base + RZN1_RTC_ALW);
+ if (!wday)
+ return 0;
+
delta_days = ((fls(wday) - 1) - tm->tm_wday + 7) % 7;
tm->tm_wday = fls(wday) - 1;
@@ -249,9 +272,6 @@ static int rzn1_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
rtc_time64_to_tm(alarm, tm);
}
- ctl1 = readl(rtc->base + RZN1_RTC_CTL1);
- alrm->enabled = !!(ctl1 & (RZN1_RTC_CTL1_ALME | RZN1_RTC_CTL1_1SE));
-
return 0;
}
@@ -259,8 +279,7 @@ static int rzn1_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct rzn1_rtc *rtc = dev_get_drvdata(dev);
struct rtc_time *tm = &alrm->time, tm_now;
- unsigned long alarm, farest;
- unsigned int days_ahead, wday;
+ time64_t alarm, farest;
int ret;
ret = rzn1_rtc_read_time(dev, &tm_now);
@@ -270,16 +289,17 @@ static int rzn1_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
/* We cannot set alarms more than one week ahead */
farest = rtc_tm_to_time64(&tm_now) + rtc->rtcdev->alarm_offset_max;
alarm = rtc_tm_to_time64(tm);
- if (time_after(alarm, farest))
+ if (alarm > farest)
return -ERANGE;
- /* Convert alarm day into week day */
- days_ahead = tm->tm_mday - tm_now.tm_mday;
- wday = (tm_now.tm_wday + days_ahead) % 7;
+ /* Disable alarm interrupts before reprogramming the alarm. */
+ ret = rzn1_rtc_alarm_irq_enable(dev, 0);
+ if (ret)
+ return ret;
writel(bin2bcd(tm->tm_min), rtc->base + RZN1_RTC_ALM);
writel(bin2bcd(tm->tm_hour), rtc->base + RZN1_RTC_ALH);
- writel(BIT(wday), rtc->base + RZN1_RTC_ALW);
+ writel(BIT(tm->tm_wday), rtc->base + RZN1_RTC_ALW);
rtc->tm_alarm = alrm->time;
@@ -298,12 +318,12 @@ static int rzn1_rtc_read_offset(struct device *dev, long *offset)
val = readl(rtc->base + RZN1_RTC_SUBU);
ppb_per_step = val & RZN1_RTC_SUBU_DEV ? 1017 : 3051;
subtract = val & RZN1_RTC_SUBU_DECR;
- val &= 0x3F;
+ val = FIELD_GET(RZN1_RTC_SUBU_RTCA0FX, val);
if (!val)
*offset = 0;
else if (subtract)
- *offset = -(((~val) & 0x3F) + 1) * ppb_per_step;
+ *offset = -(((~val) & RZN1_RTC_SUBU_RTCA0FX) + 1) * ppb_per_step;
else
*offset = (val - 1) * ppb_per_step;
@@ -345,7 +365,7 @@ static int rzn1_rtc_set_offset(struct device *dev, long offset)
subu |= steps + 1;
} else {
subu |= RZN1_RTC_SUBU_DECR;
- subu |= (~(-steps - 1)) & 0x3F;
+ subu |= (~(-steps - 1)) & RZN1_RTC_SUBU_RTCA0FX;
}
ret = readl_poll_timeout(rtc->base + RZN1_RTC_CTL2, ctl2,
@@ -376,15 +396,32 @@ static const struct rtc_class_ops rzn1_rtc_ops_scmp = {
.alarm_irq_enable = rzn1_rtc_alarm_irq_enable,
};
+static void rzn1_rtc_disable_hardware(void *data)
+{
+ struct device *dev = data;
+ struct rzn1_rtc *rtc = dev_get_drvdata(dev);
+
+ /* Disable all interrupts */
+ writel(0, rtc->base + RZN1_RTC_CTL1);
+
+ pm_runtime_put_sync(dev);
+}
+
static int rzn1_rtc_probe(struct platform_device *pdev)
{
+ const struct rzn1_rtc_data *data;
+ struct device *dev = &pdev->dev;
+ unsigned long rate = 32768;
struct rzn1_rtc *rtc;
u32 val, scmp_val = 0;
struct clk *xtal;
- unsigned long rate;
int irq, ret;
- rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
+ data = of_device_get_match_data(dev);
+ if (!data)
+ return -ENODEV;
+
+ rtc = devm_kzalloc(dev, sizeof(*rtc), GFP_KERNEL);
if (!rtc)
return -ENOMEM;
@@ -392,13 +429,13 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
rtc->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rtc->base))
- return dev_err_probe(&pdev->dev, PTR_ERR(rtc->base), "Missing reg\n");
+ return dev_err_probe(dev, PTR_ERR(rtc->base), "Missing reg\n");
irq = platform_get_irq_byname(pdev, "alarm");
if (irq < 0)
return irq;
- rtc->rtcdev = devm_rtc_allocate_device(&pdev->dev);
+ rtc->rtcdev = devm_rtc_allocate_device(dev);
if (IS_ERR(rtc->rtcdev))
return PTR_ERR(rtc->rtcdev);
@@ -406,38 +443,47 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
rtc->rtcdev->range_max = RTC_TIMESTAMP_END_2099;
rtc->rtcdev->alarm_offset_max = 7 * 86400;
- ret = devm_pm_runtime_enable(&pdev->dev);
+ ret = devm_pm_runtime_enable(dev);
if (ret < 0)
return ret;
- ret = pm_runtime_resume_and_get(&pdev->dev);
+ ret = pm_runtime_resume_and_get(dev);
if (ret < 0)
return ret;
+ ret = devm_add_action_or_reset(dev, rzn1_rtc_disable_hardware, dev);
+ if (ret)
+ return ret;
+
/* Only switch to scmp if we have an xtal clock with a valid rate and != 32768 */
- xtal = devm_clk_get_optional(&pdev->dev, "xtal");
+ xtal = devm_clk_get_optional(dev, "xtal");
if (IS_ERR(xtal)) {
- ret = PTR_ERR(xtal);
- goto dis_runtime_pm;
+ return PTR_ERR(xtal);
} else if (xtal) {
rate = clk_get_rate(xtal);
- if (rate < 32000 || rate > BIT(22)) {
- ret = -EOPNOTSUPP;
- goto dis_runtime_pm;
- }
+ if (rate < 32000 || rate > BIT(22))
+ return -EOPNOTSUPP;
- if (rate != 32768)
+ if (rate != 32768 || !data->has_subu)
scmp_val = RZN1_RTC_CTL0_SLSB_SCMP;
+ } else if (!data->has_subu) {
+ /* xtal is NULL here */
+ return dev_err_probe(dev, -EOPNOTSUPP,
+ "No valid XTAL provided and SUBU mode not supported\n");
}
+ /* Calculate the duration of two RTC_PCLK clock cycles */
+ rtc->sync_time = DIV_ROUND_UP(2 * USEC_PER_SEC, rate);
+
/* Disable controller during SUBU/SCMP setup */
val = readl(rtc->base + RZN1_RTC_CTL0) & ~RZN1_RTC_CTL0_CE;
writel(val, rtc->base + RZN1_RTC_CTL0);
- /* Wait 2-4 32k clock cycles for the disabled controller */
+ /* Wait 2-4 RTC_PCLK clock cycles for the disabled controller to stop */
ret = readl_poll_timeout(rtc->base + RZN1_RTC_CTL0, val,
- !(val & RZN1_RTC_CTL0_CEST), 62, 123);
+ !(val & RZN1_RTC_CTL0_CEST), rtc->sync_time,
+ rtc->sync_time * 2);
if (ret)
- goto dis_runtime_pm;
+ return ret;
/* Set desired modes leaving the controller disabled */
writel(RZN1_RTC_CTL0_AMPM | scmp_val, rtc->base + RZN1_RTC_CTL0);
@@ -457,53 +503,42 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
spin_lock_init(&rtc->ctl1_access_lock);
- ret = devm_request_irq(&pdev->dev, irq, rzn1_rtc_alarm_irq, 0, "RZN1 RTC Alarm", rtc);
- if (ret) {
- dev_err(&pdev->dev, "RTC alarm interrupt not available\n");
- goto dis_runtime_pm;
- }
+ ret = devm_request_irq(dev, irq, rzn1_rtc_alarm_irq, 0, "RZN1 RTC Alarm", rtc);
+ if (ret)
+ return dev_err_probe(dev, ret, "RTC alarm interrupt not available\n");
irq = platform_get_irq_byname_optional(pdev, "pps");
+ if (irq == -EPROBE_DEFER)
+ return irq;
if (irq >= 0)
- ret = devm_request_irq(&pdev->dev, irq, rzn1_rtc_1s_irq, 0, "RZN1 RTC 1s", rtc);
+ ret = devm_request_irq(dev, irq, rzn1_rtc_1s_irq, 0, "RZN1 RTC 1s", rtc);
if (irq < 0 || ret) {
set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->rtcdev->features);
clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->rtcdev->features);
- dev_warn(&pdev->dev, "RTC pps interrupt not available. Alarm has only minute accuracy\n");
+ dev_warn(dev, "RTC pps interrupt not available. Alarm has only minute accuracy\n");
}
- ret = devm_rtc_register_device(rtc->rtcdev);
- if (ret)
- goto dis_runtime_pm;
-
- return 0;
-
-dis_runtime_pm:
- pm_runtime_put(&pdev->dev);
-
- return ret;
+ return devm_rtc_register_device(rtc->rtcdev);
}
-static void rzn1_rtc_remove(struct platform_device *pdev)
-{
- struct rzn1_rtc *rtc = platform_get_drvdata(pdev);
-
- /* Disable all interrupts */
- writel(0, rtc->base + RZN1_RTC_CTL1);
+static const struct rzn1_rtc_data rzn1_rtc_rzt2h_data = {
+ .has_subu = false,
+};
- pm_runtime_put(&pdev->dev);
-}
+static const struct rzn1_rtc_data rzn1_rtc_rzn1_data = {
+ .has_subu = true,
+};
static const struct of_device_id rzn1_rtc_of_match[] = {
- { .compatible = "renesas,rzn1-rtc" },
- {},
+ { .compatible = "renesas,r9a09g077-rtc", .data = &rzn1_rtc_rzt2h_data },
+ { .compatible = "renesas,rzn1-rtc", .data = &rzn1_rtc_rzn1_data },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, rzn1_rtc_of_match);
static struct platform_driver rzn1_rtc_driver = {
.probe = rzn1_rtc_probe,
- .remove = rzn1_rtc_remove,
.driver = {
.name = "rzn1-rtc",
.of_match_table = rzn1_rtc_of_match,
@@ -512,6 +547,6 @@ static struct platform_driver rzn1_rtc_driver = {
module_platform_driver(rzn1_rtc_driver);
MODULE_AUTHOR("Michel Pollet <buserror@gmail.com>");
-MODULE_AUTHOR("Miquel Raynal <miquel.raynal@bootlin.com");
+MODULE_AUTHOR("Miquel Raynal <miquel.raynal@bootlin.com>");
MODULE_DESCRIPTION("RZ/N1 RTC driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-s32g.c b/drivers/rtc/rtc-s32g.c
index 3a0818e972eb..86716192d10f 100644
--- a/drivers/rtc/rtc-s32g.c
+++ b/drivers/rtc/rtc-s32g.c
@@ -366,6 +366,7 @@ static const struct of_device_id rtc_dt_ids[] = {
{ .compatible = "nxp,s32g2-rtc", .data = &rtc_s32g2_data },
{ /* sentinel */ },
};
+MODULE_DEVICE_TABLE(of, rtc_dt_ids);
static DEFINE_SIMPLE_DEV_PM_OPS(s32g_rtc_pm_ops,
s32g_rtc_suspend, s32g_rtc_resume);
diff --git a/drivers/rtc/rtc-spacemit-p1.c b/drivers/rtc/rtc-spacemit-p1.c
index 43ab62494bb4..1de7bd995d29 100644
--- a/drivers/rtc/rtc-spacemit-p1.c
+++ b/drivers/rtc/rtc-spacemit-p1.c
@@ -57,8 +57,9 @@ static int p1_rtc_read_time(struct device *dev, struct rtc_time *t)
u8 time[6];
int ret;
- if (!regmap_test_bits(regmap, RTC_CTRL, RTC_EN))
- return -EINVAL; /* RTC is disabled */
+ ret = regmap_test_bits(regmap, RTC_CTRL, RTC_EN);
+ if (ret <= 0)
+ return ret ?: -EINVAL; /* RTC is disabled or error */
ret = regmap_bulk_read(regmap, RTC_TIME, time, sizeof(time));
if (ret)
diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c
index c6d4522411b3..ae79ddf24f37 100644
--- a/drivers/rtc/rtc-st-lpc.c
+++ b/drivers/rtc/rtc-st-lpc.c
@@ -18,7 +18,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/rtc.h>
@@ -212,11 +211,9 @@ static int st_rtc_probe(struct platform_device *pdev)
if (IS_ERR(rtc->ioaddr))
return PTR_ERR(rtc->ioaddr);
- rtc->irq = irq_of_parse_and_map(np, 0);
- if (!rtc->irq) {
- dev_err(&pdev->dev, "IRQ missing or invalid\n");
- return -EINVAL;
- }
+ rtc->irq = platform_get_irq(pdev, 0);
+ if (rtc->irq < 0)
+ return rtc->irq;
ret = devm_request_irq(&pdev->dev, rtc->irq, st_rtc_handler,
IRQF_NO_AUTOEN, pdev->name, rtc);
diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c
index 2ae54804b87a..5bcb7536e973 100644
--- a/drivers/rtc/rtc-zynqmp.c
+++ b/drivers/rtc/rtc-zynqmp.c
@@ -334,10 +334,9 @@ static int xlnx_rtc_probe(struct platform_device *pdev)
/* Getting the rtc info */
xrtcdev->rtc_clk = devm_clk_get_optional(&pdev->dev, "rtc");
- if (IS_ERR(xrtcdev->rtc_clk)) {
- if (PTR_ERR(xrtcdev->rtc_clk) != -EPROBE_DEFER)
- dev_warn(&pdev->dev, "Device clock not found.\n");
- }
+ if (IS_ERR(xrtcdev->rtc_clk))
+ return dev_err_probe(&pdev->dev, PTR_ERR(xrtcdev->rtc_clk),
+ "Failed to get rtc clock\n");
xrtcdev->freq = clk_get_rate(xrtcdev->rtc_clk);
if (!xrtcdev->freq) {
ret = of_property_read_u32(pdev->dev.of_node, "calibration",