mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 12:52:29 -04:00
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 ...
This commit is contained in:
@@ -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>;
|
||||
};
|
||||
@@ -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>;
|
||||
};
|
||||
@@ -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:
|
||||
|
||||
@@ -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>;
|
||||
};
|
||||
63
Documentation/devicetree/bindings/rtc/rtc-cmos.yaml
Normal file
63
Documentation/devicetree/bindings/rtc/rtc-cmos.yaml
Normal file
@@ -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>;
|
||||
};
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
...
|
||||
};
|
||||
140
Documentation/devicetree/bindings/rtc/ti,omap-rtc.yaml
Normal file
140
Documentation/devicetree/bindings/rtc/ti,omap-rtc.yaml
Normal file
@@ -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;
|
||||
};
|
||||
};
|
||||
57
Documentation/devicetree/bindings/rtc/ti,palmas-rtc.yaml
Normal file
57
Documentation/devicetree/bindings/rtc/ti,palmas-rtc.yaml
Normal file
@@ -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;
|
||||
};
|
||||
};
|
||||
@@ -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/
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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[] = {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
static const struct rzn1_rtc_data rzn1_rtc_rzt2h_data = {
|
||||
.has_subu = false,
|
||||
};
|
||||
|
||||
/* Disable all interrupts */
|
||||
writel(0, rtc->base + RZN1_RTC_CTL1);
|
||||
|
||||
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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user