diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-23 01:58:23 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-23 01:58:23 -0500 |
commit | 1b8c5cd890e274781a8ef61585ae03614be9ccd8 (patch) | |
tree | cf8a6735bd8970f311daee3c6874a4fdc7de0356 | |
parent | 14b661ebb6cfa386afa5a5247eb09e24d420af3a (diff) | |
parent | 87c9fd81825363237ac5560822e2261535800597 (diff) |
Merge tag 'rtc-4.15' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
Pull RTC updates from Alexandre Belloni:
"There is nothing scary this cycle, mostly driver fixes and updates.
The core fix has been in for a while and has been tested on multiple
kernel revisions by multiple teams.
Core:
- Fix setting the alarm to the next expiring timer
New drivers:
- Mediatek MT7622 RTC
- NXP PCF85363
- Spreadtrum SC27xx PMIC RTC
Drivers updates:
- Use generic nvmem to expose the Non volatile ram for ds1305,
ds1511, m48t86 and omap
- abx80x: solve possible race condition at probe
- armada38x: support trimming the RTC oscillator
- at91rm9200: fix reading the alarm value at boot
- ds1511: allow waking platform
- m41t80: rework square wave output
- pcf8523: support trimming the RTC oscillator
- pcf8563: fix clock output rate
- pl031: make interrupt optional
- xgene: fix suspend/resume"
* tag 'rtc-4.15' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (50 commits)
dt-bindings: rtc: imxdi: Improve the bindings text
rtc: sc27xx: Add Spreadtrum SC27xx PMIC RTC driver
dt-bindings: rtc: Add Spreadtrum SC27xx RTC documentation
rtc: at91rm9200: fix reading alarm value
rtc: at91rm9200: stop calculating yday in at91_rtc_readalarm
rtc: sysfs: Use time64_t variables to set time/alarm
rtc: xgene: mark PM functions as __maybe_unused
rtc: xgene: Fix suspend/resume
rtc: pcf8563: don't alway enable the alarm
rtc: pcf8563: fix output clock rate
rtc: rx8010: Fix for incorrect return value
rtc: rx8010: Specify correct address for RX8010_RESV31
rtc: rx8010: Remove duplicate define
rtc: m41t80: remove unneeded checks from m41t80_sqw_set_rate
rtc: m41t80: avoid i2c read in m41t80_sqw_is_prepared
rtc: m41t80: avoid i2c read in m41t80_sqw_recalc_rate
rtc: m41t80: fix m41t80_sqw_round_rate return value
rtc: m41t80: m41t80_sqw_set_rate should return 0 on success
rtc: add support for NXP PCF85363 real-time clock
rtc: omap: Support scratch registers
...
30 files changed, 1891 insertions, 283 deletions
diff --git a/Documentation/devicetree/bindings/rtc/imxdi-rtc.txt b/Documentation/devicetree/bindings/rtc/imxdi-rtc.txt index 323cf26374cb..c797bc9d77d2 100644 --- a/Documentation/devicetree/bindings/rtc/imxdi-rtc.txt +++ b/Documentation/devicetree/bindings/rtc/imxdi-rtc.txt | |||
@@ -1,20 +1,20 @@ | |||
1 | * i.MX25 Real Time Clock controller | 1 | * i.MX25 Real Time Clock controller |
2 | 2 | ||
3 | This binding supports the following chips: i.MX25, i.MX53 | ||
4 | |||
5 | Required properties: | 3 | Required properties: |
6 | - compatible: should be: "fsl,imx25-rtc" | 4 | - compatible: should be: "fsl,imx25-rtc" |
7 | - reg: physical base address of the controller and length of memory mapped | 5 | - reg: physical base address of the controller and length of memory mapped |
8 | region. | 6 | region. |
7 | - clocks: should contain the phandle for the rtc clock | ||
9 | - interrupts: rtc alarm interrupt | 8 | - interrupts: rtc alarm interrupt |
10 | 9 | ||
11 | Optional properties: | 10 | Optional properties: |
12 | - interrupts: dryice security violation interrupt | 11 | - interrupts: dryice security violation interrupt (second entry) |
13 | 12 | ||
14 | Example: | 13 | Example: |
15 | 14 | ||
16 | rtc@80056000 { | 15 | rtc@53ffc000 { |
17 | compatible = "fsl,imx53-rtc", "fsl,imx25-rtc"; | 16 | compatible = "fsl,imx25-rtc"; |
18 | reg = <0x80056000 2000>; | 17 | reg = <0x53ffc000 0x4000>; |
19 | interrupts = <29 56>; | 18 | clocks = <&clks 81>; |
19 | interrupts = <25 56>; | ||
20 | }; | 20 | }; |
diff --git a/Documentation/devicetree/bindings/rtc/pcf85363.txt b/Documentation/devicetree/bindings/rtc/pcf85363.txt new file mode 100644 index 000000000000..76fdabc59742 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/pcf85363.txt | |||
@@ -0,0 +1,17 @@ | |||
1 | NXP PCF85363 Real Time Clock | ||
2 | ============================ | ||
3 | |||
4 | Required properties: | ||
5 | - compatible: Should contain "nxp,pcf85363". | ||
6 | - reg: I2C address for chip. | ||
7 | |||
8 | Optional properties: | ||
9 | - interrupts: IRQ line for the RTC (not implemented). | ||
10 | |||
11 | Example: | ||
12 | |||
13 | pcf85363: pcf85363@51 { | ||
14 | compatible = "nxp,pcf85363"; | ||
15 | reg = <0x51>; | ||
16 | }; | ||
17 | |||
diff --git a/Documentation/devicetree/bindings/rtc/rtc-mt7622.txt b/Documentation/devicetree/bindings/rtc/rtc-mt7622.txt new file mode 100644 index 000000000000..09fe8f51476f --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/rtc-mt7622.txt | |||
@@ -0,0 +1,21 @@ | |||
1 | Device-Tree bindings for MediaTek SoC based RTC | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : Should be | ||
5 | "mediatek,mt7622-rtc", "mediatek,soc-rtc" : for MT7622 SoC | ||
6 | - reg : Specifies base physical address and size of the registers; | ||
7 | - interrupts : Should contain the interrupt for RTC alarm; | ||
8 | - clocks : Specifies list of clock specifiers, corresponding to | ||
9 | entries in clock-names property; | ||
10 | - clock-names : Should contain "rtc" entries | ||
11 | |||
12 | Example: | ||
13 | |||
14 | rtc: rtc@10212800 { | ||
15 | compatible = "mediatek,mt7622-rtc", | ||
16 | "mediatek,soc-rtc"; | ||
17 | reg = <0 0x10212800 0 0x200>; | ||
18 | interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_LOW>; | ||
19 | clocks = <&topckgen CLK_TOP_RTC>; | ||
20 | clock-names = "rtc"; | ||
21 | }; | ||
diff --git a/Documentation/devicetree/bindings/rtc/sprd,sc27xx-rtc.txt b/Documentation/devicetree/bindings/rtc/sprd,sc27xx-rtc.txt new file mode 100644 index 000000000000..7c170da0d4b7 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/sprd,sc27xx-rtc.txt | |||
@@ -0,0 +1,27 @@ | |||
1 | Spreadtrum SC27xx Real Time Clock | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: should be "sprd,sc2731-rtc". | ||
5 | - reg: address offset of rtc register. | ||
6 | - interrupt-parent: phandle for the interrupt controller. | ||
7 | - interrupts: rtc alarm interrupt. | ||
8 | |||
9 | Example: | ||
10 | |||
11 | sc2731_pmic: pmic@0 { | ||
12 | compatible = "sprd,sc2731"; | ||
13 | reg = <0>; | ||
14 | spi-max-frequency = <26000000>; | ||
15 | interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>; | ||
16 | interrupt-controller; | ||
17 | #interrupt-cells = <2>; | ||
18 | #address-cells = <1>; | ||
19 | #size-cells = <0>; | ||
20 | |||
21 | rtc@280 { | ||
22 | compatible = "sprd,sc2731-rtc"; | ||
23 | reg = <0x280>; | ||
24 | interrupt-parent = <&sc2731_pmic>; | ||
25 | interrupts = <2 IRQ_TYPE_LEVEL_HIGH>; | ||
26 | }; | ||
27 | }; | ||
diff --git a/Documentation/devicetree/bindings/trivial-devices.txt b/Documentation/devicetree/bindings/trivial-devices.txt index 678039d4d5e5..5f3143f97098 100644 --- a/Documentation/devicetree/bindings/trivial-devices.txt +++ b/Documentation/devicetree/bindings/trivial-devices.txt | |||
@@ -72,7 +72,6 @@ maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator | |||
72 | maxim,max1237 Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs | 72 | maxim,max1237 Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs |
73 | maxim,max6621 PECI-to-I2C translator for PECI-to-SMBus/I2C protocol conversion | 73 | maxim,max6621 PECI-to-I2C translator for PECI-to-SMBus/I2C protocol conversion |
74 | maxim,max6625 9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface | 74 | maxim,max6625 9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface |
75 | mc,rv3029c2 Real Time Clock Module with I2C-Bus | ||
76 | mcube,mc3230 mCube 3-axis 8-bit digital accelerometer | 75 | mcube,mc3230 mCube 3-axis 8-bit digital accelerometer |
77 | memsic,mxc6225 MEMSIC 2-axis 8-bit digital accelerometer | 76 | memsic,mxc6225 MEMSIC 2-axis 8-bit digital accelerometer |
78 | microchip,mcp4531-502 Microchip 7-bit Single I2C Digital Potentiometer (5k) | 77 | microchip,mcp4531-502 Microchip 7-bit Single I2C Digital Potentiometer (5k) |
@@ -141,6 +140,7 @@ microchip,mcp4662-503 Microchip 8-bit Dual I2C Digital Potentiometer with NV Mem | |||
141 | microchip,mcp4662-104 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (100k) | 140 | microchip,mcp4662-104 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (100k) |
142 | microchip,tc654 PWM Fan Speed Controller With Fan Fault Detection | 141 | microchip,tc654 PWM Fan Speed Controller With Fan Fault Detection |
143 | microchip,tc655 PWM Fan Speed Controller With Fan Fault Detection | 142 | microchip,tc655 PWM Fan Speed Controller With Fan Fault Detection |
143 | microcrystal,rv3029 Real Time Clock Module with I2C-Bus | ||
144 | miramems,da226 MiraMEMS DA226 2-axis 14-bit digital accelerometer | 144 | miramems,da226 MiraMEMS DA226 2-axis 14-bit digital accelerometer |
145 | miramems,da280 MiraMEMS DA280 3-axis 14-bit digital accelerometer | 145 | miramems,da280 MiraMEMS DA280 3-axis 14-bit digital accelerometer |
146 | miramems,da311 MiraMEMS DA311 3-axis 12-bit digital accelerometer | 146 | miramems,da311 MiraMEMS DA311 3-axis 12-bit digital accelerometer |
diff --git a/MAINTAINERS b/MAINTAINERS index 44512c346206..aa71ab52fd76 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -1590,10 +1590,13 @@ F: drivers/rtc/rtc-armada38x.c | |||
1590 | 1590 | ||
1591 | ARM/Mediatek RTC DRIVER | 1591 | ARM/Mediatek RTC DRIVER |
1592 | M: Eddie Huang <eddie.huang@mediatek.com> | 1592 | M: Eddie Huang <eddie.huang@mediatek.com> |
1593 | M: Sean Wang <sean.wang@mediatek.com> | ||
1593 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 1594 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
1594 | L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) | 1595 | L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) |
1595 | S: Maintained | 1596 | S: Maintained |
1597 | F: Documentation/devicetree/bindings/rtc/rtc-mt7622.txt | ||
1596 | F: drivers/rtc/rtc-mt6397.c | 1598 | F: drivers/rtc/rtc-mt6397.c |
1599 | F: drivers/rtc/rtc-mt7622.c | ||
1597 | 1600 | ||
1598 | ARM/Mediatek SoC support | 1601 | ARM/Mediatek SoC support |
1599 | M: Matthias Brugger <matthias.bgg@gmail.com> | 1602 | M: Matthias Brugger <matthias.bgg@gmail.com> |
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index e0e58f3b1420..b59a31b079a5 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -433,6 +433,19 @@ config RTC_DRV_PCF85063 | |||
433 | This driver can also be built as a module. If so, the module | 433 | This driver can also be built as a module. If so, the module |
434 | will be called rtc-pcf85063. | 434 | will be called rtc-pcf85063. |
435 | 435 | ||
436 | config RTC_DRV_PCF85363 | ||
437 | tristate "NXP PCF85363" | ||
438 | depends on I2C | ||
439 | select REGMAP_I2C | ||
440 | help | ||
441 | If you say yes here you get support for the PCF85363 RTC chip. | ||
442 | |||
443 | This driver can also be built as a module. If so, the module | ||
444 | will be called rtc-pcf85363. | ||
445 | |||
446 | The nvmem interface will be named pcf85363-#, where # is the | ||
447 | zero-based instance number. | ||
448 | |||
436 | config RTC_DRV_PCF8563 | 449 | config RTC_DRV_PCF8563 |
437 | tristate "Philips PCF8563/Epson RTC8564" | 450 | tristate "Philips PCF8563/Epson RTC8564" |
438 | help | 451 | help |
@@ -1174,6 +1187,17 @@ config RTC_DRV_WM8350 | |||
1174 | This driver can also be built as a module. If so, the module | 1187 | This driver can also be built as a module. If so, the module |
1175 | will be called "rtc-wm8350". | 1188 | will be called "rtc-wm8350". |
1176 | 1189 | ||
1190 | config RTC_DRV_SC27XX | ||
1191 | tristate "Spreadtrum SC27xx RTC" | ||
1192 | depends on MFD_SC27XX_PMIC || COMPILE_TEST | ||
1193 | help | ||
1194 | If you say Y here you will get support for the RTC subsystem | ||
1195 | of the Spreadtrum SC27xx series PMICs. The SC27xx series PMICs | ||
1196 | includes the SC2720, SC2721, SC2723, SC2730 and SC2731 chips. | ||
1197 | |||
1198 | This driver can also be built as a module. If so, the module | ||
1199 | will be called rtc-sc27xx. | ||
1200 | |||
1177 | config RTC_DRV_SPEAR | 1201 | config RTC_DRV_SPEAR |
1178 | tristate "SPEAR ST RTC" | 1202 | tristate "SPEAR ST RTC" |
1179 | depends on PLAT_SPEAR || COMPILE_TEST | 1203 | depends on PLAT_SPEAR || COMPILE_TEST |
@@ -1706,14 +1730,24 @@ config RTC_DRV_MOXART | |||
1706 | will be called rtc-moxart | 1730 | will be called rtc-moxart |
1707 | 1731 | ||
1708 | config RTC_DRV_MT6397 | 1732 | config RTC_DRV_MT6397 |
1709 | tristate "Mediatek Real Time Clock driver" | 1733 | tristate "MediaTek PMIC based RTC" |
1710 | depends on MFD_MT6397 || (COMPILE_TEST && IRQ_DOMAIN) | 1734 | depends on MFD_MT6397 || (COMPILE_TEST && IRQ_DOMAIN) |
1711 | help | 1735 | help |
1712 | This selects the Mediatek(R) RTC driver. RTC is part of Mediatek | 1736 | This selects the MediaTek(R) RTC driver. RTC is part of MediaTek |
1713 | MT6397 PMIC. You should enable MT6397 PMIC MFD before select | 1737 | MT6397 PMIC. You should enable MT6397 PMIC MFD before select |
1714 | Mediatek(R) RTC driver. | 1738 | MediaTek(R) RTC driver. |
1739 | |||
1740 | If you want to use MediaTek(R) RTC interface, select Y or M here. | ||
1715 | 1741 | ||
1716 | If you want to use Mediatek(R) RTC interface, select Y or M here. | 1742 | config RTC_DRV_MT7622 |
1743 | tristate "MediaTek SoC based RTC" | ||
1744 | depends on ARCH_MEDIATEK || COMPILE_TEST | ||
1745 | help | ||
1746 | This enables support for the real time clock built in the MediaTek | ||
1747 | SoCs. | ||
1748 | |||
1749 | This drive can also be built as a module. If so, the module | ||
1750 | will be called rtc-mt7622. | ||
1717 | 1751 | ||
1718 | config RTC_DRV_XGENE | 1752 | config RTC_DRV_XGENE |
1719 | tristate "APM X-Gene RTC" | 1753 | tristate "APM X-Gene RTC" |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 0bf1fc02b82c..f2f50c11dc38 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -103,6 +103,7 @@ obj-$(CONFIG_RTC_DRV_MPC5121) += rtc-mpc5121.o | |||
103 | obj-$(CONFIG_RTC_DRV_VRTC) += rtc-mrst.o | 103 | obj-$(CONFIG_RTC_DRV_VRTC) += rtc-mrst.o |
104 | obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o | 104 | obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o |
105 | obj-$(CONFIG_RTC_DRV_MT6397) += rtc-mt6397.o | 105 | obj-$(CONFIG_RTC_DRV_MT6397) += rtc-mt6397.o |
106 | obj-$(CONFIG_RTC_DRV_MT7622) += rtc-mt7622.o | ||
106 | obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o | 107 | obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o |
107 | obj-$(CONFIG_RTC_DRV_MXC) += rtc-mxc.o | 108 | obj-$(CONFIG_RTC_DRV_MXC) += rtc-mxc.o |
108 | obj-$(CONFIG_RTC_DRV_NUC900) += rtc-nuc900.o | 109 | obj-$(CONFIG_RTC_DRV_NUC900) += rtc-nuc900.o |
@@ -114,6 +115,7 @@ obj-$(CONFIG_RTC_DRV_PCF2123) += rtc-pcf2123.o | |||
114 | obj-$(CONFIG_RTC_DRV_PCF2127) += rtc-pcf2127.o | 115 | obj-$(CONFIG_RTC_DRV_PCF2127) += rtc-pcf2127.o |
115 | obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o | 116 | obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o |
116 | obj-$(CONFIG_RTC_DRV_PCF85063) += rtc-pcf85063.o | 117 | obj-$(CONFIG_RTC_DRV_PCF85063) += rtc-pcf85063.o |
118 | obj-$(CONFIG_RTC_DRV_PCF85363) += rtc-pcf85363.o | ||
117 | obj-$(CONFIG_RTC_DRV_PCF8523) += rtc-pcf8523.o | 119 | obj-$(CONFIG_RTC_DRV_PCF8523) += rtc-pcf8523.o |
118 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o | 120 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o |
119 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o | 121 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o |
@@ -144,6 +146,7 @@ obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o | |||
144 | obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o | 146 | obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o |
145 | obj-$(CONFIG_RTC_DRV_S5M) += rtc-s5m.o | 147 | obj-$(CONFIG_RTC_DRV_S5M) += rtc-s5m.o |
146 | obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o | 148 | obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o |
149 | obj-$(CONFIG_RTC_DRV_SC27XX) += rtc-sc27xx.o | ||
147 | obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o | 150 | obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o |
148 | obj-$(CONFIG_RTC_DRV_SIRFSOC) += rtc-sirfsoc.o | 151 | obj-$(CONFIG_RTC_DRV_SIRFSOC) += rtc-sirfsoc.o |
149 | obj-$(CONFIG_RTC_DRV_SNVS) += rtc-snvs.o | 152 | obj-$(CONFIG_RTC_DRV_SNVS) += rtc-snvs.o |
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 8cec9a02c0b8..672b192f8153 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
@@ -779,7 +779,7 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) | |||
779 | } | 779 | } |
780 | 780 | ||
781 | timerqueue_add(&rtc->timerqueue, &timer->node); | 781 | timerqueue_add(&rtc->timerqueue, &timer->node); |
782 | if (!next) { | 782 | if (!next || ktime_before(timer->node.expires, next->expires)) { |
783 | struct rtc_wkalrm alarm; | 783 | struct rtc_wkalrm alarm; |
784 | int err; | 784 | int err; |
785 | alarm.time = rtc_ktime_to_tm(timer->node.expires); | 785 | alarm.time = rtc_ktime_to_tm(timer->node.expires); |
@@ -1004,6 +1004,10 @@ int rtc_read_offset(struct rtc_device *rtc, long *offset) | |||
1004 | * to compensate for differences in the actual clock rate due to temperature, | 1004 | * to compensate for differences in the actual clock rate due to temperature, |
1005 | * the crystal, capacitor, etc. | 1005 | * the crystal, capacitor, etc. |
1006 | * | 1006 | * |
1007 | * The adjustment applied is as follows: | ||
1008 | * t = t0 * (1 + offset * 1e-9) | ||
1009 | * where t0 is the measured length of 1 RTC second with offset = 0 | ||
1010 | * | ||
1007 | * Kernel interface to adjust an rtc clock offset. | 1011 | * Kernel interface to adjust an rtc clock offset. |
1008 | * Return 0 on success, or a negative number on error. | 1012 | * Return 0 on success, or a negative number on error. |
1009 | * If the rtc offset is not setable (or not implemented), return -EINVAL | 1013 | * If the rtc offset is not setable (or not implemented), return -EINVAL |
diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c index fea9a60b06cf..b033bc556f5d 100644 --- a/drivers/rtc/rtc-abx80x.c +++ b/drivers/rtc/rtc-abx80x.c | |||
@@ -614,12 +614,12 @@ static int abx80x_probe(struct i2c_client *client, | |||
614 | if (err) | 614 | if (err) |
615 | return err; | 615 | return err; |
616 | 616 | ||
617 | rtc = devm_rtc_device_register(&client->dev, "abx8xx", | 617 | rtc = devm_rtc_allocate_device(&client->dev); |
618 | &abx80x_rtc_ops, THIS_MODULE); | ||
619 | |||
620 | if (IS_ERR(rtc)) | 618 | if (IS_ERR(rtc)) |
621 | return PTR_ERR(rtc); | 619 | return PTR_ERR(rtc); |
622 | 620 | ||
621 | rtc->ops = &abx80x_rtc_ops; | ||
622 | |||
623 | i2c_set_clientdata(client, rtc); | 623 | i2c_set_clientdata(client, rtc); |
624 | 624 | ||
625 | if (client->irq > 0) { | 625 | if (client->irq > 0) { |
@@ -646,10 +646,14 @@ static int abx80x_probe(struct i2c_client *client, | |||
646 | err = devm_add_action_or_reset(&client->dev, | 646 | err = devm_add_action_or_reset(&client->dev, |
647 | rtc_calib_remove_sysfs_group, | 647 | rtc_calib_remove_sysfs_group, |
648 | &client->dev); | 648 | &client->dev); |
649 | if (err) | 649 | if (err) { |
650 | dev_err(&client->dev, | 650 | dev_err(&client->dev, |
651 | "Failed to add sysfs cleanup action: %d\n", | 651 | "Failed to add sysfs cleanup action: %d\n", |
652 | err); | 652 | err); |
653 | return err; | ||
654 | } | ||
655 | |||
656 | err = rtc_register_device(rtc); | ||
653 | 657 | ||
654 | return err; | 658 | return err; |
655 | } | 659 | } |
diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c index 21f355c37eab..1e4978c96ffd 100644 --- a/drivers/rtc/rtc-armada38x.c +++ b/drivers/rtc/rtc-armada38x.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #define RTC_IRQ_AL_EN BIT(0) | 28 | #define RTC_IRQ_AL_EN BIT(0) |
29 | #define RTC_IRQ_FREQ_EN BIT(1) | 29 | #define RTC_IRQ_FREQ_EN BIT(1) |
30 | #define RTC_IRQ_FREQ_1HZ BIT(2) | 30 | #define RTC_IRQ_FREQ_1HZ BIT(2) |
31 | #define RTC_CCR 0x18 | ||
32 | #define RTC_CCR_MODE BIT(15) | ||
31 | 33 | ||
32 | #define RTC_TIME 0xC | 34 | #define RTC_TIME 0xC |
33 | #define RTC_ALARM1 0x10 | 35 | #define RTC_ALARM1 0x10 |
@@ -343,18 +345,117 @@ static irqreturn_t armada38x_rtc_alarm_irq(int irq, void *data) | |||
343 | return IRQ_HANDLED; | 345 | return IRQ_HANDLED; |
344 | } | 346 | } |
345 | 347 | ||
348 | /* | ||
349 | * The information given in the Armada 388 functional spec is complex. | ||
350 | * They give two different formulas for calculating the offset value, | ||
351 | * but when considering "Offset" as an 8-bit signed integer, they both | ||
352 | * reduce down to (we shall rename "Offset" as "val" here): | ||
353 | * | ||
354 | * val = (f_ideal / f_measured - 1) / resolution where f_ideal = 32768 | ||
355 | * | ||
356 | * Converting to time, f = 1/t: | ||
357 | * val = (t_measured / t_ideal - 1) / resolution where t_ideal = 1/32768 | ||
358 | * | ||
359 | * => t_measured / t_ideal = val * resolution + 1 | ||
360 | * | ||
361 | * "offset" in the RTC interface is defined as: | ||
362 | * t = t0 * (1 + offset * 1e-9) | ||
363 | * where t is the desired period, t0 is the measured period with a zero | ||
364 | * offset, which is t_measured above. With t0 = t_measured and t = t_ideal, | ||
365 | * offset = (t_ideal / t_measured - 1) / 1e-9 | ||
366 | * | ||
367 | * => t_ideal / t_measured = offset * 1e-9 + 1 | ||
368 | * | ||
369 | * so: | ||
370 | * | ||
371 | * offset * 1e-9 + 1 = 1 / (val * resolution + 1) | ||
372 | * | ||
373 | * We want "resolution" to be an integer, so resolution = R * 1e-9, giving | ||
374 | * offset = 1e18 / (val * R + 1e9) - 1e9 | ||
375 | * val = (1e18 / (offset + 1e9) - 1e9) / R | ||
376 | * with a common transformation: | ||
377 | * f(x) = 1e18 / (x + 1e9) - 1e9 | ||
378 | * offset = f(val * R) | ||
379 | * val = f(offset) / R | ||
380 | * | ||
381 | * Armada 38x supports two modes, fine mode (954ppb) and coarse mode (3815ppb). | ||
382 | */ | ||
383 | static long armada38x_ppb_convert(long ppb) | ||
384 | { | ||
385 | long div = ppb + 1000000000L; | ||
386 | |||
387 | return div_s64(1000000000000000000LL + div / 2, div) - 1000000000L; | ||
388 | } | ||
389 | |||
390 | static int armada38x_rtc_read_offset(struct device *dev, long *offset) | ||
391 | { | ||
392 | struct armada38x_rtc *rtc = dev_get_drvdata(dev); | ||
393 | unsigned long ccr, flags; | ||
394 | long ppb_cor; | ||
395 | |||
396 | spin_lock_irqsave(&rtc->lock, flags); | ||
397 | ccr = rtc->data->read_rtc_reg(rtc, RTC_CCR); | ||
398 | spin_unlock_irqrestore(&rtc->lock, flags); | ||
399 | |||
400 | ppb_cor = (ccr & RTC_CCR_MODE ? 3815 : 954) * (s8)ccr; | ||
401 | /* ppb_cor + 1000000000L can never be zero */ | ||
402 | *offset = armada38x_ppb_convert(ppb_cor); | ||
403 | |||
404 | return 0; | ||
405 | } | ||
406 | |||
407 | static int armada38x_rtc_set_offset(struct device *dev, long offset) | ||
408 | { | ||
409 | struct armada38x_rtc *rtc = dev_get_drvdata(dev); | ||
410 | unsigned long ccr = 0; | ||
411 | long ppb_cor, off; | ||
412 | |||
413 | /* | ||
414 | * The maximum ppb_cor is -128 * 3815 .. 127 * 3815, but we | ||
415 | * need to clamp the input. This equates to -484270 .. 488558. | ||
416 | * Not only is this to stop out of range "off" but also to | ||
417 | * avoid the division by zero in armada38x_ppb_convert(). | ||
418 | */ | ||
419 | offset = clamp(offset, -484270L, 488558L); | ||
420 | |||
421 | ppb_cor = armada38x_ppb_convert(offset); | ||
422 | |||
423 | /* | ||
424 | * Use low update mode where possible, which gives a better | ||
425 | * resolution of correction. | ||
426 | */ | ||
427 | off = DIV_ROUND_CLOSEST(ppb_cor, 954); | ||
428 | if (off > 127 || off < -128) { | ||
429 | ccr = RTC_CCR_MODE; | ||
430 | off = DIV_ROUND_CLOSEST(ppb_cor, 3815); | ||
431 | } | ||
432 | |||
433 | /* | ||
434 | * Armada 388 requires a bit pattern in bits 14..8 depending on | ||
435 | * the sign bit: { 0, ~S, S, S, S, S, S } | ||
436 | */ | ||
437 | ccr |= (off & 0x3fff) ^ 0x2000; | ||
438 | rtc_delayed_write(ccr, rtc, RTC_CCR); | ||
439 | |||
440 | return 0; | ||
441 | } | ||
442 | |||
346 | static const struct rtc_class_ops armada38x_rtc_ops = { | 443 | static const struct rtc_class_ops armada38x_rtc_ops = { |
347 | .read_time = armada38x_rtc_read_time, | 444 | .read_time = armada38x_rtc_read_time, |
348 | .set_time = armada38x_rtc_set_time, | 445 | .set_time = armada38x_rtc_set_time, |
349 | .read_alarm = armada38x_rtc_read_alarm, | 446 | .read_alarm = armada38x_rtc_read_alarm, |
350 | .set_alarm = armada38x_rtc_set_alarm, | 447 | .set_alarm = armada38x_rtc_set_alarm, |
351 | .alarm_irq_enable = armada38x_rtc_alarm_irq_enable, | 448 | .alarm_irq_enable = armada38x_rtc_alarm_irq_enable, |
449 | .read_offset = armada38x_rtc_read_offset, | ||
450 | .set_offset = armada38x_rtc_set_offset, | ||
352 | }; | 451 | }; |
353 | 452 | ||
354 | static const struct rtc_class_ops armada38x_rtc_ops_noirq = { | 453 | static const struct rtc_class_ops armada38x_rtc_ops_noirq = { |
355 | .read_time = armada38x_rtc_read_time, | 454 | .read_time = armada38x_rtc_read_time, |
356 | .set_time = armada38x_rtc_set_time, | 455 | .set_time = armada38x_rtc_set_time, |
357 | .read_alarm = armada38x_rtc_read_alarm, | 456 | .read_alarm = armada38x_rtc_read_alarm, |
457 | .read_offset = armada38x_rtc_read_offset, | ||
458 | .set_offset = armada38x_rtc_set_offset, | ||
358 | }; | 459 | }; |
359 | 460 | ||
360 | static const struct armada38x_rtc_data armada38x_data = { | 461 | static const struct armada38x_rtc_data armada38x_data = { |
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index e221b78b6f10..de81ecedd571 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c | |||
@@ -42,8 +42,6 @@ | |||
42 | #define at91_rtc_write(field, val) \ | 42 | #define at91_rtc_write(field, val) \ |
43 | writel_relaxed((val), at91_rtc_regs + field) | 43 | writel_relaxed((val), at91_rtc_regs + field) |
44 | 44 | ||
45 | #define AT91_RTC_EPOCH 1900UL /* just like arch/arm/common/rtctime.c */ | ||
46 | |||
47 | struct at91_rtc_config { | 45 | struct at91_rtc_config { |
48 | bool use_shadow_imr; | 46 | bool use_shadow_imr; |
49 | }; | 47 | }; |
@@ -51,7 +49,6 @@ struct at91_rtc_config { | |||
51 | static const struct at91_rtc_config *at91_rtc_config; | 49 | static const struct at91_rtc_config *at91_rtc_config; |
52 | static DECLARE_COMPLETION(at91_rtc_updated); | 50 | static DECLARE_COMPLETION(at91_rtc_updated); |
53 | static DECLARE_COMPLETION(at91_rtc_upd_rdy); | 51 | static DECLARE_COMPLETION(at91_rtc_upd_rdy); |
54 | static unsigned int at91_alarm_year = AT91_RTC_EPOCH; | ||
55 | static void __iomem *at91_rtc_regs; | 52 | static void __iomem *at91_rtc_regs; |
56 | static int irq; | 53 | static int irq; |
57 | static DEFINE_SPINLOCK(at91_rtc_lock); | 54 | static DEFINE_SPINLOCK(at91_rtc_lock); |
@@ -131,8 +128,7 @@ static void at91_rtc_decodetime(unsigned int timereg, unsigned int calreg, | |||
131 | 128 | ||
132 | /* | 129 | /* |
133 | * The Calendar Alarm register does not have a field for | 130 | * The Calendar Alarm register does not have a field for |
134 | * the year - so these will return an invalid value. When an | 131 | * the year - so these will return an invalid value. |
135 | * alarm is set, at91_alarm_year will store the current year. | ||
136 | */ | 132 | */ |
137 | tm->tm_year = bcd2bin(date & AT91_RTC_CENT) * 100; /* century */ | 133 | tm->tm_year = bcd2bin(date & AT91_RTC_CENT) * 100; /* century */ |
138 | tm->tm_year += bcd2bin((date & AT91_RTC_YEAR) >> 8); /* year */ | 134 | tm->tm_year += bcd2bin((date & AT91_RTC_YEAR) >> 8); /* year */ |
@@ -208,15 +204,14 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
208 | struct rtc_time *tm = &alrm->time; | 204 | struct rtc_time *tm = &alrm->time; |
209 | 205 | ||
210 | at91_rtc_decodetime(AT91_RTC_TIMALR, AT91_RTC_CALALR, tm); | 206 | at91_rtc_decodetime(AT91_RTC_TIMALR, AT91_RTC_CALALR, tm); |
211 | tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); | 207 | tm->tm_year = -1; |
212 | tm->tm_year = at91_alarm_year - 1900; | ||
213 | 208 | ||
214 | alrm->enabled = (at91_rtc_read_imr() & AT91_RTC_ALARM) | 209 | alrm->enabled = (at91_rtc_read_imr() & AT91_RTC_ALARM) |
215 | ? 1 : 0; | 210 | ? 1 : 0; |
216 | 211 | ||
217 | dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, | 212 | dev_dbg(dev, "%s(): %02d-%02d %02d:%02d:%02d %sabled\n", __func__, |
218 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | 213 | tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, |
219 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 214 | alrm->enabled ? "en" : "dis"); |
220 | 215 | ||
221 | return 0; | 216 | return 0; |
222 | } | 217 | } |
@@ -230,8 +225,6 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
230 | 225 | ||
231 | at91_rtc_decodetime(AT91_RTC_TIMR, AT91_RTC_CALR, &tm); | 226 | at91_rtc_decodetime(AT91_RTC_TIMR, AT91_RTC_CALR, &tm); |
232 | 227 | ||
233 | at91_alarm_year = tm.tm_year; | ||
234 | |||
235 | tm.tm_mon = alrm->time.tm_mon; | 228 | tm.tm_mon = alrm->time.tm_mon; |
236 | tm.tm_mday = alrm->time.tm_mday; | 229 | tm.tm_mday = alrm->time.tm_mday; |
237 | tm.tm_hour = alrm->time.tm_hour; | 230 | tm.tm_hour = alrm->time.tm_hour; |
@@ -255,7 +248,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
255 | } | 248 | } |
256 | 249 | ||
257 | dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, | 250 | dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, |
258 | at91_alarm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, | 251 | tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, |
259 | tm.tm_min, tm.tm_sec); | 252 | tm.tm_min, tm.tm_sec); |
260 | 253 | ||
261 | return 0; | 254 | return 0; |
diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index 72b22935eb62..d8df2e9e14ad 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c | |||
@@ -514,56 +514,43 @@ static void msg_init(struct spi_message *m, struct spi_transfer *x, | |||
514 | spi_message_add_tail(x, m); | 514 | spi_message_add_tail(x, m); |
515 | } | 515 | } |
516 | 516 | ||
517 | static ssize_t | 517 | static int ds1305_nvram_read(void *priv, unsigned int off, void *buf, |
518 | ds1305_nvram_read(struct file *filp, struct kobject *kobj, | 518 | size_t count) |
519 | struct bin_attribute *attr, | ||
520 | char *buf, loff_t off, size_t count) | ||
521 | { | 519 | { |
522 | struct spi_device *spi; | 520 | struct ds1305 *ds1305 = priv; |
521 | struct spi_device *spi = ds1305->spi; | ||
523 | u8 addr; | 522 | u8 addr; |
524 | struct spi_message m; | 523 | struct spi_message m; |
525 | struct spi_transfer x[2]; | 524 | struct spi_transfer x[2]; |
526 | int status; | ||
527 | |||
528 | spi = to_spi_device(kobj_to_dev(kobj)); | ||
529 | 525 | ||
530 | addr = DS1305_NVRAM + off; | 526 | addr = DS1305_NVRAM + off; |
531 | msg_init(&m, x, &addr, count, NULL, buf); | 527 | msg_init(&m, x, &addr, count, NULL, buf); |
532 | 528 | ||
533 | status = spi_sync(spi, &m); | 529 | return spi_sync(spi, &m); |
534 | if (status < 0) | ||
535 | dev_err(&spi->dev, "nvram %s error %d\n", "read", status); | ||
536 | return (status < 0) ? status : count; | ||
537 | } | 530 | } |
538 | 531 | ||
539 | static ssize_t | 532 | static int ds1305_nvram_write(void *priv, unsigned int off, void *buf, |
540 | ds1305_nvram_write(struct file *filp, struct kobject *kobj, | 533 | size_t count) |
541 | struct bin_attribute *attr, | ||
542 | char *buf, loff_t off, size_t count) | ||
543 | { | 534 | { |
544 | struct spi_device *spi; | 535 | struct ds1305 *ds1305 = priv; |
536 | struct spi_device *spi = ds1305->spi; | ||
545 | u8 addr; | 537 | u8 addr; |
546 | struct spi_message m; | 538 | struct spi_message m; |
547 | struct spi_transfer x[2]; | 539 | struct spi_transfer x[2]; |
548 | int status; | ||
549 | |||
550 | spi = to_spi_device(kobj_to_dev(kobj)); | ||
551 | 540 | ||
552 | addr = (DS1305_WRITE | DS1305_NVRAM) + off; | 541 | addr = (DS1305_WRITE | DS1305_NVRAM) + off; |
553 | msg_init(&m, x, &addr, count, buf, NULL); | 542 | msg_init(&m, x, &addr, count, buf, NULL); |
554 | 543 | ||
555 | status = spi_sync(spi, &m); | 544 | return spi_sync(spi, &m); |
556 | if (status < 0) | ||
557 | dev_err(&spi->dev, "nvram %s error %d\n", "write", status); | ||
558 | return (status < 0) ? status : count; | ||
559 | } | 545 | } |
560 | 546 | ||
561 | static struct bin_attribute nvram = { | 547 | static struct nvmem_config ds1305_nvmem_cfg = { |
562 | .attr.name = "nvram", | 548 | .name = "ds1305_nvram", |
563 | .attr.mode = S_IRUGO | S_IWUSR, | 549 | .word_size = 1, |
564 | .read = ds1305_nvram_read, | 550 | .stride = 1, |
565 | .write = ds1305_nvram_write, | 551 | .size = DS1305_NVRAM_LEN, |
566 | .size = DS1305_NVRAM_LEN, | 552 | .reg_read = ds1305_nvram_read, |
553 | .reg_write = ds1305_nvram_write, | ||
567 | }; | 554 | }; |
568 | 555 | ||
569 | /*----------------------------------------------------------------------*/ | 556 | /*----------------------------------------------------------------------*/ |
@@ -708,10 +695,19 @@ static int ds1305_probe(struct spi_device *spi) | |||
708 | dev_dbg(&spi->dev, "AM/PM\n"); | 695 | dev_dbg(&spi->dev, "AM/PM\n"); |
709 | 696 | ||
710 | /* register RTC ... from here on, ds1305->ctrl needs locking */ | 697 | /* register RTC ... from here on, ds1305->ctrl needs locking */ |
711 | ds1305->rtc = devm_rtc_device_register(&spi->dev, "ds1305", | 698 | ds1305->rtc = devm_rtc_allocate_device(&spi->dev); |
712 | &ds1305_ops, THIS_MODULE); | ||
713 | if (IS_ERR(ds1305->rtc)) { | 699 | if (IS_ERR(ds1305->rtc)) { |
714 | status = PTR_ERR(ds1305->rtc); | 700 | return PTR_ERR(ds1305->rtc); |
701 | } | ||
702 | |||
703 | ds1305->rtc->ops = &ds1305_ops; | ||
704 | |||
705 | ds1305_nvmem_cfg.priv = ds1305; | ||
706 | ds1305->rtc->nvmem_config = &ds1305_nvmem_cfg; | ||
707 | ds1305->rtc->nvram_old_abi = true; | ||
708 | |||
709 | status = rtc_register_device(ds1305->rtc); | ||
710 | if (status) { | ||
715 | dev_dbg(&spi->dev, "register rtc --> %d\n", status); | 711 | dev_dbg(&spi->dev, "register rtc --> %d\n", status); |
716 | return status; | 712 | return status; |
717 | } | 713 | } |
@@ -734,12 +730,6 @@ static int ds1305_probe(struct spi_device *spi) | |||
734 | } | 730 | } |
735 | } | 731 | } |
736 | 732 | ||
737 | /* export NVRAM */ | ||
738 | status = sysfs_create_bin_file(&spi->dev.kobj, &nvram); | ||
739 | if (status < 0) { | ||
740 | dev_err(&spi->dev, "register nvram --> %d\n", status); | ||
741 | } | ||
742 | |||
743 | return 0; | 733 | return 0; |
744 | } | 734 | } |
745 | 735 | ||
@@ -747,8 +737,6 @@ static int ds1305_remove(struct spi_device *spi) | |||
747 | { | 737 | { |
748 | struct ds1305 *ds1305 = spi_get_drvdata(spi); | 738 | struct ds1305 *ds1305 = spi_get_drvdata(spi); |
749 | 739 | ||
750 | sysfs_remove_bin_file(&spi->dev.kobj, &nvram); | ||
751 | |||
752 | /* carefully shut down irq and workqueue, if present */ | 740 | /* carefully shut down irq and workqueue, if present */ |
753 | if (spi->irq) { | 741 | if (spi->irq) { |
754 | set_bit(FLAG_EXITING, &ds1305->flags); | 742 | set_bit(FLAG_EXITING, &ds1305->flags); |
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index e7d9215c9201..923dde912f60 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c | |||
@@ -325,6 +325,10 @@ static const struct of_device_id ds1307_of_match[] = { | |||
325 | .compatible = "isil,isl12057", | 325 | .compatible = "isil,isl12057", |
326 | .data = (void *)ds_1337 | 326 | .data = (void *)ds_1337 |
327 | }, | 327 | }, |
328 | { | ||
329 | .compatible = "epson,rx8130", | ||
330 | .data = (void *)rx_8130 | ||
331 | }, | ||
328 | { } | 332 | { } |
329 | }; | 333 | }; |
330 | MODULE_DEVICE_TABLE(of, ds1307_of_match); | 334 | MODULE_DEVICE_TABLE(of, ds1307_of_match); |
@@ -348,6 +352,7 @@ static const struct acpi_device_id ds1307_acpi_ids[] = { | |||
348 | { .id = "PT7C4338", .driver_data = ds_1307 }, | 352 | { .id = "PT7C4338", .driver_data = ds_1307 }, |
349 | { .id = "RX8025", .driver_data = rx_8025 }, | 353 | { .id = "RX8025", .driver_data = rx_8025 }, |
350 | { .id = "ISL12057", .driver_data = ds_1337 }, | 354 | { .id = "ISL12057", .driver_data = ds_1337 }, |
355 | { .id = "RX8130", .driver_data = rx_8130 }, | ||
351 | { } | 356 | { } |
352 | }; | 357 | }; |
353 | MODULE_DEVICE_TABLE(acpi, ds1307_acpi_ids); | 358 | MODULE_DEVICE_TABLE(acpi, ds1307_acpi_ids); |
@@ -787,8 +792,6 @@ static int rx8130_alarm_irq_enable(struct device *dev, unsigned int enabled) | |||
787 | * Alarm support for mcp794xx devices. | 792 | * Alarm support for mcp794xx devices. |
788 | */ | 793 | */ |
789 | 794 | ||
790 | #define MCP794XX_REG_WEEKDAY 0x3 | ||
791 | #define MCP794XX_REG_WEEKDAY_WDAY_MASK 0x7 | ||
792 | #define MCP794XX_REG_CONTROL 0x07 | 795 | #define MCP794XX_REG_CONTROL 0x07 |
793 | # define MCP794XX_BIT_ALM0_EN 0x10 | 796 | # define MCP794XX_BIT_ALM0_EN 0x10 |
794 | # define MCP794XX_BIT_ALM1_EN 0x20 | 797 | # define MCP794XX_BIT_ALM1_EN 0x20 |
@@ -877,15 +880,38 @@ static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
877 | return 0; | 880 | return 0; |
878 | } | 881 | } |
879 | 882 | ||
883 | /* | ||
884 | * We may have a random RTC weekday, therefore calculate alarm weekday based | ||
885 | * on current weekday we read from the RTC timekeeping regs | ||
886 | */ | ||
887 | static int mcp794xx_alm_weekday(struct device *dev, struct rtc_time *tm_alarm) | ||
888 | { | ||
889 | struct rtc_time tm_now; | ||
890 | int days_now, days_alarm, ret; | ||
891 | |||
892 | ret = ds1307_get_time(dev, &tm_now); | ||
893 | if (ret) | ||
894 | return ret; | ||
895 | |||
896 | days_now = div_s64(rtc_tm_to_time64(&tm_now), 24 * 60 * 60); | ||
897 | days_alarm = div_s64(rtc_tm_to_time64(tm_alarm), 24 * 60 * 60); | ||
898 | |||
899 | return (tm_now.tm_wday + days_alarm - days_now) % 7 + 1; | ||
900 | } | ||
901 | |||
880 | static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t) | 902 | static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t) |
881 | { | 903 | { |
882 | struct ds1307 *ds1307 = dev_get_drvdata(dev); | 904 | struct ds1307 *ds1307 = dev_get_drvdata(dev); |
883 | unsigned char regs[10]; | 905 | unsigned char regs[10]; |
884 | int ret; | 906 | int wday, ret; |
885 | 907 | ||
886 | if (!test_bit(HAS_ALARM, &ds1307->flags)) | 908 | if (!test_bit(HAS_ALARM, &ds1307->flags)) |
887 | return -EINVAL; | 909 | return -EINVAL; |
888 | 910 | ||
911 | wday = mcp794xx_alm_weekday(dev, &t->time); | ||
912 | if (wday < 0) | ||
913 | return wday; | ||
914 | |||
889 | dev_dbg(dev, "%s, sec=%d min=%d hour=%d wday=%d mday=%d mon=%d " | 915 | dev_dbg(dev, "%s, sec=%d min=%d hour=%d wday=%d mday=%d mon=%d " |
890 | "enabled=%d pending=%d\n", __func__, | 916 | "enabled=%d pending=%d\n", __func__, |
891 | t->time.tm_sec, t->time.tm_min, t->time.tm_hour, | 917 | t->time.tm_sec, t->time.tm_min, t->time.tm_hour, |
@@ -902,7 +928,7 @@ static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
902 | regs[3] = bin2bcd(t->time.tm_sec); | 928 | regs[3] = bin2bcd(t->time.tm_sec); |
903 | regs[4] = bin2bcd(t->time.tm_min); | 929 | regs[4] = bin2bcd(t->time.tm_min); |
904 | regs[5] = bin2bcd(t->time.tm_hour); | 930 | regs[5] = bin2bcd(t->time.tm_hour); |
905 | regs[6] = bin2bcd(t->time.tm_wday + 1); | 931 | regs[6] = wday; |
906 | regs[7] = bin2bcd(t->time.tm_mday); | 932 | regs[7] = bin2bcd(t->time.tm_mday); |
907 | regs[8] = bin2bcd(t->time.tm_mon + 1); | 933 | regs[8] = bin2bcd(t->time.tm_mon + 1); |
908 | 934 | ||
@@ -1354,14 +1380,12 @@ static int ds1307_probe(struct i2c_client *client, | |||
1354 | { | 1380 | { |
1355 | struct ds1307 *ds1307; | 1381 | struct ds1307 *ds1307; |
1356 | int err = -ENODEV; | 1382 | int err = -ENODEV; |
1357 | int tmp, wday; | 1383 | int tmp; |
1358 | const struct chip_desc *chip; | 1384 | const struct chip_desc *chip; |
1359 | bool want_irq; | 1385 | bool want_irq; |
1360 | bool ds1307_can_wakeup_device = false; | 1386 | bool ds1307_can_wakeup_device = false; |
1361 | unsigned char regs[8]; | 1387 | unsigned char regs[8]; |
1362 | struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev); | 1388 | struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev); |
1363 | struct rtc_time tm; | ||
1364 | unsigned long timestamp; | ||
1365 | u8 trickle_charger_setup = 0; | 1389 | u8 trickle_charger_setup = 0; |
1366 | 1390 | ||
1367 | ds1307 = devm_kzalloc(&client->dev, sizeof(struct ds1307), GFP_KERNEL); | 1391 | ds1307 = devm_kzalloc(&client->dev, sizeof(struct ds1307), GFP_KERNEL); |
@@ -1641,25 +1665,6 @@ read_rtc: | |||
1641 | bin2bcd(tmp)); | 1665 | bin2bcd(tmp)); |
1642 | } | 1666 | } |
1643 | 1667 | ||
1644 | /* | ||
1645 | * Some IPs have weekday reset value = 0x1 which might not correct | ||
1646 | * hence compute the wday using the current date/month/year values | ||
1647 | */ | ||
1648 | ds1307_get_time(ds1307->dev, &tm); | ||
1649 | wday = tm.tm_wday; | ||
1650 | timestamp = rtc_tm_to_time64(&tm); | ||
1651 | rtc_time64_to_tm(timestamp, &tm); | ||
1652 | |||
1653 | /* | ||
1654 | * Check if reset wday is different from the computed wday | ||
1655 | * If different then set the wday which we computed using | ||
1656 | * timestamp | ||
1657 | */ | ||
1658 | if (wday != tm.tm_wday) | ||
1659 | regmap_update_bits(ds1307->regmap, MCP794XX_REG_WEEKDAY, | ||
1660 | MCP794XX_REG_WEEKDAY_WDAY_MASK, | ||
1661 | tm.tm_wday + 1); | ||
1662 | |||
1663 | if (want_irq || ds1307_can_wakeup_device) { | 1668 | if (want_irq || ds1307_can_wakeup_device) { |
1664 | device_set_wakeup_capable(ds1307->dev, true); | 1669 | device_set_wakeup_capable(ds1307->dev, true); |
1665 | set_bit(HAS_ALARM, &ds1307->flags); | 1670 | set_bit(HAS_ALARM, &ds1307->flags); |
diff --git a/drivers/rtc/rtc-ds1390.c b/drivers/rtc/rtc-ds1390.c index aa0d2c6f1edc..4d5b007d7fc6 100644 --- a/drivers/rtc/rtc-ds1390.c +++ b/drivers/rtc/rtc-ds1390.c | |||
@@ -216,9 +216,16 @@ static int ds1390_probe(struct spi_device *spi) | |||
216 | return res; | 216 | return res; |
217 | } | 217 | } |
218 | 218 | ||
219 | static const struct of_device_id ds1390_of_match[] = { | ||
220 | { .compatible = "dallas,ds1390" }, | ||
221 | {} | ||
222 | }; | ||
223 | MODULE_DEVICE_TABLE(of, ds1390_of_match); | ||
224 | |||
219 | static struct spi_driver ds1390_driver = { | 225 | static struct spi_driver ds1390_driver = { |
220 | .driver = { | 226 | .driver = { |
221 | .name = "rtc-ds1390", | 227 | .name = "rtc-ds1390", |
228 | .of_match_table = of_match_ptr(ds1390_of_match), | ||
222 | }, | 229 | }, |
223 | .probe = ds1390_probe, | 230 | .probe = ds1390_probe, |
224 | }; | 231 | }; |
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index 1b2dcb58c0ab..1e95312a6f2e 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c | |||
@@ -398,42 +398,37 @@ static const struct rtc_class_ops ds1511_rtc_ops = { | |||
398 | .alarm_irq_enable = ds1511_rtc_alarm_irq_enable, | 398 | .alarm_irq_enable = ds1511_rtc_alarm_irq_enable, |
399 | }; | 399 | }; |
400 | 400 | ||
401 | static ssize_t | 401 | static int ds1511_nvram_read(void *priv, unsigned int pos, void *buf, |
402 | ds1511_nvram_read(struct file *filp, struct kobject *kobj, | 402 | size_t size) |
403 | struct bin_attribute *ba, | ||
404 | char *buf, loff_t pos, size_t size) | ||
405 | { | 403 | { |
406 | ssize_t count; | 404 | int i; |
407 | 405 | ||
408 | rtc_write(pos, DS1511_RAMADDR_LSB); | 406 | rtc_write(pos, DS1511_RAMADDR_LSB); |
409 | for (count = 0; count < size; count++) | 407 | for (i = 0; i < size; i++) |
410 | *buf++ = rtc_read(DS1511_RAMDATA); | 408 | *(char *)buf++ = rtc_read(DS1511_RAMDATA); |
411 | 409 | ||
412 | return count; | 410 | return 0; |
413 | } | 411 | } |
414 | 412 | ||
415 | static ssize_t | 413 | static int ds1511_nvram_write(void *priv, unsigned int pos, void *buf, |
416 | ds1511_nvram_write(struct file *filp, struct kobject *kobj, | 414 | size_t size) |
417 | struct bin_attribute *bin_attr, | ||
418 | char *buf, loff_t pos, size_t size) | ||
419 | { | 415 | { |
420 | ssize_t count; | 416 | int i; |
421 | 417 | ||
422 | rtc_write(pos, DS1511_RAMADDR_LSB); | 418 | rtc_write(pos, DS1511_RAMADDR_LSB); |
423 | for (count = 0; count < size; count++) | 419 | for (i = 0; i < size; i++) |
424 | rtc_write(*buf++, DS1511_RAMDATA); | 420 | rtc_write(*(char *)buf++, DS1511_RAMDATA); |
425 | 421 | ||
426 | return count; | 422 | return 0; |
427 | } | 423 | } |
428 | 424 | ||
429 | static struct bin_attribute ds1511_nvram_attr = { | 425 | static struct nvmem_config ds1511_nvmem_cfg = { |
430 | .attr = { | 426 | .name = "ds1511_nvram", |
431 | .name = "nvram", | 427 | .word_size = 1, |
432 | .mode = S_IRUGO | S_IWUSR, | 428 | .stride = 1, |
433 | }, | ||
434 | .size = DS1511_RAM_MAX, | 429 | .size = DS1511_RAM_MAX, |
435 | .read = ds1511_nvram_read, | 430 | .reg_read = ds1511_nvram_read, |
436 | .write = ds1511_nvram_write, | 431 | .reg_write = ds1511_nvram_write, |
437 | }; | 432 | }; |
438 | 433 | ||
439 | static int ds1511_rtc_probe(struct platform_device *pdev) | 434 | static int ds1511_rtc_probe(struct platform_device *pdev) |
@@ -477,11 +472,20 @@ static int ds1511_rtc_probe(struct platform_device *pdev) | |||
477 | spin_lock_init(&pdata->lock); | 472 | spin_lock_init(&pdata->lock); |
478 | platform_set_drvdata(pdev, pdata); | 473 | platform_set_drvdata(pdev, pdata); |
479 | 474 | ||
480 | pdata->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, | 475 | pdata->rtc = devm_rtc_allocate_device(&pdev->dev); |
481 | &ds1511_rtc_ops, THIS_MODULE); | ||
482 | if (IS_ERR(pdata->rtc)) | 476 | if (IS_ERR(pdata->rtc)) |
483 | return PTR_ERR(pdata->rtc); | 477 | return PTR_ERR(pdata->rtc); |
484 | 478 | ||
479 | pdata->rtc->ops = &ds1511_rtc_ops; | ||
480 | |||
481 | ds1511_nvmem_cfg.priv = &pdev->dev; | ||
482 | pdata->rtc->nvmem_config = &ds1511_nvmem_cfg; | ||
483 | pdata->rtc->nvram_old_abi = true; | ||
484 | |||
485 | ret = rtc_register_device(pdata->rtc); | ||
486 | if (ret) | ||
487 | return ret; | ||
488 | |||
485 | /* | 489 | /* |
486 | * if the platform has an interrupt in mind for this device, | 490 | * if the platform has an interrupt in mind for this device, |
487 | * then by all means, set it | 491 | * then by all means, set it |
@@ -496,26 +500,6 @@ static int ds1511_rtc_probe(struct platform_device *pdev) | |||
496 | } | 500 | } |
497 | } | 501 | } |
498 | 502 | ||
499 | ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr); | ||
500 | if (ret) | ||
501 | dev_err(&pdev->dev, "Unable to create sysfs entry: %s\n", | ||
502 | ds1511_nvram_attr.attr.name); | ||
503 | |||
504 | return 0; | ||
505 | } | ||
506 | |||
507 | static int ds1511_rtc_remove(struct platform_device *pdev) | ||
508 | { | ||
509 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | ||
510 | |||
511 | sysfs_remove_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr); | ||
512 | if (pdata->irq > 0) { | ||
513 | /* | ||
514 | * disable the alarm interrupt | ||
515 | */ | ||
516 | rtc_write(rtc_read(RTC_CMD) & ~RTC_TIE, RTC_CMD); | ||
517 | rtc_read(RTC_CMD1); | ||
518 | } | ||
519 | return 0; | 503 | return 0; |
520 | } | 504 | } |
521 | 505 | ||
@@ -524,7 +508,6 @@ MODULE_ALIAS("platform:ds1511"); | |||
524 | 508 | ||
525 | static struct platform_driver ds1511_rtc_driver = { | 509 | static struct platform_driver ds1511_rtc_driver = { |
526 | .probe = ds1511_rtc_probe, | 510 | .probe = ds1511_rtc_probe, |
527 | .remove = ds1511_rtc_remove, | ||
528 | .driver = { | 511 | .driver = { |
529 | .name = "ds1511", | 512 | .name = "ds1511", |
530 | }, | 513 | }, |
diff --git a/drivers/rtc/rtc-jz4740.c b/drivers/rtc/rtc-jz4740.c index 64989afffa3d..ff65a7d2b9c9 100644 --- a/drivers/rtc/rtc-jz4740.c +++ b/drivers/rtc/rtc-jz4740.c | |||
@@ -82,7 +82,7 @@ static inline uint32_t jz4740_rtc_reg_read(struct jz4740_rtc *rtc, size_t reg) | |||
82 | static int jz4740_rtc_wait_write_ready(struct jz4740_rtc *rtc) | 82 | static int jz4740_rtc_wait_write_ready(struct jz4740_rtc *rtc) |
83 | { | 83 | { |
84 | uint32_t ctrl; | 84 | uint32_t ctrl; |
85 | int timeout = 1000; | 85 | int timeout = 10000; |
86 | 86 | ||
87 | do { | 87 | do { |
88 | ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL); | 88 | ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL); |
@@ -94,7 +94,7 @@ static int jz4740_rtc_wait_write_ready(struct jz4740_rtc *rtc) | |||
94 | static inline int jz4780_rtc_enable_write(struct jz4740_rtc *rtc) | 94 | static inline int jz4780_rtc_enable_write(struct jz4740_rtc *rtc) |
95 | { | 95 | { |
96 | uint32_t ctrl; | 96 | uint32_t ctrl; |
97 | int ret, timeout = 1000; | 97 | int ret, timeout = 10000; |
98 | 98 | ||
99 | ret = jz4740_rtc_wait_write_ready(rtc); | 99 | ret = jz4740_rtc_wait_write_ready(rtc); |
100 | if (ret != 0) | 100 | if (ret != 0) |
@@ -368,7 +368,7 @@ static int jz4740_rtc_probe(struct platform_device *pdev) | |||
368 | ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SCRATCHPAD, 0x12345678); | 368 | ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SCRATCHPAD, 0x12345678); |
369 | ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, 0); | 369 | ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, 0); |
370 | if (ret) { | 370 | if (ret) { |
371 | dev_err(&pdev->dev, "Could not write write to RTC registers\n"); | 371 | dev_err(&pdev->dev, "Could not write to RTC registers\n"); |
372 | return ret; | 372 | return ret; |
373 | } | 373 | } |
374 | } | 374 | } |
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index f4c070ea8384..c90fba3ed861 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c | |||
@@ -154,6 +154,8 @@ struct m41t80_data { | |||
154 | struct rtc_device *rtc; | 154 | struct rtc_device *rtc; |
155 | #ifdef CONFIG_COMMON_CLK | 155 | #ifdef CONFIG_COMMON_CLK |
156 | struct clk_hw sqw; | 156 | struct clk_hw sqw; |
157 | unsigned long freq; | ||
158 | unsigned int sqwe; | ||
157 | #endif | 159 | #endif |
158 | }; | 160 | }; |
159 | 161 | ||
@@ -443,43 +445,40 @@ static SIMPLE_DEV_PM_OPS(m41t80_pm, m41t80_suspend, m41t80_resume); | |||
443 | #ifdef CONFIG_COMMON_CLK | 445 | #ifdef CONFIG_COMMON_CLK |
444 | #define sqw_to_m41t80_data(_hw) container_of(_hw, struct m41t80_data, sqw) | 446 | #define sqw_to_m41t80_data(_hw) container_of(_hw, struct m41t80_data, sqw) |
445 | 447 | ||
446 | static unsigned long m41t80_sqw_recalc_rate(struct clk_hw *hw, | 448 | static unsigned long m41t80_decode_freq(int setting) |
447 | unsigned long parent_rate) | 449 | { |
450 | return (setting == 0) ? 0 : (setting == 1) ? M41T80_SQW_MAX_FREQ : | ||
451 | M41T80_SQW_MAX_FREQ >> setting; | ||
452 | } | ||
453 | |||
454 | static unsigned long m41t80_get_freq(struct m41t80_data *m41t80) | ||
448 | { | 455 | { |
449 | struct m41t80_data *m41t80 = sqw_to_m41t80_data(hw); | ||
450 | struct i2c_client *client = m41t80->client; | 456 | struct i2c_client *client = m41t80->client; |
451 | int reg_sqw = (m41t80->features & M41T80_FEATURE_SQ_ALT) ? | 457 | int reg_sqw = (m41t80->features & M41T80_FEATURE_SQ_ALT) ? |
452 | M41T80_REG_WDAY : M41T80_REG_SQW; | 458 | M41T80_REG_WDAY : M41T80_REG_SQW; |
453 | int ret = i2c_smbus_read_byte_data(client, reg_sqw); | 459 | int ret = i2c_smbus_read_byte_data(client, reg_sqw); |
454 | unsigned long val = M41T80_SQW_MAX_FREQ; | ||
455 | 460 | ||
456 | if (ret < 0) | 461 | if (ret < 0) |
457 | return 0; | 462 | return 0; |
463 | return m41t80_decode_freq(ret >> 4); | ||
464 | } | ||
458 | 465 | ||
459 | ret >>= 4; | 466 | static unsigned long m41t80_sqw_recalc_rate(struct clk_hw *hw, |
460 | if (ret == 0) | 467 | unsigned long parent_rate) |
461 | val = 0; | 468 | { |
462 | else if (ret > 1) | 469 | return sqw_to_m41t80_data(hw)->freq; |
463 | val = val / (1 << ret); | ||
464 | |||
465 | return val; | ||
466 | } | 470 | } |
467 | 471 | ||
468 | static long m41t80_sqw_round_rate(struct clk_hw *hw, unsigned long rate, | 472 | static long m41t80_sqw_round_rate(struct clk_hw *hw, unsigned long rate, |
469 | unsigned long *prate) | 473 | unsigned long *prate) |
470 | { | 474 | { |
471 | int i, freq = M41T80_SQW_MAX_FREQ; | 475 | if (rate >= M41T80_SQW_MAX_FREQ) |
472 | 476 | return M41T80_SQW_MAX_FREQ; | |
473 | if (freq <= rate) | 477 | if (rate >= M41T80_SQW_MAX_FREQ / 4) |
474 | return freq; | 478 | return M41T80_SQW_MAX_FREQ / 4; |
475 | 479 | if (!rate) | |
476 | for (i = 2; i <= ilog2(M41T80_SQW_MAX_FREQ); i++) { | 480 | return 0; |
477 | freq /= 1 << i; | 481 | return 1 << ilog2(rate); |
478 | if (freq <= rate) | ||
479 | return freq; | ||
480 | } | ||
481 | |||
482 | return 0; | ||
483 | } | 482 | } |
484 | 483 | ||
485 | static int m41t80_sqw_set_rate(struct clk_hw *hw, unsigned long rate, | 484 | static int m41t80_sqw_set_rate(struct clk_hw *hw, unsigned long rate, |
@@ -491,17 +490,12 @@ static int m41t80_sqw_set_rate(struct clk_hw *hw, unsigned long rate, | |||
491 | M41T80_REG_WDAY : M41T80_REG_SQW; | 490 | M41T80_REG_WDAY : M41T80_REG_SQW; |
492 | int reg, ret, val = 0; | 491 | int reg, ret, val = 0; |
493 | 492 | ||
494 | if (rate) { | 493 | if (rate >= M41T80_SQW_MAX_FREQ) |
495 | if (!is_power_of_2(rate)) | 494 | val = 1; |
496 | return -EINVAL; | 495 | else if (rate >= M41T80_SQW_MAX_FREQ / 4) |
497 | val = ilog2(rate); | 496 | val = 2; |
498 | if (val == ilog2(M41T80_SQW_MAX_FREQ)) | 497 | else if (rate) |
499 | val = 1; | 498 | val = 15 - ilog2(rate); |
500 | else if (val < (ilog2(M41T80_SQW_MAX_FREQ) - 1)) | ||
501 | val = ilog2(M41T80_SQW_MAX_FREQ) - val; | ||
502 | else | ||
503 | return -EINVAL; | ||
504 | } | ||
505 | 499 | ||
506 | reg = i2c_smbus_read_byte_data(client, reg_sqw); | 500 | reg = i2c_smbus_read_byte_data(client, reg_sqw); |
507 | if (reg < 0) | 501 | if (reg < 0) |
@@ -510,10 +504,9 @@ static int m41t80_sqw_set_rate(struct clk_hw *hw, unsigned long rate, | |||
510 | reg = (reg & 0x0f) | (val << 4); | 504 | reg = (reg & 0x0f) | (val << 4); |
511 | 505 | ||
512 | ret = i2c_smbus_write_byte_data(client, reg_sqw, reg); | 506 | ret = i2c_smbus_write_byte_data(client, reg_sqw, reg); |
513 | if (ret < 0) | 507 | if (!ret) |
514 | return ret; | 508 | m41t80->freq = m41t80_decode_freq(val); |
515 | 509 | return ret; | |
516 | return -EINVAL; | ||
517 | } | 510 | } |
518 | 511 | ||
519 | static int m41t80_sqw_control(struct clk_hw *hw, bool enable) | 512 | static int m41t80_sqw_control(struct clk_hw *hw, bool enable) |
@@ -530,7 +523,10 @@ static int m41t80_sqw_control(struct clk_hw *hw, bool enable) | |||
530 | else | 523 | else |
531 | ret &= ~M41T80_ALMON_SQWE; | 524 | ret &= ~M41T80_ALMON_SQWE; |
532 | 525 | ||
533 | return i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, ret); | 526 | ret = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, ret); |
527 | if (!ret) | ||
528 | m41t80->sqwe = enable; | ||
529 | return ret; | ||
534 | } | 530 | } |
535 | 531 | ||
536 | static int m41t80_sqw_prepare(struct clk_hw *hw) | 532 | static int m41t80_sqw_prepare(struct clk_hw *hw) |
@@ -545,14 +541,7 @@ static void m41t80_sqw_unprepare(struct clk_hw *hw) | |||
545 | 541 | ||
546 | static int m41t80_sqw_is_prepared(struct clk_hw *hw) | 542 | static int m41t80_sqw_is_prepared(struct clk_hw *hw) |
547 | { | 543 | { |
548 | struct m41t80_data *m41t80 = sqw_to_m41t80_data(hw); | 544 | return sqw_to_m41t80_data(hw)->sqwe; |
549 | struct i2c_client *client = m41t80->client; | ||
550 | int ret = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON); | ||
551 | |||
552 | if (ret < 0) | ||
553 | return ret; | ||
554 | |||
555 | return !!(ret & M41T80_ALMON_SQWE); | ||
556 | } | 545 | } |
557 | 546 | ||
558 | static const struct clk_ops m41t80_sqw_ops = { | 547 | static const struct clk_ops m41t80_sqw_ops = { |
@@ -587,6 +576,7 @@ static struct clk *m41t80_sqw_register_clk(struct m41t80_data *m41t80) | |||
587 | init.parent_names = NULL; | 576 | init.parent_names = NULL; |
588 | init.num_parents = 0; | 577 | init.num_parents = 0; |
589 | m41t80->sqw.init = &init; | 578 | m41t80->sqw.init = &init; |
579 | m41t80->freq = m41t80_get_freq(m41t80); | ||
590 | 580 | ||
591 | /* optional override of the clockname */ | 581 | /* optional override of the clockname */ |
592 | of_property_read_string(node, "clock-output-names", &init.name); | 582 | of_property_read_string(node, "clock-output-names", &init.name); |
diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c index 02af045305dd..d9aea9b6d9cd 100644 --- a/drivers/rtc/rtc-m48t86.c +++ b/drivers/rtc/rtc-m48t86.c | |||
@@ -163,35 +163,30 @@ static const struct rtc_class_ops m48t86_rtc_ops = { | |||
163 | .proc = m48t86_rtc_proc, | 163 | .proc = m48t86_rtc_proc, |
164 | }; | 164 | }; |
165 | 165 | ||
166 | static ssize_t m48t86_nvram_read(struct file *filp, struct kobject *kobj, | 166 | static int m48t86_nvram_read(void *priv, unsigned int off, void *buf, |
167 | struct bin_attribute *attr, | 167 | size_t count) |
168 | char *buf, loff_t off, size_t count) | ||
169 | { | 168 | { |
170 | struct device *dev = kobj_to_dev(kobj); | 169 | struct device *dev = priv; |
171 | unsigned int i; | 170 | unsigned int i; |
172 | 171 | ||
173 | for (i = 0; i < count; i++) | 172 | for (i = 0; i < count; i++) |
174 | buf[i] = m48t86_readb(dev, M48T86_NVRAM(off + i)); | 173 | ((u8 *)buf)[i] = m48t86_readb(dev, M48T86_NVRAM(off + i)); |
175 | 174 | ||
176 | return count; | 175 | return 0; |
177 | } | 176 | } |
178 | 177 | ||
179 | static ssize_t m48t86_nvram_write(struct file *filp, struct kobject *kobj, | 178 | static int m48t86_nvram_write(void *priv, unsigned int off, void *buf, |
180 | struct bin_attribute *attr, | 179 | size_t count) |
181 | char *buf, loff_t off, size_t count) | ||
182 | { | 180 | { |
183 | struct device *dev = kobj_to_dev(kobj); | 181 | struct device *dev = priv; |
184 | unsigned int i; | 182 | unsigned int i; |
185 | 183 | ||
186 | for (i = 0; i < count; i++) | 184 | for (i = 0; i < count; i++) |
187 | m48t86_writeb(dev, buf[i], M48T86_NVRAM(off + i)); | 185 | m48t86_writeb(dev, ((u8 *)buf)[i], M48T86_NVRAM(off + i)); |
188 | 186 | ||
189 | return count; | 187 | return 0; |
190 | } | 188 | } |
191 | 189 | ||
192 | static BIN_ATTR(nvram, 0644, m48t86_nvram_read, m48t86_nvram_write, | ||
193 | M48T86_NVRAM_LEN); | ||
194 | |||
195 | /* | 190 | /* |
196 | * The RTC is an optional feature at purchase time on some Technologic Systems | 191 | * The RTC is an optional feature at purchase time on some Technologic Systems |
197 | * boards. Verify that it actually exists by checking if the last two bytes | 192 | * boards. Verify that it actually exists by checking if the last two bytes |
@@ -223,11 +218,21 @@ static bool m48t86_verify_chip(struct platform_device *pdev) | |||
223 | return false; | 218 | return false; |
224 | } | 219 | } |
225 | 220 | ||
221 | static struct nvmem_config m48t86_nvmem_cfg = { | ||
222 | .name = "m48t86_nvram", | ||
223 | .word_size = 1, | ||
224 | .stride = 1, | ||
225 | .size = M48T86_NVRAM_LEN, | ||
226 | .reg_read = m48t86_nvram_read, | ||
227 | .reg_write = m48t86_nvram_write, | ||
228 | }; | ||
229 | |||
226 | static int m48t86_rtc_probe(struct platform_device *pdev) | 230 | static int m48t86_rtc_probe(struct platform_device *pdev) |
227 | { | 231 | { |
228 | struct m48t86_rtc_info *info; | 232 | struct m48t86_rtc_info *info; |
229 | struct resource *res; | 233 | struct resource *res; |
230 | unsigned char reg; | 234 | unsigned char reg; |
235 | int err; | ||
231 | 236 | ||
232 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); | 237 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); |
233 | if (!info) | 238 | if (!info) |
@@ -254,25 +259,25 @@ static int m48t86_rtc_probe(struct platform_device *pdev) | |||
254 | return -ENODEV; | 259 | return -ENODEV; |
255 | } | 260 | } |
256 | 261 | ||
257 | info->rtc = devm_rtc_device_register(&pdev->dev, "m48t86", | 262 | info->rtc = devm_rtc_allocate_device(&pdev->dev); |
258 | &m48t86_rtc_ops, THIS_MODULE); | ||
259 | if (IS_ERR(info->rtc)) | 263 | if (IS_ERR(info->rtc)) |
260 | return PTR_ERR(info->rtc); | 264 | return PTR_ERR(info->rtc); |
261 | 265 | ||
266 | info->rtc->ops = &m48t86_rtc_ops; | ||
267 | |||
268 | m48t86_nvmem_cfg.priv = &pdev->dev; | ||
269 | info->rtc->nvmem_config = &m48t86_nvmem_cfg; | ||
270 | info->rtc->nvram_old_abi = true; | ||
271 | |||
272 | err = rtc_register_device(info->rtc); | ||
273 | if (err) | ||
274 | return err; | ||
275 | |||
262 | /* read battery status */ | 276 | /* read battery status */ |
263 | reg = m48t86_readb(&pdev->dev, M48T86_D); | 277 | reg = m48t86_readb(&pdev->dev, M48T86_D); |
264 | dev_info(&pdev->dev, "battery %s\n", | 278 | dev_info(&pdev->dev, "battery %s\n", |
265 | (reg & M48T86_D_VRT) ? "ok" : "exhausted"); | 279 | (reg & M48T86_D_VRT) ? "ok" : "exhausted"); |
266 | 280 | ||
267 | if (device_create_bin_file(&pdev->dev, &bin_attr_nvram)) | ||
268 | dev_err(&pdev->dev, "failed to create nvram sysfs entry\n"); | ||
269 | |||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | static int m48t86_rtc_remove(struct platform_device *pdev) | ||
274 | { | ||
275 | device_remove_bin_file(&pdev->dev, &bin_attr_nvram); | ||
276 | return 0; | 281 | return 0; |
277 | } | 282 | } |
278 | 283 | ||
@@ -281,7 +286,6 @@ static struct platform_driver m48t86_rtc_platform_driver = { | |||
281 | .name = "rtc-m48t86", | 286 | .name = "rtc-m48t86", |
282 | }, | 287 | }, |
283 | .probe = m48t86_rtc_probe, | 288 | .probe = m48t86_rtc_probe, |
284 | .remove = m48t86_rtc_remove, | ||
285 | }; | 289 | }; |
286 | 290 | ||
287 | module_platform_driver(m48t86_rtc_platform_driver); | 291 | module_platform_driver(m48t86_rtc_platform_driver); |
diff --git a/drivers/rtc/rtc-mt7622.c b/drivers/rtc/rtc-mt7622.c new file mode 100644 index 000000000000..d79b9ae4d237 --- /dev/null +++ b/drivers/rtc/rtc-mt7622.c | |||
@@ -0,0 +1,422 @@ | |||
1 | /* | ||
2 | * Driver for MediaTek SoC based RTC | ||
3 | * | ||
4 | * Copyright (C) 2017 Sean Wang <sean.wang@mediatek.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation; either version 2 of | ||
9 | * the License, or (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/clk.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/of_address.h> | ||
21 | #include <linux/of_device.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/rtc.h> | ||
24 | |||
25 | #define MTK_RTC_DEV KBUILD_MODNAME | ||
26 | |||
27 | #define MTK_RTC_PWRCHK1 0x4 | ||
28 | #define RTC_PWRCHK1_MAGIC 0xc6 | ||
29 | |||
30 | #define MTK_RTC_PWRCHK2 0x8 | ||
31 | #define RTC_PWRCHK2_MAGIC 0x9a | ||
32 | |||
33 | #define MTK_RTC_KEY 0xc | ||
34 | #define RTC_KEY_MAGIC 0x59 | ||
35 | |||
36 | #define MTK_RTC_PROT1 0x10 | ||
37 | #define RTC_PROT1_MAGIC 0xa3 | ||
38 | |||
39 | #define MTK_RTC_PROT2 0x14 | ||
40 | #define RTC_PROT2_MAGIC 0x57 | ||
41 | |||
42 | #define MTK_RTC_PROT3 0x18 | ||
43 | #define RTC_PROT3_MAGIC 0x67 | ||
44 | |||
45 | #define MTK_RTC_PROT4 0x1c | ||
46 | #define RTC_PROT4_MAGIC 0xd2 | ||
47 | |||
48 | #define MTK_RTC_CTL 0x20 | ||
49 | #define RTC_RC_STOP BIT(0) | ||
50 | |||
51 | #define MTK_RTC_DEBNCE 0x2c | ||
52 | #define RTC_DEBNCE_MASK GENMASK(2, 0) | ||
53 | |||
54 | #define MTK_RTC_INT 0x30 | ||
55 | #define RTC_INT_AL_STA BIT(4) | ||
56 | |||
57 | /* | ||
58 | * Ranges from 0x40 to 0x78 provide RTC time setup for year, month, | ||
59 | * day of month, day of week, hour, minute and second. | ||
60 | */ | ||
61 | #define MTK_RTC_TREG(_t, _f) (0x40 + (0x4 * (_f)) + ((_t) * 0x20)) | ||
62 | |||
63 | #define MTK_RTC_AL_CTL 0x7c | ||
64 | #define RTC_AL_EN BIT(0) | ||
65 | #define RTC_AL_ALL GENMASK(7, 0) | ||
66 | |||
67 | /* | ||
68 | * The offset is used in the translation for the year between in struct | ||
69 | * rtc_time and in hardware register MTK_RTC_TREG(x,MTK_YEA) | ||
70 | */ | ||
71 | #define MTK_RTC_TM_YR_OFFSET 100 | ||
72 | |||
73 | /* | ||
74 | * The lowest value for the valid tm_year. RTC hardware would take incorrectly | ||
75 | * tm_year 100 as not a leap year and thus it is also required being excluded | ||
76 | * from the valid options. | ||
77 | */ | ||
78 | #define MTK_RTC_TM_YR_L (MTK_RTC_TM_YR_OFFSET + 1) | ||
79 | |||
80 | /* | ||
81 | * The most year the RTC can hold is 99 and the next to 99 in year register | ||
82 | * would be wraparound to 0, for MT7622. | ||
83 | */ | ||
84 | #define MTK_RTC_HW_YR_LIMIT 99 | ||
85 | |||
86 | /* The highest value for the valid tm_year */ | ||
87 | #define MTK_RTC_TM_YR_H (MTK_RTC_TM_YR_OFFSET + MTK_RTC_HW_YR_LIMIT) | ||
88 | |||
89 | /* Simple macro helps to check whether the hardware supports the tm_year */ | ||
90 | #define MTK_RTC_TM_YR_VALID(_y) ((_y) >= MTK_RTC_TM_YR_L && \ | ||
91 | (_y) <= MTK_RTC_TM_YR_H) | ||
92 | |||
93 | /* Types of the function the RTC provides are time counter and alarm. */ | ||
94 | enum { | ||
95 | MTK_TC, | ||
96 | MTK_AL, | ||
97 | }; | ||
98 | |||
99 | /* Indexes are used for the pointer to relevant registers in MTK_RTC_TREG */ | ||
100 | enum { | ||
101 | MTK_YEA, | ||
102 | MTK_MON, | ||
103 | MTK_DOM, | ||
104 | MTK_DOW, | ||
105 | MTK_HOU, | ||
106 | MTK_MIN, | ||
107 | MTK_SEC | ||
108 | }; | ||
109 | |||
110 | struct mtk_rtc { | ||
111 | struct rtc_device *rtc; | ||
112 | void __iomem *base; | ||
113 | int irq; | ||
114 | struct clk *clk; | ||
115 | }; | ||
116 | |||
117 | static void mtk_w32(struct mtk_rtc *rtc, u32 reg, u32 val) | ||
118 | { | ||
119 | writel_relaxed(val, rtc->base + reg); | ||
120 | } | ||
121 | |||
122 | static u32 mtk_r32(struct mtk_rtc *rtc, u32 reg) | ||
123 | { | ||
124 | return readl_relaxed(rtc->base + reg); | ||
125 | } | ||
126 | |||
127 | static void mtk_rmw(struct mtk_rtc *rtc, u32 reg, u32 mask, u32 set) | ||
128 | { | ||
129 | u32 val; | ||
130 | |||
131 | val = mtk_r32(rtc, reg); | ||
132 | val &= ~mask; | ||
133 | val |= set; | ||
134 | mtk_w32(rtc, reg, val); | ||
135 | } | ||
136 | |||
137 | static void mtk_set(struct mtk_rtc *rtc, u32 reg, u32 val) | ||
138 | { | ||
139 | mtk_rmw(rtc, reg, 0, val); | ||
140 | } | ||
141 | |||
142 | static void mtk_clr(struct mtk_rtc *rtc, u32 reg, u32 val) | ||
143 | { | ||
144 | mtk_rmw(rtc, reg, val, 0); | ||
145 | } | ||
146 | |||
147 | static void mtk_rtc_hw_init(struct mtk_rtc *hw) | ||
148 | { | ||
149 | /* The setup of the init sequence is for allowing RTC got to work */ | ||
150 | mtk_w32(hw, MTK_RTC_PWRCHK1, RTC_PWRCHK1_MAGIC); | ||
151 | mtk_w32(hw, MTK_RTC_PWRCHK2, RTC_PWRCHK2_MAGIC); | ||
152 | mtk_w32(hw, MTK_RTC_KEY, RTC_KEY_MAGIC); | ||
153 | mtk_w32(hw, MTK_RTC_PROT1, RTC_PROT1_MAGIC); | ||
154 | mtk_w32(hw, MTK_RTC_PROT2, RTC_PROT2_MAGIC); | ||
155 | mtk_w32(hw, MTK_RTC_PROT3, RTC_PROT3_MAGIC); | ||
156 | mtk_w32(hw, MTK_RTC_PROT4, RTC_PROT4_MAGIC); | ||
157 | mtk_rmw(hw, MTK_RTC_DEBNCE, RTC_DEBNCE_MASK, 0); | ||
158 | mtk_clr(hw, MTK_RTC_CTL, RTC_RC_STOP); | ||
159 | } | ||
160 | |||
161 | static void mtk_rtc_get_alarm_or_time(struct mtk_rtc *hw, struct rtc_time *tm, | ||
162 | int time_alarm) | ||
163 | { | ||
164 | u32 year, mon, mday, wday, hour, min, sec; | ||
165 | |||
166 | /* | ||
167 | * Read again until the field of the second is not changed which | ||
168 | * ensures all fields in the consistent state. Note that MTK_SEC must | ||
169 | * be read first. In this way, it guarantees the others remain not | ||
170 | * changed when the results for two MTK_SEC consecutive reads are same. | ||
171 | */ | ||
172 | do { | ||
173 | sec = mtk_r32(hw, MTK_RTC_TREG(time_alarm, MTK_SEC)); | ||
174 | min = mtk_r32(hw, MTK_RTC_TREG(time_alarm, MTK_MIN)); | ||
175 | hour = mtk_r32(hw, MTK_RTC_TREG(time_alarm, MTK_HOU)); | ||
176 | wday = mtk_r32(hw, MTK_RTC_TREG(time_alarm, MTK_DOW)); | ||
177 | mday = mtk_r32(hw, MTK_RTC_TREG(time_alarm, MTK_DOM)); | ||
178 | mon = mtk_r32(hw, MTK_RTC_TREG(time_alarm, MTK_MON)); | ||
179 | year = mtk_r32(hw, MTK_RTC_TREG(time_alarm, MTK_YEA)); | ||
180 | } while (sec != mtk_r32(hw, MTK_RTC_TREG(time_alarm, MTK_SEC))); | ||
181 | |||
182 | tm->tm_sec = sec; | ||
183 | tm->tm_min = min; | ||
184 | tm->tm_hour = hour; | ||
185 | tm->tm_wday = wday; | ||
186 | tm->tm_mday = mday; | ||
187 | tm->tm_mon = mon - 1; | ||
188 | |||
189 | /* Rebase to the absolute year which userspace queries */ | ||
190 | tm->tm_year = year + MTK_RTC_TM_YR_OFFSET; | ||
191 | } | ||
192 | |||
193 | static void mtk_rtc_set_alarm_or_time(struct mtk_rtc *hw, struct rtc_time *tm, | ||
194 | int time_alarm) | ||
195 | { | ||
196 | u32 year; | ||
197 | |||
198 | /* Rebase to the relative year which RTC hardware requires */ | ||
199 | year = tm->tm_year - MTK_RTC_TM_YR_OFFSET; | ||
200 | |||
201 | mtk_w32(hw, MTK_RTC_TREG(time_alarm, MTK_YEA), year); | ||
202 | mtk_w32(hw, MTK_RTC_TREG(time_alarm, MTK_MON), tm->tm_mon + 1); | ||
203 | mtk_w32(hw, MTK_RTC_TREG(time_alarm, MTK_DOW), tm->tm_wday); | ||
204 | mtk_w32(hw, MTK_RTC_TREG(time_alarm, MTK_DOM), tm->tm_mday); | ||
205 | mtk_w32(hw, MTK_RTC_TREG(time_alarm, MTK_HOU), tm->tm_hour); | ||
206 | mtk_w32(hw, MTK_RTC_TREG(time_alarm, MTK_MIN), tm->tm_min); | ||
207 | mtk_w32(hw, MTK_RTC_TREG(time_alarm, MTK_SEC), tm->tm_sec); | ||
208 | } | ||
209 | |||
210 | static irqreturn_t mtk_rtc_alarmirq(int irq, void *id) | ||
211 | { | ||
212 | struct mtk_rtc *hw = (struct mtk_rtc *)id; | ||
213 | u32 irq_sta; | ||
214 | |||
215 | irq_sta = mtk_r32(hw, MTK_RTC_INT); | ||
216 | if (irq_sta & RTC_INT_AL_STA) { | ||
217 | /* Stop alarm also implicitly disables the alarm interrupt */ | ||
218 | mtk_w32(hw, MTK_RTC_AL_CTL, 0); | ||
219 | rtc_update_irq(hw->rtc, 1, RTC_IRQF | RTC_AF); | ||
220 | |||
221 | /* Ack alarm interrupt status */ | ||
222 | mtk_w32(hw, MTK_RTC_INT, RTC_INT_AL_STA); | ||
223 | return IRQ_HANDLED; | ||
224 | } | ||
225 | |||
226 | return IRQ_NONE; | ||
227 | } | ||
228 | |||
229 | static int mtk_rtc_gettime(struct device *dev, struct rtc_time *tm) | ||
230 | { | ||
231 | struct mtk_rtc *hw = dev_get_drvdata(dev); | ||
232 | |||
233 | mtk_rtc_get_alarm_or_time(hw, tm, MTK_TC); | ||
234 | |||
235 | return rtc_valid_tm(tm); | ||
236 | } | ||
237 | |||
238 | static int mtk_rtc_settime(struct device *dev, struct rtc_time *tm) | ||
239 | { | ||
240 | struct mtk_rtc *hw = dev_get_drvdata(dev); | ||
241 | |||
242 | if (!MTK_RTC_TM_YR_VALID(tm->tm_year)) | ||
243 | return -EINVAL; | ||
244 | |||
245 | /* Stop time counter before setting a new one*/ | ||
246 | mtk_set(hw, MTK_RTC_CTL, RTC_RC_STOP); | ||
247 | |||
248 | mtk_rtc_set_alarm_or_time(hw, tm, MTK_TC); | ||
249 | |||
250 | /* Restart the time counter */ | ||
251 | mtk_clr(hw, MTK_RTC_CTL, RTC_RC_STOP); | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | static int mtk_rtc_getalarm(struct device *dev, struct rtc_wkalrm *wkalrm) | ||
257 | { | ||
258 | struct mtk_rtc *hw = dev_get_drvdata(dev); | ||
259 | struct rtc_time *alrm_tm = &wkalrm->time; | ||
260 | |||
261 | mtk_rtc_get_alarm_or_time(hw, alrm_tm, MTK_AL); | ||
262 | |||
263 | wkalrm->enabled = !!(mtk_r32(hw, MTK_RTC_AL_CTL) & RTC_AL_EN); | ||
264 | wkalrm->pending = !!(mtk_r32(hw, MTK_RTC_INT) & RTC_INT_AL_STA); | ||
265 | |||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | static int mtk_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm) | ||
270 | { | ||
271 | struct mtk_rtc *hw = dev_get_drvdata(dev); | ||
272 | struct rtc_time *alrm_tm = &wkalrm->time; | ||
273 | |||
274 | if (!MTK_RTC_TM_YR_VALID(alrm_tm->tm_year)) | ||
275 | return -EINVAL; | ||
276 | |||
277 | /* | ||
278 | * Stop the alarm also implicitly including disables interrupt before | ||
279 | * setting a new one. | ||
280 | */ | ||
281 | mtk_clr(hw, MTK_RTC_AL_CTL, RTC_AL_EN); | ||
282 | |||
283 | /* | ||
284 | * Avoid contention between mtk_rtc_setalarm and IRQ handler so that | ||
285 | * disabling the interrupt and awaiting for pending IRQ handler to | ||
286 | * complete. | ||
287 | */ | ||
288 | synchronize_irq(hw->irq); | ||
289 | |||
290 | mtk_rtc_set_alarm_or_time(hw, alrm_tm, MTK_AL); | ||
291 | |||
292 | /* Restart the alarm with the new setup */ | ||
293 | mtk_w32(hw, MTK_RTC_AL_CTL, RTC_AL_ALL); | ||
294 | |||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | static const struct rtc_class_ops mtk_rtc_ops = { | ||
299 | .read_time = mtk_rtc_gettime, | ||
300 | .set_time = mtk_rtc_settime, | ||
301 | .read_alarm = mtk_rtc_getalarm, | ||
302 | .set_alarm = mtk_rtc_setalarm, | ||
303 | }; | ||
304 | |||
305 | static const struct of_device_id mtk_rtc_match[] = { | ||
306 | { .compatible = "mediatek,mt7622-rtc" }, | ||
307 | { .compatible = "mediatek,soc-rtc" }, | ||
308 | {}, | ||
309 | }; | ||
310 | |||
311 | static int mtk_rtc_probe(struct platform_device *pdev) | ||
312 | { | ||
313 | struct mtk_rtc *hw; | ||
314 | struct resource *res; | ||
315 | int ret; | ||
316 | |||
317 | hw = devm_kzalloc(&pdev->dev, sizeof(*hw), GFP_KERNEL); | ||
318 | if (!hw) | ||
319 | return -ENOMEM; | ||
320 | |||
321 | platform_set_drvdata(pdev, hw); | ||
322 | |||
323 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
324 | hw->base = devm_ioremap_resource(&pdev->dev, res); | ||
325 | if (IS_ERR(hw->base)) | ||
326 | return PTR_ERR(hw->base); | ||
327 | |||
328 | hw->clk = devm_clk_get(&pdev->dev, "rtc"); | ||
329 | if (IS_ERR(hw->clk)) { | ||
330 | dev_err(&pdev->dev, "No clock\n"); | ||
331 | return PTR_ERR(hw->clk); | ||
332 | } | ||
333 | |||
334 | ret = clk_prepare_enable(hw->clk); | ||
335 | if (ret) | ||
336 | return ret; | ||
337 | |||
338 | hw->irq = platform_get_irq(pdev, 0); | ||
339 | if (hw->irq < 0) { | ||
340 | dev_err(&pdev->dev, "No IRQ resource\n"); | ||
341 | ret = hw->irq; | ||
342 | goto err; | ||
343 | } | ||
344 | |||
345 | ret = devm_request_irq(&pdev->dev, hw->irq, mtk_rtc_alarmirq, | ||
346 | 0, dev_name(&pdev->dev), hw); | ||
347 | if (ret) { | ||
348 | dev_err(&pdev->dev, "Can't request IRQ\n"); | ||
349 | goto err; | ||
350 | } | ||
351 | |||
352 | mtk_rtc_hw_init(hw); | ||
353 | |||
354 | device_init_wakeup(&pdev->dev, true); | ||
355 | |||
356 | hw->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, | ||
357 | &mtk_rtc_ops, THIS_MODULE); | ||
358 | if (IS_ERR(hw->rtc)) { | ||
359 | ret = PTR_ERR(hw->rtc); | ||
360 | dev_err(&pdev->dev, "Unable to register device\n"); | ||
361 | goto err; | ||
362 | } | ||
363 | |||
364 | return 0; | ||
365 | err: | ||
366 | clk_disable_unprepare(hw->clk); | ||
367 | |||
368 | return ret; | ||
369 | } | ||
370 | |||
371 | static int mtk_rtc_remove(struct platform_device *pdev) | ||
372 | { | ||
373 | struct mtk_rtc *hw = platform_get_drvdata(pdev); | ||
374 | |||
375 | clk_disable_unprepare(hw->clk); | ||
376 | |||
377 | return 0; | ||
378 | } | ||
379 | |||
380 | #ifdef CONFIG_PM_SLEEP | ||
381 | static int mtk_rtc_suspend(struct device *dev) | ||
382 | { | ||
383 | struct mtk_rtc *hw = dev_get_drvdata(dev); | ||
384 | |||
385 | if (device_may_wakeup(dev)) | ||
386 | enable_irq_wake(hw->irq); | ||
387 | |||
388 | return 0; | ||
389 | } | ||
390 | |||
391 | static int mtk_rtc_resume(struct device *dev) | ||
392 | { | ||
393 | struct mtk_rtc *hw = dev_get_drvdata(dev); | ||
394 | |||
395 | if (device_may_wakeup(dev)) | ||
396 | disable_irq_wake(hw->irq); | ||
397 | |||
398 | return 0; | ||
399 | } | ||
400 | |||
401 | static SIMPLE_DEV_PM_OPS(mtk_rtc_pm_ops, mtk_rtc_suspend, mtk_rtc_resume); | ||
402 | |||
403 | #define MTK_RTC_PM_OPS (&mtk_rtc_pm_ops) | ||
404 | #else /* CONFIG_PM */ | ||
405 | #define MTK_RTC_PM_OPS NULL | ||
406 | #endif /* CONFIG_PM */ | ||
407 | |||
408 | static struct platform_driver mtk_rtc_driver = { | ||
409 | .probe = mtk_rtc_probe, | ||
410 | .remove = mtk_rtc_remove, | ||
411 | .driver = { | ||
412 | .name = MTK_RTC_DEV, | ||
413 | .of_match_table = mtk_rtc_match, | ||
414 | .pm = MTK_RTC_PM_OPS, | ||
415 | }, | ||
416 | }; | ||
417 | |||
418 | module_platform_driver(mtk_rtc_driver); | ||
419 | |||
420 | MODULE_DESCRIPTION("MediaTek SoC based RTC Driver"); | ||
421 | MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); | ||
422 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index 13f7cd11c07e..1d666ac9ef70 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c | |||
@@ -70,6 +70,10 @@ | |||
70 | #define OMAP_RTC_COMP_MSB_REG 0x50 | 70 | #define OMAP_RTC_COMP_MSB_REG 0x50 |
71 | #define OMAP_RTC_OSC_REG 0x54 | 71 | #define OMAP_RTC_OSC_REG 0x54 |
72 | 72 | ||
73 | #define OMAP_RTC_SCRATCH0_REG 0x60 | ||
74 | #define OMAP_RTC_SCRATCH1_REG 0x64 | ||
75 | #define OMAP_RTC_SCRATCH2_REG 0x68 | ||
76 | |||
73 | #define OMAP_RTC_KICK0_REG 0x6c | 77 | #define OMAP_RTC_KICK0_REG 0x6c |
74 | #define OMAP_RTC_KICK1_REG 0x70 | 78 | #define OMAP_RTC_KICK1_REG 0x70 |
75 | 79 | ||
@@ -667,6 +671,45 @@ static struct pinctrl_desc rtc_pinctrl_desc = { | |||
667 | .owner = THIS_MODULE, | 671 | .owner = THIS_MODULE, |
668 | }; | 672 | }; |
669 | 673 | ||
674 | static int omap_rtc_scratch_read(void *priv, unsigned int offset, void *_val, | ||
675 | size_t bytes) | ||
676 | { | ||
677 | struct omap_rtc *rtc = priv; | ||
678 | u32 *val = _val; | ||
679 | int i; | ||
680 | |||
681 | for (i = 0; i < bytes / 4; i++) | ||
682 | val[i] = rtc_readl(rtc, | ||
683 | OMAP_RTC_SCRATCH0_REG + offset + (i * 4)); | ||
684 | |||
685 | return 0; | ||
686 | } | ||
687 | |||
688 | static int omap_rtc_scratch_write(void *priv, unsigned int offset, void *_val, | ||
689 | size_t bytes) | ||
690 | { | ||
691 | struct omap_rtc *rtc = priv; | ||
692 | u32 *val = _val; | ||
693 | int i; | ||
694 | |||
695 | rtc->type->unlock(rtc); | ||
696 | for (i = 0; i < bytes / 4; i++) | ||
697 | rtc_writel(rtc, | ||
698 | OMAP_RTC_SCRATCH0_REG + offset + (i * 4), val[i]); | ||
699 | rtc->type->lock(rtc); | ||
700 | |||
701 | return 0; | ||
702 | } | ||
703 | |||
704 | static struct nvmem_config omap_rtc_nvmem_config = { | ||
705 | .name = "omap_rtc_scratch", | ||
706 | .word_size = 4, | ||
707 | .stride = 4, | ||
708 | .size = OMAP_RTC_KICK0_REG - OMAP_RTC_SCRATCH0_REG, | ||
709 | .reg_read = omap_rtc_scratch_read, | ||
710 | .reg_write = omap_rtc_scratch_write, | ||
711 | }; | ||
712 | |||
670 | static int omap_rtc_probe(struct platform_device *pdev) | 713 | static int omap_rtc_probe(struct platform_device *pdev) |
671 | { | 714 | { |
672 | struct omap_rtc *rtc; | 715 | struct omap_rtc *rtc; |
@@ -797,13 +840,16 @@ static int omap_rtc_probe(struct platform_device *pdev) | |||
797 | 840 | ||
798 | device_init_wakeup(&pdev->dev, true); | 841 | device_init_wakeup(&pdev->dev, true); |
799 | 842 | ||
800 | rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, | 843 | rtc->rtc = devm_rtc_allocate_device(&pdev->dev); |
801 | &omap_rtc_ops, THIS_MODULE); | ||
802 | if (IS_ERR(rtc->rtc)) { | 844 | if (IS_ERR(rtc->rtc)) { |
803 | ret = PTR_ERR(rtc->rtc); | 845 | ret = PTR_ERR(rtc->rtc); |
804 | goto err; | 846 | goto err; |
805 | } | 847 | } |
806 | 848 | ||
849 | rtc->rtc->ops = &omap_rtc_ops; | ||
850 | omap_rtc_nvmem_config.priv = rtc; | ||
851 | rtc->rtc->nvmem_config = &omap_rtc_nvmem_config; | ||
852 | |||
807 | /* handle periodic and alarm irqs */ | 853 | /* handle periodic and alarm irqs */ |
808 | ret = devm_request_irq(&pdev->dev, rtc->irq_timer, rtc_irq, 0, | 854 | ret = devm_request_irq(&pdev->dev, rtc->irq_timer, rtc_irq, 0, |
809 | dev_name(&rtc->rtc->dev), rtc); | 855 | dev_name(&rtc->rtc->dev), rtc); |
@@ -830,9 +876,14 @@ static int omap_rtc_probe(struct platform_device *pdev) | |||
830 | rtc->pctldev = pinctrl_register(&rtc_pinctrl_desc, &pdev->dev, rtc); | 876 | rtc->pctldev = pinctrl_register(&rtc_pinctrl_desc, &pdev->dev, rtc); |
831 | if (IS_ERR(rtc->pctldev)) { | 877 | if (IS_ERR(rtc->pctldev)) { |
832 | dev_err(&pdev->dev, "Couldn't register pinctrl driver\n"); | 878 | dev_err(&pdev->dev, "Couldn't register pinctrl driver\n"); |
833 | return PTR_ERR(rtc->pctldev); | 879 | ret = PTR_ERR(rtc->pctldev); |
880 | goto err; | ||
834 | } | 881 | } |
835 | 882 | ||
883 | ret = rtc_register_device(rtc->rtc); | ||
884 | if (ret) | ||
885 | goto err; | ||
886 | |||
836 | return 0; | 887 | return 0; |
837 | 888 | ||
838 | err: | 889 | err: |
diff --git a/drivers/rtc/rtc-pcf8523.c b/drivers/rtc/rtc-pcf8523.c index 28c48b3c1946..c312af0db729 100644 --- a/drivers/rtc/rtc-pcf8523.c +++ b/drivers/rtc/rtc-pcf8523.c | |||
@@ -35,6 +35,9 @@ | |||
35 | #define REG_MONTHS 0x08 | 35 | #define REG_MONTHS 0x08 |
36 | #define REG_YEARS 0x09 | 36 | #define REG_YEARS 0x09 |
37 | 37 | ||
38 | #define REG_OFFSET 0x0e | ||
39 | #define REG_OFFSET_MODE BIT(7) | ||
40 | |||
38 | struct pcf8523 { | 41 | struct pcf8523 { |
39 | struct rtc_device *rtc; | 42 | struct rtc_device *rtc; |
40 | }; | 43 | }; |
@@ -272,10 +275,47 @@ static int pcf8523_rtc_ioctl(struct device *dev, unsigned int cmd, | |||
272 | #define pcf8523_rtc_ioctl NULL | 275 | #define pcf8523_rtc_ioctl NULL |
273 | #endif | 276 | #endif |
274 | 277 | ||
278 | static int pcf8523_rtc_read_offset(struct device *dev, long *offset) | ||
279 | { | ||
280 | struct i2c_client *client = to_i2c_client(dev); | ||
281 | int err; | ||
282 | u8 value; | ||
283 | s8 val; | ||
284 | |||
285 | err = pcf8523_read(client, REG_OFFSET, &value); | ||
286 | if (err < 0) | ||
287 | return err; | ||
288 | |||
289 | /* sign extend the 7-bit offset value */ | ||
290 | val = value << 1; | ||
291 | *offset = (value & REG_OFFSET_MODE ? 4069 : 4340) * (val >> 1); | ||
292 | |||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | static int pcf8523_rtc_set_offset(struct device *dev, long offset) | ||
297 | { | ||
298 | struct i2c_client *client = to_i2c_client(dev); | ||
299 | long reg_m0, reg_m1; | ||
300 | u8 value; | ||
301 | |||
302 | reg_m0 = clamp(DIV_ROUND_CLOSEST(offset, 4340), -64L, 63L); | ||
303 | reg_m1 = clamp(DIV_ROUND_CLOSEST(offset, 4069), -64L, 63L); | ||
304 | |||
305 | if (abs(reg_m0 * 4340 - offset) < abs(reg_m1 * 4069 - offset)) | ||
306 | value = reg_m0 & 0x7f; | ||
307 | else | ||
308 | value = (reg_m1 & 0x7f) | REG_OFFSET_MODE; | ||
309 | |||
310 | return pcf8523_write(client, REG_OFFSET, value); | ||
311 | } | ||
312 | |||
275 | static const struct rtc_class_ops pcf8523_rtc_ops = { | 313 | static const struct rtc_class_ops pcf8523_rtc_ops = { |
276 | .read_time = pcf8523_rtc_read_time, | 314 | .read_time = pcf8523_rtc_read_time, |
277 | .set_time = pcf8523_rtc_set_time, | 315 | .set_time = pcf8523_rtc_set_time, |
278 | .ioctl = pcf8523_rtc_ioctl, | 316 | .ioctl = pcf8523_rtc_ioctl, |
317 | .read_offset = pcf8523_rtc_read_offset, | ||
318 | .set_offset = pcf8523_rtc_set_offset, | ||
279 | }; | 319 | }; |
280 | 320 | ||
281 | static int pcf8523_probe(struct i2c_client *client, | 321 | static int pcf8523_probe(struct i2c_client *client, |
diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c new file mode 100644 index 000000000000..ea04e9f0930b --- /dev/null +++ b/drivers/rtc/rtc-pcf85363.c | |||
@@ -0,0 +1,220 @@ | |||
1 | /* | ||
2 | * drivers/rtc/rtc-pcf85363.c | ||
3 | * | ||
4 | * Driver for NXP PCF85363 real-time clock. | ||
5 | * | ||
6 | * Copyright (C) 2017 Eric Nelson | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * Based loosely on rtc-8583 by Russell King, Wolfram Sang and Juergen Beisert | ||
13 | */ | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/i2c.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/rtc.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/err.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/bcd.h> | ||
22 | #include <linux/of.h> | ||
23 | #include <linux/of_device.h> | ||
24 | #include <linux/regmap.h> | ||
25 | |||
26 | /* | ||
27 | * Date/Time registers | ||
28 | */ | ||
29 | #define DT_100THS 0x00 | ||
30 | #define DT_SECS 0x01 | ||
31 | #define DT_MINUTES 0x02 | ||
32 | #define DT_HOURS 0x03 | ||
33 | #define DT_DAYS 0x04 | ||
34 | #define DT_WEEKDAYS 0x05 | ||
35 | #define DT_MONTHS 0x06 | ||
36 | #define DT_YEARS 0x07 | ||
37 | |||
38 | /* | ||
39 | * Alarm registers | ||
40 | */ | ||
41 | #define DT_SECOND_ALM1 0x08 | ||
42 | #define DT_MINUTE_ALM1 0x09 | ||
43 | #define DT_HOUR_ALM1 0x0a | ||
44 | #define DT_DAY_ALM1 0x0b | ||
45 | #define DT_MONTH_ALM1 0x0c | ||
46 | #define DT_MINUTE_ALM2 0x0d | ||
47 | #define DT_HOUR_ALM2 0x0e | ||
48 | #define DT_WEEKDAY_ALM2 0x0f | ||
49 | #define DT_ALARM_EN 0x10 | ||
50 | |||
51 | /* | ||
52 | * Time stamp registers | ||
53 | */ | ||
54 | #define DT_TIMESTAMP1 0x11 | ||
55 | #define DT_TIMESTAMP2 0x17 | ||
56 | #define DT_TIMESTAMP3 0x1d | ||
57 | #define DT_TS_MODE 0x23 | ||
58 | |||
59 | /* | ||
60 | * control registers | ||
61 | */ | ||
62 | #define CTRL_OFFSET 0x24 | ||
63 | #define CTRL_OSCILLATOR 0x25 | ||
64 | #define CTRL_BATTERY 0x26 | ||
65 | #define CTRL_PIN_IO 0x27 | ||
66 | #define CTRL_FUNCTION 0x28 | ||
67 | #define CTRL_INTA_EN 0x29 | ||
68 | #define CTRL_INTB_EN 0x2a | ||
69 | #define CTRL_FLAGS 0x2b | ||
70 | #define CTRL_RAMBYTE 0x2c | ||
71 | #define CTRL_WDOG 0x2d | ||
72 | #define CTRL_STOP_EN 0x2e | ||
73 | #define CTRL_RESETS 0x2f | ||
74 | #define CTRL_RAM 0x40 | ||
75 | |||
76 | #define NVRAM_SIZE 0x40 | ||
77 | |||
78 | static struct i2c_driver pcf85363_driver; | ||
79 | |||
80 | struct pcf85363 { | ||
81 | struct device *dev; | ||
82 | struct rtc_device *rtc; | ||
83 | struct nvmem_config nvmem_cfg; | ||
84 | struct regmap *regmap; | ||
85 | }; | ||
86 | |||
87 | static int pcf85363_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
88 | { | ||
89 | struct pcf85363 *pcf85363 = dev_get_drvdata(dev); | ||
90 | unsigned char buf[DT_YEARS + 1]; | ||
91 | int ret, len = sizeof(buf); | ||
92 | |||
93 | /* read the RTC date and time registers all at once */ | ||
94 | ret = regmap_bulk_read(pcf85363->regmap, DT_100THS, buf, len); | ||
95 | if (ret) { | ||
96 | dev_err(dev, "%s: error %d\n", __func__, ret); | ||
97 | return ret; | ||
98 | } | ||
99 | |||
100 | tm->tm_year = bcd2bin(buf[DT_YEARS]); | ||
101 | /* adjust for 1900 base of rtc_time */ | ||
102 | tm->tm_year += 100; | ||
103 | |||
104 | tm->tm_wday = buf[DT_WEEKDAYS] & 7; | ||
105 | buf[DT_SECS] &= 0x7F; | ||
106 | tm->tm_sec = bcd2bin(buf[DT_SECS]); | ||
107 | buf[DT_MINUTES] &= 0x7F; | ||
108 | tm->tm_min = bcd2bin(buf[DT_MINUTES]); | ||
109 | tm->tm_hour = bcd2bin(buf[DT_HOURS]); | ||
110 | tm->tm_mday = bcd2bin(buf[DT_DAYS]); | ||
111 | tm->tm_mon = bcd2bin(buf[DT_MONTHS]) - 1; | ||
112 | |||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | static int pcf85363_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
117 | { | ||
118 | struct pcf85363 *pcf85363 = dev_get_drvdata(dev); | ||
119 | unsigned char buf[DT_YEARS + 1]; | ||
120 | int len = sizeof(buf); | ||
121 | |||
122 | buf[DT_100THS] = 0; | ||
123 | buf[DT_SECS] = bin2bcd(tm->tm_sec); | ||
124 | buf[DT_MINUTES] = bin2bcd(tm->tm_min); | ||
125 | buf[DT_HOURS] = bin2bcd(tm->tm_hour); | ||
126 | buf[DT_DAYS] = bin2bcd(tm->tm_mday); | ||
127 | buf[DT_WEEKDAYS] = tm->tm_wday; | ||
128 | buf[DT_MONTHS] = bin2bcd(tm->tm_mon + 1); | ||
129 | buf[DT_YEARS] = bin2bcd(tm->tm_year % 100); | ||
130 | |||
131 | return regmap_bulk_write(pcf85363->regmap, DT_100THS, | ||
132 | buf, len); | ||
133 | } | ||
134 | |||
135 | static const struct rtc_class_ops rtc_ops = { | ||
136 | .read_time = pcf85363_rtc_read_time, | ||
137 | .set_time = pcf85363_rtc_set_time, | ||
138 | }; | ||
139 | |||
140 | static int pcf85363_nvram_read(void *priv, unsigned int offset, void *val, | ||
141 | size_t bytes) | ||
142 | { | ||
143 | struct pcf85363 *pcf85363 = priv; | ||
144 | |||
145 | return regmap_bulk_read(pcf85363->regmap, CTRL_RAM + offset, | ||
146 | val, bytes); | ||
147 | } | ||
148 | |||
149 | static int pcf85363_nvram_write(void *priv, unsigned int offset, void *val, | ||
150 | size_t bytes) | ||
151 | { | ||
152 | struct pcf85363 *pcf85363 = priv; | ||
153 | |||
154 | return regmap_bulk_write(pcf85363->regmap, CTRL_RAM + offset, | ||
155 | val, bytes); | ||
156 | } | ||
157 | |||
158 | static const struct regmap_config regmap_config = { | ||
159 | .reg_bits = 8, | ||
160 | .val_bits = 8, | ||
161 | }; | ||
162 | |||
163 | static int pcf85363_probe(struct i2c_client *client, | ||
164 | const struct i2c_device_id *id) | ||
165 | { | ||
166 | struct pcf85363 *pcf85363; | ||
167 | |||
168 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) | ||
169 | return -ENODEV; | ||
170 | |||
171 | pcf85363 = devm_kzalloc(&client->dev, sizeof(struct pcf85363), | ||
172 | GFP_KERNEL); | ||
173 | if (!pcf85363) | ||
174 | return -ENOMEM; | ||
175 | |||
176 | pcf85363->regmap = devm_regmap_init_i2c(client, ®map_config); | ||
177 | if (IS_ERR(pcf85363->regmap)) { | ||
178 | dev_err(&client->dev, "regmap allocation failed\n"); | ||
179 | return PTR_ERR(pcf85363->regmap); | ||
180 | } | ||
181 | |||
182 | pcf85363->dev = &client->dev; | ||
183 | i2c_set_clientdata(client, pcf85363); | ||
184 | |||
185 | pcf85363->rtc = devm_rtc_allocate_device(pcf85363->dev); | ||
186 | if (IS_ERR(pcf85363->rtc)) | ||
187 | return PTR_ERR(pcf85363->rtc); | ||
188 | |||
189 | pcf85363->nvmem_cfg.name = "pcf85363-"; | ||
190 | pcf85363->nvmem_cfg.word_size = 1; | ||
191 | pcf85363->nvmem_cfg.stride = 1; | ||
192 | pcf85363->nvmem_cfg.size = NVRAM_SIZE; | ||
193 | pcf85363->nvmem_cfg.reg_read = pcf85363_nvram_read; | ||
194 | pcf85363->nvmem_cfg.reg_write = pcf85363_nvram_write; | ||
195 | pcf85363->nvmem_cfg.priv = pcf85363; | ||
196 | pcf85363->rtc->nvmem_config = &pcf85363->nvmem_cfg; | ||
197 | pcf85363->rtc->ops = &rtc_ops; | ||
198 | |||
199 | return rtc_register_device(pcf85363->rtc); | ||
200 | } | ||
201 | |||
202 | static const struct of_device_id dev_ids[] = { | ||
203 | { .compatible = "nxp,pcf85363" }, | ||
204 | {} | ||
205 | }; | ||
206 | MODULE_DEVICE_TABLE(of, dev_ids); | ||
207 | |||
208 | static struct i2c_driver pcf85363_driver = { | ||
209 | .driver = { | ||
210 | .name = "pcf85363", | ||
211 | .of_match_table = of_match_ptr(dev_ids), | ||
212 | }, | ||
213 | .probe = pcf85363_probe, | ||
214 | }; | ||
215 | |||
216 | module_i2c_driver(pcf85363_driver); | ||
217 | |||
218 | MODULE_AUTHOR("Eric Nelson"); | ||
219 | MODULE_DESCRIPTION("pcf85363 I2C RTC driver"); | ||
220 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index cea6ea4df970..3efc86c25d27 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c | |||
@@ -387,7 +387,7 @@ static int pcf8563_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *tm) | |||
387 | if (err) | 387 | if (err) |
388 | return err; | 388 | return err; |
389 | 389 | ||
390 | return pcf8563_set_alarm_mode(client, 1); | 390 | return pcf8563_set_alarm_mode(client, !!tm->enabled); |
391 | } | 391 | } |
392 | 392 | ||
393 | static int pcf8563_irq_enable(struct device *dev, unsigned int enabled) | 393 | static int pcf8563_irq_enable(struct device *dev, unsigned int enabled) |
@@ -422,7 +422,7 @@ static unsigned long pcf8563_clkout_recalc_rate(struct clk_hw *hw, | |||
422 | return 0; | 422 | return 0; |
423 | 423 | ||
424 | buf &= PCF8563_REG_CLKO_F_MASK; | 424 | buf &= PCF8563_REG_CLKO_F_MASK; |
425 | return clkout_rates[ret]; | 425 | return clkout_rates[buf]; |
426 | } | 426 | } |
427 | 427 | ||
428 | static long pcf8563_clkout_round_rate(struct clk_hw *hw, unsigned long rate, | 428 | static long pcf8563_clkout_round_rate(struct clk_hw *hw, unsigned long rate, |
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index e1687e19c59f..82eb7da2c478 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c | |||
@@ -308,10 +308,9 @@ static int pl031_remove(struct amba_device *adev) | |||
308 | 308 | ||
309 | dev_pm_clear_wake_irq(&adev->dev); | 309 | dev_pm_clear_wake_irq(&adev->dev); |
310 | device_init_wakeup(&adev->dev, false); | 310 | device_init_wakeup(&adev->dev, false); |
311 | free_irq(adev->irq[0], ldata); | 311 | if (adev->irq[0]) |
312 | free_irq(adev->irq[0], ldata); | ||
312 | rtc_device_unregister(ldata->rtc); | 313 | rtc_device_unregister(ldata->rtc); |
313 | iounmap(ldata->base); | ||
314 | kfree(ldata); | ||
315 | amba_release_regions(adev); | 314 | amba_release_regions(adev); |
316 | 315 | ||
317 | return 0; | 316 | return 0; |
@@ -322,25 +321,28 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) | |||
322 | int ret; | 321 | int ret; |
323 | struct pl031_local *ldata; | 322 | struct pl031_local *ldata; |
324 | struct pl031_vendor_data *vendor = id->data; | 323 | struct pl031_vendor_data *vendor = id->data; |
325 | struct rtc_class_ops *ops = &vendor->ops; | 324 | struct rtc_class_ops *ops; |
326 | unsigned long time, data; | 325 | unsigned long time, data; |
327 | 326 | ||
328 | ret = amba_request_regions(adev, NULL); | 327 | ret = amba_request_regions(adev, NULL); |
329 | if (ret) | 328 | if (ret) |
330 | goto err_req; | 329 | goto err_req; |
331 | 330 | ||
332 | ldata = kzalloc(sizeof(struct pl031_local), GFP_KERNEL); | 331 | ldata = devm_kzalloc(&adev->dev, sizeof(struct pl031_local), |
333 | if (!ldata) { | 332 | GFP_KERNEL); |
333 | ops = devm_kmemdup(&adev->dev, &vendor->ops, sizeof(vendor->ops), | ||
334 | GFP_KERNEL); | ||
335 | if (!ldata || !ops) { | ||
334 | ret = -ENOMEM; | 336 | ret = -ENOMEM; |
335 | goto out; | 337 | goto out; |
336 | } | 338 | } |
337 | ldata->vendor = vendor; | ||
338 | |||
339 | ldata->base = ioremap(adev->res.start, resource_size(&adev->res)); | ||
340 | 339 | ||
340 | ldata->vendor = vendor; | ||
341 | ldata->base = devm_ioremap(&adev->dev, adev->res.start, | ||
342 | resource_size(&adev->res)); | ||
341 | if (!ldata->base) { | 343 | if (!ldata->base) { |
342 | ret = -ENOMEM; | 344 | ret = -ENOMEM; |
343 | goto out_no_remap; | 345 | goto out; |
344 | } | 346 | } |
345 | 347 | ||
346 | amba_set_drvdata(adev, ldata); | 348 | amba_set_drvdata(adev, ldata); |
@@ -373,28 +375,32 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) | |||
373 | } | 375 | } |
374 | } | 376 | } |
375 | 377 | ||
378 | if (!adev->irq[0]) { | ||
379 | /* When there's no interrupt, no point in exposing the alarm */ | ||
380 | ops->read_alarm = NULL; | ||
381 | ops->set_alarm = NULL; | ||
382 | ops->alarm_irq_enable = NULL; | ||
383 | } | ||
384 | |||
376 | device_init_wakeup(&adev->dev, true); | 385 | device_init_wakeup(&adev->dev, true); |
377 | ldata->rtc = rtc_device_register("pl031", &adev->dev, ops, | 386 | ldata->rtc = rtc_device_register("pl031", &adev->dev, ops, |
378 | THIS_MODULE); | 387 | THIS_MODULE); |
379 | if (IS_ERR(ldata->rtc)) { | 388 | if (IS_ERR(ldata->rtc)) { |
380 | ret = PTR_ERR(ldata->rtc); | 389 | ret = PTR_ERR(ldata->rtc); |
381 | goto out_no_rtc; | 390 | goto out; |
382 | } | 391 | } |
383 | 392 | ||
384 | if (request_irq(adev->irq[0], pl031_interrupt, | 393 | if (adev->irq[0]) { |
385 | vendor->irqflags, "rtc-pl031", ldata)) { | 394 | ret = request_irq(adev->irq[0], pl031_interrupt, |
386 | ret = -EIO; | 395 | vendor->irqflags, "rtc-pl031", ldata); |
387 | goto out_no_irq; | 396 | if (ret) |
397 | goto out_no_irq; | ||
398 | dev_pm_set_wake_irq(&adev->dev, adev->irq[0]); | ||
388 | } | 399 | } |
389 | dev_pm_set_wake_irq(&adev->dev, adev->irq[0]); | ||
390 | return 0; | 400 | return 0; |
391 | 401 | ||
392 | out_no_irq: | 402 | out_no_irq: |
393 | rtc_device_unregister(ldata->rtc); | 403 | rtc_device_unregister(ldata->rtc); |
394 | out_no_rtc: | ||
395 | iounmap(ldata->base); | ||
396 | out_no_remap: | ||
397 | kfree(ldata); | ||
398 | out: | 404 | out: |
399 | amba_release_regions(adev); | 405 | amba_release_regions(adev); |
400 | err_req: | 406 | err_req: |
@@ -446,7 +452,7 @@ static struct pl031_vendor_data stv2_pl031 = { | |||
446 | .irqflags = IRQF_SHARED | IRQF_COND_SUSPEND, | 452 | .irqflags = IRQF_SHARED | IRQF_COND_SUSPEND, |
447 | }; | 453 | }; |
448 | 454 | ||
449 | static struct amba_id pl031_ids[] = { | 455 | static const struct amba_id pl031_ids[] = { |
450 | { | 456 | { |
451 | .id = 0x00041031, | 457 | .id = 0x00041031, |
452 | .mask = 0x000fffff, | 458 | .mask = 0x000fffff, |
diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c index aa09771de04f..3d6174eb32f6 100644 --- a/drivers/rtc/rtc-rv3029c2.c +++ b/drivers/rtc/rtc-rv3029c2.c | |||
@@ -282,13 +282,13 @@ static int rv3029_eeprom_read(struct device *dev, u8 reg, | |||
282 | static int rv3029_eeprom_write(struct device *dev, u8 reg, | 282 | static int rv3029_eeprom_write(struct device *dev, u8 reg, |
283 | u8 const buf[], size_t len) | 283 | u8 const buf[], size_t len) |
284 | { | 284 | { |
285 | int ret, err; | 285 | int ret; |
286 | size_t i; | 286 | size_t i; |
287 | u8 tmp; | 287 | u8 tmp; |
288 | 288 | ||
289 | err = rv3029_eeprom_enter(dev); | 289 | ret = rv3029_eeprom_enter(dev); |
290 | if (err < 0) | 290 | if (ret < 0) |
291 | return err; | 291 | return ret; |
292 | 292 | ||
293 | for (i = 0; i < len; i++, reg++) { | 293 | for (i = 0; i < len; i++, reg++) { |
294 | ret = rv3029_read_regs(dev, reg, &tmp, 1); | 294 | ret = rv3029_read_regs(dev, reg, &tmp, 1); |
@@ -304,11 +304,11 @@ static int rv3029_eeprom_write(struct device *dev, u8 reg, | |||
304 | break; | 304 | break; |
305 | } | 305 | } |
306 | 306 | ||
307 | err = rv3029_eeprom_exit(dev); | 307 | ret = rv3029_eeprom_exit(dev); |
308 | if (err < 0) | 308 | if (ret < 0) |
309 | return err; | 309 | return ret; |
310 | 310 | ||
311 | return ret; | 311 | return 0; |
312 | } | 312 | } |
313 | 313 | ||
314 | static int rv3029_eeprom_update_bits(struct device *dev, | 314 | static int rv3029_eeprom_update_bits(struct device *dev, |
@@ -876,6 +876,8 @@ static const struct i2c_device_id rv3029_id[] = { | |||
876 | MODULE_DEVICE_TABLE(i2c, rv3029_id); | 876 | MODULE_DEVICE_TABLE(i2c, rv3029_id); |
877 | 877 | ||
878 | static const struct of_device_id rv3029_of_match[] = { | 878 | static const struct of_device_id rv3029_of_match[] = { |
879 | { .compatible = "microcrystal,rv3029" }, | ||
880 | /* Backward compatibility only, do not use compatibles below: */ | ||
879 | { .compatible = "rv3029" }, | 881 | { .compatible = "rv3029" }, |
880 | { .compatible = "rv3029c2" }, | 882 | { .compatible = "rv3029c2" }, |
881 | { .compatible = "mc,rv3029c2" }, | 883 | { .compatible = "mc,rv3029c2" }, |
diff --git a/drivers/rtc/rtc-rx8010.c b/drivers/rtc/rtc-rx8010.c index 1ed3403ff8ac..5c5938ab3d86 100644 --- a/drivers/rtc/rtc-rx8010.c +++ b/drivers/rtc/rtc-rx8010.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #define RX8010_MDAY 0x14 | 24 | #define RX8010_MDAY 0x14 |
25 | #define RX8010_MONTH 0x15 | 25 | #define RX8010_MONTH 0x15 |
26 | #define RX8010_YEAR 0x16 | 26 | #define RX8010_YEAR 0x16 |
27 | #define RX8010_YEAR 0x16 | ||
28 | #define RX8010_RESV17 0x17 | 27 | #define RX8010_RESV17 0x17 |
29 | #define RX8010_ALMIN 0x18 | 28 | #define RX8010_ALMIN 0x18 |
30 | #define RX8010_ALHOUR 0x19 | 29 | #define RX8010_ALHOUR 0x19 |
@@ -36,7 +35,7 @@ | |||
36 | #define RX8010_CTRL 0x1F | 35 | #define RX8010_CTRL 0x1F |
37 | /* 0x20 to 0x2F are user registers */ | 36 | /* 0x20 to 0x2F are user registers */ |
38 | #define RX8010_RESV30 0x30 | 37 | #define RX8010_RESV30 0x30 |
39 | #define RX8010_RESV31 0x32 | 38 | #define RX8010_RESV31 0x31 |
40 | #define RX8010_IRQ 0x32 | 39 | #define RX8010_IRQ 0x32 |
41 | 40 | ||
42 | #define RX8010_EXT_WADA BIT(3) | 41 | #define RX8010_EXT_WADA BIT(3) |
@@ -248,7 +247,7 @@ static int rx8010_init_client(struct i2c_client *client) | |||
248 | 247 | ||
249 | rx8010->ctrlreg = (ctrl[1] & ~RX8010_CTRL_TEST); | 248 | rx8010->ctrlreg = (ctrl[1] & ~RX8010_CTRL_TEST); |
250 | 249 | ||
251 | return err; | 250 | return 0; |
252 | } | 251 | } |
253 | 252 | ||
254 | static int rx8010_read_alarm(struct device *dev, struct rtc_wkalrm *t) | 253 | static int rx8010_read_alarm(struct device *dev, struct rtc_wkalrm *t) |
@@ -277,7 +276,7 @@ static int rx8010_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
277 | t->enabled = !!(rx8010->ctrlreg & RX8010_CTRL_AIE); | 276 | t->enabled = !!(rx8010->ctrlreg & RX8010_CTRL_AIE); |
278 | t->pending = (flagreg & RX8010_FLAG_AF) && t->enabled; | 277 | t->pending = (flagreg & RX8010_FLAG_AF) && t->enabled; |
279 | 278 | ||
280 | return err; | 279 | return 0; |
281 | } | 280 | } |
282 | 281 | ||
283 | static int rx8010_set_alarm(struct device *dev, struct rtc_wkalrm *t) | 282 | static int rx8010_set_alarm(struct device *dev, struct rtc_wkalrm *t) |
diff --git a/drivers/rtc/rtc-sc27xx.c b/drivers/rtc/rtc-sc27xx.c new file mode 100644 index 000000000000..d544d5268757 --- /dev/null +++ b/drivers/rtc/rtc-sc27xx.c | |||
@@ -0,0 +1,662 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Spreadtrum Communications Inc. | ||
3 | * | ||
4 | * SPDX-License-Identifier: GPL-2.0 | ||
5 | */ | ||
6 | |||
7 | #include <linux/bitops.h> | ||
8 | #include <linux/delay.h> | ||
9 | #include <linux/err.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/of.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/regmap.h> | ||
14 | #include <linux/rtc.h> | ||
15 | |||
16 | #define SPRD_RTC_SEC_CNT_VALUE 0x0 | ||
17 | #define SPRD_RTC_MIN_CNT_VALUE 0x4 | ||
18 | #define SPRD_RTC_HOUR_CNT_VALUE 0x8 | ||
19 | #define SPRD_RTC_DAY_CNT_VALUE 0xc | ||
20 | #define SPRD_RTC_SEC_CNT_UPD 0x10 | ||
21 | #define SPRD_RTC_MIN_CNT_UPD 0x14 | ||
22 | #define SPRD_RTC_HOUR_CNT_UPD 0x18 | ||
23 | #define SPRD_RTC_DAY_CNT_UPD 0x1c | ||
24 | #define SPRD_RTC_SEC_ALM_UPD 0x20 | ||
25 | #define SPRD_RTC_MIN_ALM_UPD 0x24 | ||
26 | #define SPRD_RTC_HOUR_ALM_UPD 0x28 | ||
27 | #define SPRD_RTC_DAY_ALM_UPD 0x2c | ||
28 | #define SPRD_RTC_INT_EN 0x30 | ||
29 | #define SPRD_RTC_INT_RAW_STS 0x34 | ||
30 | #define SPRD_RTC_INT_CLR 0x38 | ||
31 | #define SPRD_RTC_INT_MASK_STS 0x3C | ||
32 | #define SPRD_RTC_SEC_ALM_VALUE 0x40 | ||
33 | #define SPRD_RTC_MIN_ALM_VALUE 0x44 | ||
34 | #define SPRD_RTC_HOUR_ALM_VALUE 0x48 | ||
35 | #define SPRD_RTC_DAY_ALM_VALUE 0x4c | ||
36 | #define SPRD_RTC_SPG_VALUE 0x50 | ||
37 | #define SPRD_RTC_SPG_UPD 0x54 | ||
38 | #define SPRD_RTC_SEC_AUXALM_UPD 0x60 | ||
39 | #define SPRD_RTC_MIN_AUXALM_UPD 0x64 | ||
40 | #define SPRD_RTC_HOUR_AUXALM_UPD 0x68 | ||
41 | #define SPRD_RTC_DAY_AUXALM_UPD 0x6c | ||
42 | |||
43 | /* BIT & MASK definition for SPRD_RTC_INT_* registers */ | ||
44 | #define SPRD_RTC_SEC_EN BIT(0) | ||
45 | #define SPRD_RTC_MIN_EN BIT(1) | ||
46 | #define SPRD_RTC_HOUR_EN BIT(2) | ||
47 | #define SPRD_RTC_DAY_EN BIT(3) | ||
48 | #define SPRD_RTC_ALARM_EN BIT(4) | ||
49 | #define SPRD_RTC_HRS_FORMAT_EN BIT(5) | ||
50 | #define SPRD_RTC_AUXALM_EN BIT(6) | ||
51 | #define SPRD_RTC_SPG_UPD_EN BIT(7) | ||
52 | #define SPRD_RTC_SEC_UPD_EN BIT(8) | ||
53 | #define SPRD_RTC_MIN_UPD_EN BIT(9) | ||
54 | #define SPRD_RTC_HOUR_UPD_EN BIT(10) | ||
55 | #define SPRD_RTC_DAY_UPD_EN BIT(11) | ||
56 | #define SPRD_RTC_ALMSEC_UPD_EN BIT(12) | ||
57 | #define SPRD_RTC_ALMMIN_UPD_EN BIT(13) | ||
58 | #define SPRD_RTC_ALMHOUR_UPD_EN BIT(14) | ||
59 | #define SPRD_RTC_ALMDAY_UPD_EN BIT(15) | ||
60 | #define SPRD_RTC_INT_MASK GENMASK(15, 0) | ||
61 | |||
62 | #define SPRD_RTC_TIME_INT_MASK \ | ||
63 | (SPRD_RTC_SEC_UPD_EN | SPRD_RTC_MIN_UPD_EN | \ | ||
64 | SPRD_RTC_HOUR_UPD_EN | SPRD_RTC_DAY_UPD_EN) | ||
65 | |||
66 | #define SPRD_RTC_ALMTIME_INT_MASK \ | ||
67 | (SPRD_RTC_ALMSEC_UPD_EN | SPRD_RTC_ALMMIN_UPD_EN | \ | ||
68 | SPRD_RTC_ALMHOUR_UPD_EN | SPRD_RTC_ALMDAY_UPD_EN) | ||
69 | |||
70 | #define SPRD_RTC_ALM_INT_MASK \ | ||
71 | (SPRD_RTC_SEC_EN | SPRD_RTC_MIN_EN | \ | ||
72 | SPRD_RTC_HOUR_EN | SPRD_RTC_DAY_EN | \ | ||
73 | SPRD_RTC_ALARM_EN | SPRD_RTC_AUXALM_EN) | ||
74 | |||
75 | /* second/minute/hour/day values mask definition */ | ||
76 | #define SPRD_RTC_SEC_MASK GENMASK(5, 0) | ||
77 | #define SPRD_RTC_MIN_MASK GENMASK(5, 0) | ||
78 | #define SPRD_RTC_HOUR_MASK GENMASK(4, 0) | ||
79 | #define SPRD_RTC_DAY_MASK GENMASK(15, 0) | ||
80 | |||
81 | /* alarm lock definition for SPRD_RTC_SPG_UPD register */ | ||
82 | #define SPRD_RTC_ALMLOCK_MASK GENMASK(7, 0) | ||
83 | #define SPRD_RTC_ALM_UNLOCK 0xa5 | ||
84 | #define SPRD_RTC_ALM_LOCK (~SPRD_RTC_ALM_UNLOCK & \ | ||
85 | SPRD_RTC_ALMLOCK_MASK) | ||
86 | |||
87 | /* SPG values definition for SPRD_RTC_SPG_UPD register */ | ||
88 | #define SPRD_RTC_POWEROFF_ALM_FLAG BIT(8) | ||
89 | #define SPRD_RTC_POWER_RESET_FLAG BIT(9) | ||
90 | |||
91 | /* timeout of synchronizing time and alarm registers (us) */ | ||
92 | #define SPRD_RTC_POLL_TIMEOUT 200000 | ||
93 | #define SPRD_RTC_POLL_DELAY_US 20000 | ||
94 | |||
95 | struct sprd_rtc { | ||
96 | struct rtc_device *rtc; | ||
97 | struct regmap *regmap; | ||
98 | struct device *dev; | ||
99 | u32 base; | ||
100 | int irq; | ||
101 | bool valid; | ||
102 | }; | ||
103 | |||
104 | /* | ||
105 | * The Spreadtrum RTC controller has 3 groups registers, including time, normal | ||
106 | * alarm and auxiliary alarm. The time group registers are used to set RTC time, | ||
107 | * the normal alarm registers are used to set normal alarm, and the auxiliary | ||
108 | * alarm registers are used to set auxiliary alarm. Both alarm event and | ||
109 | * auxiliary alarm event can wake up system from deep sleep, but only alarm | ||
110 | * event can power up system from power down status. | ||
111 | */ | ||
112 | enum sprd_rtc_reg_types { | ||
113 | SPRD_RTC_TIME, | ||
114 | SPRD_RTC_ALARM, | ||
115 | SPRD_RTC_AUX_ALARM, | ||
116 | }; | ||
117 | |||
118 | static int sprd_rtc_clear_alarm_ints(struct sprd_rtc *rtc) | ||
119 | { | ||
120 | return regmap_write(rtc->regmap, rtc->base + SPRD_RTC_INT_CLR, | ||
121 | SPRD_RTC_ALM_INT_MASK); | ||
122 | } | ||
123 | |||
124 | static int sprd_rtc_disable_ints(struct sprd_rtc *rtc) | ||
125 | { | ||
126 | int ret; | ||
127 | |||
128 | ret = regmap_update_bits(rtc->regmap, rtc->base + SPRD_RTC_INT_EN, | ||
129 | SPRD_RTC_INT_MASK, 0); | ||
130 | if (ret) | ||
131 | return ret; | ||
132 | |||
133 | return regmap_write(rtc->regmap, rtc->base + SPRD_RTC_INT_CLR, | ||
134 | SPRD_RTC_INT_MASK); | ||
135 | } | ||
136 | |||
137 | static int sprd_rtc_lock_alarm(struct sprd_rtc *rtc, bool lock) | ||
138 | { | ||
139 | int ret; | ||
140 | u32 val; | ||
141 | |||
142 | ret = regmap_read(rtc->regmap, rtc->base + SPRD_RTC_SPG_VALUE, &val); | ||
143 | if (ret) | ||
144 | return ret; | ||
145 | |||
146 | val &= ~(SPRD_RTC_ALMLOCK_MASK | SPRD_RTC_POWEROFF_ALM_FLAG); | ||
147 | if (lock) | ||
148 | val |= SPRD_RTC_ALM_LOCK; | ||
149 | else | ||
150 | val |= SPRD_RTC_ALM_UNLOCK | SPRD_RTC_POWEROFF_ALM_FLAG; | ||
151 | |||
152 | ret = regmap_write(rtc->regmap, rtc->base + SPRD_RTC_SPG_UPD, val); | ||
153 | if (ret) | ||
154 | return ret; | ||
155 | |||
156 | /* wait until the SPG value is updated successfully */ | ||
157 | ret = regmap_read_poll_timeout(rtc->regmap, | ||
158 | rtc->base + SPRD_RTC_INT_RAW_STS, val, | ||
159 | (val & SPRD_RTC_SPG_UPD_EN), | ||
160 | SPRD_RTC_POLL_DELAY_US, | ||
161 | SPRD_RTC_POLL_TIMEOUT); | ||
162 | if (ret) { | ||
163 | dev_err(rtc->dev, "failed to update SPG value:%d\n", ret); | ||
164 | return ret; | ||
165 | } | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | static int sprd_rtc_get_secs(struct sprd_rtc *rtc, enum sprd_rtc_reg_types type, | ||
171 | time64_t *secs) | ||
172 | { | ||
173 | u32 sec_reg, min_reg, hour_reg, day_reg; | ||
174 | u32 val, sec, min, hour, day; | ||
175 | int ret; | ||
176 | |||
177 | switch (type) { | ||
178 | case SPRD_RTC_TIME: | ||
179 | sec_reg = SPRD_RTC_SEC_CNT_VALUE; | ||
180 | min_reg = SPRD_RTC_MIN_CNT_VALUE; | ||
181 | hour_reg = SPRD_RTC_HOUR_CNT_VALUE; | ||
182 | day_reg = SPRD_RTC_DAY_CNT_VALUE; | ||
183 | break; | ||
184 | case SPRD_RTC_ALARM: | ||
185 | sec_reg = SPRD_RTC_SEC_ALM_VALUE; | ||
186 | min_reg = SPRD_RTC_MIN_ALM_VALUE; | ||
187 | hour_reg = SPRD_RTC_HOUR_ALM_VALUE; | ||
188 | day_reg = SPRD_RTC_DAY_ALM_VALUE; | ||
189 | break; | ||
190 | case SPRD_RTC_AUX_ALARM: | ||
191 | sec_reg = SPRD_RTC_SEC_AUXALM_UPD; | ||
192 | min_reg = SPRD_RTC_MIN_AUXALM_UPD; | ||
193 | hour_reg = SPRD_RTC_HOUR_AUXALM_UPD; | ||
194 | day_reg = SPRD_RTC_DAY_AUXALM_UPD; | ||
195 | break; | ||
196 | default: | ||
197 | return -EINVAL; | ||
198 | } | ||
199 | |||
200 | ret = regmap_read(rtc->regmap, rtc->base + sec_reg, &val); | ||
201 | if (ret) | ||
202 | return ret; | ||
203 | |||
204 | sec = val & SPRD_RTC_SEC_MASK; | ||
205 | |||
206 | ret = regmap_read(rtc->regmap, rtc->base + min_reg, &val); | ||
207 | if (ret) | ||
208 | return ret; | ||
209 | |||
210 | min = val & SPRD_RTC_MIN_MASK; | ||
211 | |||
212 | ret = regmap_read(rtc->regmap, rtc->base + hour_reg, &val); | ||
213 | if (ret) | ||
214 | return ret; | ||
215 | |||
216 | hour = val & SPRD_RTC_HOUR_MASK; | ||
217 | |||
218 | ret = regmap_read(rtc->regmap, rtc->base + day_reg, &val); | ||
219 | if (ret) | ||
220 | return ret; | ||
221 | |||
222 | day = val & SPRD_RTC_DAY_MASK; | ||
223 | *secs = (((time64_t)(day * 24) + hour) * 60 + min) * 60 + sec; | ||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | static int sprd_rtc_set_secs(struct sprd_rtc *rtc, enum sprd_rtc_reg_types type, | ||
228 | time64_t secs) | ||
229 | { | ||
230 | u32 sec_reg, min_reg, hour_reg, day_reg, sts_mask; | ||
231 | u32 sec, min, hour, day, val; | ||
232 | int ret, rem; | ||
233 | |||
234 | /* convert seconds to RTC time format */ | ||
235 | day = div_s64_rem(secs, 86400, &rem); | ||
236 | hour = rem / 3600; | ||
237 | rem -= hour * 3600; | ||
238 | min = rem / 60; | ||
239 | sec = rem - min * 60; | ||
240 | |||
241 | switch (type) { | ||
242 | case SPRD_RTC_TIME: | ||
243 | sec_reg = SPRD_RTC_SEC_CNT_UPD; | ||
244 | min_reg = SPRD_RTC_MIN_CNT_UPD; | ||
245 | hour_reg = SPRD_RTC_HOUR_CNT_UPD; | ||
246 | day_reg = SPRD_RTC_DAY_CNT_UPD; | ||
247 | sts_mask = SPRD_RTC_TIME_INT_MASK; | ||
248 | break; | ||
249 | case SPRD_RTC_ALARM: | ||
250 | sec_reg = SPRD_RTC_SEC_ALM_UPD; | ||
251 | min_reg = SPRD_RTC_MIN_ALM_UPD; | ||
252 | hour_reg = SPRD_RTC_HOUR_ALM_UPD; | ||
253 | day_reg = SPRD_RTC_DAY_ALM_UPD; | ||
254 | sts_mask = SPRD_RTC_ALMTIME_INT_MASK; | ||
255 | break; | ||
256 | case SPRD_RTC_AUX_ALARM: | ||
257 | sec_reg = SPRD_RTC_SEC_AUXALM_UPD; | ||
258 | min_reg = SPRD_RTC_MIN_AUXALM_UPD; | ||
259 | hour_reg = SPRD_RTC_HOUR_AUXALM_UPD; | ||
260 | day_reg = SPRD_RTC_DAY_AUXALM_UPD; | ||
261 | sts_mask = 0; | ||
262 | break; | ||
263 | default: | ||
264 | return -EINVAL; | ||
265 | } | ||
266 | |||
267 | ret = regmap_write(rtc->regmap, rtc->base + sec_reg, sec); | ||
268 | if (ret) | ||
269 | return ret; | ||
270 | |||
271 | ret = regmap_write(rtc->regmap, rtc->base + min_reg, min); | ||
272 | if (ret) | ||
273 | return ret; | ||
274 | |||
275 | ret = regmap_write(rtc->regmap, rtc->base + hour_reg, hour); | ||
276 | if (ret) | ||
277 | return ret; | ||
278 | |||
279 | ret = regmap_write(rtc->regmap, rtc->base + day_reg, day); | ||
280 | if (ret) | ||
281 | return ret; | ||
282 | |||
283 | if (type == SPRD_RTC_AUX_ALARM) | ||
284 | return 0; | ||
285 | |||
286 | /* | ||
287 | * Since the time and normal alarm registers are put in always-power-on | ||
288 | * region supplied by VDDRTC, then these registers changing time will | ||
289 | * be very long, about 125ms. Thus here we should wait until all | ||
290 | * values are updated successfully. | ||
291 | */ | ||
292 | ret = regmap_read_poll_timeout(rtc->regmap, | ||
293 | rtc->base + SPRD_RTC_INT_RAW_STS, val, | ||
294 | ((val & sts_mask) == sts_mask), | ||
295 | SPRD_RTC_POLL_DELAY_US, | ||
296 | SPRD_RTC_POLL_TIMEOUT); | ||
297 | if (ret < 0) { | ||
298 | dev_err(rtc->dev, "set time/alarm values timeout\n"); | ||
299 | return ret; | ||
300 | } | ||
301 | |||
302 | return regmap_write(rtc->regmap, rtc->base + SPRD_RTC_INT_CLR, | ||
303 | sts_mask); | ||
304 | } | ||
305 | |||
306 | static int sprd_rtc_read_aux_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
307 | { | ||
308 | struct sprd_rtc *rtc = dev_get_drvdata(dev); | ||
309 | time64_t secs; | ||
310 | u32 val; | ||
311 | int ret; | ||
312 | |||
313 | ret = sprd_rtc_get_secs(rtc, SPRD_RTC_AUX_ALARM, &secs); | ||
314 | if (ret) | ||
315 | return ret; | ||
316 | |||
317 | rtc_time64_to_tm(secs, &alrm->time); | ||
318 | |||
319 | ret = regmap_read(rtc->regmap, rtc->base + SPRD_RTC_INT_EN, &val); | ||
320 | if (ret) | ||
321 | return ret; | ||
322 | |||
323 | alrm->enabled = !!(val & SPRD_RTC_AUXALM_EN); | ||
324 | |||
325 | ret = regmap_read(rtc->regmap, rtc->base + SPRD_RTC_INT_RAW_STS, &val); | ||
326 | if (ret) | ||
327 | return ret; | ||
328 | |||
329 | alrm->pending = !!(val & SPRD_RTC_AUXALM_EN); | ||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | static int sprd_rtc_set_aux_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
334 | { | ||
335 | struct sprd_rtc *rtc = dev_get_drvdata(dev); | ||
336 | time64_t secs = rtc_tm_to_time64(&alrm->time); | ||
337 | int ret; | ||
338 | |||
339 | /* clear the auxiliary alarm interrupt status */ | ||
340 | ret = regmap_write(rtc->regmap, rtc->base + SPRD_RTC_INT_CLR, | ||
341 | SPRD_RTC_AUXALM_EN); | ||
342 | if (ret) | ||
343 | return ret; | ||
344 | |||
345 | ret = sprd_rtc_set_secs(rtc, SPRD_RTC_AUX_ALARM, secs); | ||
346 | if (ret) | ||
347 | return ret; | ||
348 | |||
349 | if (alrm->enabled) { | ||
350 | ret = regmap_update_bits(rtc->regmap, | ||
351 | rtc->base + SPRD_RTC_INT_EN, | ||
352 | SPRD_RTC_AUXALM_EN, | ||
353 | SPRD_RTC_AUXALM_EN); | ||
354 | } else { | ||
355 | ret = regmap_update_bits(rtc->regmap, | ||
356 | rtc->base + SPRD_RTC_INT_EN, | ||
357 | SPRD_RTC_AUXALM_EN, 0); | ||
358 | } | ||
359 | |||
360 | return ret; | ||
361 | } | ||
362 | |||
363 | static int sprd_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
364 | { | ||
365 | struct sprd_rtc *rtc = dev_get_drvdata(dev); | ||
366 | time64_t secs; | ||
367 | int ret; | ||
368 | |||
369 | if (!rtc->valid) { | ||
370 | dev_warn(dev, "RTC values are invalid\n"); | ||
371 | return -EINVAL; | ||
372 | } | ||
373 | |||
374 | ret = sprd_rtc_get_secs(rtc, SPRD_RTC_TIME, &secs); | ||
375 | if (ret) | ||
376 | return ret; | ||
377 | |||
378 | rtc_time64_to_tm(secs, tm); | ||
379 | return rtc_valid_tm(tm); | ||
380 | } | ||
381 | |||
382 | static int sprd_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
383 | { | ||
384 | struct sprd_rtc *rtc = dev_get_drvdata(dev); | ||
385 | time64_t secs = rtc_tm_to_time64(tm); | ||
386 | u32 val; | ||
387 | int ret; | ||
388 | |||
389 | ret = sprd_rtc_set_secs(rtc, SPRD_RTC_TIME, secs); | ||
390 | if (ret) | ||
391 | return ret; | ||
392 | |||
393 | if (!rtc->valid) { | ||
394 | /* | ||
395 | * Set SPRD_RTC_POWER_RESET_FLAG to indicate now RTC has valid | ||
396 | * time values. | ||
397 | */ | ||
398 | ret = regmap_update_bits(rtc->regmap, | ||
399 | rtc->base + SPRD_RTC_SPG_UPD, | ||
400 | SPRD_RTC_POWER_RESET_FLAG, | ||
401 | SPRD_RTC_POWER_RESET_FLAG); | ||
402 | if (ret) | ||
403 | return ret; | ||
404 | |||
405 | ret = regmap_read_poll_timeout(rtc->regmap, | ||
406 | rtc->base + SPRD_RTC_INT_RAW_STS, | ||
407 | val, (val & SPRD_RTC_SPG_UPD_EN), | ||
408 | SPRD_RTC_POLL_DELAY_US, | ||
409 | SPRD_RTC_POLL_TIMEOUT); | ||
410 | if (ret) { | ||
411 | dev_err(rtc->dev, "failed to update SPG value:%d\n", | ||
412 | ret); | ||
413 | return ret; | ||
414 | } | ||
415 | |||
416 | rtc->valid = true; | ||
417 | } | ||
418 | |||
419 | return 0; | ||
420 | } | ||
421 | |||
422 | static int sprd_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
423 | { | ||
424 | struct sprd_rtc *rtc = dev_get_drvdata(dev); | ||
425 | time64_t secs; | ||
426 | int ret; | ||
427 | u32 val; | ||
428 | |||
429 | /* | ||
430 | * If aie_timer is enabled, we should get the normal alarm time. | ||
431 | * Otherwise we should get auxiliary alarm time. | ||
432 | */ | ||
433 | if (rtc->rtc && rtc->rtc->aie_timer.enabled == 0) | ||
434 | return sprd_rtc_read_aux_alarm(dev, alrm); | ||
435 | |||
436 | ret = sprd_rtc_get_secs(rtc, SPRD_RTC_ALARM, &secs); | ||
437 | if (ret) | ||
438 | return ret; | ||
439 | |||
440 | rtc_time64_to_tm(secs, &alrm->time); | ||
441 | |||
442 | ret = regmap_read(rtc->regmap, rtc->base + SPRD_RTC_INT_EN, &val); | ||
443 | if (ret) | ||
444 | return ret; | ||
445 | |||
446 | alrm->enabled = !!(val & SPRD_RTC_ALARM_EN); | ||
447 | |||
448 | ret = regmap_read(rtc->regmap, rtc->base + SPRD_RTC_INT_RAW_STS, &val); | ||
449 | if (ret) | ||
450 | return ret; | ||
451 | |||
452 | alrm->pending = !!(val & SPRD_RTC_ALARM_EN); | ||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | static int sprd_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
457 | { | ||
458 | struct sprd_rtc *rtc = dev_get_drvdata(dev); | ||
459 | time64_t secs = rtc_tm_to_time64(&alrm->time); | ||
460 | struct rtc_time aie_time = | ||
461 | rtc_ktime_to_tm(rtc->rtc->aie_timer.node.expires); | ||
462 | int ret; | ||
463 | |||
464 | /* | ||
465 | * We have 2 groups alarms: normal alarm and auxiliary alarm. Since | ||
466 | * both normal alarm event and auxiliary alarm event can wake up system | ||
467 | * from deep sleep, but only alarm event can power up system from power | ||
468 | * down status. Moreover we do not need to poll about 125ms when | ||
469 | * updating auxiliary alarm registers. Thus we usually set auxiliary | ||
470 | * alarm when wake up system from deep sleep, and for other scenarios, | ||
471 | * we should set normal alarm with polling status. | ||
472 | * | ||
473 | * So here we check if the alarm time is set by aie_timer, if yes, we | ||
474 | * should set normal alarm, if not, we should set auxiliary alarm which | ||
475 | * means it is just a wake event. | ||
476 | */ | ||
477 | if (!rtc->rtc->aie_timer.enabled || rtc_tm_sub(&aie_time, &alrm->time)) | ||
478 | return sprd_rtc_set_aux_alarm(dev, alrm); | ||
479 | |||
480 | /* clear the alarm interrupt status firstly */ | ||
481 | ret = regmap_write(rtc->regmap, rtc->base + SPRD_RTC_INT_CLR, | ||
482 | SPRD_RTC_ALARM_EN); | ||
483 | if (ret) | ||
484 | return ret; | ||
485 | |||
486 | ret = sprd_rtc_set_secs(rtc, SPRD_RTC_ALARM, secs); | ||
487 | if (ret) | ||
488 | return ret; | ||
489 | |||
490 | if (alrm->enabled) { | ||
491 | ret = regmap_update_bits(rtc->regmap, | ||
492 | rtc->base + SPRD_RTC_INT_EN, | ||
493 | SPRD_RTC_ALARM_EN, | ||
494 | SPRD_RTC_ALARM_EN); | ||
495 | if (ret) | ||
496 | return ret; | ||
497 | |||
498 | /* unlock the alarm to enable the alarm function. */ | ||
499 | ret = sprd_rtc_lock_alarm(rtc, false); | ||
500 | } else { | ||
501 | regmap_update_bits(rtc->regmap, | ||
502 | rtc->base + SPRD_RTC_INT_EN, | ||
503 | SPRD_RTC_ALARM_EN, 0); | ||
504 | |||
505 | /* | ||
506 | * Lock the alarm function in case fake alarm event will power | ||
507 | * up systems. | ||
508 | */ | ||
509 | ret = sprd_rtc_lock_alarm(rtc, true); | ||
510 | } | ||
511 | |||
512 | return ret; | ||
513 | } | ||
514 | |||
515 | static int sprd_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | ||
516 | { | ||
517 | struct sprd_rtc *rtc = dev_get_drvdata(dev); | ||
518 | int ret; | ||
519 | |||
520 | if (enabled) { | ||
521 | ret = regmap_update_bits(rtc->regmap, | ||
522 | rtc->base + SPRD_RTC_INT_EN, | ||
523 | SPRD_RTC_ALARM_EN | SPRD_RTC_AUXALM_EN, | ||
524 | SPRD_RTC_ALARM_EN | SPRD_RTC_AUXALM_EN); | ||
525 | if (ret) | ||
526 | return ret; | ||
527 | |||
528 | ret = sprd_rtc_lock_alarm(rtc, false); | ||
529 | } else { | ||
530 | regmap_update_bits(rtc->regmap, rtc->base + SPRD_RTC_INT_EN, | ||
531 | SPRD_RTC_ALARM_EN | SPRD_RTC_AUXALM_EN, 0); | ||
532 | |||
533 | ret = sprd_rtc_lock_alarm(rtc, true); | ||
534 | } | ||
535 | |||
536 | return ret; | ||
537 | } | ||
538 | |||
539 | static const struct rtc_class_ops sprd_rtc_ops = { | ||
540 | .read_time = sprd_rtc_read_time, | ||
541 | .set_time = sprd_rtc_set_time, | ||
542 | .read_alarm = sprd_rtc_read_alarm, | ||
543 | .set_alarm = sprd_rtc_set_alarm, | ||
544 | .alarm_irq_enable = sprd_rtc_alarm_irq_enable, | ||
545 | }; | ||
546 | |||
547 | static irqreturn_t sprd_rtc_handler(int irq, void *dev_id) | ||
548 | { | ||
549 | struct sprd_rtc *rtc = dev_id; | ||
550 | int ret; | ||
551 | |||
552 | ret = sprd_rtc_clear_alarm_ints(rtc); | ||
553 | if (ret) | ||
554 | return IRQ_RETVAL(ret); | ||
555 | |||
556 | rtc_update_irq(rtc->rtc, 1, RTC_AF | RTC_IRQF); | ||
557 | return IRQ_HANDLED; | ||
558 | } | ||
559 | |||
560 | static int sprd_rtc_check_power_down(struct sprd_rtc *rtc) | ||
561 | { | ||
562 | u32 val; | ||
563 | int ret; | ||
564 | |||
565 | ret = regmap_read(rtc->regmap, rtc->base + SPRD_RTC_SPG_VALUE, &val); | ||
566 | if (ret) | ||
567 | return ret; | ||
568 | |||
569 | /* | ||
570 | * If the SPRD_RTC_POWER_RESET_FLAG was not set, which means the RTC has | ||
571 | * been powered down, so the RTC time values are invalid. | ||
572 | */ | ||
573 | rtc->valid = (val & SPRD_RTC_POWER_RESET_FLAG) ? true : false; | ||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | static int sprd_rtc_probe(struct platform_device *pdev) | ||
578 | { | ||
579 | struct device_node *node = pdev->dev.of_node; | ||
580 | struct sprd_rtc *rtc; | ||
581 | int ret; | ||
582 | |||
583 | rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); | ||
584 | if (!rtc) | ||
585 | return -ENOMEM; | ||
586 | |||
587 | rtc->regmap = dev_get_regmap(pdev->dev.parent, NULL); | ||
588 | if (!rtc->regmap) | ||
589 | return -ENODEV; | ||
590 | |||
591 | ret = of_property_read_u32(node, "reg", &rtc->base); | ||
592 | if (ret) { | ||
593 | dev_err(&pdev->dev, "failed to get RTC base address\n"); | ||
594 | return ret; | ||
595 | } | ||
596 | |||
597 | rtc->irq = platform_get_irq(pdev, 0); | ||
598 | if (rtc->irq < 0) { | ||
599 | dev_err(&pdev->dev, "failed to get RTC irq number\n"); | ||
600 | return rtc->irq; | ||
601 | } | ||
602 | |||
603 | rtc->dev = &pdev->dev; | ||
604 | platform_set_drvdata(pdev, rtc); | ||
605 | |||
606 | /* clear all RTC interrupts and disable all RTC interrupts */ | ||
607 | ret = sprd_rtc_disable_ints(rtc); | ||
608 | if (ret) { | ||
609 | dev_err(&pdev->dev, "failed to disable RTC interrupts\n"); | ||
610 | return ret; | ||
611 | } | ||
612 | |||
613 | /* check if RTC time values are valid */ | ||
614 | ret = sprd_rtc_check_power_down(rtc); | ||
615 | if (ret) { | ||
616 | dev_err(&pdev->dev, "failed to check RTC time values\n"); | ||
617 | return ret; | ||
618 | } | ||
619 | |||
620 | ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL, | ||
621 | sprd_rtc_handler, | ||
622 | IRQF_ONESHOT | IRQF_EARLY_RESUME, | ||
623 | pdev->name, rtc); | ||
624 | if (ret < 0) { | ||
625 | dev_err(&pdev->dev, "failed to request RTC irq\n"); | ||
626 | return ret; | ||
627 | } | ||
628 | |||
629 | rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, | ||
630 | &sprd_rtc_ops, THIS_MODULE); | ||
631 | if (IS_ERR(rtc->rtc)) | ||
632 | return PTR_ERR(rtc->rtc); | ||
633 | |||
634 | device_init_wakeup(&pdev->dev, 1); | ||
635 | return 0; | ||
636 | } | ||
637 | |||
638 | static int sprd_rtc_remove(struct platform_device *pdev) | ||
639 | { | ||
640 | device_init_wakeup(&pdev->dev, 0); | ||
641 | return 0; | ||
642 | } | ||
643 | |||
644 | static const struct of_device_id sprd_rtc_of_match[] = { | ||
645 | { .compatible = "sprd,sc2731-rtc", }, | ||
646 | { }, | ||
647 | }; | ||
648 | MODULE_DEVICE_TABLE(of, sprd_rtc_of_match); | ||
649 | |||
650 | static struct platform_driver sprd_rtc_driver = { | ||
651 | .driver = { | ||
652 | .name = "sprd-rtc", | ||
653 | .of_match_table = sprd_rtc_of_match, | ||
654 | }, | ||
655 | .probe = sprd_rtc_probe, | ||
656 | .remove = sprd_rtc_remove, | ||
657 | }; | ||
658 | module_platform_driver(sprd_rtc_driver); | ||
659 | |||
660 | MODULE_LICENSE("GPL v2"); | ||
661 | MODULE_DESCRIPTION("Spreadtrum RTC Device Driver"); | ||
662 | MODULE_AUTHOR("Baolin Wang <baolin.wang@spreadtrum.com>"); | ||
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c index e364550eb9a7..92ff2edb86a6 100644 --- a/drivers/rtc/rtc-sysfs.c +++ b/drivers/rtc/rtc-sysfs.c | |||
@@ -72,9 +72,10 @@ since_epoch_show(struct device *dev, struct device_attribute *attr, char *buf) | |||
72 | 72 | ||
73 | retval = rtc_read_time(to_rtc_device(dev), &tm); | 73 | retval = rtc_read_time(to_rtc_device(dev), &tm); |
74 | if (retval == 0) { | 74 | if (retval == 0) { |
75 | unsigned long time; | 75 | time64_t time; |
76 | rtc_tm_to_time(&tm, &time); | 76 | |
77 | retval = sprintf(buf, "%lu\n", time); | 77 | time = rtc_tm_to_time64(&tm); |
78 | retval = sprintf(buf, "%lld\n", time); | ||
78 | } | 79 | } |
79 | 80 | ||
80 | return retval; | 81 | return retval; |
@@ -132,7 +133,7 @@ static ssize_t | |||
132 | wakealarm_show(struct device *dev, struct device_attribute *attr, char *buf) | 133 | wakealarm_show(struct device *dev, struct device_attribute *attr, char *buf) |
133 | { | 134 | { |
134 | ssize_t retval; | 135 | ssize_t retval; |
135 | unsigned long alarm; | 136 | time64_t alarm; |
136 | struct rtc_wkalrm alm; | 137 | struct rtc_wkalrm alm; |
137 | 138 | ||
138 | /* Don't show disabled alarms. For uniformity, RTC alarms are | 139 | /* Don't show disabled alarms. For uniformity, RTC alarms are |
@@ -145,8 +146,8 @@ wakealarm_show(struct device *dev, struct device_attribute *attr, char *buf) | |||
145 | */ | 146 | */ |
146 | retval = rtc_read_alarm(to_rtc_device(dev), &alm); | 147 | retval = rtc_read_alarm(to_rtc_device(dev), &alm); |
147 | if (retval == 0 && alm.enabled) { | 148 | if (retval == 0 && alm.enabled) { |
148 | rtc_tm_to_time(&alm.time, &alarm); | 149 | alarm = rtc_tm_to_time64(&alm.time); |
149 | retval = sprintf(buf, "%lu\n", alarm); | 150 | retval = sprintf(buf, "%lld\n", alarm); |
150 | } | 151 | } |
151 | 152 | ||
152 | return retval; | 153 | return retval; |
@@ -157,8 +158,8 @@ wakealarm_store(struct device *dev, struct device_attribute *attr, | |||
157 | const char *buf, size_t n) | 158 | const char *buf, size_t n) |
158 | { | 159 | { |
159 | ssize_t retval; | 160 | ssize_t retval; |
160 | unsigned long now, alarm; | 161 | time64_t now, alarm; |
161 | unsigned long push = 0; | 162 | time64_t push = 0; |
162 | struct rtc_wkalrm alm; | 163 | struct rtc_wkalrm alm; |
163 | struct rtc_device *rtc = to_rtc_device(dev); | 164 | struct rtc_device *rtc = to_rtc_device(dev); |
164 | const char *buf_ptr; | 165 | const char *buf_ptr; |
@@ -170,7 +171,7 @@ wakealarm_store(struct device *dev, struct device_attribute *attr, | |||
170 | retval = rtc_read_time(rtc, &alm.time); | 171 | retval = rtc_read_time(rtc, &alm.time); |
171 | if (retval < 0) | 172 | if (retval < 0) |
172 | return retval; | 173 | return retval; |
173 | rtc_tm_to_time(&alm.time, &now); | 174 | now = rtc_tm_to_time64(&alm.time); |
174 | 175 | ||
175 | buf_ptr = buf; | 176 | buf_ptr = buf; |
176 | if (*buf_ptr == '+') { | 177 | if (*buf_ptr == '+') { |
@@ -181,7 +182,7 @@ wakealarm_store(struct device *dev, struct device_attribute *attr, | |||
181 | } else | 182 | } else |
182 | adjust = 1; | 183 | adjust = 1; |
183 | } | 184 | } |
184 | retval = kstrtoul(buf_ptr, 0, &alarm); | 185 | retval = kstrtos64(buf_ptr, 0, &alarm); |
185 | if (retval) | 186 | if (retval) |
186 | return retval; | 187 | return retval; |
187 | if (adjust) { | 188 | if (adjust) { |
@@ -197,7 +198,7 @@ wakealarm_store(struct device *dev, struct device_attribute *attr, | |||
197 | return retval; | 198 | return retval; |
198 | if (alm.enabled) { | 199 | if (alm.enabled) { |
199 | if (push) { | 200 | if (push) { |
200 | rtc_tm_to_time(&alm.time, &push); | 201 | push = rtc_tm_to_time64(&alm.time); |
201 | alarm += push; | 202 | alarm += push; |
202 | } else | 203 | } else |
203 | return -EBUSY; | 204 | return -EBUSY; |
@@ -212,7 +213,7 @@ wakealarm_store(struct device *dev, struct device_attribute *attr, | |||
212 | */ | 213 | */ |
213 | alarm = now + 300; | 214 | alarm = now + 300; |
214 | } | 215 | } |
215 | rtc_time_to_tm(alarm, &alm.time); | 216 | rtc_time64_to_tm(alarm, &alm.time); |
216 | 217 | ||
217 | retval = rtc_set_alarm(rtc, &alm); | 218 | retval = rtc_set_alarm(rtc, &alm); |
218 | return (retval < 0) ? retval : n; | 219 | return (retval < 0) ? retval : n; |
diff --git a/drivers/rtc/rtc-xgene.c b/drivers/rtc/rtc-xgene.c index 65b432a096fe..0c34d3b81279 100644 --- a/drivers/rtc/rtc-xgene.c +++ b/drivers/rtc/rtc-xgene.c | |||
@@ -52,6 +52,7 @@ struct xgene_rtc_dev { | |||
52 | void __iomem *csr_base; | 52 | void __iomem *csr_base; |
53 | struct clk *clk; | 53 | struct clk *clk; |
54 | unsigned int irq_wake; | 54 | unsigned int irq_wake; |
55 | unsigned int irq_enabled; | ||
55 | }; | 56 | }; |
56 | 57 | ||
57 | static int xgene_rtc_read_time(struct device *dev, struct rtc_time *tm) | 58 | static int xgene_rtc_read_time(struct device *dev, struct rtc_time *tm) |
@@ -104,15 +105,19 @@ static int xgene_rtc_alarm_irq_enable(struct device *dev, u32 enabled) | |||
104 | return 0; | 105 | return 0; |
105 | } | 106 | } |
106 | 107 | ||
108 | static int xgene_rtc_alarm_irq_enabled(struct device *dev) | ||
109 | { | ||
110 | struct xgene_rtc_dev *pdata = dev_get_drvdata(dev); | ||
111 | |||
112 | return readl(pdata->csr_base + RTC_CCR) & RTC_CCR_IE ? 1 : 0; | ||
113 | } | ||
114 | |||
107 | static int xgene_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | 115 | static int xgene_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
108 | { | 116 | { |
109 | struct xgene_rtc_dev *pdata = dev_get_drvdata(dev); | 117 | struct xgene_rtc_dev *pdata = dev_get_drvdata(dev); |
110 | unsigned long rtc_time; | ||
111 | unsigned long alarm_time; | 118 | unsigned long alarm_time; |
112 | 119 | ||
113 | rtc_time = readl(pdata->csr_base + RTC_CCVR); | ||
114 | rtc_tm_to_time(&alrm->time, &alarm_time); | 120 | rtc_tm_to_time(&alrm->time, &alarm_time); |
115 | |||
116 | pdata->alarm_time = alarm_time; | 121 | pdata->alarm_time = alarm_time; |
117 | writel((u32) pdata->alarm_time, pdata->csr_base + RTC_CMR); | 122 | writel((u32) pdata->alarm_time, pdata->csr_base + RTC_CMR); |
118 | 123 | ||
@@ -180,12 +185,18 @@ static int xgene_rtc_probe(struct platform_device *pdev) | |||
180 | dev_err(&pdev->dev, "Couldn't get the clock for RTC\n"); | 185 | dev_err(&pdev->dev, "Couldn't get the clock for RTC\n"); |
181 | return -ENODEV; | 186 | return -ENODEV; |
182 | } | 187 | } |
183 | clk_prepare_enable(pdata->clk); | 188 | ret = clk_prepare_enable(pdata->clk); |
189 | if (ret) | ||
190 | return ret; | ||
184 | 191 | ||
185 | /* Turn on the clock and the crystal */ | 192 | /* Turn on the clock and the crystal */ |
186 | writel(RTC_CCR_EN, pdata->csr_base + RTC_CCR); | 193 | writel(RTC_CCR_EN, pdata->csr_base + RTC_CCR); |
187 | 194 | ||
188 | device_init_wakeup(&pdev->dev, 1); | 195 | ret = device_init_wakeup(&pdev->dev, 1); |
196 | if (ret) { | ||
197 | clk_disable_unprepare(pdata->clk); | ||
198 | return ret; | ||
199 | } | ||
189 | 200 | ||
190 | pdata->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, | 201 | pdata->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, |
191 | &xgene_rtc_ops, THIS_MODULE); | 202 | &xgene_rtc_ops, THIS_MODULE); |
@@ -210,45 +221,55 @@ static int xgene_rtc_remove(struct platform_device *pdev) | |||
210 | return 0; | 221 | return 0; |
211 | } | 222 | } |
212 | 223 | ||
213 | #ifdef CONFIG_PM_SLEEP | 224 | static int __maybe_unused xgene_rtc_suspend(struct device *dev) |
214 | static int xgene_rtc_suspend(struct device *dev) | ||
215 | { | 225 | { |
216 | struct platform_device *pdev = to_platform_device(dev); | 226 | struct platform_device *pdev = to_platform_device(dev); |
217 | struct xgene_rtc_dev *pdata = platform_get_drvdata(pdev); | 227 | struct xgene_rtc_dev *pdata = platform_get_drvdata(pdev); |
218 | int irq; | 228 | int irq; |
219 | 229 | ||
220 | irq = platform_get_irq(pdev, 0); | 230 | irq = platform_get_irq(pdev, 0); |
231 | |||
232 | /* | ||
233 | * If this RTC alarm will be used for waking the system up, | ||
234 | * don't disable it of course. Else we just disable the alarm | ||
235 | * and await suspension. | ||
236 | */ | ||
221 | if (device_may_wakeup(&pdev->dev)) { | 237 | if (device_may_wakeup(&pdev->dev)) { |
222 | if (!enable_irq_wake(irq)) | 238 | if (!enable_irq_wake(irq)) |
223 | pdata->irq_wake = 1; | 239 | pdata->irq_wake = 1; |
224 | } else { | 240 | } else { |
241 | pdata->irq_enabled = xgene_rtc_alarm_irq_enabled(dev); | ||
225 | xgene_rtc_alarm_irq_enable(dev, 0); | 242 | xgene_rtc_alarm_irq_enable(dev, 0); |
226 | clk_disable(pdata->clk); | 243 | clk_disable_unprepare(pdata->clk); |
227 | } | 244 | } |
228 | |||
229 | return 0; | 245 | return 0; |
230 | } | 246 | } |
231 | 247 | ||
232 | static int xgene_rtc_resume(struct device *dev) | 248 | static int __maybe_unused xgene_rtc_resume(struct device *dev) |
233 | { | 249 | { |
234 | struct platform_device *pdev = to_platform_device(dev); | 250 | struct platform_device *pdev = to_platform_device(dev); |
235 | struct xgene_rtc_dev *pdata = platform_get_drvdata(pdev); | 251 | struct xgene_rtc_dev *pdata = platform_get_drvdata(pdev); |
236 | int irq; | 252 | int irq; |
253 | int rc; | ||
237 | 254 | ||
238 | irq = platform_get_irq(pdev, 0); | 255 | irq = platform_get_irq(pdev, 0); |
256 | |||
239 | if (device_may_wakeup(&pdev->dev)) { | 257 | if (device_may_wakeup(&pdev->dev)) { |
240 | if (pdata->irq_wake) { | 258 | if (pdata->irq_wake) { |
241 | disable_irq_wake(irq); | 259 | disable_irq_wake(irq); |
242 | pdata->irq_wake = 0; | 260 | pdata->irq_wake = 0; |
243 | } | 261 | } |
244 | } else { | 262 | } else { |
245 | clk_enable(pdata->clk); | 263 | rc = clk_prepare_enable(pdata->clk); |
246 | xgene_rtc_alarm_irq_enable(dev, 1); | 264 | if (rc) { |
265 | dev_err(dev, "Unable to enable clock error %d\n", rc); | ||
266 | return rc; | ||
267 | } | ||
268 | xgene_rtc_alarm_irq_enable(dev, pdata->irq_enabled); | ||
247 | } | 269 | } |
248 | 270 | ||
249 | return 0; | 271 | return 0; |
250 | } | 272 | } |
251 | #endif | ||
252 | 273 | ||
253 | static SIMPLE_DEV_PM_OPS(xgene_rtc_pm_ops, xgene_rtc_suspend, xgene_rtc_resume); | 274 | static SIMPLE_DEV_PM_OPS(xgene_rtc_pm_ops, xgene_rtc_suspend, xgene_rtc_resume); |
254 | 275 | ||