diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-28 09:53:43 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-28 09:53:43 -0700 |
| commit | 275bc4eedf2c6081200998954efcb5eb90413a41 (patch) | |
| tree | f8f0b71a819301d7283fff7cc21f1f9e44170d6f | |
| parent | afe0579334f622c803f2864f22c04c20c320bd80 (diff) | |
| parent | afce9701d6423a63194a349d2f1e34c50ce76482 (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
...
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", |
