diff options
Diffstat (limited to 'drivers/rtc')
72 files changed, 6442 insertions, 1794 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 48ca7132cc05..ce2aabf5c550 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -3,10 +3,10 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | config RTC_LIB | 5 | config RTC_LIB |
6 | tristate | 6 | bool |
7 | 7 | ||
8 | menuconfig RTC_CLASS | 8 | menuconfig RTC_CLASS |
9 | tristate "Real Time Clock" | 9 | bool "Real Time Clock" |
10 | default n | 10 | default n |
11 | depends on !S390 | 11 | depends on !S390 |
12 | select RTC_LIB | 12 | select RTC_LIB |
@@ -15,9 +15,6 @@ menuconfig RTC_CLASS | |||
15 | be allowed to plug one or more RTCs to your system. You will | 15 | be allowed to plug one or more RTCs to your system. You will |
16 | probably want to enable one or more of the interfaces below. | 16 | probably want to enable one or more of the interfaces below. |
17 | 17 | ||
18 | This driver can also be built as a module. If so, the module | ||
19 | will be called rtc-core. | ||
20 | |||
21 | if RTC_CLASS | 18 | if RTC_CLASS |
22 | 19 | ||
23 | config RTC_HCTOSYS | 20 | config RTC_HCTOSYS |
@@ -128,6 +125,16 @@ comment "I2C RTC drivers" | |||
128 | 125 | ||
129 | if I2C | 126 | if I2C |
130 | 127 | ||
128 | config RTC_DRV_88PM860X | ||
129 | tristate "Marvell 88PM860x" | ||
130 | depends on RTC_CLASS && I2C && MFD_88PM860X | ||
131 | help | ||
132 | If you say yes here you get support for RTC function in Marvell | ||
133 | 88PM860x chips. | ||
134 | |||
135 | This driver can also be built as a module. If so, the module | ||
136 | will be called rtc-88pm860x. | ||
137 | |||
131 | config RTC_DRV_DS1307 | 138 | config RTC_DRV_DS1307 |
132 | tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025" | 139 | tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025" |
133 | help | 140 | help |
@@ -171,7 +178,8 @@ config RTC_DRV_DS3232 | |||
171 | depends on RTC_CLASS && I2C | 178 | depends on RTC_CLASS && I2C |
172 | help | 179 | help |
173 | If you say yes here you get support for Dallas Semiconductor | 180 | If you say yes here you get support for Dallas Semiconductor |
174 | DS3232 real-time clock chips. | 181 | DS3232 real-time clock chips. If an interrupt is associated |
182 | with the device, the alarm functionality is supported. | ||
175 | 183 | ||
176 | This driver can also be built as a module. If so, the module | 184 | This driver can also be built as a module. If so, the module |
177 | will be called rtc-ds3232. | 185 | will be called rtc-ds3232. |
@@ -195,6 +203,16 @@ config RTC_DRV_MAX8925 | |||
195 | This driver can also be built as a module. If so, the module | 203 | This driver can also be built as a module. If so, the module |
196 | will be called rtc-max8925. | 204 | will be called rtc-max8925. |
197 | 205 | ||
206 | config RTC_DRV_MAX8998 | ||
207 | tristate "Maxim MAX8998" | ||
208 | depends on MFD_MAX8998 | ||
209 | help | ||
210 | If you say yes here you will get support for the | ||
211 | RTC of Maxim MAX8998 PMIC. | ||
212 | |||
213 | This driver can also be built as a module. If so, the module | ||
214 | will be called rtc-max8998. | ||
215 | |||
198 | config RTC_DRV_RS5C372 | 216 | config RTC_DRV_RS5C372 |
199 | tristate "Ricoh R2025S/D, RS5C372A/B, RV5C386, RV5C387A" | 217 | tristate "Ricoh R2025S/D, RS5C372A/B, RV5C386, RV5C387A" |
200 | help | 218 | help |
@@ -343,12 +361,39 @@ config RTC_DRV_RX8025 | |||
343 | This driver can also be built as a module. If so, the module | 361 | This driver can also be built as a module. If so, the module |
344 | will be called rtc-rx8025. | 362 | will be called rtc-rx8025. |
345 | 363 | ||
364 | config RTC_DRV_EM3027 | ||
365 | tristate "EM Microelectronic EM3027" | ||
366 | help | ||
367 | If you say yes here you get support for the EM | ||
368 | Microelectronic EM3027 RTC chips. | ||
369 | |||
370 | This driver can also be built as a module. If so, the module | ||
371 | will be called rtc-em3027. | ||
372 | |||
373 | config RTC_DRV_RV3029C2 | ||
374 | tristate "Micro Crystal RTC" | ||
375 | help | ||
376 | If you say yes here you get support for the Micro Crystal | ||
377 | RV3029-C2 RTC chips. | ||
378 | |||
379 | This driver can also be built as a module. If so, the module | ||
380 | will be called rtc-rv3029c2. | ||
381 | |||
346 | endif # I2C | 382 | endif # I2C |
347 | 383 | ||
348 | comment "SPI RTC drivers" | 384 | comment "SPI RTC drivers" |
349 | 385 | ||
350 | if SPI_MASTER | 386 | if SPI_MASTER |
351 | 387 | ||
388 | config RTC_DRV_M41T93 | ||
389 | tristate "ST M41T93" | ||
390 | help | ||
391 | If you say yes here you will get support for the | ||
392 | ST M41T93 SPI RTC chip. | ||
393 | |||
394 | This driver can also be built as a module. If so, the module | ||
395 | will be called rtc-m41t93. | ||
396 | |||
352 | config RTC_DRV_M41T94 | 397 | config RTC_DRV_M41T94 |
353 | tristate "ST M41T94" | 398 | tristate "ST M41T94" |
354 | help | 399 | help |
@@ -452,6 +497,18 @@ config RTC_DRV_CMOS | |||
452 | This driver can also be built as a module. If so, the module | 497 | This driver can also be built as a module. If so, the module |
453 | will be called rtc-cmos. | 498 | will be called rtc-cmos. |
454 | 499 | ||
500 | config RTC_DRV_VRTC | ||
501 | tristate "Virtual RTC for Moorestown platforms" | ||
502 | depends on X86_MRST | ||
503 | default y if X86_MRST | ||
504 | |||
505 | help | ||
506 | Say "yes" here to get direct support for the real time clock | ||
507 | found on Moorestown platforms. The VRTC is a emulated RTC that | ||
508 | derives its clock source from a real RTC in the PMIC. The MC146818 | ||
509 | style programming interface is mostly conserved, but any | ||
510 | updates are done via IPC calls to the system controller FW. | ||
511 | |||
455 | config RTC_DRV_DS1216 | 512 | config RTC_DRV_DS1216 |
456 | tristate "Dallas DS1216" | 513 | tristate "Dallas DS1216" |
457 | depends on SNI_RM | 514 | depends on SNI_RM |
@@ -625,6 +682,14 @@ config RTC_DRV_WM8350 | |||
625 | This driver can also be built as a module. If so, the module | 682 | This driver can also be built as a module. If so, the module |
626 | will be called "rtc-wm8350". | 683 | will be called "rtc-wm8350". |
627 | 684 | ||
685 | config RTC_DRV_SPEAR | ||
686 | tristate "SPEAR ST RTC" | ||
687 | depends on PLAT_SPEAR | ||
688 | default y | ||
689 | help | ||
690 | If you say Y here you will get support for the RTC found on | ||
691 | spear | ||
692 | |||
628 | config RTC_DRV_PCF50633 | 693 | config RTC_DRV_PCF50633 |
629 | depends on MFD_PCF50633 | 694 | depends on MFD_PCF50633 |
630 | tristate "NXP PCF50633 RTC" | 695 | tristate "NXP PCF50633 RTC" |
@@ -765,15 +830,15 @@ config RTC_DRV_AT32AP700X | |||
765 | AT32AP700x family processors. | 830 | AT32AP700x family processors. |
766 | 831 | ||
767 | config RTC_DRV_AT91RM9200 | 832 | config RTC_DRV_AT91RM9200 |
768 | tristate "AT91RM9200 or AT91SAM9RL" | 833 | tristate "AT91RM9200 or some AT91SAM9 RTC" |
769 | depends on ARCH_AT91RM9200 || ARCH_AT91SAM9RL | 834 | depends on ARCH_AT91RM9200 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 |
770 | help | 835 | help |
771 | Driver for the internal RTC (Realtime Clock) module found on | 836 | Driver for the internal RTC (Realtime Clock) module found on |
772 | Atmel AT91RM9200's and AT91SAM9RL chips. On SAM9RL chips | 837 | Atmel AT91RM9200's and some AT91SAM9 chips. On AT91SAM9 chips |
773 | this is powered by the backup power supply. | 838 | this is powered by the backup power supply. |
774 | 839 | ||
775 | config RTC_DRV_AT91SAM9 | 840 | config RTC_DRV_AT91SAM9 |
776 | tristate "AT91SAM9x/AT91CAP9" | 841 | tristate "AT91SAM9x/AT91CAP9 RTT as RTC" |
777 | depends on ARCH_AT91 && !(ARCH_AT91RM9200 || ARCH_AT91X40) | 842 | depends on ARCH_AT91 && !(ARCH_AT91RM9200 || ARCH_AT91X40) |
778 | help | 843 | help |
779 | RTC driver for the Atmel AT91SAM9x and AT91CAP9 internal RTT | 844 | RTC driver for the Atmel AT91SAM9x and AT91CAP9 internal RTT |
@@ -781,8 +846,8 @@ config RTC_DRV_AT91SAM9 | |||
781 | supply (such as a small coin cell battery), but do not need to | 846 | supply (such as a small coin cell battery), but do not need to |
782 | be used as RTCs. | 847 | be used as RTCs. |
783 | 848 | ||
784 | (On AT91SAM9rl chips you probably want to use the dedicated RTC | 849 | (On AT91SAM9rl and AT91SAM9G45 chips you probably want to use the |
785 | module and leave the RTT available for other uses.) | 850 | dedicated RTC module and leave the RTT available for other uses.) |
786 | 851 | ||
787 | config RTC_DRV_AT91SAM9_RTT | 852 | config RTC_DRV_AT91SAM9_RTT |
788 | int | 853 | int |
@@ -854,6 +919,13 @@ config RTC_DRV_PXA | |||
854 | This RTC driver uses PXA RTC registers available since pxa27x | 919 | This RTC driver uses PXA RTC registers available since pxa27x |
855 | series (RDxR, RYxR) instead of legacy RCNR, RTAR. | 920 | series (RDxR, RYxR) instead of legacy RCNR, RTAR. |
856 | 921 | ||
922 | config RTC_DRV_VT8500 | ||
923 | tristate "VIA/WonderMedia 85xx SoC RTC" | ||
924 | depends on ARCH_VT8500 | ||
925 | help | ||
926 | If you say Y here you will get access to the real time clock | ||
927 | built into your VIA VT8500 SoC or its relatives. | ||
928 | |||
857 | 929 | ||
858 | config RTC_DRV_SUN4V | 930 | config RTC_DRV_SUN4V |
859 | bool "SUN4V Hypervisor RTC" | 931 | bool "SUN4V Hypervisor RTC" |
@@ -925,11 +997,12 @@ config RTC_DRV_PCAP | |||
925 | If you say Y here you will get support for the RTC found on | 997 | If you say Y here you will get support for the RTC found on |
926 | the PCAP2 ASIC used on some Motorola phones. | 998 | the PCAP2 ASIC used on some Motorola phones. |
927 | 999 | ||
928 | config RTC_DRV_MC13783 | 1000 | config RTC_DRV_MC13XXX |
929 | depends on MFD_MC13783 | 1001 | depends on MFD_MC13XXX |
930 | tristate "Freescale MC13783 RTC" | 1002 | tristate "Freescale MC13xxx RTC" |
931 | help | 1003 | help |
932 | This enables support for the Freescale MC13783 PMIC RTC | 1004 | This enables support for the RTCs found on Freescale's PMICs |
1005 | MC13783 and MC13892. | ||
933 | 1006 | ||
934 | config RTC_DRV_MPC5121 | 1007 | config RTC_DRV_MPC5121 |
935 | tristate "Freescale MPC5121 built-in RTC" | 1008 | tristate "Freescale MPC5121 built-in RTC" |
@@ -952,4 +1025,39 @@ config RTC_DRV_JZ4740 | |||
952 | This driver can also be buillt as a module. If so, the module | 1025 | This driver can also be buillt as a module. If so, the module |
953 | will be called rtc-jz4740. | 1026 | will be called rtc-jz4740. |
954 | 1027 | ||
1028 | config RTC_DRV_LPC32XX | ||
1029 | depends on ARCH_LPC32XX | ||
1030 | tristate "NXP LPC32XX RTC" | ||
1031 | help | ||
1032 | This enables support for the NXP RTC in the LPC32XX | ||
1033 | |||
1034 | This driver can also be buillt as a module. If so, the module | ||
1035 | will be called rtc-lpc32xx. | ||
1036 | |||
1037 | config RTC_DRV_TEGRA | ||
1038 | tristate "NVIDIA Tegra Internal RTC driver" | ||
1039 | depends on RTC_CLASS && ARCH_TEGRA | ||
1040 | help | ||
1041 | If you say yes here you get support for the | ||
1042 | Tegra 200 series internal RTC module. | ||
1043 | |||
1044 | This drive can also be built as a module. If so, the module | ||
1045 | will be called rtc-tegra. | ||
1046 | |||
1047 | config RTC_DRV_TILE | ||
1048 | tristate "Tilera hypervisor RTC support" | ||
1049 | depends on TILE | ||
1050 | help | ||
1051 | Enable support for the Linux driver side of the Tilera | ||
1052 | hypervisor's real-time clock interface. | ||
1053 | |||
1054 | config RTC_DRV_PUV3 | ||
1055 | tristate "PKUnity v3 RTC support" | ||
1056 | depends on ARCH_PUV3 | ||
1057 | help | ||
1058 | This enables support for the RTC in the PKUnity-v3 SoCs. | ||
1059 | |||
1060 | This drive can also be built as a module. If so, the module | ||
1061 | will be called rtc-puv3. | ||
1062 | |||
955 | endif # RTC_CLASS | 1063 | endif # RTC_CLASS |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 0f207b3b5833..0ffefe877bfa 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -2,9 +2,7 @@ | |||
2 | # Makefile for RTC class/drivers. | 2 | # Makefile for RTC class/drivers. |
3 | # | 3 | # |
4 | 4 | ||
5 | ifeq ($(CONFIG_RTC_DEBUG),y) | 5 | ccflags-$(CONFIG_RTC_DEBUG) := -DDEBUG |
6 | EXTRA_CFLAGS += -DDEBUG | ||
7 | endif | ||
8 | 6 | ||
9 | obj-$(CONFIG_RTC_LIB) += rtc-lib.o | 7 | obj-$(CONFIG_RTC_LIB) += rtc-lib.o |
10 | obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o | 8 | obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o |
@@ -17,6 +15,7 @@ rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o | |||
17 | 15 | ||
18 | # Keep the list ordered. | 16 | # Keep the list ordered. |
19 | 17 | ||
18 | obj-$(CONFIG_RTC_DRV_88PM860X) += rtc-88pm860x.o | ||
20 | obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o | 19 | obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o |
21 | obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o | 20 | obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o |
22 | obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o | 21 | obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o |
@@ -30,6 +29,7 @@ obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o | |||
30 | obj-$(CONFIG_RTC_DRV_COH901331) += rtc-coh901331.o | 29 | obj-$(CONFIG_RTC_DRV_COH901331) += rtc-coh901331.o |
31 | obj-$(CONFIG_RTC_DRV_DAVINCI) += rtc-davinci.o | 30 | obj-$(CONFIG_RTC_DRV_DAVINCI) += rtc-davinci.o |
32 | obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o | 31 | obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o |
32 | obj-$(CONFIG_RTC_DRV_VRTC) += rtc-mrst.o | ||
33 | obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o | 33 | obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o |
34 | obj-$(CONFIG_RTC_DRV_DS1286) += rtc-ds1286.o | 34 | obj-$(CONFIG_RTC_DRV_DS1286) += rtc-ds1286.o |
35 | obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o | 35 | obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o |
@@ -44,6 +44,7 @@ obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o | |||
44 | obj-$(CONFIG_RTC_DRV_DS3232) += rtc-ds3232.o | 44 | obj-$(CONFIG_RTC_DRV_DS3232) += rtc-ds3232.o |
45 | obj-$(CONFIG_RTC_DRV_DS3234) += rtc-ds3234.o | 45 | obj-$(CONFIG_RTC_DRV_DS3234) += rtc-ds3234.o |
46 | obj-$(CONFIG_RTC_DRV_EFI) += rtc-efi.o | 46 | obj-$(CONFIG_RTC_DRV_EFI) += rtc-efi.o |
47 | obj-$(CONFIG_RTC_DRV_EM3027) += rtc-em3027.o | ||
47 | obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o | 48 | obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o |
48 | obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o | 49 | obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o |
49 | obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o | 50 | obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o |
@@ -51,7 +52,9 @@ obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.o | |||
51 | obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o | 52 | obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o |
52 | obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o | 53 | obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o |
53 | obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o | 54 | obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o |
55 | obj-$(CONFIG_RTC_DRV_LPC32XX) += rtc-lpc32xx.o | ||
54 | obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o | 56 | obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o |
57 | obj-$(CONFIG_RTC_DRV_M41T93) += rtc-m41t93.o | ||
55 | obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o | 58 | obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o |
56 | obj-$(CONFIG_RTC_DRV_M48T35) += rtc-m48t35.o | 59 | obj-$(CONFIG_RTC_DRV_M48T35) += rtc-m48t35.o |
57 | obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o | 60 | obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o |
@@ -59,8 +62,9 @@ obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o | |||
59 | obj-$(CONFIG_RTC_MXC) += rtc-mxc.o | 62 | obj-$(CONFIG_RTC_MXC) += rtc-mxc.o |
60 | obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o | 63 | obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o |
61 | obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o | 64 | obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o |
65 | obj-$(CONFIG_RTC_DRV_MAX8998) += rtc-max8998.o | ||
62 | obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o | 66 | obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o |
63 | obj-$(CONFIG_RTC_DRV_MC13783) += rtc-mc13783.o | 67 | obj-$(CONFIG_RTC_DRV_MC13XXX) += rtc-mc13xxx.o |
64 | obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o | 68 | obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o |
65 | obj-$(CONFIG_RTC_DRV_MPC5121) += rtc-mpc5121.o | 69 | obj-$(CONFIG_RTC_DRV_MPC5121) += rtc-mpc5121.o |
66 | obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o | 70 | obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o |
@@ -74,27 +78,33 @@ obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o | |||
74 | obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o | 78 | obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o |
75 | obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o | 79 | obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o |
76 | obj-$(CONFIG_RTC_DRV_PS3) += rtc-ps3.o | 80 | obj-$(CONFIG_RTC_DRV_PS3) += rtc-ps3.o |
81 | obj-$(CONFIG_RTC_DRV_PUV3) += rtc-puv3.o | ||
77 | obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o | 82 | obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o |
78 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o | 83 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o |
79 | obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c01.o | 84 | obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c01.o |
80 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o | 85 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o |
81 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o | 86 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o |
82 | obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o | 87 | obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o |
88 | obj-$(CONFIG_RTC_DRV_RV3029C2) += rtc-rv3029c2.o | ||
83 | obj-$(CONFIG_RTC_DRV_RX8025) += rtc-rx8025.o | 89 | obj-$(CONFIG_RTC_DRV_RX8025) += rtc-rx8025.o |
84 | obj-$(CONFIG_RTC_DRV_RX8581) += rtc-rx8581.o | 90 | obj-$(CONFIG_RTC_DRV_RX8581) += rtc-rx8581.o |
85 | obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o | 91 | obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o |
86 | obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o | 92 | obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o |
87 | obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o | 93 | obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o |
88 | obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o | 94 | obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o |
95 | obj-$(CONFIG_RTC_DRV_SPEAR) += rtc-spear.o | ||
89 | obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o | 96 | obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o |
90 | obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o | 97 | obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o |
91 | obj-$(CONFIG_RTC_DRV_STMP) += rtc-stmp3xxx.o | 98 | obj-$(CONFIG_RTC_DRV_STMP) += rtc-stmp3xxx.o |
92 | obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o | 99 | obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o |
100 | obj-$(CONFIG_RTC_DRV_TEGRA) += rtc-tegra.o | ||
93 | obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o | 101 | obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o |
102 | obj-$(CONFIG_RTC_DRV_TILE) += rtc-tile.o | ||
94 | obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o | 103 | obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o |
95 | obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o | 104 | obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o |
96 | obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o | 105 | obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o |
97 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o | 106 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o |
107 | obj-$(CONFIG_RTC_DRV_VT8500) += rtc-vt8500.o | ||
98 | obj-$(CONFIG_RTC_DRV_WM831X) += rtc-wm831x.o | 108 | obj-$(CONFIG_RTC_DRV_WM831X) += rtc-wm831x.o |
99 | obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o | 109 | obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o |
100 | obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o | 110 | obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o |
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 565562ba6ac9..4194e59e14cd 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/kdev_t.h> | 16 | #include <linux/kdev_t.h> |
17 | #include <linux/idr.h> | 17 | #include <linux/idr.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/workqueue.h> | ||
19 | 20 | ||
20 | #include "rtc-core.h" | 21 | #include "rtc-core.h" |
21 | 22 | ||
@@ -40,26 +41,21 @@ static void rtc_device_release(struct device *dev) | |||
40 | * system's wall clock; restore it on resume(). | 41 | * system's wall clock; restore it on resume(). |
41 | */ | 42 | */ |
42 | 43 | ||
43 | static struct timespec delta; | ||
44 | static time_t oldtime; | 44 | static time_t oldtime; |
45 | static struct timespec oldts; | ||
45 | 46 | ||
46 | static int rtc_suspend(struct device *dev, pm_message_t mesg) | 47 | static int rtc_suspend(struct device *dev, pm_message_t mesg) |
47 | { | 48 | { |
48 | struct rtc_device *rtc = to_rtc_device(dev); | 49 | struct rtc_device *rtc = to_rtc_device(dev); |
49 | struct rtc_time tm; | 50 | struct rtc_time tm; |
50 | struct timespec ts = current_kernel_time(); | ||
51 | 51 | ||
52 | if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) | 52 | if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) |
53 | return 0; | 53 | return 0; |
54 | 54 | ||
55 | rtc_read_time(rtc, &tm); | 55 | rtc_read_time(rtc, &tm); |
56 | ktime_get_ts(&oldts); | ||
56 | rtc_tm_to_time(&tm, &oldtime); | 57 | rtc_tm_to_time(&tm, &oldtime); |
57 | 58 | ||
58 | /* RTC precision is 1 second; adjust delta for avg 1/2 sec err */ | ||
59 | set_normalized_timespec(&delta, | ||
60 | ts.tv_sec - oldtime, | ||
61 | ts.tv_nsec - (NSEC_PER_SEC >> 1)); | ||
62 | |||
63 | return 0; | 59 | return 0; |
64 | } | 60 | } |
65 | 61 | ||
@@ -69,10 +65,12 @@ static int rtc_resume(struct device *dev) | |||
69 | struct rtc_time tm; | 65 | struct rtc_time tm; |
70 | time_t newtime; | 66 | time_t newtime; |
71 | struct timespec time; | 67 | struct timespec time; |
68 | struct timespec newts; | ||
72 | 69 | ||
73 | if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) | 70 | if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) |
74 | return 0; | 71 | return 0; |
75 | 72 | ||
73 | ktime_get_ts(&newts); | ||
76 | rtc_read_time(rtc, &tm); | 74 | rtc_read_time(rtc, &tm); |
77 | if (rtc_valid_tm(&tm) != 0) { | 75 | if (rtc_valid_tm(&tm) != 0) { |
78 | pr_debug("%s: bogus resume time\n", dev_name(&rtc->dev)); | 76 | pr_debug("%s: bogus resume time\n", dev_name(&rtc->dev)); |
@@ -84,15 +82,13 @@ static int rtc_resume(struct device *dev) | |||
84 | pr_debug("%s: time travel!\n", dev_name(&rtc->dev)); | 82 | pr_debug("%s: time travel!\n", dev_name(&rtc->dev)); |
85 | return 0; | 83 | return 0; |
86 | } | 84 | } |
85 | /* calculate the RTC time delta */ | ||
86 | set_normalized_timespec(&time, newtime - oldtime, 0); | ||
87 | 87 | ||
88 | /* restore wall clock using delta against this RTC; | 88 | /* subtract kernel time between rtc_suspend to rtc_resume */ |
89 | * adjust again for avg 1/2 second RTC sampling error | 89 | time = timespec_sub(time, timespec_sub(newts, oldts)); |
90 | */ | ||
91 | set_normalized_timespec(&time, | ||
92 | newtime + delta.tv_sec, | ||
93 | (NSEC_PER_SEC >> 1) + delta.tv_nsec); | ||
94 | do_settimeofday(&time); | ||
95 | 90 | ||
91 | timekeeping_inject_sleeptime(&time); | ||
96 | return 0; | 92 | return 0; |
97 | } | 93 | } |
98 | 94 | ||
@@ -116,6 +112,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, | |||
116 | struct module *owner) | 112 | struct module *owner) |
117 | { | 113 | { |
118 | struct rtc_device *rtc; | 114 | struct rtc_device *rtc; |
115 | struct rtc_wkalrm alrm; | ||
119 | int id, err; | 116 | int id, err; |
120 | 117 | ||
121 | if (idr_pre_get(&rtc_idr, GFP_KERNEL) == 0) { | 118 | if (idr_pre_get(&rtc_idr, GFP_KERNEL) == 0) { |
@@ -142,6 +139,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, | |||
142 | rtc->id = id; | 139 | rtc->id = id; |
143 | rtc->ops = ops; | 140 | rtc->ops = ops; |
144 | rtc->owner = owner; | 141 | rtc->owner = owner; |
142 | rtc->irq_freq = 1; | ||
145 | rtc->max_user_freq = 64; | 143 | rtc->max_user_freq = 64; |
146 | rtc->dev.parent = dev; | 144 | rtc->dev.parent = dev; |
147 | rtc->dev.class = rtc_class; | 145 | rtc->dev.class = rtc_class; |
@@ -152,14 +150,34 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, | |||
152 | spin_lock_init(&rtc->irq_task_lock); | 150 | spin_lock_init(&rtc->irq_task_lock); |
153 | init_waitqueue_head(&rtc->irq_queue); | 151 | init_waitqueue_head(&rtc->irq_queue); |
154 | 152 | ||
153 | /* Init timerqueue */ | ||
154 | timerqueue_init_head(&rtc->timerqueue); | ||
155 | INIT_WORK(&rtc->irqwork, rtc_timer_do_work); | ||
156 | /* Init aie timer */ | ||
157 | rtc_timer_init(&rtc->aie_timer, rtc_aie_update_irq, (void *)rtc); | ||
158 | /* Init uie timer */ | ||
159 | rtc_timer_init(&rtc->uie_rtctimer, rtc_uie_update_irq, (void *)rtc); | ||
160 | /* Init pie timer */ | ||
161 | hrtimer_init(&rtc->pie_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
162 | rtc->pie_timer.function = rtc_pie_update_irq; | ||
163 | rtc->pie_enabled = 0; | ||
164 | |||
165 | /* Check to see if there is an ALARM already set in hw */ | ||
166 | err = __rtc_read_alarm(rtc, &alrm); | ||
167 | |||
168 | if (!err && !rtc_valid_tm(&alrm.time)) | ||
169 | rtc_initialize_alarm(rtc, &alrm); | ||
170 | |||
155 | strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); | 171 | strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); |
156 | dev_set_name(&rtc->dev, "rtc%d", id); | 172 | dev_set_name(&rtc->dev, "rtc%d", id); |
157 | 173 | ||
158 | rtc_dev_prepare(rtc); | 174 | rtc_dev_prepare(rtc); |
159 | 175 | ||
160 | err = device_register(&rtc->dev); | 176 | err = device_register(&rtc->dev); |
161 | if (err) | 177 | if (err) { |
178 | put_device(&rtc->dev); | ||
162 | goto exit_kfree; | 179 | goto exit_kfree; |
180 | } | ||
163 | 181 | ||
164 | rtc_dev_add_device(rtc); | 182 | rtc_dev_add_device(rtc); |
165 | rtc_sysfs_add_device(rtc); | 183 | rtc_sysfs_add_device(rtc); |
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index a0c816238aa9..df68618f6dbb 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
@@ -14,15 +14,14 @@ | |||
14 | #include <linux/rtc.h> | 14 | #include <linux/rtc.h> |
15 | #include <linux/sched.h> | 15 | #include <linux/sched.h> |
16 | #include <linux/log2.h> | 16 | #include <linux/log2.h> |
17 | #include <linux/workqueue.h> | ||
17 | 18 | ||
18 | int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) | 19 | static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer); |
20 | static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer); | ||
21 | |||
22 | static int __rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) | ||
19 | { | 23 | { |
20 | int err; | 24 | int err; |
21 | |||
22 | err = mutex_lock_interruptible(&rtc->ops_lock); | ||
23 | if (err) | ||
24 | return err; | ||
25 | |||
26 | if (!rtc->ops) | 25 | if (!rtc->ops) |
27 | err = -ENODEV; | 26 | err = -ENODEV; |
28 | else if (!rtc->ops->read_time) | 27 | else if (!rtc->ops->read_time) |
@@ -31,7 +30,18 @@ int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) | |||
31 | memset(tm, 0, sizeof(struct rtc_time)); | 30 | memset(tm, 0, sizeof(struct rtc_time)); |
32 | err = rtc->ops->read_time(rtc->dev.parent, tm); | 31 | err = rtc->ops->read_time(rtc->dev.parent, tm); |
33 | } | 32 | } |
33 | return err; | ||
34 | } | ||
35 | |||
36 | int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) | ||
37 | { | ||
38 | int err; | ||
34 | 39 | ||
40 | err = mutex_lock_interruptible(&rtc->ops_lock); | ||
41 | if (err) | ||
42 | return err; | ||
43 | |||
44 | err = __rtc_read_time(rtc, tm); | ||
35 | mutex_unlock(&rtc->ops_lock); | 45 | mutex_unlock(&rtc->ops_lock); |
36 | return err; | 46 | return err; |
37 | } | 47 | } |
@@ -127,7 +137,7 @@ static int rtc_read_alarm_internal(struct rtc_device *rtc, struct rtc_wkalrm *al | |||
127 | return err; | 137 | return err; |
128 | } | 138 | } |
129 | 139 | ||
130 | int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | 140 | int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) |
131 | { | 141 | { |
132 | int err; | 142 | int err; |
133 | struct rtc_time before, now; | 143 | struct rtc_time before, now; |
@@ -190,8 +200,6 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | |||
190 | err = rtc_read_alarm_internal(rtc, alarm); | 200 | err = rtc_read_alarm_internal(rtc, alarm); |
191 | if (err) | 201 | if (err) |
192 | return err; | 202 | return err; |
193 | if (!alarm->enabled) | ||
194 | return 0; | ||
195 | 203 | ||
196 | /* full-function RTCs won't have such missing fields */ | 204 | /* full-function RTCs won't have such missing fields */ |
197 | if (rtc_valid_tm(&alarm->time) == 0) | 205 | if (rtc_valid_tm(&alarm->time) == 0) |
@@ -287,19 +295,51 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | |||
287 | done: | 295 | done: |
288 | return 0; | 296 | return 0; |
289 | } | 297 | } |
290 | EXPORT_SYMBOL_GPL(rtc_read_alarm); | ||
291 | 298 | ||
292 | int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | 299 | int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) |
293 | { | 300 | { |
294 | int err; | 301 | int err; |
295 | 302 | ||
296 | err = rtc_valid_tm(&alarm->time); | 303 | err = mutex_lock_interruptible(&rtc->ops_lock); |
297 | if (err != 0) | 304 | if (err) |
298 | return err; | 305 | return err; |
306 | if (rtc->ops == NULL) | ||
307 | err = -ENODEV; | ||
308 | else if (!rtc->ops->read_alarm) | ||
309 | err = -EINVAL; | ||
310 | else { | ||
311 | memset(alarm, 0, sizeof(struct rtc_wkalrm)); | ||
312 | alarm->enabled = rtc->aie_timer.enabled; | ||
313 | alarm->time = rtc_ktime_to_tm(rtc->aie_timer.node.expires); | ||
314 | } | ||
315 | mutex_unlock(&rtc->ops_lock); | ||
299 | 316 | ||
300 | err = mutex_lock_interruptible(&rtc->ops_lock); | 317 | return err; |
318 | } | ||
319 | EXPORT_SYMBOL_GPL(rtc_read_alarm); | ||
320 | |||
321 | static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | ||
322 | { | ||
323 | struct rtc_time tm; | ||
324 | long now, scheduled; | ||
325 | int err; | ||
326 | |||
327 | err = rtc_valid_tm(&alarm->time); | ||
301 | if (err) | 328 | if (err) |
302 | return err; | 329 | return err; |
330 | rtc_tm_to_time(&alarm->time, &scheduled); | ||
331 | |||
332 | /* Make sure we're not setting alarms in the past */ | ||
333 | err = __rtc_read_time(rtc, &tm); | ||
334 | rtc_tm_to_time(&tm, &now); | ||
335 | if (scheduled <= now) | ||
336 | return -ETIME; | ||
337 | /* | ||
338 | * XXX - We just checked to make sure the alarm time is not | ||
339 | * in the past, but there is still a race window where if | ||
340 | * the is alarm set for the next second and the second ticks | ||
341 | * over right here, before we set the alarm. | ||
342 | */ | ||
303 | 343 | ||
304 | if (!rtc->ops) | 344 | if (!rtc->ops) |
305 | err = -ENODEV; | 345 | err = -ENODEV; |
@@ -308,18 +348,75 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | |||
308 | else | 348 | else |
309 | err = rtc->ops->set_alarm(rtc->dev.parent, alarm); | 349 | err = rtc->ops->set_alarm(rtc->dev.parent, alarm); |
310 | 350 | ||
351 | return err; | ||
352 | } | ||
353 | |||
354 | int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | ||
355 | { | ||
356 | int err; | ||
357 | |||
358 | err = rtc_valid_tm(&alarm->time); | ||
359 | if (err != 0) | ||
360 | return err; | ||
361 | |||
362 | err = mutex_lock_interruptible(&rtc->ops_lock); | ||
363 | if (err) | ||
364 | return err; | ||
365 | if (rtc->aie_timer.enabled) { | ||
366 | rtc_timer_remove(rtc, &rtc->aie_timer); | ||
367 | } | ||
368 | rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time); | ||
369 | rtc->aie_timer.period = ktime_set(0, 0); | ||
370 | if (alarm->enabled) { | ||
371 | err = rtc_timer_enqueue(rtc, &rtc->aie_timer); | ||
372 | } | ||
311 | mutex_unlock(&rtc->ops_lock); | 373 | mutex_unlock(&rtc->ops_lock); |
312 | return err; | 374 | return err; |
313 | } | 375 | } |
314 | EXPORT_SYMBOL_GPL(rtc_set_alarm); | 376 | EXPORT_SYMBOL_GPL(rtc_set_alarm); |
315 | 377 | ||
378 | /* Called once per device from rtc_device_register */ | ||
379 | int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | ||
380 | { | ||
381 | int err; | ||
382 | |||
383 | err = rtc_valid_tm(&alarm->time); | ||
384 | if (err != 0) | ||
385 | return err; | ||
386 | |||
387 | err = mutex_lock_interruptible(&rtc->ops_lock); | ||
388 | if (err) | ||
389 | return err; | ||
390 | |||
391 | rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time); | ||
392 | rtc->aie_timer.period = ktime_set(0, 0); | ||
393 | if (alarm->enabled) { | ||
394 | rtc->aie_timer.enabled = 1; | ||
395 | timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node); | ||
396 | } | ||
397 | mutex_unlock(&rtc->ops_lock); | ||
398 | return err; | ||
399 | } | ||
400 | EXPORT_SYMBOL_GPL(rtc_initialize_alarm); | ||
401 | |||
402 | |||
403 | |||
316 | int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled) | 404 | int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled) |
317 | { | 405 | { |
318 | int err = mutex_lock_interruptible(&rtc->ops_lock); | 406 | int err = mutex_lock_interruptible(&rtc->ops_lock); |
319 | if (err) | 407 | if (err) |
320 | return err; | 408 | return err; |
321 | 409 | ||
322 | if (!rtc->ops) | 410 | if (rtc->aie_timer.enabled != enabled) { |
411 | if (enabled) | ||
412 | err = rtc_timer_enqueue(rtc, &rtc->aie_timer); | ||
413 | else | ||
414 | rtc_timer_remove(rtc, &rtc->aie_timer); | ||
415 | } | ||
416 | |||
417 | if (err) | ||
418 | /* nothing */; | ||
419 | else if (!rtc->ops) | ||
323 | err = -ENODEV; | 420 | err = -ENODEV; |
324 | else if (!rtc->ops->alarm_irq_enable) | 421 | else if (!rtc->ops->alarm_irq_enable) |
325 | err = -EINVAL; | 422 | err = -EINVAL; |
@@ -340,19 +437,28 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) | |||
340 | #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL | 437 | #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL |
341 | if (enabled == 0 && rtc->uie_irq_active) { | 438 | if (enabled == 0 && rtc->uie_irq_active) { |
342 | mutex_unlock(&rtc->ops_lock); | 439 | mutex_unlock(&rtc->ops_lock); |
343 | return rtc_dev_update_irq_enable_emul(rtc, enabled); | 440 | return rtc_dev_update_irq_enable_emul(rtc, 0); |
344 | } | 441 | } |
345 | #endif | 442 | #endif |
443 | /* make sure we're changing state */ | ||
444 | if (rtc->uie_rtctimer.enabled == enabled) | ||
445 | goto out; | ||
446 | |||
447 | if (enabled) { | ||
448 | struct rtc_time tm; | ||
449 | ktime_t now, onesec; | ||
450 | |||
451 | __rtc_read_time(rtc, &tm); | ||
452 | onesec = ktime_set(1, 0); | ||
453 | now = rtc_tm_to_ktime(tm); | ||
454 | rtc->uie_rtctimer.node.expires = ktime_add(now, onesec); | ||
455 | rtc->uie_rtctimer.period = ktime_set(1, 0); | ||
456 | err = rtc_timer_enqueue(rtc, &rtc->uie_rtctimer); | ||
457 | } else | ||
458 | rtc_timer_remove(rtc, &rtc->uie_rtctimer); | ||
346 | 459 | ||
347 | if (!rtc->ops) | 460 | out: |
348 | err = -ENODEV; | ||
349 | else if (!rtc->ops->update_irq_enable) | ||
350 | err = -EINVAL; | ||
351 | else | ||
352 | err = rtc->ops->update_irq_enable(rtc->dev.parent, enabled); | ||
353 | |||
354 | mutex_unlock(&rtc->ops_lock); | 461 | mutex_unlock(&rtc->ops_lock); |
355 | |||
356 | #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL | 462 | #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL |
357 | /* | 463 | /* |
358 | * Enable emulation if the driver did not provide | 464 | * Enable emulation if the driver did not provide |
@@ -364,25 +470,30 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) | |||
364 | err = rtc_dev_update_irq_enable_emul(rtc, enabled); | 470 | err = rtc_dev_update_irq_enable_emul(rtc, enabled); |
365 | #endif | 471 | #endif |
366 | return err; | 472 | return err; |
473 | |||
367 | } | 474 | } |
368 | EXPORT_SYMBOL_GPL(rtc_update_irq_enable); | 475 | EXPORT_SYMBOL_GPL(rtc_update_irq_enable); |
369 | 476 | ||
477 | |||
370 | /** | 478 | /** |
371 | * rtc_update_irq - report RTC periodic, alarm, and/or update irqs | 479 | * rtc_handle_legacy_irq - AIE, UIE and PIE event hook |
372 | * @rtc: the rtc device | 480 | * @rtc: pointer to the rtc device |
373 | * @num: how many irqs are being reported (usually one) | 481 | * |
374 | * @events: mask of RTC_IRQF with one or more of RTC_PF, RTC_AF, RTC_UF | 482 | * This function is called when an AIE, UIE or PIE mode interrupt |
375 | * Context: any | 483 | * has occurred (or been emulated). |
484 | * | ||
485 | * Triggers the registered irq_task function callback. | ||
376 | */ | 486 | */ |
377 | void rtc_update_irq(struct rtc_device *rtc, | 487 | void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode) |
378 | unsigned long num, unsigned long events) | ||
379 | { | 488 | { |
380 | unsigned long flags; | 489 | unsigned long flags; |
381 | 490 | ||
491 | /* mark one irq of the appropriate mode */ | ||
382 | spin_lock_irqsave(&rtc->irq_lock, flags); | 492 | spin_lock_irqsave(&rtc->irq_lock, flags); |
383 | rtc->irq_data = (rtc->irq_data + (num << 8)) | events; | 493 | rtc->irq_data = (rtc->irq_data + (num << 8)) | (RTC_IRQF|mode); |
384 | spin_unlock_irqrestore(&rtc->irq_lock, flags); | 494 | spin_unlock_irqrestore(&rtc->irq_lock, flags); |
385 | 495 | ||
496 | /* call the task func */ | ||
386 | spin_lock_irqsave(&rtc->irq_task_lock, flags); | 497 | spin_lock_irqsave(&rtc->irq_task_lock, flags); |
387 | if (rtc->irq_task) | 498 | if (rtc->irq_task) |
388 | rtc->irq_task->func(rtc->irq_task->private_data); | 499 | rtc->irq_task->func(rtc->irq_task->private_data); |
@@ -391,6 +502,69 @@ void rtc_update_irq(struct rtc_device *rtc, | |||
391 | wake_up_interruptible(&rtc->irq_queue); | 502 | wake_up_interruptible(&rtc->irq_queue); |
392 | kill_fasync(&rtc->async_queue, SIGIO, POLL_IN); | 503 | kill_fasync(&rtc->async_queue, SIGIO, POLL_IN); |
393 | } | 504 | } |
505 | |||
506 | |||
507 | /** | ||
508 | * rtc_aie_update_irq - AIE mode rtctimer hook | ||
509 | * @private: pointer to the rtc_device | ||
510 | * | ||
511 | * This functions is called when the aie_timer expires. | ||
512 | */ | ||
513 | void rtc_aie_update_irq(void *private) | ||
514 | { | ||
515 | struct rtc_device *rtc = (struct rtc_device *)private; | ||
516 | rtc_handle_legacy_irq(rtc, 1, RTC_AF); | ||
517 | } | ||
518 | |||
519 | |||
520 | /** | ||
521 | * rtc_uie_update_irq - UIE mode rtctimer hook | ||
522 | * @private: pointer to the rtc_device | ||
523 | * | ||
524 | * This functions is called when the uie_timer expires. | ||
525 | */ | ||
526 | void rtc_uie_update_irq(void *private) | ||
527 | { | ||
528 | struct rtc_device *rtc = (struct rtc_device *)private; | ||
529 | rtc_handle_legacy_irq(rtc, 1, RTC_UF); | ||
530 | } | ||
531 | |||
532 | |||
533 | /** | ||
534 | * rtc_pie_update_irq - PIE mode hrtimer hook | ||
535 | * @timer: pointer to the pie mode hrtimer | ||
536 | * | ||
537 | * This function is used to emulate PIE mode interrupts | ||
538 | * using an hrtimer. This function is called when the periodic | ||
539 | * hrtimer expires. | ||
540 | */ | ||
541 | enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer) | ||
542 | { | ||
543 | struct rtc_device *rtc; | ||
544 | ktime_t period; | ||
545 | int count; | ||
546 | rtc = container_of(timer, struct rtc_device, pie_timer); | ||
547 | |||
548 | period = ktime_set(0, NSEC_PER_SEC/rtc->irq_freq); | ||
549 | count = hrtimer_forward_now(timer, period); | ||
550 | |||
551 | rtc_handle_legacy_irq(rtc, count, RTC_PF); | ||
552 | |||
553 | return HRTIMER_RESTART; | ||
554 | } | ||
555 | |||
556 | /** | ||
557 | * rtc_update_irq - Triggered when a RTC interrupt occurs. | ||
558 | * @rtc: the rtc device | ||
559 | * @num: how many irqs are being reported (usually one) | ||
560 | * @events: mask of RTC_IRQF with one or more of RTC_PF, RTC_AF, RTC_UF | ||
561 | * Context: any | ||
562 | */ | ||
563 | void rtc_update_irq(struct rtc_device *rtc, | ||
564 | unsigned long num, unsigned long events) | ||
565 | { | ||
566 | schedule_work(&rtc->irqwork); | ||
567 | } | ||
394 | EXPORT_SYMBOL_GPL(rtc_update_irq); | 568 | EXPORT_SYMBOL_GPL(rtc_update_irq); |
395 | 569 | ||
396 | static int __rtc_match(struct device *dev, void *data) | 570 | static int __rtc_match(struct device *dev, void *data) |
@@ -477,18 +651,20 @@ int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled | |||
477 | int err = 0; | 651 | int err = 0; |
478 | unsigned long flags; | 652 | unsigned long flags; |
479 | 653 | ||
480 | if (rtc->ops->irq_set_state == NULL) | ||
481 | return -ENXIO; | ||
482 | |||
483 | spin_lock_irqsave(&rtc->irq_task_lock, flags); | 654 | spin_lock_irqsave(&rtc->irq_task_lock, flags); |
484 | if (rtc->irq_task != NULL && task == NULL) | 655 | if (rtc->irq_task != NULL && task == NULL) |
485 | err = -EBUSY; | 656 | err = -EBUSY; |
486 | if (rtc->irq_task != task) | 657 | if (rtc->irq_task != task) |
487 | err = -EACCES; | 658 | err = -EACCES; |
488 | spin_unlock_irqrestore(&rtc->irq_task_lock, flags); | ||
489 | 659 | ||
490 | if (err == 0) | 660 | if (enabled) { |
491 | err = rtc->ops->irq_set_state(rtc->dev.parent, enabled); | 661 | ktime_t period = ktime_set(0, NSEC_PER_SEC/rtc->irq_freq); |
662 | hrtimer_start(&rtc->pie_timer, period, HRTIMER_MODE_REL); | ||
663 | } else { | ||
664 | hrtimer_cancel(&rtc->pie_timer); | ||
665 | } | ||
666 | rtc->pie_enabled = enabled; | ||
667 | spin_unlock_irqrestore(&rtc->irq_task_lock, flags); | ||
492 | 668 | ||
493 | return err; | 669 | return err; |
494 | } | 670 | } |
@@ -509,21 +685,206 @@ int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq) | |||
509 | int err = 0; | 685 | int err = 0; |
510 | unsigned long flags; | 686 | unsigned long flags; |
511 | 687 | ||
512 | if (rtc->ops->irq_set_freq == NULL) | 688 | if (freq <= 0) |
513 | return -ENXIO; | 689 | return -EINVAL; |
514 | 690 | ||
515 | spin_lock_irqsave(&rtc->irq_task_lock, flags); | 691 | spin_lock_irqsave(&rtc->irq_task_lock, flags); |
516 | if (rtc->irq_task != NULL && task == NULL) | 692 | if (rtc->irq_task != NULL && task == NULL) |
517 | err = -EBUSY; | 693 | err = -EBUSY; |
518 | if (rtc->irq_task != task) | 694 | if (rtc->irq_task != task) |
519 | err = -EACCES; | 695 | err = -EACCES; |
520 | spin_unlock_irqrestore(&rtc->irq_task_lock, flags); | ||
521 | |||
522 | if (err == 0) { | 696 | if (err == 0) { |
523 | err = rtc->ops->irq_set_freq(rtc->dev.parent, freq); | 697 | rtc->irq_freq = freq; |
524 | if (err == 0) | 698 | if (rtc->pie_enabled) { |
525 | rtc->irq_freq = freq; | 699 | ktime_t period; |
700 | hrtimer_cancel(&rtc->pie_timer); | ||
701 | period = ktime_set(0, NSEC_PER_SEC/rtc->irq_freq); | ||
702 | hrtimer_start(&rtc->pie_timer, period, | ||
703 | HRTIMER_MODE_REL); | ||
704 | } | ||
526 | } | 705 | } |
706 | spin_unlock_irqrestore(&rtc->irq_task_lock, flags); | ||
527 | return err; | 707 | return err; |
528 | } | 708 | } |
529 | EXPORT_SYMBOL_GPL(rtc_irq_set_freq); | 709 | EXPORT_SYMBOL_GPL(rtc_irq_set_freq); |
710 | |||
711 | /** | ||
712 | * rtc_timer_enqueue - Adds a rtc_timer to the rtc_device timerqueue | ||
713 | * @rtc rtc device | ||
714 | * @timer timer being added. | ||
715 | * | ||
716 | * Enqueues a timer onto the rtc devices timerqueue and sets | ||
717 | * the next alarm event appropriately. | ||
718 | * | ||
719 | * Sets the enabled bit on the added timer. | ||
720 | * | ||
721 | * Must hold ops_lock for proper serialization of timerqueue | ||
722 | */ | ||
723 | static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) | ||
724 | { | ||
725 | timer->enabled = 1; | ||
726 | timerqueue_add(&rtc->timerqueue, &timer->node); | ||
727 | if (&timer->node == timerqueue_getnext(&rtc->timerqueue)) { | ||
728 | struct rtc_wkalrm alarm; | ||
729 | int err; | ||
730 | alarm.time = rtc_ktime_to_tm(timer->node.expires); | ||
731 | alarm.enabled = 1; | ||
732 | err = __rtc_set_alarm(rtc, &alarm); | ||
733 | if (err == -ETIME) | ||
734 | schedule_work(&rtc->irqwork); | ||
735 | else if (err) { | ||
736 | timerqueue_del(&rtc->timerqueue, &timer->node); | ||
737 | timer->enabled = 0; | ||
738 | return err; | ||
739 | } | ||
740 | } | ||
741 | return 0; | ||
742 | } | ||
743 | |||
744 | /** | ||
745 | * rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue | ||
746 | * @rtc rtc device | ||
747 | * @timer timer being removed. | ||
748 | * | ||
749 | * Removes a timer onto the rtc devices timerqueue and sets | ||
750 | * the next alarm event appropriately. | ||
751 | * | ||
752 | * Clears the enabled bit on the removed timer. | ||
753 | * | ||
754 | * Must hold ops_lock for proper serialization of timerqueue | ||
755 | */ | ||
756 | static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer) | ||
757 | { | ||
758 | struct timerqueue_node *next = timerqueue_getnext(&rtc->timerqueue); | ||
759 | timerqueue_del(&rtc->timerqueue, &timer->node); | ||
760 | timer->enabled = 0; | ||
761 | if (next == &timer->node) { | ||
762 | struct rtc_wkalrm alarm; | ||
763 | int err; | ||
764 | next = timerqueue_getnext(&rtc->timerqueue); | ||
765 | if (!next) | ||
766 | return; | ||
767 | alarm.time = rtc_ktime_to_tm(next->expires); | ||
768 | alarm.enabled = 1; | ||
769 | err = __rtc_set_alarm(rtc, &alarm); | ||
770 | if (err == -ETIME) | ||
771 | schedule_work(&rtc->irqwork); | ||
772 | } | ||
773 | } | ||
774 | |||
775 | /** | ||
776 | * rtc_timer_do_work - Expires rtc timers | ||
777 | * @rtc rtc device | ||
778 | * @timer timer being removed. | ||
779 | * | ||
780 | * Expires rtc timers. Reprograms next alarm event if needed. | ||
781 | * Called via worktask. | ||
782 | * | ||
783 | * Serializes access to timerqueue via ops_lock mutex | ||
784 | */ | ||
785 | void rtc_timer_do_work(struct work_struct *work) | ||
786 | { | ||
787 | struct rtc_timer *timer; | ||
788 | struct timerqueue_node *next; | ||
789 | ktime_t now; | ||
790 | struct rtc_time tm; | ||
791 | |||
792 | struct rtc_device *rtc = | ||
793 | container_of(work, struct rtc_device, irqwork); | ||
794 | |||
795 | mutex_lock(&rtc->ops_lock); | ||
796 | again: | ||
797 | __rtc_read_time(rtc, &tm); | ||
798 | now = rtc_tm_to_ktime(tm); | ||
799 | while ((next = timerqueue_getnext(&rtc->timerqueue))) { | ||
800 | if (next->expires.tv64 > now.tv64) | ||
801 | break; | ||
802 | |||
803 | /* expire timer */ | ||
804 | timer = container_of(next, struct rtc_timer, node); | ||
805 | timerqueue_del(&rtc->timerqueue, &timer->node); | ||
806 | timer->enabled = 0; | ||
807 | if (timer->task.func) | ||
808 | timer->task.func(timer->task.private_data); | ||
809 | |||
810 | /* Re-add/fwd periodic timers */ | ||
811 | if (ktime_to_ns(timer->period)) { | ||
812 | timer->node.expires = ktime_add(timer->node.expires, | ||
813 | timer->period); | ||
814 | timer->enabled = 1; | ||
815 | timerqueue_add(&rtc->timerqueue, &timer->node); | ||
816 | } | ||
817 | } | ||
818 | |||
819 | /* Set next alarm */ | ||
820 | if (next) { | ||
821 | struct rtc_wkalrm alarm; | ||
822 | int err; | ||
823 | alarm.time = rtc_ktime_to_tm(next->expires); | ||
824 | alarm.enabled = 1; | ||
825 | err = __rtc_set_alarm(rtc, &alarm); | ||
826 | if (err == -ETIME) | ||
827 | goto again; | ||
828 | } | ||
829 | |||
830 | mutex_unlock(&rtc->ops_lock); | ||
831 | } | ||
832 | |||
833 | |||
834 | /* rtc_timer_init - Initializes an rtc_timer | ||
835 | * @timer: timer to be intiialized | ||
836 | * @f: function pointer to be called when timer fires | ||
837 | * @data: private data passed to function pointer | ||
838 | * | ||
839 | * Kernel interface to initializing an rtc_timer. | ||
840 | */ | ||
841 | void rtc_timer_init(struct rtc_timer *timer, void (*f)(void* p), void* data) | ||
842 | { | ||
843 | timerqueue_init(&timer->node); | ||
844 | timer->enabled = 0; | ||
845 | timer->task.func = f; | ||
846 | timer->task.private_data = data; | ||
847 | } | ||
848 | |||
849 | /* rtc_timer_start - Sets an rtc_timer to fire in the future | ||
850 | * @ rtc: rtc device to be used | ||
851 | * @ timer: timer being set | ||
852 | * @ expires: time at which to expire the timer | ||
853 | * @ period: period that the timer will recur | ||
854 | * | ||
855 | * Kernel interface to set an rtc_timer | ||
856 | */ | ||
857 | int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer* timer, | ||
858 | ktime_t expires, ktime_t period) | ||
859 | { | ||
860 | int ret = 0; | ||
861 | mutex_lock(&rtc->ops_lock); | ||
862 | if (timer->enabled) | ||
863 | rtc_timer_remove(rtc, timer); | ||
864 | |||
865 | timer->node.expires = expires; | ||
866 | timer->period = period; | ||
867 | |||
868 | ret = rtc_timer_enqueue(rtc, timer); | ||
869 | |||
870 | mutex_unlock(&rtc->ops_lock); | ||
871 | return ret; | ||
872 | } | ||
873 | |||
874 | /* rtc_timer_cancel - Stops an rtc_timer | ||
875 | * @ rtc: rtc device to be used | ||
876 | * @ timer: timer being set | ||
877 | * | ||
878 | * Kernel interface to cancel an rtc_timer | ||
879 | */ | ||
880 | int rtc_timer_cancel(struct rtc_device *rtc, struct rtc_timer* timer) | ||
881 | { | ||
882 | int ret = 0; | ||
883 | mutex_lock(&rtc->ops_lock); | ||
884 | if (timer->enabled) | ||
885 | rtc_timer_remove(rtc, timer); | ||
886 | mutex_unlock(&rtc->ops_lock); | ||
887 | return ret; | ||
888 | } | ||
889 | |||
890 | |||
diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c new file mode 100644 index 000000000000..64b847b7f970 --- /dev/null +++ b/drivers/rtc/rtc-88pm860x.c | |||
@@ -0,0 +1,427 @@ | |||
1 | /* | ||
2 | * Real Time Clock driver for Marvell 88PM860x PMIC | ||
3 | * | ||
4 | * Copyright (c) 2010 Marvell International Ltd. | ||
5 | * Author: Haojian Zhuang <haojian.zhuang@marvell.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/slab.h> | ||
16 | #include <linux/mutex.h> | ||
17 | #include <linux/rtc.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/mfd/core.h> | ||
20 | #include <linux/mfd/88pm860x.h> | ||
21 | |||
22 | #define VRTC_CALIBRATION | ||
23 | |||
24 | struct pm860x_rtc_info { | ||
25 | struct pm860x_chip *chip; | ||
26 | struct i2c_client *i2c; | ||
27 | struct rtc_device *rtc_dev; | ||
28 | struct device *dev; | ||
29 | struct delayed_work calib_work; | ||
30 | |||
31 | int irq; | ||
32 | int vrtc; | ||
33 | int (*sync)(unsigned int ticks); | ||
34 | }; | ||
35 | |||
36 | #define REG_VRTC_MEAS1 0x7D | ||
37 | |||
38 | #define REG0_ADDR 0xB0 | ||
39 | #define REG1_ADDR 0xB2 | ||
40 | #define REG2_ADDR 0xB4 | ||
41 | #define REG3_ADDR 0xB6 | ||
42 | |||
43 | #define REG0_DATA 0xB1 | ||
44 | #define REG1_DATA 0xB3 | ||
45 | #define REG2_DATA 0xB5 | ||
46 | #define REG3_DATA 0xB7 | ||
47 | |||
48 | /* bit definitions of Measurement Enable Register 2 (0x51) */ | ||
49 | #define MEAS2_VRTC (1 << 0) | ||
50 | |||
51 | /* bit definitions of RTC Register 1 (0xA0) */ | ||
52 | #define ALARM_EN (1 << 3) | ||
53 | #define ALARM_WAKEUP (1 << 4) | ||
54 | #define ALARM (1 << 5) | ||
55 | #define RTC1_USE_XO (1 << 7) | ||
56 | |||
57 | #define VRTC_CALIB_INTERVAL (HZ * 60 * 10) /* 10 minutes */ | ||
58 | |||
59 | static irqreturn_t rtc_update_handler(int irq, void *data) | ||
60 | { | ||
61 | struct pm860x_rtc_info *info = (struct pm860x_rtc_info *)data; | ||
62 | int mask; | ||
63 | |||
64 | mask = ALARM | ALARM_WAKEUP; | ||
65 | pm860x_set_bits(info->i2c, PM8607_RTC1, mask | ALARM_EN, mask); | ||
66 | rtc_update_irq(info->rtc_dev, 1, RTC_AF); | ||
67 | return IRQ_HANDLED; | ||
68 | } | ||
69 | |||
70 | static int pm860x_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | ||
71 | { | ||
72 | struct pm860x_rtc_info *info = dev_get_drvdata(dev); | ||
73 | |||
74 | if (enabled) | ||
75 | pm860x_set_bits(info->i2c, PM8607_RTC1, ALARM, ALARM); | ||
76 | else | ||
77 | pm860x_set_bits(info->i2c, PM8607_RTC1, ALARM, 0); | ||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | /* | ||
82 | * Calculate the next alarm time given the requested alarm time mask | ||
83 | * and the current time. | ||
84 | */ | ||
85 | static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, | ||
86 | struct rtc_time *alrm) | ||
87 | { | ||
88 | unsigned long next_time; | ||
89 | unsigned long now_time; | ||
90 | |||
91 | next->tm_year = now->tm_year; | ||
92 | next->tm_mon = now->tm_mon; | ||
93 | next->tm_mday = now->tm_mday; | ||
94 | next->tm_hour = alrm->tm_hour; | ||
95 | next->tm_min = alrm->tm_min; | ||
96 | next->tm_sec = alrm->tm_sec; | ||
97 | |||
98 | rtc_tm_to_time(now, &now_time); | ||
99 | rtc_tm_to_time(next, &next_time); | ||
100 | |||
101 | if (next_time < now_time) { | ||
102 | /* Advance one day */ | ||
103 | next_time += 60 * 60 * 24; | ||
104 | rtc_time_to_tm(next_time, next); | ||
105 | } | ||
106 | } | ||
107 | |||
108 | static int pm860x_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
109 | { | ||
110 | struct pm860x_rtc_info *info = dev_get_drvdata(dev); | ||
111 | unsigned char buf[8]; | ||
112 | unsigned long ticks, base, data; | ||
113 | |||
114 | pm860x_page_bulk_read(info->i2c, REG0_ADDR, 8, buf); | ||
115 | dev_dbg(info->dev, "%x-%x-%x-%x-%x-%x-%x-%x\n", buf[0], buf[1], | ||
116 | buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); | ||
117 | base = (buf[1] << 24) | (buf[3] << 16) | (buf[5] << 8) | buf[7]; | ||
118 | |||
119 | /* load 32-bit read-only counter */ | ||
120 | pm860x_bulk_read(info->i2c, PM8607_RTC_COUNTER1, 4, buf); | ||
121 | data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; | ||
122 | ticks = base + data; | ||
123 | dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", | ||
124 | base, data, ticks); | ||
125 | |||
126 | rtc_time_to_tm(ticks, tm); | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | static int pm860x_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
132 | { | ||
133 | struct pm860x_rtc_info *info = dev_get_drvdata(dev); | ||
134 | unsigned char buf[4]; | ||
135 | unsigned long ticks, base, data; | ||
136 | |||
137 | if ((tm->tm_year < 70) || (tm->tm_year > 138)) { | ||
138 | dev_dbg(info->dev, "Set time %d out of range. " | ||
139 | "Please set time between 1970 to 2038.\n", | ||
140 | 1900 + tm->tm_year); | ||
141 | return -EINVAL; | ||
142 | } | ||
143 | rtc_tm_to_time(tm, &ticks); | ||
144 | |||
145 | /* load 32-bit read-only counter */ | ||
146 | pm860x_bulk_read(info->i2c, PM8607_RTC_COUNTER1, 4, buf); | ||
147 | data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; | ||
148 | base = ticks - data; | ||
149 | dev_dbg(info->dev, "set base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", | ||
150 | base, data, ticks); | ||
151 | |||
152 | pm860x_page_reg_write(info->i2c, REG0_DATA, (base >> 24) & 0xFF); | ||
153 | pm860x_page_reg_write(info->i2c, REG1_DATA, (base >> 16) & 0xFF); | ||
154 | pm860x_page_reg_write(info->i2c, REG2_DATA, (base >> 8) & 0xFF); | ||
155 | pm860x_page_reg_write(info->i2c, REG3_DATA, base & 0xFF); | ||
156 | |||
157 | if (info->sync) | ||
158 | info->sync(ticks); | ||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | static int pm860x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
163 | { | ||
164 | struct pm860x_rtc_info *info = dev_get_drvdata(dev); | ||
165 | unsigned char buf[8]; | ||
166 | unsigned long ticks, base, data; | ||
167 | int ret; | ||
168 | |||
169 | pm860x_page_bulk_read(info->i2c, REG0_ADDR, 8, buf); | ||
170 | dev_dbg(info->dev, "%x-%x-%x-%x-%x-%x-%x-%x\n", buf[0], buf[1], | ||
171 | buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); | ||
172 | base = (buf[1] << 24) | (buf[3] << 16) | (buf[5] << 8) | buf[7]; | ||
173 | |||
174 | pm860x_bulk_read(info->i2c, PM8607_RTC_EXPIRE1, 4, buf); | ||
175 | data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; | ||
176 | ticks = base + data; | ||
177 | dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", | ||
178 | base, data, ticks); | ||
179 | |||
180 | rtc_time_to_tm(ticks, &alrm->time); | ||
181 | ret = pm860x_reg_read(info->i2c, PM8607_RTC1); | ||
182 | alrm->enabled = (ret & ALARM_EN) ? 1 : 0; | ||
183 | alrm->pending = (ret & (ALARM | ALARM_WAKEUP)) ? 1 : 0; | ||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | static int pm860x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
188 | { | ||
189 | struct pm860x_rtc_info *info = dev_get_drvdata(dev); | ||
190 | struct rtc_time now_tm, alarm_tm; | ||
191 | unsigned long ticks, base, data; | ||
192 | unsigned char buf[8]; | ||
193 | int mask; | ||
194 | |||
195 | pm860x_set_bits(info->i2c, PM8607_RTC1, ALARM_EN, 0); | ||
196 | |||
197 | pm860x_page_bulk_read(info->i2c, REG0_ADDR, 8, buf); | ||
198 | dev_dbg(info->dev, "%x-%x-%x-%x-%x-%x-%x-%x\n", buf[0], buf[1], | ||
199 | buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); | ||
200 | base = (buf[1] << 24) | (buf[3] << 16) | (buf[5] << 8) | buf[7]; | ||
201 | |||
202 | /* load 32-bit read-only counter */ | ||
203 | pm860x_bulk_read(info->i2c, PM8607_RTC_COUNTER1, 4, buf); | ||
204 | data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; | ||
205 | ticks = base + data; | ||
206 | dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", | ||
207 | base, data, ticks); | ||
208 | |||
209 | rtc_time_to_tm(ticks, &now_tm); | ||
210 | rtc_next_alarm_time(&alarm_tm, &now_tm, &alrm->time); | ||
211 | /* get new ticks for alarm in 24 hours */ | ||
212 | rtc_tm_to_time(&alarm_tm, &ticks); | ||
213 | data = ticks - base; | ||
214 | |||
215 | buf[0] = data & 0xff; | ||
216 | buf[1] = (data >> 8) & 0xff; | ||
217 | buf[2] = (data >> 16) & 0xff; | ||
218 | buf[3] = (data >> 24) & 0xff; | ||
219 | pm860x_bulk_write(info->i2c, PM8607_RTC_EXPIRE1, 4, buf); | ||
220 | if (alrm->enabled) { | ||
221 | mask = ALARM | ALARM_WAKEUP | ALARM_EN; | ||
222 | pm860x_set_bits(info->i2c, PM8607_RTC1, mask, mask); | ||
223 | } else { | ||
224 | mask = ALARM | ALARM_WAKEUP | ALARM_EN; | ||
225 | pm860x_set_bits(info->i2c, PM8607_RTC1, mask, | ||
226 | ALARM | ALARM_WAKEUP); | ||
227 | } | ||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | static const struct rtc_class_ops pm860x_rtc_ops = { | ||
232 | .read_time = pm860x_rtc_read_time, | ||
233 | .set_time = pm860x_rtc_set_time, | ||
234 | .read_alarm = pm860x_rtc_read_alarm, | ||
235 | .set_alarm = pm860x_rtc_set_alarm, | ||
236 | .alarm_irq_enable = pm860x_rtc_alarm_irq_enable, | ||
237 | }; | ||
238 | |||
239 | #ifdef VRTC_CALIBRATION | ||
240 | static void calibrate_vrtc_work(struct work_struct *work) | ||
241 | { | ||
242 | struct pm860x_rtc_info *info = container_of(work, | ||
243 | struct pm860x_rtc_info, calib_work.work); | ||
244 | unsigned char buf[2]; | ||
245 | unsigned int sum, data, mean, vrtc_set; | ||
246 | int i; | ||
247 | |||
248 | for (i = 0, sum = 0; i < 16; i++) { | ||
249 | msleep(100); | ||
250 | pm860x_bulk_read(info->i2c, REG_VRTC_MEAS1, 2, buf); | ||
251 | data = (buf[0] << 4) | buf[1]; | ||
252 | data = (data * 5400) >> 12; /* convert to mv */ | ||
253 | sum += data; | ||
254 | } | ||
255 | mean = sum >> 4; | ||
256 | vrtc_set = 2700 + (info->vrtc & 0x3) * 200; | ||
257 | dev_dbg(info->dev, "mean:%d, vrtc_set:%d\n", mean, vrtc_set); | ||
258 | |||
259 | sum = pm860x_reg_read(info->i2c, PM8607_RTC_MISC1); | ||
260 | data = sum & 0x3; | ||
261 | if ((mean + 200) < vrtc_set) { | ||
262 | /* try higher voltage */ | ||
263 | if (++data == 4) | ||
264 | goto out; | ||
265 | data = (sum & 0xf8) | (data & 0x3); | ||
266 | pm860x_reg_write(info->i2c, PM8607_RTC_MISC1, data); | ||
267 | } else if ((mean - 200) > vrtc_set) { | ||
268 | /* try lower voltage */ | ||
269 | if (data-- == 0) | ||
270 | goto out; | ||
271 | data = (sum & 0xf8) | (data & 0x3); | ||
272 | pm860x_reg_write(info->i2c, PM8607_RTC_MISC1, data); | ||
273 | } else | ||
274 | goto out; | ||
275 | dev_dbg(info->dev, "set 0x%x to RTC_MISC1\n", data); | ||
276 | /* trigger next calibration since VRTC is updated */ | ||
277 | schedule_delayed_work(&info->calib_work, VRTC_CALIB_INTERVAL); | ||
278 | return; | ||
279 | out: | ||
280 | /* disable measurement */ | ||
281 | pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, 0); | ||
282 | dev_dbg(info->dev, "finish VRTC calibration\n"); | ||
283 | return; | ||
284 | } | ||
285 | #endif | ||
286 | |||
287 | static int __devinit pm860x_rtc_probe(struct platform_device *pdev) | ||
288 | { | ||
289 | struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); | ||
290 | struct pm860x_rtc_pdata *pdata = NULL; | ||
291 | struct pm860x_rtc_info *info; | ||
292 | struct rtc_time tm; | ||
293 | unsigned long ticks = 0; | ||
294 | int ret; | ||
295 | |||
296 | pdata = pdev->dev.platform_data; | ||
297 | if (pdata == NULL) | ||
298 | dev_warn(&pdev->dev, "No platform data!\n"); | ||
299 | |||
300 | info = kzalloc(sizeof(struct pm860x_rtc_info), GFP_KERNEL); | ||
301 | if (!info) | ||
302 | return -ENOMEM; | ||
303 | info->irq = platform_get_irq(pdev, 0); | ||
304 | if (info->irq < 0) { | ||
305 | dev_err(&pdev->dev, "No IRQ resource!\n"); | ||
306 | ret = -EINVAL; | ||
307 | goto out; | ||
308 | } | ||
309 | |||
310 | info->chip = chip; | ||
311 | info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; | ||
312 | info->dev = &pdev->dev; | ||
313 | dev_set_drvdata(&pdev->dev, info); | ||
314 | |||
315 | ret = request_threaded_irq(info->irq, NULL, rtc_update_handler, | ||
316 | IRQF_ONESHOT, "rtc", info); | ||
317 | if (ret < 0) { | ||
318 | dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", | ||
319 | info->irq, ret); | ||
320 | goto out; | ||
321 | } | ||
322 | |||
323 | /* set addresses of 32-bit base value for RTC time */ | ||
324 | pm860x_page_reg_write(info->i2c, REG0_ADDR, REG0_DATA); | ||
325 | pm860x_page_reg_write(info->i2c, REG1_ADDR, REG1_DATA); | ||
326 | pm860x_page_reg_write(info->i2c, REG2_ADDR, REG2_DATA); | ||
327 | pm860x_page_reg_write(info->i2c, REG3_ADDR, REG3_DATA); | ||
328 | |||
329 | ret = pm860x_rtc_read_time(&pdev->dev, &tm); | ||
330 | if (ret < 0) { | ||
331 | dev_err(&pdev->dev, "Failed to read initial time.\n"); | ||
332 | goto out_rtc; | ||
333 | } | ||
334 | if ((tm.tm_year < 70) || (tm.tm_year > 138)) { | ||
335 | tm.tm_year = 70; | ||
336 | tm.tm_mon = 0; | ||
337 | tm.tm_mday = 1; | ||
338 | tm.tm_hour = 0; | ||
339 | tm.tm_min = 0; | ||
340 | tm.tm_sec = 0; | ||
341 | ret = pm860x_rtc_set_time(&pdev->dev, &tm); | ||
342 | if (ret < 0) { | ||
343 | dev_err(&pdev->dev, "Failed to set initial time.\n"); | ||
344 | goto out_rtc; | ||
345 | } | ||
346 | } | ||
347 | rtc_tm_to_time(&tm, &ticks); | ||
348 | if (pdata && pdata->sync) { | ||
349 | pdata->sync(ticks); | ||
350 | info->sync = pdata->sync; | ||
351 | } | ||
352 | |||
353 | info->rtc_dev = rtc_device_register("88pm860x-rtc", &pdev->dev, | ||
354 | &pm860x_rtc_ops, THIS_MODULE); | ||
355 | ret = PTR_ERR(info->rtc_dev); | ||
356 | if (IS_ERR(info->rtc_dev)) { | ||
357 | dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); | ||
358 | goto out_rtc; | ||
359 | } | ||
360 | |||
361 | /* | ||
362 | * enable internal XO instead of internal 3.25MHz clock since it can | ||
363 | * free running in PMIC power-down state. | ||
364 | */ | ||
365 | pm860x_set_bits(info->i2c, PM8607_RTC1, RTC1_USE_XO, RTC1_USE_XO); | ||
366 | |||
367 | #ifdef VRTC_CALIBRATION | ||
368 | /* <00> -- 2.7V, <01> -- 2.9V, <10> -- 3.1V, <11> -- 3.3V */ | ||
369 | if (pdata && pdata->vrtc) | ||
370 | info->vrtc = pdata->vrtc & 0x3; | ||
371 | else | ||
372 | info->vrtc = 1; | ||
373 | pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, MEAS2_VRTC); | ||
374 | |||
375 | /* calibrate VRTC */ | ||
376 | INIT_DELAYED_WORK(&info->calib_work, calibrate_vrtc_work); | ||
377 | schedule_delayed_work(&info->calib_work, VRTC_CALIB_INTERVAL); | ||
378 | #endif /* VRTC_CALIBRATION */ | ||
379 | return 0; | ||
380 | out_rtc: | ||
381 | free_irq(info->irq, info); | ||
382 | out: | ||
383 | kfree(info); | ||
384 | return ret; | ||
385 | } | ||
386 | |||
387 | static int __devexit pm860x_rtc_remove(struct platform_device *pdev) | ||
388 | { | ||
389 | struct pm860x_rtc_info *info = platform_get_drvdata(pdev); | ||
390 | |||
391 | #ifdef VRTC_CALIBRATION | ||
392 | flush_scheduled_work(); | ||
393 | /* disable measurement */ | ||
394 | pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, 0); | ||
395 | #endif /* VRTC_CALIBRATION */ | ||
396 | |||
397 | platform_set_drvdata(pdev, NULL); | ||
398 | rtc_device_unregister(info->rtc_dev); | ||
399 | free_irq(info->irq, info); | ||
400 | kfree(info); | ||
401 | return 0; | ||
402 | } | ||
403 | |||
404 | static struct platform_driver pm860x_rtc_driver = { | ||
405 | .driver = { | ||
406 | .name = "88pm860x-rtc", | ||
407 | .owner = THIS_MODULE, | ||
408 | }, | ||
409 | .probe = pm860x_rtc_probe, | ||
410 | .remove = __devexit_p(pm860x_rtc_remove), | ||
411 | }; | ||
412 | |||
413 | static int __init pm860x_rtc_init(void) | ||
414 | { | ||
415 | return platform_driver_register(&pm860x_rtc_driver); | ||
416 | } | ||
417 | module_init(pm860x_rtc_init); | ||
418 | |||
419 | static void __exit pm860x_rtc_exit(void) | ||
420 | { | ||
421 | platform_driver_unregister(&pm860x_rtc_driver); | ||
422 | } | ||
423 | module_exit(pm860x_rtc_exit); | ||
424 | |||
425 | MODULE_DESCRIPTION("Marvell 88PM860x RTC driver"); | ||
426 | MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); | ||
427 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c index 2fda03125e55..e346705aae92 100644 --- a/drivers/rtc/rtc-ab8500.c +++ b/drivers/rtc/rtc-ab8500.c | |||
@@ -14,26 +14,26 @@ | |||
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
16 | #include <linux/rtc.h> | 16 | #include <linux/rtc.h> |
17 | #include <linux/mfd/abx500.h> | ||
17 | #include <linux/mfd/ab8500.h> | 18 | #include <linux/mfd/ab8500.h> |
18 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
19 | 20 | ||
20 | #define AB8500_RTC_SOFF_STAT_REG 0x0F00 | 21 | #define AB8500_RTC_SOFF_STAT_REG 0x00 |
21 | #define AB8500_RTC_CC_CONF_REG 0x0F01 | 22 | #define AB8500_RTC_CC_CONF_REG 0x01 |
22 | #define AB8500_RTC_READ_REQ_REG 0x0F02 | 23 | #define AB8500_RTC_READ_REQ_REG 0x02 |
23 | #define AB8500_RTC_WATCH_TSECMID_REG 0x0F03 | 24 | #define AB8500_RTC_WATCH_TSECMID_REG 0x03 |
24 | #define AB8500_RTC_WATCH_TSECHI_REG 0x0F04 | 25 | #define AB8500_RTC_WATCH_TSECHI_REG 0x04 |
25 | #define AB8500_RTC_WATCH_TMIN_LOW_REG 0x0F05 | 26 | #define AB8500_RTC_WATCH_TMIN_LOW_REG 0x05 |
26 | #define AB8500_RTC_WATCH_TMIN_MID_REG 0x0F06 | 27 | #define AB8500_RTC_WATCH_TMIN_MID_REG 0x06 |
27 | #define AB8500_RTC_WATCH_TMIN_HI_REG 0x0F07 | 28 | #define AB8500_RTC_WATCH_TMIN_HI_REG 0x07 |
28 | #define AB8500_RTC_ALRM_MIN_LOW_REG 0x0F08 | 29 | #define AB8500_RTC_ALRM_MIN_LOW_REG 0x08 |
29 | #define AB8500_RTC_ALRM_MIN_MID_REG 0x0F09 | 30 | #define AB8500_RTC_ALRM_MIN_MID_REG 0x09 |
30 | #define AB8500_RTC_ALRM_MIN_HI_REG 0x0F0A | 31 | #define AB8500_RTC_ALRM_MIN_HI_REG 0x0A |
31 | #define AB8500_RTC_STAT_REG 0x0F0B | 32 | #define AB8500_RTC_STAT_REG 0x0B |
32 | #define AB8500_RTC_BKUP_CHG_REG 0x0F0C | 33 | #define AB8500_RTC_BKUP_CHG_REG 0x0C |
33 | #define AB8500_RTC_FORCE_BKUP_REG 0x0F0D | 34 | #define AB8500_RTC_FORCE_BKUP_REG 0x0D |
34 | #define AB8500_RTC_CALIB_REG 0x0F0E | 35 | #define AB8500_RTC_CALIB_REG 0x0E |
35 | #define AB8500_RTC_SWITCH_STAT_REG 0x0F0F | 36 | #define AB8500_RTC_SWITCH_STAT_REG 0x0F |
36 | #define AB8500_REV_REG 0x1080 | ||
37 | 37 | ||
38 | /* RtcReadRequest bits */ | 38 | /* RtcReadRequest bits */ |
39 | #define RTC_READ_REQUEST 0x01 | 39 | #define RTC_READ_REQUEST 0x01 |
@@ -46,13 +46,13 @@ | |||
46 | #define COUNTS_PER_SEC (0xF000 / 60) | 46 | #define COUNTS_PER_SEC (0xF000 / 60) |
47 | #define AB8500_RTC_EPOCH 2000 | 47 | #define AB8500_RTC_EPOCH 2000 |
48 | 48 | ||
49 | static const unsigned long ab8500_rtc_time_regs[] = { | 49 | static const u8 ab8500_rtc_time_regs[] = { |
50 | AB8500_RTC_WATCH_TMIN_HI_REG, AB8500_RTC_WATCH_TMIN_MID_REG, | 50 | AB8500_RTC_WATCH_TMIN_HI_REG, AB8500_RTC_WATCH_TMIN_MID_REG, |
51 | AB8500_RTC_WATCH_TMIN_LOW_REG, AB8500_RTC_WATCH_TSECHI_REG, | 51 | AB8500_RTC_WATCH_TMIN_LOW_REG, AB8500_RTC_WATCH_TSECHI_REG, |
52 | AB8500_RTC_WATCH_TSECMID_REG | 52 | AB8500_RTC_WATCH_TSECMID_REG |
53 | }; | 53 | }; |
54 | 54 | ||
55 | static const unsigned long ab8500_rtc_alarm_regs[] = { | 55 | static const u8 ab8500_rtc_alarm_regs[] = { |
56 | AB8500_RTC_ALRM_MIN_HI_REG, AB8500_RTC_ALRM_MIN_MID_REG, | 56 | AB8500_RTC_ALRM_MIN_HI_REG, AB8500_RTC_ALRM_MIN_MID_REG, |
57 | AB8500_RTC_ALRM_MIN_LOW_REG | 57 | AB8500_RTC_ALRM_MIN_LOW_REG |
58 | }; | 58 | }; |
@@ -76,29 +76,30 @@ static unsigned long get_elapsed_seconds(int year) | |||
76 | 76 | ||
77 | static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm) | 77 | static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm) |
78 | { | 78 | { |
79 | struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); | ||
80 | unsigned long timeout = jiffies + HZ; | 79 | unsigned long timeout = jiffies + HZ; |
81 | int retval, i; | 80 | int retval, i; |
82 | unsigned long mins, secs; | 81 | unsigned long mins, secs; |
83 | unsigned char buf[ARRAY_SIZE(ab8500_rtc_time_regs)]; | 82 | unsigned char buf[ARRAY_SIZE(ab8500_rtc_time_regs)]; |
83 | u8 value; | ||
84 | 84 | ||
85 | /* Request a data read */ | 85 | /* Request a data read */ |
86 | retval = ab8500_write(ab8500, AB8500_RTC_READ_REQ_REG, | 86 | retval = abx500_set_register_interruptible(dev, |
87 | RTC_READ_REQUEST); | 87 | AB8500_RTC, AB8500_RTC_READ_REQ_REG, RTC_READ_REQUEST); |
88 | if (retval < 0) | 88 | if (retval < 0) |
89 | return retval; | 89 | return retval; |
90 | 90 | ||
91 | /* Early AB8500 chips will not clear the rtc read request bit */ | 91 | /* Early AB8500 chips will not clear the rtc read request bit */ |
92 | if (ab8500->revision == 0) { | 92 | if (abx500_get_chip_id(dev) == 0) { |
93 | msleep(1); | 93 | msleep(1); |
94 | } else { | 94 | } else { |
95 | /* Wait for some cycles after enabling the rtc read in ab8500 */ | 95 | /* Wait for some cycles after enabling the rtc read in ab8500 */ |
96 | while (time_before(jiffies, timeout)) { | 96 | while (time_before(jiffies, timeout)) { |
97 | retval = ab8500_read(ab8500, AB8500_RTC_READ_REQ_REG); | 97 | retval = abx500_get_register_interruptible(dev, |
98 | AB8500_RTC, AB8500_RTC_READ_REQ_REG, &value); | ||
98 | if (retval < 0) | 99 | if (retval < 0) |
99 | return retval; | 100 | return retval; |
100 | 101 | ||
101 | if (!(retval & RTC_READ_REQUEST)) | 102 | if (!(value & RTC_READ_REQUEST)) |
102 | break; | 103 | break; |
103 | 104 | ||
104 | msleep(1); | 105 | msleep(1); |
@@ -107,10 +108,11 @@ static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
107 | 108 | ||
108 | /* Read the Watchtime registers */ | 109 | /* Read the Watchtime registers */ |
109 | for (i = 0; i < ARRAY_SIZE(ab8500_rtc_time_regs); i++) { | 110 | for (i = 0; i < ARRAY_SIZE(ab8500_rtc_time_regs); i++) { |
110 | retval = ab8500_read(ab8500, ab8500_rtc_time_regs[i]); | 111 | retval = abx500_get_register_interruptible(dev, |
112 | AB8500_RTC, ab8500_rtc_time_regs[i], &value); | ||
111 | if (retval < 0) | 113 | if (retval < 0) |
112 | return retval; | 114 | return retval; |
113 | buf[i] = retval; | 115 | buf[i] = value; |
114 | } | 116 | } |
115 | 117 | ||
116 | mins = (buf[0] << 16) | (buf[1] << 8) | buf[2]; | 118 | mins = (buf[0] << 16) | (buf[1] << 8) | buf[2]; |
@@ -128,7 +130,6 @@ static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
128 | 130 | ||
129 | static int ab8500_rtc_set_time(struct device *dev, struct rtc_time *tm) | 131 | static int ab8500_rtc_set_time(struct device *dev, struct rtc_time *tm) |
130 | { | 132 | { |
131 | struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); | ||
132 | int retval, i; | 133 | int retval, i; |
133 | unsigned char buf[ARRAY_SIZE(ab8500_rtc_time_regs)]; | 134 | unsigned char buf[ARRAY_SIZE(ab8500_rtc_time_regs)]; |
134 | unsigned long no_secs, no_mins, secs = 0; | 135 | unsigned long no_secs, no_mins, secs = 0; |
@@ -162,27 +163,29 @@ static int ab8500_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
162 | buf[0] = (no_mins >> 16) & 0xFF; | 163 | buf[0] = (no_mins >> 16) & 0xFF; |
163 | 164 | ||
164 | for (i = 0; i < ARRAY_SIZE(ab8500_rtc_time_regs); i++) { | 165 | for (i = 0; i < ARRAY_SIZE(ab8500_rtc_time_regs); i++) { |
165 | retval = ab8500_write(ab8500, ab8500_rtc_time_regs[i], buf[i]); | 166 | retval = abx500_set_register_interruptible(dev, AB8500_RTC, |
167 | ab8500_rtc_time_regs[i], buf[i]); | ||
166 | if (retval < 0) | 168 | if (retval < 0) |
167 | return retval; | 169 | return retval; |
168 | } | 170 | } |
169 | 171 | ||
170 | /* Request a data write */ | 172 | /* Request a data write */ |
171 | return ab8500_write(ab8500, AB8500_RTC_READ_REQ_REG, RTC_WRITE_REQUEST); | 173 | return abx500_set_register_interruptible(dev, AB8500_RTC, |
174 | AB8500_RTC_READ_REQ_REG, RTC_WRITE_REQUEST); | ||
172 | } | 175 | } |
173 | 176 | ||
174 | static int ab8500_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | 177 | static int ab8500_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) |
175 | { | 178 | { |
176 | struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); | ||
177 | int retval, i; | 179 | int retval, i; |
178 | int rtc_ctrl; | 180 | u8 rtc_ctrl, value; |
179 | unsigned char buf[ARRAY_SIZE(ab8500_rtc_alarm_regs)]; | 181 | unsigned char buf[ARRAY_SIZE(ab8500_rtc_alarm_regs)]; |
180 | unsigned long secs, mins; | 182 | unsigned long secs, mins; |
181 | 183 | ||
182 | /* Check if the alarm is enabled or not */ | 184 | /* Check if the alarm is enabled or not */ |
183 | rtc_ctrl = ab8500_read(ab8500, AB8500_RTC_STAT_REG); | 185 | retval = abx500_get_register_interruptible(dev, AB8500_RTC, |
184 | if (rtc_ctrl < 0) | 186 | AB8500_RTC_STAT_REG, &rtc_ctrl); |
185 | return rtc_ctrl; | 187 | if (retval < 0) |
188 | return retval; | ||
186 | 189 | ||
187 | if (rtc_ctrl & RTC_ALARM_ENA) | 190 | if (rtc_ctrl & RTC_ALARM_ENA) |
188 | alarm->enabled = 1; | 191 | alarm->enabled = 1; |
@@ -192,10 +195,11 @@ static int ab8500_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
192 | alarm->pending = 0; | 195 | alarm->pending = 0; |
193 | 196 | ||
194 | for (i = 0; i < ARRAY_SIZE(ab8500_rtc_alarm_regs); i++) { | 197 | for (i = 0; i < ARRAY_SIZE(ab8500_rtc_alarm_regs); i++) { |
195 | retval = ab8500_read(ab8500, ab8500_rtc_alarm_regs[i]); | 198 | retval = abx500_get_register_interruptible(dev, AB8500_RTC, |
199 | ab8500_rtc_alarm_regs[i], &value); | ||
196 | if (retval < 0) | 200 | if (retval < 0) |
197 | return retval; | 201 | return retval; |
198 | buf[i] = retval; | 202 | buf[i] = value; |
199 | } | 203 | } |
200 | 204 | ||
201 | mins = (buf[0] << 16) | (buf[1] << 8) | (buf[2]); | 205 | mins = (buf[0] << 16) | (buf[1] << 8) | (buf[2]); |
@@ -211,15 +215,13 @@ static int ab8500_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
211 | 215 | ||
212 | static int ab8500_rtc_irq_enable(struct device *dev, unsigned int enabled) | 216 | static int ab8500_rtc_irq_enable(struct device *dev, unsigned int enabled) |
213 | { | 217 | { |
214 | struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); | 218 | return abx500_mask_and_set_register_interruptible(dev, AB8500_RTC, |
215 | 219 | AB8500_RTC_STAT_REG, RTC_ALARM_ENA, | |
216 | return ab8500_set_bits(ab8500, AB8500_RTC_STAT_REG, RTC_ALARM_ENA, | 220 | enabled ? RTC_ALARM_ENA : 0); |
217 | enabled ? RTC_ALARM_ENA : 0); | ||
218 | } | 221 | } |
219 | 222 | ||
220 | static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) | 223 | static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) |
221 | { | 224 | { |
222 | struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); | ||
223 | int retval, i; | 225 | int retval, i; |
224 | unsigned char buf[ARRAY_SIZE(ab8500_rtc_alarm_regs)]; | 226 | unsigned char buf[ARRAY_SIZE(ab8500_rtc_alarm_regs)]; |
225 | unsigned long mins, secs = 0; | 227 | unsigned long mins, secs = 0; |
@@ -247,7 +249,8 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
247 | 249 | ||
248 | /* Set the alarm time */ | 250 | /* Set the alarm time */ |
249 | for (i = 0; i < ARRAY_SIZE(ab8500_rtc_alarm_regs); i++) { | 251 | for (i = 0; i < ARRAY_SIZE(ab8500_rtc_alarm_regs); i++) { |
250 | retval = ab8500_write(ab8500, ab8500_rtc_alarm_regs[i], buf[i]); | 252 | retval = abx500_set_register_interruptible(dev, AB8500_RTC, |
253 | ab8500_rtc_alarm_regs[i], buf[i]); | ||
251 | if (retval < 0) | 254 | if (retval < 0) |
252 | return retval; | 255 | return retval; |
253 | } | 256 | } |
@@ -276,10 +279,9 @@ static const struct rtc_class_ops ab8500_rtc_ops = { | |||
276 | 279 | ||
277 | static int __devinit ab8500_rtc_probe(struct platform_device *pdev) | 280 | static int __devinit ab8500_rtc_probe(struct platform_device *pdev) |
278 | { | 281 | { |
279 | struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); | ||
280 | int err; | 282 | int err; |
281 | struct rtc_device *rtc; | 283 | struct rtc_device *rtc; |
282 | int rtc_ctrl; | 284 | u8 rtc_ctrl; |
283 | int irq; | 285 | int irq; |
284 | 286 | ||
285 | irq = platform_get_irq_byname(pdev, "ALARM"); | 287 | irq = platform_get_irq_byname(pdev, "ALARM"); |
@@ -287,17 +289,18 @@ static int __devinit ab8500_rtc_probe(struct platform_device *pdev) | |||
287 | return irq; | 289 | return irq; |
288 | 290 | ||
289 | /* For RTC supply test */ | 291 | /* For RTC supply test */ |
290 | err = ab8500_set_bits(ab8500, AB8500_RTC_STAT_REG, RTC_STATUS_DATA, | 292 | err = abx500_mask_and_set_register_interruptible(&pdev->dev, AB8500_RTC, |
291 | RTC_STATUS_DATA); | 293 | AB8500_RTC_STAT_REG, RTC_STATUS_DATA, RTC_STATUS_DATA); |
292 | if (err < 0) | 294 | if (err < 0) |
293 | return err; | 295 | return err; |
294 | 296 | ||
295 | /* Wait for reset by the PorRtc */ | 297 | /* Wait for reset by the PorRtc */ |
296 | msleep(1); | 298 | msleep(1); |
297 | 299 | ||
298 | rtc_ctrl = ab8500_read(ab8500, AB8500_RTC_STAT_REG); | 300 | err = abx500_get_register_interruptible(&pdev->dev, AB8500_RTC, |
299 | if (rtc_ctrl < 0) | 301 | AB8500_RTC_STAT_REG, &rtc_ctrl); |
300 | return rtc_ctrl; | 302 | if (err < 0) |
303 | return err; | ||
301 | 304 | ||
302 | /* Check if the RTC Supply fails */ | 305 | /* Check if the RTC Supply fails */ |
303 | if (!(rtc_ctrl & RTC_STATUS_DATA)) { | 306 | if (!(rtc_ctrl & RTC_STATUS_DATA)) { |
diff --git a/drivers/rtc/rtc-at32ap700x.c b/drivers/rtc/rtc-at32ap700x.c index b2752b6e7a2f..e725d51e773d 100644 --- a/drivers/rtc/rtc-at32ap700x.c +++ b/drivers/rtc/rtc-at32ap700x.c | |||
@@ -134,36 +134,29 @@ static int at32_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
134 | return ret; | 134 | return ret; |
135 | } | 135 | } |
136 | 136 | ||
137 | static int at32_rtc_ioctl(struct device *dev, unsigned int cmd, | 137 | static int at32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) |
138 | unsigned long arg) | ||
139 | { | 138 | { |
140 | struct rtc_at32ap700x *rtc = dev_get_drvdata(dev); | 139 | struct rtc_at32ap700x *rtc = dev_get_drvdata(dev); |
141 | int ret = 0; | 140 | int ret = 0; |
142 | 141 | ||
143 | spin_lock_irq(&rtc->lock); | 142 | spin_lock_irq(&rtc->lock); |
144 | 143 | ||
145 | switch (cmd) { | 144 | if(enabled) { |
146 | case RTC_AIE_ON: | ||
147 | if (rtc_readl(rtc, VAL) > rtc->alarm_time) { | 145 | if (rtc_readl(rtc, VAL) > rtc->alarm_time) { |
148 | ret = -EINVAL; | 146 | ret = -EINVAL; |
149 | break; | 147 | goto out; |
150 | } | 148 | } |
151 | rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL) | 149 | rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL) |
152 | | RTC_BIT(CTRL_TOPEN)); | 150 | | RTC_BIT(CTRL_TOPEN)); |
153 | rtc_writel(rtc, ICR, RTC_BIT(ICR_TOPI)); | 151 | rtc_writel(rtc, ICR, RTC_BIT(ICR_TOPI)); |
154 | rtc_writel(rtc, IER, RTC_BIT(IER_TOPI)); | 152 | rtc_writel(rtc, IER, RTC_BIT(IER_TOPI)); |
155 | break; | 153 | } else { |
156 | case RTC_AIE_OFF: | ||
157 | rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL) | 154 | rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL) |
158 | & ~RTC_BIT(CTRL_TOPEN)); | 155 | & ~RTC_BIT(CTRL_TOPEN)); |
159 | rtc_writel(rtc, IDR, RTC_BIT(IDR_TOPI)); | 156 | rtc_writel(rtc, IDR, RTC_BIT(IDR_TOPI)); |
160 | rtc_writel(rtc, ICR, RTC_BIT(ICR_TOPI)); | 157 | rtc_writel(rtc, ICR, RTC_BIT(ICR_TOPI)); |
161 | break; | ||
162 | default: | ||
163 | ret = -ENOIOCTLCMD; | ||
164 | break; | ||
165 | } | 158 | } |
166 | 159 | out: | |
167 | spin_unlock_irq(&rtc->lock); | 160 | spin_unlock_irq(&rtc->lock); |
168 | 161 | ||
169 | return ret; | 162 | return ret; |
@@ -195,11 +188,11 @@ static irqreturn_t at32_rtc_interrupt(int irq, void *dev_id) | |||
195 | } | 188 | } |
196 | 189 | ||
197 | static struct rtc_class_ops at32_rtc_ops = { | 190 | static struct rtc_class_ops at32_rtc_ops = { |
198 | .ioctl = at32_rtc_ioctl, | ||
199 | .read_time = at32_rtc_readtime, | 191 | .read_time = at32_rtc_readtime, |
200 | .set_time = at32_rtc_settime, | 192 | .set_time = at32_rtc_settime, |
201 | .read_alarm = at32_rtc_readalarm, | 193 | .read_alarm = at32_rtc_readalarm, |
202 | .set_alarm = at32_rtc_setalarm, | 194 | .set_alarm = at32_rtc_setalarm, |
195 | .alarm_irq_enable = at32_rtc_alarm_irq_enable, | ||
203 | }; | 196 | }; |
204 | 197 | ||
205 | static int __init at32_rtc_probe(struct platform_device *pdev) | 198 | static int __init at32_rtc_probe(struct platform_device *pdev) |
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index bc8bbca9a2e2..e39b77a4609a 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c | |||
@@ -60,7 +60,7 @@ static void at91_rtc_decodetime(unsigned int timereg, unsigned int calreg, | |||
60 | /* | 60 | /* |
61 | * The Calendar Alarm register does not have a field for | 61 | * The Calendar Alarm register does not have a field for |
62 | * the year - so these will return an invalid value. When an | 62 | * the year - so these will return an invalid value. When an |
63 | * alarm is set, at91_alarm_year wille store the current year. | 63 | * alarm is set, at91_alarm_year will store the current year. |
64 | */ | 64 | */ |
65 | tm->tm_year = bcd2bin(date & AT91_RTC_CENT) * 100; /* century */ | 65 | tm->tm_year = bcd2bin(date & AT91_RTC_CENT) * 100; /* century */ |
66 | tm->tm_year += bcd2bin((date & AT91_RTC_YEAR) >> 8); /* year */ | 66 | tm->tm_year += bcd2bin((date & AT91_RTC_YEAR) >> 8); /* year */ |
@@ -183,40 +183,18 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
183 | return 0; | 183 | return 0; |
184 | } | 184 | } |
185 | 185 | ||
186 | /* | 186 | static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) |
187 | * Handle commands from user-space | ||
188 | */ | ||
189 | static int at91_rtc_ioctl(struct device *dev, unsigned int cmd, | ||
190 | unsigned long arg) | ||
191 | { | 187 | { |
192 | int ret = 0; | 188 | pr_debug("%s(): cmd=%08x\n", __func__, enabled); |
193 | 189 | ||
194 | pr_debug("%s(): cmd=%08x, arg=%08lx.\n", __func__, cmd, arg); | 190 | if (enabled) { |
195 | |||
196 | /* important: scrub old status before enabling IRQs */ | ||
197 | switch (cmd) { | ||
198 | case RTC_AIE_OFF: /* alarm off */ | ||
199 | at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM); | ||
200 | break; | ||
201 | case RTC_AIE_ON: /* alarm on */ | ||
202 | at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM); | 191 | at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM); |
203 | at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); | 192 | at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); |
204 | break; | 193 | } else |
205 | case RTC_UIE_OFF: /* update off */ | 194 | at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM); |
206 | at91_sys_write(AT91_RTC_IDR, AT91_RTC_SECEV); | ||
207 | break; | ||
208 | case RTC_UIE_ON: /* update on */ | ||
209 | at91_sys_write(AT91_RTC_SCCR, AT91_RTC_SECEV); | ||
210 | at91_sys_write(AT91_RTC_IER, AT91_RTC_SECEV); | ||
211 | break; | ||
212 | default: | ||
213 | ret = -ENOIOCTLCMD; | ||
214 | break; | ||
215 | } | ||
216 | 195 | ||
217 | return ret; | 196 | return 0; |
218 | } | 197 | } |
219 | |||
220 | /* | 198 | /* |
221 | * Provide additional RTC information in /proc/driver/rtc | 199 | * Provide additional RTC information in /proc/driver/rtc |
222 | */ | 200 | */ |
@@ -264,12 +242,12 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) | |||
264 | } | 242 | } |
265 | 243 | ||
266 | static const struct rtc_class_ops at91_rtc_ops = { | 244 | static const struct rtc_class_ops at91_rtc_ops = { |
267 | .ioctl = at91_rtc_ioctl, | ||
268 | .read_time = at91_rtc_readtime, | 245 | .read_time = at91_rtc_readtime, |
269 | .set_time = at91_rtc_settime, | 246 | .set_time = at91_rtc_settime, |
270 | .read_alarm = at91_rtc_readalarm, | 247 | .read_alarm = at91_rtc_readalarm, |
271 | .set_alarm = at91_rtc_setalarm, | 248 | .set_alarm = at91_rtc_setalarm, |
272 | .proc = at91_rtc_proc, | 249 | .proc = at91_rtc_proc, |
250 | .alarm_irq_enable = at91_rtc_alarm_irq_enable, | ||
273 | }; | 251 | }; |
274 | 252 | ||
275 | /* | 253 | /* |
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index f677e0710ca1..a3ad957507dc 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c | |||
@@ -216,37 +216,17 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
216 | return 0; | 216 | return 0; |
217 | } | 217 | } |
218 | 218 | ||
219 | /* | 219 | static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) |
220 | * Handle commands from user-space | ||
221 | */ | ||
222 | static int at91_rtc_ioctl(struct device *dev, unsigned int cmd, | ||
223 | unsigned long arg) | ||
224 | { | 220 | { |
225 | struct sam9_rtc *rtc = dev_get_drvdata(dev); | 221 | struct sam9_rtc *rtc = dev_get_drvdata(dev); |
226 | int ret = 0; | ||
227 | u32 mr = rtt_readl(rtc, MR); | 222 | u32 mr = rtt_readl(rtc, MR); |
228 | 223 | ||
229 | dev_dbg(dev, "ioctl: cmd=%08x, arg=%08lx, mr %08x\n", cmd, arg, mr); | 224 | dev_dbg(dev, "alarm_irq_enable: enabled=%08x, mr %08x\n", enabled, mr); |
230 | 225 | if (enabled) | |
231 | switch (cmd) { | ||
232 | case RTC_AIE_OFF: /* alarm off */ | ||
233 | rtt_writel(rtc, MR, mr & ~AT91_RTT_ALMIEN); | ||
234 | break; | ||
235 | case RTC_AIE_ON: /* alarm on */ | ||
236 | rtt_writel(rtc, MR, mr | AT91_RTT_ALMIEN); | 226 | rtt_writel(rtc, MR, mr | AT91_RTT_ALMIEN); |
237 | break; | 227 | else |
238 | case RTC_UIE_OFF: /* update off */ | 228 | rtt_writel(rtc, MR, mr & ~AT91_RTT_ALMIEN); |
239 | rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN); | 229 | return 0; |
240 | break; | ||
241 | case RTC_UIE_ON: /* update on */ | ||
242 | rtt_writel(rtc, MR, mr | AT91_RTT_RTTINCIEN); | ||
243 | break; | ||
244 | default: | ||
245 | ret = -ENOIOCTLCMD; | ||
246 | break; | ||
247 | } | ||
248 | |||
249 | return ret; | ||
250 | } | 230 | } |
251 | 231 | ||
252 | /* | 232 | /* |
@@ -296,12 +276,12 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc) | |||
296 | } | 276 | } |
297 | 277 | ||
298 | static const struct rtc_class_ops at91_rtc_ops = { | 278 | static const struct rtc_class_ops at91_rtc_ops = { |
299 | .ioctl = at91_rtc_ioctl, | ||
300 | .read_time = at91_rtc_readtime, | 279 | .read_time = at91_rtc_readtime, |
301 | .set_time = at91_rtc_settime, | 280 | .set_time = at91_rtc_settime, |
302 | .read_alarm = at91_rtc_readalarm, | 281 | .read_alarm = at91_rtc_readalarm, |
303 | .set_alarm = at91_rtc_setalarm, | 282 | .set_alarm = at91_rtc_setalarm, |
304 | .proc = at91_rtc_proc, | 283 | .proc = at91_rtc_proc, |
284 | .alarm_irq_enable = at91_rtc_alarm_irq_enable, | ||
305 | }; | 285 | }; |
306 | 286 | ||
307 | /* | 287 | /* |
diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index d4fb82d85e9b..90d866272c8e 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Blackfin On-Chip Real Time Clock Driver | 2 | * Blackfin On-Chip Real Time Clock Driver |
3 | * Supports BF51x/BF52x/BF53[123]/BF53[467]/BF54x | 3 | * Supports BF51x/BF52x/BF53[123]/BF53[467]/BF54x |
4 | * | 4 | * |
5 | * Copyright 2004-2009 Analog Devices Inc. | 5 | * Copyright 2004-2010 Analog Devices Inc. |
6 | * | 6 | * |
7 | * Enter bugs at http://blackfin.uclinux.org/ | 7 | * Enter bugs at http://blackfin.uclinux.org/ |
8 | * | 8 | * |
@@ -20,9 +20,9 @@ | |||
20 | * write would be discarded and things quickly fall apart. | 20 | * write would be discarded and things quickly fall apart. |
21 | * | 21 | * |
22 | * To keep this delay from significantly degrading performance (we, in theory, | 22 | * To keep this delay from significantly degrading performance (we, in theory, |
23 | * would have to sleep for up to 1 second everytime we wanted to write a | 23 | * would have to sleep for up to 1 second every time we wanted to write a |
24 | * register), we only check the write pending status before we start to issue | 24 | * register), we only check the write pending status before we start to issue |
25 | * a new write. We bank on the idea that it doesnt matter when the sync | 25 | * a new write. We bank on the idea that it doesn't matter when the sync |
26 | * happens so long as we don't attempt another write before it does. The only | 26 | * happens so long as we don't attempt another write before it does. The only |
27 | * time userspace would take this penalty is when they try and do multiple | 27 | * time userspace would take this penalty is when they try and do multiple |
28 | * operations right after another ... but in this case, they need to take the | 28 | * operations right after another ... but in this case, they need to take the |
@@ -183,29 +183,33 @@ static irqreturn_t bfin_rtc_interrupt(int irq, void *dev_id) | |||
183 | struct bfin_rtc *rtc = dev_get_drvdata(dev); | 183 | struct bfin_rtc *rtc = dev_get_drvdata(dev); |
184 | unsigned long events = 0; | 184 | unsigned long events = 0; |
185 | bool write_complete = false; | 185 | bool write_complete = false; |
186 | u16 rtc_istat, rtc_ictl; | 186 | u16 rtc_istat, rtc_istat_clear, rtc_ictl, bits; |
187 | 187 | ||
188 | dev_dbg_stamp(dev); | 188 | dev_dbg_stamp(dev); |
189 | 189 | ||
190 | rtc_istat = bfin_read_RTC_ISTAT(); | 190 | rtc_istat = bfin_read_RTC_ISTAT(); |
191 | rtc_ictl = bfin_read_RTC_ICTL(); | 191 | rtc_ictl = bfin_read_RTC_ICTL(); |
192 | rtc_istat_clear = 0; | ||
192 | 193 | ||
193 | if (rtc_istat & RTC_ISTAT_WRITE_COMPLETE) { | 194 | bits = RTC_ISTAT_WRITE_COMPLETE; |
194 | bfin_write_RTC_ISTAT(RTC_ISTAT_WRITE_COMPLETE); | 195 | if (rtc_istat & bits) { |
196 | rtc_istat_clear |= bits; | ||
195 | write_complete = true; | 197 | write_complete = true; |
196 | complete(&bfin_write_complete); | 198 | complete(&bfin_write_complete); |
197 | } | 199 | } |
198 | 200 | ||
199 | if (rtc_ictl & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)) { | 201 | bits = (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY); |
200 | if (rtc_istat & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)) { | 202 | if (rtc_ictl & bits) { |
201 | bfin_write_RTC_ISTAT(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY); | 203 | if (rtc_istat & bits) { |
204 | rtc_istat_clear |= bits; | ||
202 | events |= RTC_AF | RTC_IRQF; | 205 | events |= RTC_AF | RTC_IRQF; |
203 | } | 206 | } |
204 | } | 207 | } |
205 | 208 | ||
206 | if (rtc_ictl & RTC_ISTAT_SEC) { | 209 | bits = RTC_ISTAT_SEC; |
207 | if (rtc_istat & RTC_ISTAT_SEC) { | 210 | if (rtc_ictl & bits) { |
208 | bfin_write_RTC_ISTAT(RTC_ISTAT_SEC); | 211 | if (rtc_istat & bits) { |
212 | rtc_istat_clear |= bits; | ||
209 | events |= RTC_UF | RTC_IRQF; | 213 | events |= RTC_UF | RTC_IRQF; |
210 | } | 214 | } |
211 | } | 215 | } |
@@ -213,9 +217,10 @@ static irqreturn_t bfin_rtc_interrupt(int irq, void *dev_id) | |||
213 | if (events) | 217 | if (events) |
214 | rtc_update_irq(rtc->rtc_dev, 1, events); | 218 | rtc_update_irq(rtc->rtc_dev, 1, events); |
215 | 219 | ||
216 | if (write_complete || events) | 220 | if (write_complete || events) { |
221 | bfin_write_RTC_ISTAT(rtc_istat_clear); | ||
217 | return IRQ_HANDLED; | 222 | return IRQ_HANDLED; |
218 | else | 223 | } else |
219 | return IRQ_NONE; | 224 | return IRQ_NONE; |
220 | } | 225 | } |
221 | 226 | ||
@@ -235,40 +240,18 @@ static void bfin_rtc_int_set_alarm(struct bfin_rtc *rtc) | |||
235 | */ | 240 | */ |
236 | bfin_rtc_int_set(rtc->rtc_alarm.tm_yday == -1 ? RTC_ISTAT_ALARM : RTC_ISTAT_ALARM_DAY); | 241 | bfin_rtc_int_set(rtc->rtc_alarm.tm_yday == -1 ? RTC_ISTAT_ALARM : RTC_ISTAT_ALARM_DAY); |
237 | } | 242 | } |
238 | static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | 243 | |
244 | static int bfin_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | ||
239 | { | 245 | { |
240 | struct bfin_rtc *rtc = dev_get_drvdata(dev); | 246 | struct bfin_rtc *rtc = dev_get_drvdata(dev); |
241 | int ret = 0; | ||
242 | 247 | ||
243 | dev_dbg_stamp(dev); | 248 | dev_dbg_stamp(dev); |
244 | 249 | if (enabled) | |
245 | bfin_rtc_sync_pending(dev); | ||
246 | |||
247 | switch (cmd) { | ||
248 | case RTC_UIE_ON: | ||
249 | dev_dbg_stamp(dev); | ||
250 | bfin_rtc_int_set(RTC_ISTAT_SEC); | ||
251 | break; | ||
252 | case RTC_UIE_OFF: | ||
253 | dev_dbg_stamp(dev); | ||
254 | bfin_rtc_int_clear(~RTC_ISTAT_SEC); | ||
255 | break; | ||
256 | |||
257 | case RTC_AIE_ON: | ||
258 | dev_dbg_stamp(dev); | ||
259 | bfin_rtc_int_set_alarm(rtc); | 250 | bfin_rtc_int_set_alarm(rtc); |
260 | break; | 251 | else |
261 | case RTC_AIE_OFF: | ||
262 | dev_dbg_stamp(dev); | ||
263 | bfin_rtc_int_clear(~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)); | 252 | bfin_rtc_int_clear(~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)); |
264 | break; | ||
265 | 253 | ||
266 | default: | 254 | return 0; |
267 | dev_dbg_stamp(dev); | ||
268 | ret = -ENOIOCTLCMD; | ||
269 | } | ||
270 | |||
271 | return ret; | ||
272 | } | 255 | } |
273 | 256 | ||
274 | static int bfin_rtc_read_time(struct device *dev, struct rtc_time *tm) | 257 | static int bfin_rtc_read_time(struct device *dev, struct rtc_time *tm) |
@@ -351,12 +334,12 @@ static int bfin_rtc_proc(struct device *dev, struct seq_file *seq) | |||
351 | } | 334 | } |
352 | 335 | ||
353 | static struct rtc_class_ops bfin_rtc_ops = { | 336 | static struct rtc_class_ops bfin_rtc_ops = { |
354 | .ioctl = bfin_rtc_ioctl, | ||
355 | .read_time = bfin_rtc_read_time, | 337 | .read_time = bfin_rtc_read_time, |
356 | .set_time = bfin_rtc_set_time, | 338 | .set_time = bfin_rtc_set_time, |
357 | .read_alarm = bfin_rtc_read_alarm, | 339 | .read_alarm = bfin_rtc_read_alarm, |
358 | .set_alarm = bfin_rtc_set_alarm, | 340 | .set_alarm = bfin_rtc_set_alarm, |
359 | .proc = bfin_rtc_proc, | 341 | .proc = bfin_rtc_proc, |
342 | .alarm_irq_enable = bfin_rtc_alarm_irq_enable, | ||
360 | }; | 343 | }; |
361 | 344 | ||
362 | static int __devinit bfin_rtc_probe(struct platform_device *pdev) | 345 | static int __devinit bfin_rtc_probe(struct platform_device *pdev) |
@@ -422,9 +405,13 @@ static int __devexit bfin_rtc_remove(struct platform_device *pdev) | |||
422 | #ifdef CONFIG_PM | 405 | #ifdef CONFIG_PM |
423 | static int bfin_rtc_suspend(struct platform_device *pdev, pm_message_t state) | 406 | static int bfin_rtc_suspend(struct platform_device *pdev, pm_message_t state) |
424 | { | 407 | { |
425 | if (device_may_wakeup(&pdev->dev)) { | 408 | struct device *dev = &pdev->dev; |
409 | |||
410 | dev_dbg_stamp(dev); | ||
411 | |||
412 | if (device_may_wakeup(dev)) { | ||
426 | enable_irq_wake(IRQ_RTC); | 413 | enable_irq_wake(IRQ_RTC); |
427 | bfin_rtc_sync_pending(&pdev->dev); | 414 | bfin_rtc_sync_pending(dev); |
428 | } else | 415 | } else |
429 | bfin_rtc_int_clear(0); | 416 | bfin_rtc_int_clear(0); |
430 | 417 | ||
@@ -433,7 +420,11 @@ static int bfin_rtc_suspend(struct platform_device *pdev, pm_message_t state) | |||
433 | 420 | ||
434 | static int bfin_rtc_resume(struct platform_device *pdev) | 421 | static int bfin_rtc_resume(struct platform_device *pdev) |
435 | { | 422 | { |
436 | if (device_may_wakeup(&pdev->dev)) | 423 | struct device *dev = &pdev->dev; |
424 | |||
425 | dev_dbg_stamp(dev); | ||
426 | |||
427 | if (device_may_wakeup(dev)) | ||
437 | disable_irq_wake(IRQ_RTC); | 428 | disable_irq_wake(IRQ_RTC); |
438 | 429 | ||
439 | /* | 430 | /* |
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 5856167a0c90..911e75cdc125 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -36,6 +36,9 @@ | |||
36 | #include <linux/platform_device.h> | 36 | #include <linux/platform_device.h> |
37 | #include <linux/mod_devicetable.h> | 37 | #include <linux/mod_devicetable.h> |
38 | #include <linux/log2.h> | 38 | #include <linux/log2.h> |
39 | #include <linux/pm.h> | ||
40 | #include <linux/of.h> | ||
41 | #include <linux/of_platform.h> | ||
39 | 42 | ||
40 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ | 43 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ |
41 | #include <asm-generic/rtc.h> | 44 | #include <asm-generic/rtc.h> |
@@ -374,50 +377,6 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
374 | return 0; | 377 | return 0; |
375 | } | 378 | } |
376 | 379 | ||
377 | static int cmos_irq_set_freq(struct device *dev, int freq) | ||
378 | { | ||
379 | struct cmos_rtc *cmos = dev_get_drvdata(dev); | ||
380 | int f; | ||
381 | unsigned long flags; | ||
382 | |||
383 | if (!is_valid_irq(cmos->irq)) | ||
384 | return -ENXIO; | ||
385 | |||
386 | if (!is_power_of_2(freq)) | ||
387 | return -EINVAL; | ||
388 | /* 0 = no irqs; 1 = 2^15 Hz ... 15 = 2^0 Hz */ | ||
389 | f = ffs(freq); | ||
390 | if (f-- > 16) | ||
391 | return -EINVAL; | ||
392 | f = 16 - f; | ||
393 | |||
394 | spin_lock_irqsave(&rtc_lock, flags); | ||
395 | hpet_set_periodic_freq(freq); | ||
396 | CMOS_WRITE(RTC_REF_CLCK_32KHZ | f, RTC_FREQ_SELECT); | ||
397 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
398 | |||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | static int cmos_irq_set_state(struct device *dev, int enabled) | ||
403 | { | ||
404 | struct cmos_rtc *cmos = dev_get_drvdata(dev); | ||
405 | unsigned long flags; | ||
406 | |||
407 | if (!is_valid_irq(cmos->irq)) | ||
408 | return -ENXIO; | ||
409 | |||
410 | spin_lock_irqsave(&rtc_lock, flags); | ||
411 | |||
412 | if (enabled) | ||
413 | cmos_irq_enable(cmos, RTC_PIE); | ||
414 | else | ||
415 | cmos_irq_disable(cmos, RTC_PIE); | ||
416 | |||
417 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
418 | return 0; | ||
419 | } | ||
420 | |||
421 | static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled) | 380 | static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled) |
422 | { | 381 | { |
423 | struct cmos_rtc *cmos = dev_get_drvdata(dev); | 382 | struct cmos_rtc *cmos = dev_get_drvdata(dev); |
@@ -437,25 +396,6 @@ static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled) | |||
437 | return 0; | 396 | return 0; |
438 | } | 397 | } |
439 | 398 | ||
440 | static int cmos_update_irq_enable(struct device *dev, unsigned int enabled) | ||
441 | { | ||
442 | struct cmos_rtc *cmos = dev_get_drvdata(dev); | ||
443 | unsigned long flags; | ||
444 | |||
445 | if (!is_valid_irq(cmos->irq)) | ||
446 | return -EINVAL; | ||
447 | |||
448 | spin_lock_irqsave(&rtc_lock, flags); | ||
449 | |||
450 | if (enabled) | ||
451 | cmos_irq_enable(cmos, RTC_UIE); | ||
452 | else | ||
453 | cmos_irq_disable(cmos, RTC_UIE); | ||
454 | |||
455 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
456 | return 0; | ||
457 | } | ||
458 | |||
459 | #if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE) | 399 | #if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE) |
460 | 400 | ||
461 | static int cmos_procfs(struct device *dev, struct seq_file *seq) | 401 | static int cmos_procfs(struct device *dev, struct seq_file *seq) |
@@ -500,10 +440,7 @@ static const struct rtc_class_ops cmos_rtc_ops = { | |||
500 | .read_alarm = cmos_read_alarm, | 440 | .read_alarm = cmos_read_alarm, |
501 | .set_alarm = cmos_set_alarm, | 441 | .set_alarm = cmos_set_alarm, |
502 | .proc = cmos_procfs, | 442 | .proc = cmos_procfs, |
503 | .irq_set_freq = cmos_irq_set_freq, | ||
504 | .irq_set_state = cmos_irq_set_state, | ||
505 | .alarm_irq_enable = cmos_alarm_irq_enable, | 443 | .alarm_irq_enable = cmos_alarm_irq_enable, |
506 | .update_irq_enable = cmos_update_irq_enable, | ||
507 | }; | 444 | }; |
508 | 445 | ||
509 | /*----------------------------------------------------------------*/ | 446 | /*----------------------------------------------------------------*/ |
@@ -687,7 +624,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
687 | #if defined(CONFIG_ATARI) | 624 | #if defined(CONFIG_ATARI) |
688 | address_space = 64; | 625 | address_space = 64; |
689 | #elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) \ | 626 | #elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) \ |
690 | || defined(__sparc__) || defined(__mips__) | 627 | || defined(__sparc__) || defined(__mips__) \ |
628 | || defined(__powerpc__) | ||
691 | address_space = 128; | 629 | address_space = 128; |
692 | #else | 630 | #else |
693 | #warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes. | 631 | #warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes. |
@@ -850,7 +788,7 @@ static void __exit cmos_do_remove(struct device *dev) | |||
850 | 788 | ||
851 | #ifdef CONFIG_PM | 789 | #ifdef CONFIG_PM |
852 | 790 | ||
853 | static int cmos_suspend(struct device *dev, pm_message_t mesg) | 791 | static int cmos_suspend(struct device *dev) |
854 | { | 792 | { |
855 | struct cmos_rtc *cmos = dev_get_drvdata(dev); | 793 | struct cmos_rtc *cmos = dev_get_drvdata(dev); |
856 | unsigned char tmp; | 794 | unsigned char tmp; |
@@ -898,7 +836,7 @@ static int cmos_suspend(struct device *dev, pm_message_t mesg) | |||
898 | */ | 836 | */ |
899 | static inline int cmos_poweroff(struct device *dev) | 837 | static inline int cmos_poweroff(struct device *dev) |
900 | { | 838 | { |
901 | return cmos_suspend(dev, PMSG_HIBERNATE); | 839 | return cmos_suspend(dev); |
902 | } | 840 | } |
903 | 841 | ||
904 | static int cmos_resume(struct device *dev) | 842 | static int cmos_resume(struct device *dev) |
@@ -945,9 +883,9 @@ static int cmos_resume(struct device *dev) | |||
945 | return 0; | 883 | return 0; |
946 | } | 884 | } |
947 | 885 | ||
886 | static SIMPLE_DEV_PM_OPS(cmos_pm_ops, cmos_suspend, cmos_resume); | ||
887 | |||
948 | #else | 888 | #else |
949 | #define cmos_suspend NULL | ||
950 | #define cmos_resume NULL | ||
951 | 889 | ||
952 | static inline int cmos_poweroff(struct device *dev) | 890 | static inline int cmos_poweroff(struct device *dev) |
953 | { | 891 | { |
@@ -1077,7 +1015,7 @@ static void __exit cmos_pnp_remove(struct pnp_dev *pnp) | |||
1077 | 1015 | ||
1078 | static int cmos_pnp_suspend(struct pnp_dev *pnp, pm_message_t mesg) | 1016 | static int cmos_pnp_suspend(struct pnp_dev *pnp, pm_message_t mesg) |
1079 | { | 1017 | { |
1080 | return cmos_suspend(&pnp->dev, mesg); | 1018 | return cmos_suspend(&pnp->dev); |
1081 | } | 1019 | } |
1082 | 1020 | ||
1083 | static int cmos_pnp_resume(struct pnp_dev *pnp) | 1021 | static int cmos_pnp_resume(struct pnp_dev *pnp) |
@@ -1121,6 +1059,47 @@ static struct pnp_driver cmos_pnp_driver = { | |||
1121 | 1059 | ||
1122 | #endif /* CONFIG_PNP */ | 1060 | #endif /* CONFIG_PNP */ |
1123 | 1061 | ||
1062 | #ifdef CONFIG_OF | ||
1063 | static const struct of_device_id of_cmos_match[] = { | ||
1064 | { | ||
1065 | .compatible = "motorola,mc146818", | ||
1066 | }, | ||
1067 | { }, | ||
1068 | }; | ||
1069 | MODULE_DEVICE_TABLE(of, of_cmos_match); | ||
1070 | |||
1071 | static __init void cmos_of_init(struct platform_device *pdev) | ||
1072 | { | ||
1073 | struct device_node *node = pdev->dev.of_node; | ||
1074 | struct rtc_time time; | ||
1075 | int ret; | ||
1076 | const __be32 *val; | ||
1077 | |||
1078 | if (!node) | ||
1079 | return; | ||
1080 | |||
1081 | val = of_get_property(node, "ctrl-reg", NULL); | ||
1082 | if (val) | ||
1083 | CMOS_WRITE(be32_to_cpup(val), RTC_CONTROL); | ||
1084 | |||
1085 | val = of_get_property(node, "freq-reg", NULL); | ||
1086 | if (val) | ||
1087 | CMOS_WRITE(be32_to_cpup(val), RTC_FREQ_SELECT); | ||
1088 | |||
1089 | get_rtc_time(&time); | ||
1090 | ret = rtc_valid_tm(&time); | ||
1091 | if (ret) { | ||
1092 | struct rtc_time def_time = { | ||
1093 | .tm_year = 1, | ||
1094 | .tm_mday = 1, | ||
1095 | }; | ||
1096 | set_rtc_time(&def_time); | ||
1097 | } | ||
1098 | } | ||
1099 | #else | ||
1100 | static inline void cmos_of_init(struct platform_device *pdev) {} | ||
1101 | #define of_cmos_match NULL | ||
1102 | #endif | ||
1124 | /*----------------------------------------------------------------*/ | 1103 | /*----------------------------------------------------------------*/ |
1125 | 1104 | ||
1126 | /* Platform setup should have set up an RTC device, when PNP is | 1105 | /* Platform setup should have set up an RTC device, when PNP is |
@@ -1129,6 +1108,7 @@ static struct pnp_driver cmos_pnp_driver = { | |||
1129 | 1108 | ||
1130 | static int __init cmos_platform_probe(struct platform_device *pdev) | 1109 | static int __init cmos_platform_probe(struct platform_device *pdev) |
1131 | { | 1110 | { |
1111 | cmos_of_init(pdev); | ||
1132 | cmos_wake_setup(&pdev->dev); | 1112 | cmos_wake_setup(&pdev->dev); |
1133 | return cmos_do_probe(&pdev->dev, | 1113 | return cmos_do_probe(&pdev->dev, |
1134 | platform_get_resource(pdev, IORESOURCE_IO, 0), | 1114 | platform_get_resource(pdev, IORESOURCE_IO, 0), |
@@ -1157,8 +1137,10 @@ static struct platform_driver cmos_platform_driver = { | |||
1157 | .shutdown = cmos_platform_shutdown, | 1137 | .shutdown = cmos_platform_shutdown, |
1158 | .driver = { | 1138 | .driver = { |
1159 | .name = (char *) driver_name, | 1139 | .name = (char *) driver_name, |
1160 | .suspend = cmos_suspend, | 1140 | #ifdef CONFIG_PM |
1161 | .resume = cmos_resume, | 1141 | .pm = &cmos_pm_ops, |
1142 | #endif | ||
1143 | .of_match_table = of_cmos_match, | ||
1162 | } | 1144 | } |
1163 | }; | 1145 | }; |
1164 | 1146 | ||
diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c index 316f484999b5..80f9c88214c5 100644 --- a/drivers/rtc/rtc-coh901331.c +++ b/drivers/rtc/rtc-coh901331.c | |||
@@ -220,6 +220,7 @@ static int __init coh901331_probe(struct platform_device *pdev) | |||
220 | } | 220 | } |
221 | clk_disable(rtap->clk); | 221 | clk_disable(rtap->clk); |
222 | 222 | ||
223 | platform_set_drvdata(pdev, rtap); | ||
223 | rtap->rtc = rtc_device_register("coh901331", &pdev->dev, &coh901331_ops, | 224 | rtap->rtc = rtc_device_register("coh901331", &pdev->dev, &coh901331_ops, |
224 | THIS_MODULE); | 225 | THIS_MODULE); |
225 | if (IS_ERR(rtap->rtc)) { | 226 | if (IS_ERR(rtap->rtc)) { |
@@ -227,11 +228,10 @@ static int __init coh901331_probe(struct platform_device *pdev) | |||
227 | goto out_no_rtc; | 228 | goto out_no_rtc; |
228 | } | 229 | } |
229 | 230 | ||
230 | platform_set_drvdata(pdev, rtap); | ||
231 | |||
232 | return 0; | 231 | return 0; |
233 | 232 | ||
234 | out_no_rtc: | 233 | out_no_rtc: |
234 | platform_set_drvdata(pdev, NULL); | ||
235 | out_no_clk_enable: | 235 | out_no_clk_enable: |
236 | clk_put(rtap->clk); | 236 | clk_put(rtap->clk); |
237 | out_no_clk: | 237 | out_no_clk: |
diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c index 34647fc1ee98..755e1fe914af 100644 --- a/drivers/rtc/rtc-davinci.c +++ b/drivers/rtc/rtc-davinci.c | |||
@@ -231,10 +231,6 @@ davinci_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | |||
231 | case RTC_WIE_OFF: | 231 | case RTC_WIE_OFF: |
232 | rtc_ctrl &= ~PRTCSS_RTC_CTRL_WEN; | 232 | rtc_ctrl &= ~PRTCSS_RTC_CTRL_WEN; |
233 | break; | 233 | break; |
234 | case RTC_UIE_OFF: | ||
235 | case RTC_UIE_ON: | ||
236 | ret = -ENOTTY; | ||
237 | break; | ||
238 | default: | 234 | default: |
239 | ret = -ENOIOCTLCMD; | 235 | ret = -ENOIOCTLCMD; |
240 | } | 236 | } |
@@ -473,55 +469,6 @@ static int davinci_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
473 | return 0; | 469 | return 0; |
474 | } | 470 | } |
475 | 471 | ||
476 | static int davinci_rtc_irq_set_state(struct device *dev, int enabled) | ||
477 | { | ||
478 | struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev); | ||
479 | unsigned long flags; | ||
480 | u8 rtc_ctrl; | ||
481 | |||
482 | spin_lock_irqsave(&davinci_rtc_lock, flags); | ||
483 | |||
484 | rtc_ctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL); | ||
485 | |||
486 | if (enabled) { | ||
487 | while (rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL) | ||
488 | & PRTCSS_RTC_CTRL_WDTBUS) | ||
489 | cpu_relax(); | ||
490 | |||
491 | rtc_ctrl |= PRTCSS_RTC_CTRL_TE; | ||
492 | rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL); | ||
493 | |||
494 | rtcss_write(davinci_rtc, 0x0, PRTCSS_RTC_CLKC_CNT); | ||
495 | |||
496 | rtc_ctrl |= PRTCSS_RTC_CTRL_TIEN | | ||
497 | PRTCSS_RTC_CTRL_TMMD | | ||
498 | PRTCSS_RTC_CTRL_TMRFLG; | ||
499 | } else | ||
500 | rtc_ctrl &= ~PRTCSS_RTC_CTRL_TIEN; | ||
501 | |||
502 | rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL); | ||
503 | |||
504 | spin_unlock_irqrestore(&davinci_rtc_lock, flags); | ||
505 | |||
506 | return 0; | ||
507 | } | ||
508 | |||
509 | static int davinci_rtc_irq_set_freq(struct device *dev, int freq) | ||
510 | { | ||
511 | struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev); | ||
512 | unsigned long flags; | ||
513 | u16 tmr_counter = (0x8000 >> (ffs(freq) - 1)); | ||
514 | |||
515 | spin_lock_irqsave(&davinci_rtc_lock, flags); | ||
516 | |||
517 | rtcss_write(davinci_rtc, tmr_counter & 0xFF, PRTCSS_RTC_TMR0); | ||
518 | rtcss_write(davinci_rtc, (tmr_counter & 0xFF00) >> 8, PRTCSS_RTC_TMR1); | ||
519 | |||
520 | spin_unlock_irqrestore(&davinci_rtc_lock, flags); | ||
521 | |||
522 | return 0; | ||
523 | } | ||
524 | |||
525 | static struct rtc_class_ops davinci_rtc_ops = { | 472 | static struct rtc_class_ops davinci_rtc_ops = { |
526 | .ioctl = davinci_rtc_ioctl, | 473 | .ioctl = davinci_rtc_ioctl, |
527 | .read_time = davinci_rtc_read_time, | 474 | .read_time = davinci_rtc_read_time, |
@@ -529,8 +476,6 @@ static struct rtc_class_ops davinci_rtc_ops = { | |||
529 | .alarm_irq_enable = davinci_rtc_alarm_irq_enable, | 476 | .alarm_irq_enable = davinci_rtc_alarm_irq_enable, |
530 | .read_alarm = davinci_rtc_read_alarm, | 477 | .read_alarm = davinci_rtc_read_alarm, |
531 | .set_alarm = davinci_rtc_set_alarm, | 478 | .set_alarm = davinci_rtc_set_alarm, |
532 | .irq_set_state = davinci_rtc_irq_set_state, | ||
533 | .irq_set_freq = davinci_rtc_irq_set_freq, | ||
534 | }; | 479 | }; |
535 | 480 | ||
536 | static int __init davinci_rtc_probe(struct platform_device *pdev) | 481 | static int __init davinci_rtc_probe(struct platform_device *pdev) |
@@ -579,6 +524,8 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) | |||
579 | goto fail2; | 524 | goto fail2; |
580 | } | 525 | } |
581 | 526 | ||
527 | platform_set_drvdata(pdev, davinci_rtc); | ||
528 | |||
582 | davinci_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, | 529 | davinci_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, |
583 | &davinci_rtc_ops, THIS_MODULE); | 530 | &davinci_rtc_ops, THIS_MODULE); |
584 | if (IS_ERR(davinci_rtc->rtc)) { | 531 | if (IS_ERR(davinci_rtc->rtc)) { |
@@ -608,8 +555,6 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) | |||
608 | 555 | ||
609 | rtcss_write(davinci_rtc, PRTCSS_RTC_CCTRL_CAEN, PRTCSS_RTC_CCTRL); | 556 | rtcss_write(davinci_rtc, PRTCSS_RTC_CCTRL_CAEN, PRTCSS_RTC_CCTRL); |
610 | 557 | ||
611 | platform_set_drvdata(pdev, davinci_rtc); | ||
612 | |||
613 | device_init_wakeup(&pdev->dev, 0); | 558 | device_init_wakeup(&pdev->dev, 0); |
614 | 559 | ||
615 | return 0; | 560 | return 0; |
@@ -617,6 +562,7 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) | |||
617 | fail4: | 562 | fail4: |
618 | rtc_device_unregister(davinci_rtc->rtc); | 563 | rtc_device_unregister(davinci_rtc->rtc); |
619 | fail3: | 564 | fail3: |
565 | platform_set_drvdata(pdev, NULL); | ||
620 | iounmap(davinci_rtc->base); | 566 | iounmap(davinci_rtc->base); |
621 | fail2: | 567 | fail2: |
622 | release_mem_region(davinci_rtc->pbase, davinci_rtc->base_size); | 568 | release_mem_region(davinci_rtc->pbase, davinci_rtc->base_size); |
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 62227cd52410..cace6d3aed9a 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c | |||
@@ -76,7 +76,7 @@ static void rtc_uie_task(struct work_struct *work) | |||
76 | } | 76 | } |
77 | spin_unlock_irq(&rtc->irq_lock); | 77 | spin_unlock_irq(&rtc->irq_lock); |
78 | if (num) | 78 | if (num) |
79 | rtc_update_irq(rtc, num, RTC_UF | RTC_IRQF); | 79 | rtc_handle_legacy_irq(rtc, num, RTC_UF); |
80 | } | 80 | } |
81 | static void rtc_uie_timer(unsigned long data) | 81 | static void rtc_uie_timer(unsigned long data) |
82 | { | 82 | { |
@@ -253,19 +253,7 @@ static long rtc_dev_ioctl(struct file *file, | |||
253 | if (err) | 253 | if (err) |
254 | goto done; | 254 | goto done; |
255 | 255 | ||
256 | /* try the driver's ioctl interface */ | 256 | /* |
257 | if (ops->ioctl) { | ||
258 | err = ops->ioctl(rtc->dev.parent, cmd, arg); | ||
259 | if (err != -ENOIOCTLCMD) { | ||
260 | mutex_unlock(&rtc->ops_lock); | ||
261 | return err; | ||
262 | } | ||
263 | } | ||
264 | |||
265 | /* if the driver does not provide the ioctl interface | ||
266 | * or if that particular ioctl was not implemented | ||
267 | * (-ENOIOCTLCMD), we will try to emulate here. | ||
268 | * | ||
269 | * Drivers *SHOULD NOT* provide ioctl implementations | 257 | * Drivers *SHOULD NOT* provide ioctl implementations |
270 | * for these requests. Instead, provide methods to | 258 | * for these requests. Instead, provide methods to |
271 | * support the following code, so that the RTC's main | 259 | * support the following code, so that the RTC's main |
@@ -428,7 +416,13 @@ static long rtc_dev_ioctl(struct file *file, | |||
428 | return err; | 416 | return err; |
429 | 417 | ||
430 | default: | 418 | default: |
431 | err = -ENOTTY; | 419 | /* Finally try the driver's ioctl interface */ |
420 | if (ops->ioctl) { | ||
421 | err = ops->ioctl(rtc->dev.parent, cmd, arg); | ||
422 | if (err == -ENOIOCTLCMD) | ||
423 | err = -ENOTTY; | ||
424 | } else | ||
425 | err = -ENOTTY; | ||
432 | break; | 426 | break; |
433 | } | 427 | } |
434 | 428 | ||
diff --git a/drivers/rtc/rtc-ds1286.c b/drivers/rtc/rtc-ds1286.c index bf430f9091ed..47e681df31e2 100644 --- a/drivers/rtc/rtc-ds1286.c +++ b/drivers/rtc/rtc-ds1286.c | |||
@@ -40,6 +40,26 @@ static inline void ds1286_rtc_write(struct ds1286_priv *priv, u8 data, int reg) | |||
40 | __raw_writel(data, &priv->rtcregs[reg]); | 40 | __raw_writel(data, &priv->rtcregs[reg]); |
41 | } | 41 | } |
42 | 42 | ||
43 | |||
44 | static int ds1286_alarm_irq_enable(struct device *dev, unsigned int enabled) | ||
45 | { | ||
46 | struct ds1286_priv *priv = dev_get_drvdata(dev); | ||
47 | unsigned long flags; | ||
48 | unsigned char val; | ||
49 | |||
50 | /* Allow or mask alarm interrupts */ | ||
51 | spin_lock_irqsave(&priv->lock, flags); | ||
52 | val = ds1286_rtc_read(priv, RTC_CMD); | ||
53 | if (enabled) | ||
54 | val &= ~RTC_TDM; | ||
55 | else | ||
56 | val |= RTC_TDM; | ||
57 | ds1286_rtc_write(priv, val, RTC_CMD); | ||
58 | spin_unlock_irqrestore(&priv->lock, flags); | ||
59 | |||
60 | return 0; | ||
61 | } | ||
62 | |||
43 | #ifdef CONFIG_RTC_INTF_DEV | 63 | #ifdef CONFIG_RTC_INTF_DEV |
44 | 64 | ||
45 | static int ds1286_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | 65 | static int ds1286_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) |
@@ -49,22 +69,6 @@ static int ds1286_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | |||
49 | unsigned char val; | 69 | unsigned char val; |
50 | 70 | ||
51 | switch (cmd) { | 71 | switch (cmd) { |
52 | case RTC_AIE_OFF: | ||
53 | /* Mask alarm int. enab. bit */ | ||
54 | spin_lock_irqsave(&priv->lock, flags); | ||
55 | val = ds1286_rtc_read(priv, RTC_CMD); | ||
56 | val |= RTC_TDM; | ||
57 | ds1286_rtc_write(priv, val, RTC_CMD); | ||
58 | spin_unlock_irqrestore(&priv->lock, flags); | ||
59 | break; | ||
60 | case RTC_AIE_ON: | ||
61 | /* Allow alarm interrupts. */ | ||
62 | spin_lock_irqsave(&priv->lock, flags); | ||
63 | val = ds1286_rtc_read(priv, RTC_CMD); | ||
64 | val &= ~RTC_TDM; | ||
65 | ds1286_rtc_write(priv, val, RTC_CMD); | ||
66 | spin_unlock_irqrestore(&priv->lock, flags); | ||
67 | break; | ||
68 | case RTC_WIE_OFF: | 72 | case RTC_WIE_OFF: |
69 | /* Mask watchdog int. enab. bit */ | 73 | /* Mask watchdog int. enab. bit */ |
70 | spin_lock_irqsave(&priv->lock, flags); | 74 | spin_lock_irqsave(&priv->lock, flags); |
@@ -316,12 +320,13 @@ static int ds1286_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
316 | } | 320 | } |
317 | 321 | ||
318 | static const struct rtc_class_ops ds1286_ops = { | 322 | static const struct rtc_class_ops ds1286_ops = { |
319 | .ioctl = ds1286_ioctl, | 323 | .ioctl = ds1286_ioctl, |
320 | .proc = ds1286_proc, | 324 | .proc = ds1286_proc, |
321 | .read_time = ds1286_read_time, | 325 | .read_time = ds1286_read_time, |
322 | .set_time = ds1286_set_time, | 326 | .set_time = ds1286_set_time, |
323 | .read_alarm = ds1286_read_alarm, | 327 | .read_alarm = ds1286_read_alarm, |
324 | .set_alarm = ds1286_set_alarm, | 328 | .set_alarm = ds1286_set_alarm, |
329 | .alarm_irq_enable = ds1286_alarm_irq_enable, | ||
325 | }; | 330 | }; |
326 | 331 | ||
327 | static int __devinit ds1286_probe(struct platform_device *pdev) | 332 | static int __devinit ds1286_probe(struct platform_device *pdev) |
@@ -350,6 +355,7 @@ static int __devinit ds1286_probe(struct platform_device *pdev) | |||
350 | goto out; | 355 | goto out; |
351 | } | 356 | } |
352 | spin_lock_init(&priv->lock); | 357 | spin_lock_init(&priv->lock); |
358 | platform_set_drvdata(pdev, priv); | ||
353 | rtc = rtc_device_register("ds1286", &pdev->dev, | 359 | rtc = rtc_device_register("ds1286", &pdev->dev, |
354 | &ds1286_ops, THIS_MODULE); | 360 | &ds1286_ops, THIS_MODULE); |
355 | if (IS_ERR(rtc)) { | 361 | if (IS_ERR(rtc)) { |
@@ -357,7 +363,6 @@ static int __devinit ds1286_probe(struct platform_device *pdev) | |||
357 | goto out; | 363 | goto out; |
358 | } | 364 | } |
359 | priv->rtc = rtc; | 365 | priv->rtc = rtc; |
360 | platform_set_drvdata(pdev, priv); | ||
361 | return 0; | 366 | return 0; |
362 | 367 | ||
363 | out: | 368 | out: |
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c index 359d1e04626c..f0d638922644 100644 --- a/drivers/rtc/rtc-ds1302.c +++ b/drivers/rtc/rtc-ds1302.c | |||
@@ -35,7 +35,7 @@ | |||
35 | 35 | ||
36 | #ifdef CONFIG_SH_SECUREEDGE5410 | 36 | #ifdef CONFIG_SH_SECUREEDGE5410 |
37 | #include <asm/rtc.h> | 37 | #include <asm/rtc.h> |
38 | #include <mach/snapgear.h> | 38 | #include <mach/secureedge5410.h> |
39 | 39 | ||
40 | #define RTC_RESET 0x1000 | 40 | #define RTC_RESET 0x1000 |
41 | #define RTC_IODATA 0x0800 | 41 | #define RTC_IODATA 0x0800 |
diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index 48da85e97ca4..57fbcc149ba7 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c | |||
@@ -139,49 +139,32 @@ static u8 hour2bcd(bool hr12, int hour) | |||
139 | * Interface to RTC framework | 139 | * Interface to RTC framework |
140 | */ | 140 | */ |
141 | 141 | ||
142 | #ifdef CONFIG_RTC_INTF_DEV | 142 | static int ds1305_alarm_irq_enable(struct device *dev, unsigned int enabled) |
143 | |||
144 | /* | ||
145 | * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl) | ||
146 | */ | ||
147 | static int ds1305_ioctl(struct device *dev, unsigned cmd, unsigned long arg) | ||
148 | { | 143 | { |
149 | struct ds1305 *ds1305 = dev_get_drvdata(dev); | 144 | struct ds1305 *ds1305 = dev_get_drvdata(dev); |
150 | u8 buf[2]; | 145 | u8 buf[2]; |
151 | int status = -ENOIOCTLCMD; | 146 | long err = -EINVAL; |
152 | 147 | ||
153 | buf[0] = DS1305_WRITE | DS1305_CONTROL; | 148 | buf[0] = DS1305_WRITE | DS1305_CONTROL; |
154 | buf[1] = ds1305->ctrl[0]; | 149 | buf[1] = ds1305->ctrl[0]; |
155 | 150 | ||
156 | switch (cmd) { | 151 | if (enabled) { |
157 | case RTC_AIE_OFF: | ||
158 | status = 0; | ||
159 | if (!(buf[1] & DS1305_AEI0)) | ||
160 | goto done; | ||
161 | buf[1] &= ~DS1305_AEI0; | ||
162 | break; | ||
163 | |||
164 | case RTC_AIE_ON: | ||
165 | status = 0; | ||
166 | if (ds1305->ctrl[0] & DS1305_AEI0) | 152 | if (ds1305->ctrl[0] & DS1305_AEI0) |
167 | goto done; | 153 | goto done; |
168 | buf[1] |= DS1305_AEI0; | 154 | buf[1] |= DS1305_AEI0; |
169 | break; | 155 | } else { |
170 | } | 156 | if (!(buf[1] & DS1305_AEI0)) |
171 | if (status == 0) { | 157 | goto done; |
172 | status = spi_write_then_read(ds1305->spi, buf, sizeof buf, | 158 | buf[1] &= ~DS1305_AEI0; |
173 | NULL, 0); | ||
174 | if (status >= 0) | ||
175 | ds1305->ctrl[0] = buf[1]; | ||
176 | } | 159 | } |
177 | 160 | err = spi_write_then_read(ds1305->spi, buf, sizeof buf, NULL, 0); | |
161 | if (err >= 0) | ||
162 | ds1305->ctrl[0] = buf[1]; | ||
178 | done: | 163 | done: |
179 | return status; | 164 | return err; |
165 | |||
180 | } | 166 | } |
181 | 167 | ||
182 | #else | ||
183 | #define ds1305_ioctl NULL | ||
184 | #endif | ||
185 | 168 | ||
186 | /* | 169 | /* |
187 | * Get/set of date and time is pretty normal. | 170 | * Get/set of date and time is pretty normal. |
@@ -460,12 +443,12 @@ done: | |||
460 | #endif | 443 | #endif |
461 | 444 | ||
462 | static const struct rtc_class_ops ds1305_ops = { | 445 | static const struct rtc_class_ops ds1305_ops = { |
463 | .ioctl = ds1305_ioctl, | ||
464 | .read_time = ds1305_get_time, | 446 | .read_time = ds1305_get_time, |
465 | .set_time = ds1305_set_time, | 447 | .set_time = ds1305_set_time, |
466 | .read_alarm = ds1305_get_alarm, | 448 | .read_alarm = ds1305_get_alarm, |
467 | .set_alarm = ds1305_set_alarm, | 449 | .set_alarm = ds1305_set_alarm, |
468 | .proc = ds1305_proc, | 450 | .proc = ds1305_proc, |
451 | .alarm_irq_enable = ds1305_alarm_irq_enable, | ||
469 | }; | 452 | }; |
470 | 453 | ||
471 | static void ds1305_work(struct work_struct *work) | 454 | static void ds1305_work(struct work_struct *work) |
@@ -813,7 +796,7 @@ static int __devexit ds1305_remove(struct spi_device *spi) | |||
813 | if (spi->irq) { | 796 | if (spi->irq) { |
814 | set_bit(FLAG_EXITING, &ds1305->flags); | 797 | set_bit(FLAG_EXITING, &ds1305->flags); |
815 | free_irq(spi->irq, ds1305); | 798 | free_irq(spi->irq, ds1305); |
816 | flush_scheduled_work(); | 799 | cancel_work_sync(&ds1305->work); |
817 | } | 800 | } |
818 | 801 | ||
819 | rtc_device_unregister(ds1305->rtc); | 802 | rtc_device_unregister(ds1305->rtc); |
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index d827ce570a8c..b2005b44e4f7 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c | |||
@@ -106,9 +106,9 @@ struct ds1307 { | |||
106 | struct i2c_client *client; | 106 | struct i2c_client *client; |
107 | struct rtc_device *rtc; | 107 | struct rtc_device *rtc; |
108 | struct work_struct work; | 108 | struct work_struct work; |
109 | s32 (*read_block_data)(struct i2c_client *client, u8 command, | 109 | s32 (*read_block_data)(const struct i2c_client *client, u8 command, |
110 | u8 length, u8 *values); | 110 | u8 length, u8 *values); |
111 | s32 (*write_block_data)(struct i2c_client *client, u8 command, | 111 | s32 (*write_block_data)(const struct i2c_client *client, u8 command, |
112 | u8 length, const u8 *values); | 112 | u8 length, const u8 *values); |
113 | }; | 113 | }; |
114 | 114 | ||
@@ -149,6 +149,7 @@ static const struct i2c_device_id ds1307_id[] = { | |||
149 | { "ds1340", ds_1340 }, | 149 | { "ds1340", ds_1340 }, |
150 | { "ds3231", ds_3231 }, | 150 | { "ds3231", ds_3231 }, |
151 | { "m41t00", m41t00 }, | 151 | { "m41t00", m41t00 }, |
152 | { "pt7c4338", ds_1307 }, | ||
152 | { "rx8025", rx_8025 }, | 153 | { "rx8025", rx_8025 }, |
153 | { } | 154 | { } |
154 | }; | 155 | }; |
@@ -158,8 +159,8 @@ MODULE_DEVICE_TABLE(i2c, ds1307_id); | |||
158 | 159 | ||
159 | #define BLOCK_DATA_MAX_TRIES 10 | 160 | #define BLOCK_DATA_MAX_TRIES 10 |
160 | 161 | ||
161 | static s32 ds1307_read_block_data_once(struct i2c_client *client, u8 command, | 162 | static s32 ds1307_read_block_data_once(const struct i2c_client *client, |
162 | u8 length, u8 *values) | 163 | u8 command, u8 length, u8 *values) |
163 | { | 164 | { |
164 | s32 i, data; | 165 | s32 i, data; |
165 | 166 | ||
@@ -172,7 +173,7 @@ static s32 ds1307_read_block_data_once(struct i2c_client *client, u8 command, | |||
172 | return i; | 173 | return i; |
173 | } | 174 | } |
174 | 175 | ||
175 | static s32 ds1307_read_block_data(struct i2c_client *client, u8 command, | 176 | static s32 ds1307_read_block_data(const struct i2c_client *client, u8 command, |
176 | u8 length, u8 *values) | 177 | u8 length, u8 *values) |
177 | { | 178 | { |
178 | u8 oldvalues[I2C_SMBUS_BLOCK_MAX]; | 179 | u8 oldvalues[I2C_SMBUS_BLOCK_MAX]; |
@@ -198,7 +199,7 @@ static s32 ds1307_read_block_data(struct i2c_client *client, u8 command, | |||
198 | return length; | 199 | return length; |
199 | } | 200 | } |
200 | 201 | ||
201 | static s32 ds1307_write_block_data(struct i2c_client *client, u8 command, | 202 | static s32 ds1307_write_block_data(const struct i2c_client *client, u8 command, |
202 | u8 length, const u8 *values) | 203 | u8 length, const u8 *values) |
203 | { | 204 | { |
204 | u8 currvalues[I2C_SMBUS_BLOCK_MAX]; | 205 | u8 currvalues[I2C_SMBUS_BLOCK_MAX]; |
@@ -495,50 +496,27 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
495 | return 0; | 496 | return 0; |
496 | } | 497 | } |
497 | 498 | ||
498 | static int ds1307_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | 499 | static int ds1307_alarm_irq_enable(struct device *dev, unsigned int enabled) |
499 | { | 500 | { |
500 | struct i2c_client *client = to_i2c_client(dev); | 501 | struct i2c_client *client = to_i2c_client(dev); |
501 | struct ds1307 *ds1307 = i2c_get_clientdata(client); | 502 | struct ds1307 *ds1307 = i2c_get_clientdata(client); |
502 | int ret; | 503 | int ret; |
503 | 504 | ||
504 | switch (cmd) { | 505 | if (!test_bit(HAS_ALARM, &ds1307->flags)) |
505 | case RTC_AIE_OFF: | 506 | return -ENOTTY; |
506 | if (!test_bit(HAS_ALARM, &ds1307->flags)) | ||
507 | return -ENOTTY; | ||
508 | |||
509 | ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL); | ||
510 | if (ret < 0) | ||
511 | return ret; | ||
512 | |||
513 | ret &= ~DS1337_BIT_A1IE; | ||
514 | |||
515 | ret = i2c_smbus_write_byte_data(client, | ||
516 | DS1337_REG_CONTROL, ret); | ||
517 | if (ret < 0) | ||
518 | return ret; | ||
519 | |||
520 | break; | ||
521 | |||
522 | case RTC_AIE_ON: | ||
523 | if (!test_bit(HAS_ALARM, &ds1307->flags)) | ||
524 | return -ENOTTY; | ||
525 | 507 | ||
526 | ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL); | 508 | ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL); |
527 | if (ret < 0) | 509 | if (ret < 0) |
528 | return ret; | 510 | return ret; |
529 | 511 | ||
512 | if (enabled) | ||
530 | ret |= DS1337_BIT_A1IE; | 513 | ret |= DS1337_BIT_A1IE; |
514 | else | ||
515 | ret &= ~DS1337_BIT_A1IE; | ||
531 | 516 | ||
532 | ret = i2c_smbus_write_byte_data(client, | 517 | ret = i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, ret); |
533 | DS1337_REG_CONTROL, ret); | 518 | if (ret < 0) |
534 | if (ret < 0) | 519 | return ret; |
535 | return ret; | ||
536 | |||
537 | break; | ||
538 | |||
539 | default: | ||
540 | return -ENOIOCTLCMD; | ||
541 | } | ||
542 | 520 | ||
543 | return 0; | 521 | return 0; |
544 | } | 522 | } |
@@ -548,7 +526,7 @@ static const struct rtc_class_ops ds13xx_rtc_ops = { | |||
548 | .set_time = ds1307_set_time, | 526 | .set_time = ds1307_set_time, |
549 | .read_alarm = ds1337_read_alarm, | 527 | .read_alarm = ds1337_read_alarm, |
550 | .set_alarm = ds1337_set_alarm, | 528 | .set_alarm = ds1337_set_alarm, |
551 | .ioctl = ds1307_ioctl, | 529 | .alarm_irq_enable = ds1307_alarm_irq_enable, |
552 | }; | 530 | }; |
553 | 531 | ||
554 | /*----------------------------------------------------------------------*/ | 532 | /*----------------------------------------------------------------------*/ |
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index 1f0007fd4431..e6e71deb188f 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/bcd.h> | 25 | #include <linux/bcd.h> |
26 | #include <linux/workqueue.h> | 26 | #include <linux/workqueue.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/pm.h> | ||
28 | 29 | ||
29 | #define DS1374_REG_TOD0 0x00 /* Time of Day */ | 30 | #define DS1374_REG_TOD0 0x00 /* Time of Day */ |
30 | #define DS1374_REG_TOD1 0x01 | 31 | #define DS1374_REG_TOD1 0x01 |
@@ -307,42 +308,25 @@ unlock: | |||
307 | mutex_unlock(&ds1374->mutex); | 308 | mutex_unlock(&ds1374->mutex); |
308 | } | 309 | } |
309 | 310 | ||
310 | static int ds1374_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | 311 | static int ds1374_alarm_irq_enable(struct device *dev, unsigned int enabled) |
311 | { | 312 | { |
312 | struct i2c_client *client = to_i2c_client(dev); | 313 | struct i2c_client *client = to_i2c_client(dev); |
313 | struct ds1374 *ds1374 = i2c_get_clientdata(client); | 314 | struct ds1374 *ds1374 = i2c_get_clientdata(client); |
314 | int ret = -ENOIOCTLCMD; | 315 | int ret; |
315 | 316 | ||
316 | mutex_lock(&ds1374->mutex); | 317 | mutex_lock(&ds1374->mutex); |
317 | 318 | ||
318 | switch (cmd) { | 319 | ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR); |
319 | case RTC_AIE_OFF: | 320 | if (ret < 0) |
320 | ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR); | 321 | goto out; |
321 | if (ret < 0) | ||
322 | goto out; | ||
323 | |||
324 | ret &= ~DS1374_REG_CR_WACE; | ||
325 | |||
326 | ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret); | ||
327 | if (ret < 0) | ||
328 | goto out; | ||
329 | |||
330 | break; | ||
331 | |||
332 | case RTC_AIE_ON: | ||
333 | ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR); | ||
334 | if (ret < 0) | ||
335 | goto out; | ||
336 | 322 | ||
323 | if (enabled) { | ||
337 | ret |= DS1374_REG_CR_WACE | DS1374_REG_CR_AIE; | 324 | ret |= DS1374_REG_CR_WACE | DS1374_REG_CR_AIE; |
338 | ret &= ~DS1374_REG_CR_WDALM; | 325 | ret &= ~DS1374_REG_CR_WDALM; |
339 | 326 | } else { | |
340 | ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret); | 327 | ret &= ~DS1374_REG_CR_WACE; |
341 | if (ret < 0) | ||
342 | goto out; | ||
343 | |||
344 | break; | ||
345 | } | 328 | } |
329 | ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret); | ||
346 | 330 | ||
347 | out: | 331 | out: |
348 | mutex_unlock(&ds1374->mutex); | 332 | mutex_unlock(&ds1374->mutex); |
@@ -354,7 +338,7 @@ static const struct rtc_class_ops ds1374_rtc_ops = { | |||
354 | .set_time = ds1374_set_time, | 338 | .set_time = ds1374_set_time, |
355 | .read_alarm = ds1374_read_alarm, | 339 | .read_alarm = ds1374_read_alarm, |
356 | .set_alarm = ds1374_set_alarm, | 340 | .set_alarm = ds1374_set_alarm, |
357 | .ioctl = ds1374_ioctl, | 341 | .alarm_irq_enable = ds1374_alarm_irq_enable, |
358 | }; | 342 | }; |
359 | 343 | ||
360 | static int ds1374_probe(struct i2c_client *client, | 344 | static int ds1374_probe(struct i2c_client *client, |
@@ -417,7 +401,7 @@ static int __devexit ds1374_remove(struct i2c_client *client) | |||
417 | mutex_unlock(&ds1374->mutex); | 401 | mutex_unlock(&ds1374->mutex); |
418 | 402 | ||
419 | free_irq(client->irq, client); | 403 | free_irq(client->irq, client); |
420 | flush_scheduled_work(); | 404 | cancel_work_sync(&ds1374->work); |
421 | } | 405 | } |
422 | 406 | ||
423 | rtc_device_unregister(ds1374->rtc); | 407 | rtc_device_unregister(ds1374->rtc); |
@@ -426,32 +410,38 @@ static int __devexit ds1374_remove(struct i2c_client *client) | |||
426 | } | 410 | } |
427 | 411 | ||
428 | #ifdef CONFIG_PM | 412 | #ifdef CONFIG_PM |
429 | static int ds1374_suspend(struct i2c_client *client, pm_message_t state) | 413 | static int ds1374_suspend(struct device *dev) |
430 | { | 414 | { |
415 | struct i2c_client *client = to_i2c_client(dev); | ||
416 | |||
431 | if (client->irq >= 0 && device_may_wakeup(&client->dev)) | 417 | if (client->irq >= 0 && device_may_wakeup(&client->dev)) |
432 | enable_irq_wake(client->irq); | 418 | enable_irq_wake(client->irq); |
433 | return 0; | 419 | return 0; |
434 | } | 420 | } |
435 | 421 | ||
436 | static int ds1374_resume(struct i2c_client *client) | 422 | static int ds1374_resume(struct device *dev) |
437 | { | 423 | { |
424 | struct i2c_client *client = to_i2c_client(dev); | ||
425 | |||
438 | if (client->irq >= 0 && device_may_wakeup(&client->dev)) | 426 | if (client->irq >= 0 && device_may_wakeup(&client->dev)) |
439 | disable_irq_wake(client->irq); | 427 | disable_irq_wake(client->irq); |
440 | return 0; | 428 | return 0; |
441 | } | 429 | } |
430 | |||
431 | static SIMPLE_DEV_PM_OPS(ds1374_pm, ds1374_suspend, ds1374_resume); | ||
432 | |||
433 | #define DS1374_PM (&ds1374_pm) | ||
442 | #else | 434 | #else |
443 | #define ds1374_suspend NULL | 435 | #define DS1374_PM NULL |
444 | #define ds1374_resume NULL | ||
445 | #endif | 436 | #endif |
446 | 437 | ||
447 | static struct i2c_driver ds1374_driver = { | 438 | static struct i2c_driver ds1374_driver = { |
448 | .driver = { | 439 | .driver = { |
449 | .name = "rtc-ds1374", | 440 | .name = "rtc-ds1374", |
450 | .owner = THIS_MODULE, | 441 | .owner = THIS_MODULE, |
442 | .pm = DS1374_PM, | ||
451 | }, | 443 | }, |
452 | .probe = ds1374_probe, | 444 | .probe = ds1374_probe, |
453 | .suspend = ds1374_suspend, | ||
454 | .resume = ds1374_resume, | ||
455 | .remove = __devexit_p(ds1374_remove), | 445 | .remove = __devexit_p(ds1374_remove), |
456 | .id_table = ds1374_id, | 446 | .id_table = ds1374_id, |
457 | }; | 447 | }; |
diff --git a/drivers/rtc/rtc-ds1390.c b/drivers/rtc/rtc-ds1390.c index 26a86d235051..b038d2cfef26 100644 --- a/drivers/rtc/rtc-ds1390.c +++ b/drivers/rtc/rtc-ds1390.c | |||
@@ -158,7 +158,7 @@ static int __devinit ds1390_probe(struct spi_device *spi) | |||
158 | 158 | ||
159 | static int __devexit ds1390_remove(struct spi_device *spi) | 159 | static int __devexit ds1390_remove(struct spi_device *spi) |
160 | { | 160 | { |
161 | struct ds1390 *chip = platform_get_drvdata(spi); | 161 | struct ds1390 *chip = spi_get_drvdata(spi); |
162 | 162 | ||
163 | rtc_device_unregister(chip->rtc); | 163 | rtc_device_unregister(chip->rtc); |
164 | kfree(chip); | 164 | kfree(chip); |
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index 37268e97de49..fbabc773dded 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c | |||
@@ -397,29 +397,12 @@ static int ds1511_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | |||
397 | return 0; | 397 | return 0; |
398 | } | 398 | } |
399 | 399 | ||
400 | static int ds1511_rtc_update_irq_enable(struct device *dev, | ||
401 | unsigned int enabled) | ||
402 | { | ||
403 | struct platform_device *pdev = to_platform_device(dev); | ||
404 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | ||
405 | |||
406 | if (pdata->irq <= 0) | ||
407 | return -EINVAL; | ||
408 | if (enabled) | ||
409 | pdata->irqen |= RTC_UF; | ||
410 | else | ||
411 | pdata->irqen &= ~RTC_UF; | ||
412 | ds1511_rtc_update_alarm(pdata); | ||
413 | return 0; | ||
414 | } | ||
415 | |||
416 | static const struct rtc_class_ops ds1511_rtc_ops = { | 400 | static const struct rtc_class_ops ds1511_rtc_ops = { |
417 | .read_time = ds1511_rtc_read_time, | 401 | .read_time = ds1511_rtc_read_time, |
418 | .set_time = ds1511_rtc_set_time, | 402 | .set_time = ds1511_rtc_set_time, |
419 | .read_alarm = ds1511_rtc_read_alarm, | 403 | .read_alarm = ds1511_rtc_read_alarm, |
420 | .set_alarm = ds1511_rtc_set_alarm, | 404 | .set_alarm = ds1511_rtc_set_alarm, |
421 | .alarm_irq_enable = ds1511_rtc_alarm_irq_enable, | 405 | .alarm_irq_enable = ds1511_rtc_alarm_irq_enable, |
422 | .update_irq_enable = ds1511_rtc_update_irq_enable, | ||
423 | }; | 406 | }; |
424 | 407 | ||
425 | static ssize_t | 408 | static ssize_t |
@@ -485,7 +468,7 @@ ds1511_nvram_write(struct file *filp, struct kobject *kobj, | |||
485 | static struct bin_attribute ds1511_nvram_attr = { | 468 | static struct bin_attribute ds1511_nvram_attr = { |
486 | .attr = { | 469 | .attr = { |
487 | .name = "nvram", | 470 | .name = "nvram", |
488 | .mode = S_IRUGO | S_IWUGO, | 471 | .mode = S_IRUGO | S_IWUSR, |
489 | }, | 472 | }, |
490 | .size = DS1511_RAM_MAX, | 473 | .size = DS1511_RAM_MAX, |
491 | .read = ds1511_nvram_read, | 474 | .read = ds1511_nvram_read, |
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index ff432e2ca275..fee41b97c9e8 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c | |||
@@ -227,29 +227,12 @@ static int ds1553_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | |||
227 | return 0; | 227 | return 0; |
228 | } | 228 | } |
229 | 229 | ||
230 | static int ds1553_rtc_update_irq_enable(struct device *dev, | ||
231 | unsigned int enabled) | ||
232 | { | ||
233 | struct platform_device *pdev = to_platform_device(dev); | ||
234 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | ||
235 | |||
236 | if (pdata->irq <= 0) | ||
237 | return -EINVAL; | ||
238 | if (enabled) | ||
239 | pdata->irqen |= RTC_UF; | ||
240 | else | ||
241 | pdata->irqen &= ~RTC_UF; | ||
242 | ds1553_rtc_update_alarm(pdata); | ||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | static const struct rtc_class_ops ds1553_rtc_ops = { | 230 | static const struct rtc_class_ops ds1553_rtc_ops = { |
247 | .read_time = ds1553_rtc_read_time, | 231 | .read_time = ds1553_rtc_read_time, |
248 | .set_time = ds1553_rtc_set_time, | 232 | .set_time = ds1553_rtc_set_time, |
249 | .read_alarm = ds1553_rtc_read_alarm, | 233 | .read_alarm = ds1553_rtc_read_alarm, |
250 | .set_alarm = ds1553_rtc_set_alarm, | 234 | .set_alarm = ds1553_rtc_set_alarm, |
251 | .alarm_irq_enable = ds1553_rtc_alarm_irq_enable, | 235 | .alarm_irq_enable = ds1553_rtc_alarm_irq_enable, |
252 | .update_irq_enable = ds1553_rtc_update_irq_enable, | ||
253 | }; | 236 | }; |
254 | 237 | ||
255 | static ssize_t ds1553_nvram_read(struct file *filp, struct kobject *kobj, | 238 | static ssize_t ds1553_nvram_read(struct file *filp, struct kobject *kobj, |
diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index 9de8516e3531..27b7bf672ac6 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c | |||
@@ -1,7 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * RTC client/driver for the Maxim/Dallas DS3232 Real-Time Clock over I2C | 2 | * RTC client/driver for the Maxim/Dallas DS3232 Real-Time Clock over I2C |
3 | * | 3 | * |
4 | * Copyright (C) 2009-2010 Freescale Semiconductor. | 4 | * Copyright (C) 2009-2011 Freescale Semiconductor. |
5 | * Author: Jack Lan <jack.lan@freescale.com> | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of the GNU General Public License as published by the | 8 | * under the terms of the GNU General Public License as published by the |
@@ -140,9 +141,11 @@ static int ds3232_read_time(struct device *dev, struct rtc_time *time) | |||
140 | time->tm_hour = bcd2bin(hour); | 141 | time->tm_hour = bcd2bin(hour); |
141 | } | 142 | } |
142 | 143 | ||
143 | time->tm_wday = bcd2bin(week); | 144 | /* Day of the week in linux range is 0~6 while 1~7 in RTC chip */ |
145 | time->tm_wday = bcd2bin(week) - 1; | ||
144 | time->tm_mday = bcd2bin(day); | 146 | time->tm_mday = bcd2bin(day); |
145 | time->tm_mon = bcd2bin(month & 0x7F); | 147 | /* linux tm_mon range:0~11, while month range is 1~12 in RTC chip */ |
148 | time->tm_mon = bcd2bin(month & 0x7F) - 1; | ||
146 | if (century) | 149 | if (century) |
147 | add_century = 100; | 150 | add_century = 100; |
148 | 151 | ||
@@ -161,9 +164,11 @@ static int ds3232_set_time(struct device *dev, struct rtc_time *time) | |||
161 | buf[0] = bin2bcd(time->tm_sec); | 164 | buf[0] = bin2bcd(time->tm_sec); |
162 | buf[1] = bin2bcd(time->tm_min); | 165 | buf[1] = bin2bcd(time->tm_min); |
163 | buf[2] = bin2bcd(time->tm_hour); | 166 | buf[2] = bin2bcd(time->tm_hour); |
164 | buf[3] = bin2bcd(time->tm_wday); /* Day of the week */ | 167 | /* Day of the week in linux range is 0~6 while 1~7 in RTC chip */ |
168 | buf[3] = bin2bcd(time->tm_wday + 1); | ||
165 | buf[4] = bin2bcd(time->tm_mday); /* Date */ | 169 | buf[4] = bin2bcd(time->tm_mday); /* Date */ |
166 | buf[5] = bin2bcd(time->tm_mon); | 170 | /* linux tm_mon range:0~11, while month range is 1~12 in RTC chip */ |
171 | buf[5] = bin2bcd(time->tm_mon + 1); | ||
167 | if (time->tm_year >= 100) { | 172 | if (time->tm_year >= 100) { |
168 | buf[5] |= 0x80; | 173 | buf[5] |= 0x80; |
169 | buf[6] = bin2bcd(time->tm_year - 100); | 174 | buf[6] = bin2bcd(time->tm_year - 100); |
@@ -175,6 +180,165 @@ static int ds3232_set_time(struct device *dev, struct rtc_time *time) | |||
175 | DS3232_REG_SECONDS, 7, buf); | 180 | DS3232_REG_SECONDS, 7, buf); |
176 | } | 181 | } |
177 | 182 | ||
183 | /* | ||
184 | * DS3232 has two alarm, we only use alarm1 | ||
185 | * According to linux specification, only support one-shot alarm | ||
186 | * no periodic alarm mode | ||
187 | */ | ||
188 | static int ds3232_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | ||
189 | { | ||
190 | struct i2c_client *client = to_i2c_client(dev); | ||
191 | struct ds3232 *ds3232 = i2c_get_clientdata(client); | ||
192 | int control, stat; | ||
193 | int ret; | ||
194 | u8 buf[4]; | ||
195 | |||
196 | mutex_lock(&ds3232->mutex); | ||
197 | |||
198 | ret = i2c_smbus_read_byte_data(client, DS3232_REG_SR); | ||
199 | if (ret < 0) | ||
200 | goto out; | ||
201 | stat = ret; | ||
202 | ret = i2c_smbus_read_byte_data(client, DS3232_REG_CR); | ||
203 | if (ret < 0) | ||
204 | goto out; | ||
205 | control = ret; | ||
206 | ret = i2c_smbus_read_i2c_block_data(client, DS3232_REG_ALARM1, 4, buf); | ||
207 | if (ret < 0) | ||
208 | goto out; | ||
209 | |||
210 | alarm->time.tm_sec = bcd2bin(buf[0] & 0x7F); | ||
211 | alarm->time.tm_min = bcd2bin(buf[1] & 0x7F); | ||
212 | alarm->time.tm_hour = bcd2bin(buf[2] & 0x7F); | ||
213 | alarm->time.tm_mday = bcd2bin(buf[3] & 0x7F); | ||
214 | |||
215 | alarm->time.tm_mon = -1; | ||
216 | alarm->time.tm_year = -1; | ||
217 | alarm->time.tm_wday = -1; | ||
218 | alarm->time.tm_yday = -1; | ||
219 | alarm->time.tm_isdst = -1; | ||
220 | |||
221 | alarm->enabled = !!(control & DS3232_REG_CR_A1IE); | ||
222 | alarm->pending = !!(stat & DS3232_REG_SR_A1F); | ||
223 | |||
224 | ret = 0; | ||
225 | out: | ||
226 | mutex_unlock(&ds3232->mutex); | ||
227 | return ret; | ||
228 | } | ||
229 | |||
230 | /* | ||
231 | * linux rtc-module does not support wday alarm | ||
232 | * and only 24h time mode supported indeed | ||
233 | */ | ||
234 | static int ds3232_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) | ||
235 | { | ||
236 | struct i2c_client *client = to_i2c_client(dev); | ||
237 | struct ds3232 *ds3232 = i2c_get_clientdata(client); | ||
238 | int control, stat; | ||
239 | int ret; | ||
240 | u8 buf[4]; | ||
241 | |||
242 | if (client->irq <= 0) | ||
243 | return -EINVAL; | ||
244 | |||
245 | mutex_lock(&ds3232->mutex); | ||
246 | |||
247 | buf[0] = bin2bcd(alarm->time.tm_sec); | ||
248 | buf[1] = bin2bcd(alarm->time.tm_min); | ||
249 | buf[2] = bin2bcd(alarm->time.tm_hour); | ||
250 | buf[3] = bin2bcd(alarm->time.tm_mday); | ||
251 | |||
252 | /* clear alarm interrupt enable bit */ | ||
253 | ret = i2c_smbus_read_byte_data(client, DS3232_REG_CR); | ||
254 | if (ret < 0) | ||
255 | goto out; | ||
256 | control = ret; | ||
257 | control &= ~(DS3232_REG_CR_A1IE | DS3232_REG_CR_A2IE); | ||
258 | ret = i2c_smbus_write_byte_data(client, DS3232_REG_CR, control); | ||
259 | if (ret < 0) | ||
260 | goto out; | ||
261 | |||
262 | /* clear any pending alarm flag */ | ||
263 | ret = i2c_smbus_read_byte_data(client, DS3232_REG_SR); | ||
264 | if (ret < 0) | ||
265 | goto out; | ||
266 | stat = ret; | ||
267 | stat &= ~(DS3232_REG_SR_A1F | DS3232_REG_SR_A2F); | ||
268 | ret = i2c_smbus_write_byte_data(client, DS3232_REG_SR, stat); | ||
269 | if (ret < 0) | ||
270 | goto out; | ||
271 | |||
272 | ret = i2c_smbus_write_i2c_block_data(client, DS3232_REG_ALARM1, 4, buf); | ||
273 | |||
274 | if (alarm->enabled) { | ||
275 | control |= DS3232_REG_CR_A1IE; | ||
276 | ret = i2c_smbus_write_byte_data(client, DS3232_REG_CR, control); | ||
277 | } | ||
278 | out: | ||
279 | mutex_unlock(&ds3232->mutex); | ||
280 | return ret; | ||
281 | } | ||
282 | |||
283 | static void ds3232_update_alarm(struct i2c_client *client) | ||
284 | { | ||
285 | struct ds3232 *ds3232 = i2c_get_clientdata(client); | ||
286 | int control; | ||
287 | int ret; | ||
288 | u8 buf[4]; | ||
289 | |||
290 | mutex_lock(&ds3232->mutex); | ||
291 | |||
292 | ret = i2c_smbus_read_i2c_block_data(client, DS3232_REG_ALARM1, 4, buf); | ||
293 | if (ret < 0) | ||
294 | goto unlock; | ||
295 | |||
296 | buf[0] = bcd2bin(buf[0]) < 0 || (ds3232->rtc->irq_data & RTC_UF) ? | ||
297 | 0x80 : buf[0]; | ||
298 | buf[1] = bcd2bin(buf[1]) < 0 || (ds3232->rtc->irq_data & RTC_UF) ? | ||
299 | 0x80 : buf[1]; | ||
300 | buf[2] = bcd2bin(buf[2]) < 0 || (ds3232->rtc->irq_data & RTC_UF) ? | ||
301 | 0x80 : buf[2]; | ||
302 | buf[3] = bcd2bin(buf[3]) < 0 || (ds3232->rtc->irq_data & RTC_UF) ? | ||
303 | 0x80 : buf[3]; | ||
304 | |||
305 | ret = i2c_smbus_write_i2c_block_data(client, DS3232_REG_ALARM1, 4, buf); | ||
306 | if (ret < 0) | ||
307 | goto unlock; | ||
308 | |||
309 | control = i2c_smbus_read_byte_data(client, DS3232_REG_CR); | ||
310 | if (control < 0) | ||
311 | goto unlock; | ||
312 | |||
313 | if (ds3232->rtc->irq_data & (RTC_AF | RTC_UF)) | ||
314 | /* enable alarm1 interrupt */ | ||
315 | control |= DS3232_REG_CR_A1IE; | ||
316 | else | ||
317 | /* disable alarm1 interrupt */ | ||
318 | control &= ~(DS3232_REG_CR_A1IE); | ||
319 | i2c_smbus_write_byte_data(client, DS3232_REG_CR, control); | ||
320 | |||
321 | unlock: | ||
322 | mutex_unlock(&ds3232->mutex); | ||
323 | } | ||
324 | |||
325 | static int ds3232_alarm_irq_enable(struct device *dev, unsigned int enabled) | ||
326 | { | ||
327 | struct i2c_client *client = to_i2c_client(dev); | ||
328 | struct ds3232 *ds3232 = i2c_get_clientdata(client); | ||
329 | |||
330 | if (client->irq <= 0) | ||
331 | return -EINVAL; | ||
332 | |||
333 | if (enabled) | ||
334 | ds3232->rtc->irq_data |= RTC_AF; | ||
335 | else | ||
336 | ds3232->rtc->irq_data &= ~RTC_AF; | ||
337 | |||
338 | ds3232_update_alarm(client); | ||
339 | return 0; | ||
340 | } | ||
341 | |||
178 | static irqreturn_t ds3232_irq(int irq, void *dev_id) | 342 | static irqreturn_t ds3232_irq(int irq, void *dev_id) |
179 | { | 343 | { |
180 | struct i2c_client *client = dev_id; | 344 | struct i2c_client *client = dev_id; |
@@ -222,6 +386,9 @@ unlock: | |||
222 | static const struct rtc_class_ops ds3232_rtc_ops = { | 386 | static const struct rtc_class_ops ds3232_rtc_ops = { |
223 | .read_time = ds3232_read_time, | 387 | .read_time = ds3232_read_time, |
224 | .set_time = ds3232_set_time, | 388 | .set_time = ds3232_set_time, |
389 | .read_alarm = ds3232_read_alarm, | ||
390 | .set_alarm = ds3232_set_alarm, | ||
391 | .alarm_irq_enable = ds3232_alarm_irq_enable, | ||
225 | }; | 392 | }; |
226 | 393 | ||
227 | static int __devinit ds3232_probe(struct i2c_client *client, | 394 | static int __devinit ds3232_probe(struct i2c_client *client, |
@@ -282,7 +449,7 @@ static int __devexit ds3232_remove(struct i2c_client *client) | |||
282 | mutex_unlock(&ds3232->mutex); | 449 | mutex_unlock(&ds3232->mutex); |
283 | 450 | ||
284 | free_irq(client->irq, client); | 451 | free_irq(client->irq, client); |
285 | flush_scheduled_work(); | 452 | cancel_work_sync(&ds3232->work); |
286 | } | 453 | } |
287 | 454 | ||
288 | rtc_device_unregister(ds3232->rtc); | 455 | rtc_device_unregister(ds3232->rtc); |
diff --git a/drivers/rtc/rtc-ds3234.c b/drivers/rtc/rtc-ds3234.c index a774ca35b5f7..bbd26228f532 100644 --- a/drivers/rtc/rtc-ds3234.c +++ b/drivers/rtc/rtc-ds3234.c | |||
@@ -158,7 +158,7 @@ static int __devinit ds3234_probe(struct spi_device *spi) | |||
158 | 158 | ||
159 | static int __devexit ds3234_remove(struct spi_device *spi) | 159 | static int __devexit ds3234_remove(struct spi_device *spi) |
160 | { | 160 | { |
161 | struct rtc_device *rtc = platform_get_drvdata(spi); | 161 | struct rtc_device *rtc = spi_get_drvdata(spi); |
162 | 162 | ||
163 | rtc_device_unregister(rtc); | 163 | rtc_device_unregister(rtc); |
164 | return 0; | 164 | return 0; |
diff --git a/drivers/rtc/rtc-em3027.c b/drivers/rtc/rtc-em3027.c new file mode 100644 index 000000000000..d8e1c2578553 --- /dev/null +++ b/drivers/rtc/rtc-em3027.c | |||
@@ -0,0 +1,161 @@ | |||
1 | /* | ||
2 | * An rtc/i2c driver for the EM Microelectronic EM3027 | ||
3 | * Copyright 2011 CompuLab, Ltd. | ||
4 | * | ||
5 | * Author: Mike Rapoport <mike@compulab.co.il> | ||
6 | * | ||
7 | * Based on rtc-ds1672.c by Alessandro Zummo <a.zummo@towertech.it> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/i2c.h> | ||
15 | #include <linux/rtc.h> | ||
16 | #include <linux/bcd.h> | ||
17 | |||
18 | /* Registers */ | ||
19 | #define EM3027_REG_ON_OFF_CTRL 0x00 | ||
20 | #define EM3027_REG_IRQ_CTRL 0x01 | ||
21 | #define EM3027_REG_IRQ_FLAGS 0x02 | ||
22 | #define EM3027_REG_STATUS 0x03 | ||
23 | #define EM3027_REG_RST_CTRL 0x04 | ||
24 | |||
25 | #define EM3027_REG_WATCH_SEC 0x08 | ||
26 | #define EM3027_REG_WATCH_MIN 0x09 | ||
27 | #define EM3027_REG_WATCH_HOUR 0x0a | ||
28 | #define EM3027_REG_WATCH_DATE 0x0b | ||
29 | #define EM3027_REG_WATCH_DAY 0x0c | ||
30 | #define EM3027_REG_WATCH_MON 0x0d | ||
31 | #define EM3027_REG_WATCH_YEAR 0x0e | ||
32 | |||
33 | #define EM3027_REG_ALARM_SEC 0x10 | ||
34 | #define EM3027_REG_ALARM_MIN 0x11 | ||
35 | #define EM3027_REG_ALARM_HOUR 0x12 | ||
36 | #define EM3027_REG_ALARM_DATE 0x13 | ||
37 | #define EM3027_REG_ALARM_DAY 0x14 | ||
38 | #define EM3027_REG_ALARM_MON 0x15 | ||
39 | #define EM3027_REG_ALARM_YEAR 0x16 | ||
40 | |||
41 | static struct i2c_driver em3027_driver; | ||
42 | |||
43 | static int em3027_get_time(struct device *dev, struct rtc_time *tm) | ||
44 | { | ||
45 | struct i2c_client *client = to_i2c_client(dev); | ||
46 | |||
47 | unsigned char addr = EM3027_REG_WATCH_SEC; | ||
48 | unsigned char buf[7]; | ||
49 | |||
50 | struct i2c_msg msgs[] = { | ||
51 | {client->addr, 0, 1, &addr}, /* setup read addr */ | ||
52 | {client->addr, I2C_M_RD, 7, buf}, /* read time/date */ | ||
53 | }; | ||
54 | |||
55 | /* read time/date registers */ | ||
56 | if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { | ||
57 | dev_err(&client->dev, "%s: read error\n", __func__); | ||
58 | return -EIO; | ||
59 | } | ||
60 | |||
61 | tm->tm_sec = bcd2bin(buf[0]); | ||
62 | tm->tm_min = bcd2bin(buf[1]); | ||
63 | tm->tm_hour = bcd2bin(buf[2]); | ||
64 | tm->tm_mday = bcd2bin(buf[3]); | ||
65 | tm->tm_wday = bcd2bin(buf[4]); | ||
66 | tm->tm_mon = bcd2bin(buf[5]); | ||
67 | tm->tm_year = bcd2bin(buf[6]) + 100; | ||
68 | |||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | static int em3027_set_time(struct device *dev, struct rtc_time *tm) | ||
73 | { | ||
74 | struct i2c_client *client = to_i2c_client(dev); | ||
75 | unsigned char buf[8]; | ||
76 | |||
77 | struct i2c_msg msg = { | ||
78 | client->addr, 0, 8, buf, /* write time/date */ | ||
79 | }; | ||
80 | |||
81 | buf[0] = EM3027_REG_WATCH_SEC; | ||
82 | buf[1] = bin2bcd(tm->tm_sec); | ||
83 | buf[2] = bin2bcd(tm->tm_min); | ||
84 | buf[3] = bin2bcd(tm->tm_hour); | ||
85 | buf[4] = bin2bcd(tm->tm_mday); | ||
86 | buf[5] = bin2bcd(tm->tm_wday); | ||
87 | buf[6] = bin2bcd(tm->tm_mon); | ||
88 | buf[7] = bin2bcd(tm->tm_year % 100); | ||
89 | |||
90 | /* write time/date registers */ | ||
91 | if ((i2c_transfer(client->adapter, &msg, 1)) != 1) { | ||
92 | dev_err(&client->dev, "%s: write error\n", __func__); | ||
93 | return -EIO; | ||
94 | } | ||
95 | |||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | static const struct rtc_class_ops em3027_rtc_ops = { | ||
100 | .read_time = em3027_get_time, | ||
101 | .set_time = em3027_set_time, | ||
102 | }; | ||
103 | |||
104 | static int em3027_probe(struct i2c_client *client, | ||
105 | const struct i2c_device_id *id) | ||
106 | { | ||
107 | struct rtc_device *rtc; | ||
108 | |||
109 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) | ||
110 | return -ENODEV; | ||
111 | |||
112 | rtc = rtc_device_register(em3027_driver.driver.name, &client->dev, | ||
113 | &em3027_rtc_ops, THIS_MODULE); | ||
114 | if (IS_ERR(rtc)) | ||
115 | return PTR_ERR(rtc); | ||
116 | |||
117 | i2c_set_clientdata(client, rtc); | ||
118 | |||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | static int em3027_remove(struct i2c_client *client) | ||
123 | { | ||
124 | struct rtc_device *rtc = i2c_get_clientdata(client); | ||
125 | |||
126 | if (rtc) | ||
127 | rtc_device_unregister(rtc); | ||
128 | |||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | static struct i2c_device_id em3027_id[] = { | ||
133 | { "em3027", 0 }, | ||
134 | { } | ||
135 | }; | ||
136 | |||
137 | static struct i2c_driver em3027_driver = { | ||
138 | .driver = { | ||
139 | .name = "rtc-em3027", | ||
140 | }, | ||
141 | .probe = &em3027_probe, | ||
142 | .remove = &em3027_remove, | ||
143 | .id_table = em3027_id, | ||
144 | }; | ||
145 | |||
146 | static int __init em3027_init(void) | ||
147 | { | ||
148 | return i2c_add_driver(&em3027_driver); | ||
149 | } | ||
150 | |||
151 | static void __exit em3027_exit(void) | ||
152 | { | ||
153 | i2c_del_driver(&em3027_driver); | ||
154 | } | ||
155 | |||
156 | MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>"); | ||
157 | MODULE_DESCRIPTION("EM Microelectronic EM3027 RTC driver"); | ||
158 | MODULE_LICENSE("GPL"); | ||
159 | |||
160 | module_init(em3027_init); | ||
161 | module_exit(em3027_exit); | ||
diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c index 11ae64dcbf3c..335551d333b2 100644 --- a/drivers/rtc/rtc-ep93xx.c +++ b/drivers/rtc/rtc-ep93xx.c | |||
@@ -151,6 +151,7 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev) | |||
151 | return -ENXIO; | 151 | return -ENXIO; |
152 | 152 | ||
153 | pdev->dev.platform_data = ep93xx_rtc; | 153 | pdev->dev.platform_data = ep93xx_rtc; |
154 | platform_set_drvdata(pdev, rtc); | ||
154 | 155 | ||
155 | rtc = rtc_device_register(pdev->name, | 156 | rtc = rtc_device_register(pdev->name, |
156 | &pdev->dev, &ep93xx_rtc_ops, THIS_MODULE); | 157 | &pdev->dev, &ep93xx_rtc_ops, THIS_MODULE); |
@@ -159,8 +160,6 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev) | |||
159 | goto exit; | 160 | goto exit; |
160 | } | 161 | } |
161 | 162 | ||
162 | platform_set_drvdata(pdev, rtc); | ||
163 | |||
164 | err = sysfs_create_group(&pdev->dev.kobj, &ep93xx_rtc_sysfs_files); | 163 | err = sysfs_create_group(&pdev->dev.kobj, &ep93xx_rtc_sysfs_files); |
165 | if (err) | 164 | if (err) |
166 | goto fail; | 165 | goto fail; |
@@ -168,9 +167,9 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev) | |||
168 | return 0; | 167 | return 0; |
169 | 168 | ||
170 | fail: | 169 | fail: |
171 | platform_set_drvdata(pdev, NULL); | ||
172 | rtc_device_unregister(rtc); | 170 | rtc_device_unregister(rtc); |
173 | exit: | 171 | exit: |
172 | platform_set_drvdata(pdev, NULL); | ||
174 | pdev->dev.platform_data = NULL; | 173 | pdev->dev.platform_data = NULL; |
175 | return err; | 174 | return err; |
176 | } | 175 | } |
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index 468200c38ecb..da8beb8cae51 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c | |||
@@ -39,6 +39,8 @@ | |||
39 | #define ISL1208_REG_SR_BAT (1<<1) /* battery */ | 39 | #define ISL1208_REG_SR_BAT (1<<1) /* battery */ |
40 | #define ISL1208_REG_SR_RTCF (1<<0) /* rtc fail */ | 40 | #define ISL1208_REG_SR_RTCF (1<<0) /* rtc fail */ |
41 | #define ISL1208_REG_INT 0x08 | 41 | #define ISL1208_REG_INT 0x08 |
42 | #define ISL1208_REG_INT_ALME (1<<6) /* alarm enable */ | ||
43 | #define ISL1208_REG_INT_IM (1<<7) /* interrupt/alarm mode */ | ||
42 | #define ISL1208_REG_09 0x09 /* reserved */ | 44 | #define ISL1208_REG_09 0x09 /* reserved */ |
43 | #define ISL1208_REG_ATR 0x0a | 45 | #define ISL1208_REG_ATR 0x0a |
44 | #define ISL1208_REG_DTR 0x0b | 46 | #define ISL1208_REG_DTR 0x0b |
@@ -202,6 +204,30 @@ isl1208_i2c_set_usr(struct i2c_client *client, u16 usr) | |||
202 | } | 204 | } |
203 | 205 | ||
204 | static int | 206 | static int |
207 | isl1208_rtc_toggle_alarm(struct i2c_client *client, int enable) | ||
208 | { | ||
209 | int icr = i2c_smbus_read_byte_data(client, ISL1208_REG_INT); | ||
210 | |||
211 | if (icr < 0) { | ||
212 | dev_err(&client->dev, "%s: reading INT failed\n", __func__); | ||
213 | return icr; | ||
214 | } | ||
215 | |||
216 | if (enable) | ||
217 | icr |= ISL1208_REG_INT_ALME | ISL1208_REG_INT_IM; | ||
218 | else | ||
219 | icr &= ~(ISL1208_REG_INT_ALME | ISL1208_REG_INT_IM); | ||
220 | |||
221 | icr = i2c_smbus_write_byte_data(client, ISL1208_REG_INT, icr); | ||
222 | if (icr < 0) { | ||
223 | dev_err(&client->dev, "%s: writing INT failed\n", __func__); | ||
224 | return icr; | ||
225 | } | ||
226 | |||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | static int | ||
205 | isl1208_rtc_proc(struct device *dev, struct seq_file *seq) | 231 | isl1208_rtc_proc(struct device *dev, struct seq_file *seq) |
206 | { | 232 | { |
207 | struct i2c_client *const client = to_i2c_client(dev); | 233 | struct i2c_client *const client = to_i2c_client(dev); |
@@ -288,9 +314,8 @@ isl1208_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm) | |||
288 | { | 314 | { |
289 | struct rtc_time *const tm = &alarm->time; | 315 | struct rtc_time *const tm = &alarm->time; |
290 | u8 regs[ISL1208_ALARM_SECTION_LEN] = { 0, }; | 316 | u8 regs[ISL1208_ALARM_SECTION_LEN] = { 0, }; |
291 | int sr; | 317 | int icr, yr, sr = isl1208_i2c_get_sr(client); |
292 | 318 | ||
293 | sr = isl1208_i2c_get_sr(client); | ||
294 | if (sr < 0) { | 319 | if (sr < 0) { |
295 | dev_err(&client->dev, "%s: reading SR failed\n", __func__); | 320 | dev_err(&client->dev, "%s: reading SR failed\n", __func__); |
296 | return sr; | 321 | return sr; |
@@ -313,6 +338,73 @@ isl1208_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm) | |||
313 | bcd2bin(regs[ISL1208_REG_MOA - ISL1208_REG_SCA] & 0x1f) - 1; | 338 | bcd2bin(regs[ISL1208_REG_MOA - ISL1208_REG_SCA] & 0x1f) - 1; |
314 | tm->tm_wday = bcd2bin(regs[ISL1208_REG_DWA - ISL1208_REG_SCA] & 0x03); | 339 | tm->tm_wday = bcd2bin(regs[ISL1208_REG_DWA - ISL1208_REG_SCA] & 0x03); |
315 | 340 | ||
341 | /* The alarm doesn't store the year so get it from the rtc section */ | ||
342 | yr = i2c_smbus_read_byte_data(client, ISL1208_REG_YR); | ||
343 | if (yr < 0) { | ||
344 | dev_err(&client->dev, "%s: reading RTC YR failed\n", __func__); | ||
345 | return yr; | ||
346 | } | ||
347 | tm->tm_year = bcd2bin(yr) + 100; | ||
348 | |||
349 | icr = i2c_smbus_read_byte_data(client, ISL1208_REG_INT); | ||
350 | if (icr < 0) { | ||
351 | dev_err(&client->dev, "%s: reading INT failed\n", __func__); | ||
352 | return icr; | ||
353 | } | ||
354 | alarm->enabled = !!(icr & ISL1208_REG_INT_ALME); | ||
355 | |||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | static int | ||
360 | isl1208_i2c_set_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm) | ||
361 | { | ||
362 | struct rtc_time *alarm_tm = &alarm->time; | ||
363 | u8 regs[ISL1208_ALARM_SECTION_LEN] = { 0, }; | ||
364 | const int offs = ISL1208_REG_SCA; | ||
365 | unsigned long rtc_secs, alarm_secs; | ||
366 | struct rtc_time rtc_tm; | ||
367 | int err, enable; | ||
368 | |||
369 | err = isl1208_i2c_read_time(client, &rtc_tm); | ||
370 | if (err) | ||
371 | return err; | ||
372 | err = rtc_tm_to_time(&rtc_tm, &rtc_secs); | ||
373 | if (err) | ||
374 | return err; | ||
375 | err = rtc_tm_to_time(alarm_tm, &alarm_secs); | ||
376 | if (err) | ||
377 | return err; | ||
378 | |||
379 | /* If the alarm time is before the current time disable the alarm */ | ||
380 | if (!alarm->enabled || alarm_secs <= rtc_secs) | ||
381 | enable = 0x00; | ||
382 | else | ||
383 | enable = 0x80; | ||
384 | |||
385 | /* Program the alarm and enable it for each setting */ | ||
386 | regs[ISL1208_REG_SCA - offs] = bin2bcd(alarm_tm->tm_sec) | enable; | ||
387 | regs[ISL1208_REG_MNA - offs] = bin2bcd(alarm_tm->tm_min) | enable; | ||
388 | regs[ISL1208_REG_HRA - offs] = bin2bcd(alarm_tm->tm_hour) | | ||
389 | ISL1208_REG_HR_MIL | enable; | ||
390 | |||
391 | regs[ISL1208_REG_DTA - offs] = bin2bcd(alarm_tm->tm_mday) | enable; | ||
392 | regs[ISL1208_REG_MOA - offs] = bin2bcd(alarm_tm->tm_mon + 1) | enable; | ||
393 | regs[ISL1208_REG_DWA - offs] = bin2bcd(alarm_tm->tm_wday & 7) | enable; | ||
394 | |||
395 | /* write ALARM registers */ | ||
396 | err = isl1208_i2c_set_regs(client, offs, regs, | ||
397 | ISL1208_ALARM_SECTION_LEN); | ||
398 | if (err < 0) { | ||
399 | dev_err(&client->dev, "%s: writing ALARM section failed\n", | ||
400 | __func__); | ||
401 | return err; | ||
402 | } | ||
403 | |||
404 | err = isl1208_rtc_toggle_alarm(client, enable); | ||
405 | if (err) | ||
406 | return err; | ||
407 | |||
316 | return 0; | 408 | return 0; |
317 | } | 409 | } |
318 | 410 | ||
@@ -391,12 +483,63 @@ isl1208_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
391 | return isl1208_i2c_read_alarm(to_i2c_client(dev), alarm); | 483 | return isl1208_i2c_read_alarm(to_i2c_client(dev), alarm); |
392 | } | 484 | } |
393 | 485 | ||
486 | static int | ||
487 | isl1208_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) | ||
488 | { | ||
489 | return isl1208_i2c_set_alarm(to_i2c_client(dev), alarm); | ||
490 | } | ||
491 | |||
492 | static irqreturn_t | ||
493 | isl1208_rtc_interrupt(int irq, void *data) | ||
494 | { | ||
495 | unsigned long timeout = jiffies + msecs_to_jiffies(1000); | ||
496 | struct i2c_client *client = data; | ||
497 | int handled = 0, sr, err; | ||
498 | |||
499 | /* | ||
500 | * I2C reads get NAK'ed if we read straight away after an interrupt? | ||
501 | * Using a mdelay/msleep didn't seem to help either, so we work around | ||
502 | * this by continually trying to read the register for a short time. | ||
503 | */ | ||
504 | while (1) { | ||
505 | sr = isl1208_i2c_get_sr(client); | ||
506 | if (sr >= 0) | ||
507 | break; | ||
508 | |||
509 | if (time_after(jiffies, timeout)) { | ||
510 | dev_err(&client->dev, "%s: reading SR failed\n", | ||
511 | __func__); | ||
512 | return sr; | ||
513 | } | ||
514 | } | ||
515 | |||
516 | if (sr & ISL1208_REG_SR_ALM) { | ||
517 | dev_dbg(&client->dev, "alarm!\n"); | ||
518 | |||
519 | /* Clear the alarm */ | ||
520 | sr &= ~ISL1208_REG_SR_ALM; | ||
521 | sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, sr); | ||
522 | if (sr < 0) | ||
523 | dev_err(&client->dev, "%s: writing SR failed\n", | ||
524 | __func__); | ||
525 | else | ||
526 | handled = 1; | ||
527 | |||
528 | /* Disable the alarm */ | ||
529 | err = isl1208_rtc_toggle_alarm(client, 0); | ||
530 | if (err) | ||
531 | return err; | ||
532 | } | ||
533 | |||
534 | return handled ? IRQ_HANDLED : IRQ_NONE; | ||
535 | } | ||
536 | |||
394 | static const struct rtc_class_ops isl1208_rtc_ops = { | 537 | static const struct rtc_class_ops isl1208_rtc_ops = { |
395 | .proc = isl1208_rtc_proc, | 538 | .proc = isl1208_rtc_proc, |
396 | .read_time = isl1208_rtc_read_time, | 539 | .read_time = isl1208_rtc_read_time, |
397 | .set_time = isl1208_rtc_set_time, | 540 | .set_time = isl1208_rtc_set_time, |
398 | .read_alarm = isl1208_rtc_read_alarm, | 541 | .read_alarm = isl1208_rtc_read_alarm, |
399 | /*.set_alarm = isl1208_rtc_set_alarm, */ | 542 | .set_alarm = isl1208_rtc_set_alarm, |
400 | }; | 543 | }; |
401 | 544 | ||
402 | /* sysfs interface */ | 545 | /* sysfs interface */ |
@@ -488,11 +631,29 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
488 | dev_info(&client->dev, | 631 | dev_info(&client->dev, |
489 | "chip found, driver version " DRV_VERSION "\n"); | 632 | "chip found, driver version " DRV_VERSION "\n"); |
490 | 633 | ||
634 | if (client->irq > 0) { | ||
635 | rc = request_threaded_irq(client->irq, NULL, | ||
636 | isl1208_rtc_interrupt, | ||
637 | IRQF_SHARED, | ||
638 | isl1208_driver.driver.name, client); | ||
639 | if (!rc) { | ||
640 | device_init_wakeup(&client->dev, 1); | ||
641 | enable_irq_wake(client->irq); | ||
642 | } else { | ||
643 | dev_err(&client->dev, | ||
644 | "Unable to request irq %d, no alarm support\n", | ||
645 | client->irq); | ||
646 | client->irq = 0; | ||
647 | } | ||
648 | } | ||
649 | |||
491 | rtc = rtc_device_register(isl1208_driver.driver.name, | 650 | rtc = rtc_device_register(isl1208_driver.driver.name, |
492 | &client->dev, &isl1208_rtc_ops, | 651 | &client->dev, &isl1208_rtc_ops, |
493 | THIS_MODULE); | 652 | THIS_MODULE); |
494 | if (IS_ERR(rtc)) | 653 | if (IS_ERR(rtc)) { |
495 | return PTR_ERR(rtc); | 654 | rc = PTR_ERR(rtc); |
655 | goto exit_free_irq; | ||
656 | } | ||
496 | 657 | ||
497 | i2c_set_clientdata(client, rtc); | 658 | i2c_set_clientdata(client, rtc); |
498 | 659 | ||
@@ -514,6 +675,9 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
514 | 675 | ||
515 | exit_unregister: | 676 | exit_unregister: |
516 | rtc_device_unregister(rtc); | 677 | rtc_device_unregister(rtc); |
678 | exit_free_irq: | ||
679 | if (client->irq) | ||
680 | free_irq(client->irq, client); | ||
517 | 681 | ||
518 | return rc; | 682 | return rc; |
519 | } | 683 | } |
@@ -525,6 +689,8 @@ isl1208_remove(struct i2c_client *client) | |||
525 | 689 | ||
526 | sysfs_remove_group(&client->dev.kobj, &isl1208_rtc_sysfs_files); | 690 | sysfs_remove_group(&client->dev.kobj, &isl1208_rtc_sysfs_files); |
527 | rtc_device_unregister(rtc); | 691 | rtc_device_unregister(rtc); |
692 | if (client->irq) | ||
693 | free_irq(client->irq, client); | ||
528 | 694 | ||
529 | return 0; | 695 | return 0; |
530 | } | 696 | } |
diff --git a/drivers/rtc/rtc-jz4740.c b/drivers/rtc/rtc-jz4740.c index 2619d57b91d7..b6473631d182 100644 --- a/drivers/rtc/rtc-jz4740.c +++ b/drivers/rtc/rtc-jz4740.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> | 2 | * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> |
3 | * Copyright (C) 2010, Paul Cercueil <paul@crapouillou.net> | ||
3 | * JZ4740 SoC RTC driver | 4 | * JZ4740 SoC RTC driver |
4 | * | 5 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
@@ -161,17 +162,12 @@ static int jz4740_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
161 | 162 | ||
162 | ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC_ALARM, secs); | 163 | ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC_ALARM, secs); |
163 | if (!ret) | 164 | if (!ret) |
164 | ret = jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_AE, alrm->enabled); | 165 | ret = jz4740_rtc_ctrl_set_bits(rtc, |
166 | JZ_RTC_CTRL_AE | JZ_RTC_CTRL_AF_IRQ, alrm->enabled); | ||
165 | 167 | ||
166 | return ret; | 168 | return ret; |
167 | } | 169 | } |
168 | 170 | ||
169 | static int jz4740_rtc_update_irq_enable(struct device *dev, unsigned int enable) | ||
170 | { | ||
171 | struct jz4740_rtc *rtc = dev_get_drvdata(dev); | ||
172 | return jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_1HZ_IRQ, enable); | ||
173 | } | ||
174 | |||
175 | static int jz4740_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) | 171 | static int jz4740_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) |
176 | { | 172 | { |
177 | struct jz4740_rtc *rtc = dev_get_drvdata(dev); | 173 | struct jz4740_rtc *rtc = dev_get_drvdata(dev); |
@@ -183,7 +179,6 @@ static struct rtc_class_ops jz4740_rtc_ops = { | |||
183 | .set_mmss = jz4740_rtc_set_mmss, | 179 | .set_mmss = jz4740_rtc_set_mmss, |
184 | .read_alarm = jz4740_rtc_read_alarm, | 180 | .read_alarm = jz4740_rtc_read_alarm, |
185 | .set_alarm = jz4740_rtc_set_alarm, | 181 | .set_alarm = jz4740_rtc_set_alarm, |
186 | .update_irq_enable = jz4740_rtc_update_irq_enable, | ||
187 | .alarm_irq_enable = jz4740_rtc_alarm_irq_enable, | 182 | .alarm_irq_enable = jz4740_rtc_alarm_irq_enable, |
188 | }; | 183 | }; |
189 | 184 | ||
@@ -258,6 +253,8 @@ static int __devinit jz4740_rtc_probe(struct platform_device *pdev) | |||
258 | 253 | ||
259 | platform_set_drvdata(pdev, rtc); | 254 | platform_set_drvdata(pdev, rtc); |
260 | 255 | ||
256 | device_init_wakeup(&pdev->dev, 1); | ||
257 | |||
261 | rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, &jz4740_rtc_ops, | 258 | rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, &jz4740_rtc_ops, |
262 | THIS_MODULE); | 259 | THIS_MODULE); |
263 | if (IS_ERR(rtc->rtc)) { | 260 | if (IS_ERR(rtc->rtc)) { |
@@ -318,12 +315,43 @@ static int __devexit jz4740_rtc_remove(struct platform_device *pdev) | |||
318 | return 0; | 315 | return 0; |
319 | } | 316 | } |
320 | 317 | ||
318 | |||
319 | #ifdef CONFIG_PM | ||
320 | static int jz4740_rtc_suspend(struct device *dev) | ||
321 | { | ||
322 | struct jz4740_rtc *rtc = dev_get_drvdata(dev); | ||
323 | |||
324 | if (device_may_wakeup(dev)) | ||
325 | enable_irq_wake(rtc->irq); | ||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | static int jz4740_rtc_resume(struct device *dev) | ||
330 | { | ||
331 | struct jz4740_rtc *rtc = dev_get_drvdata(dev); | ||
332 | |||
333 | if (device_may_wakeup(dev)) | ||
334 | disable_irq_wake(rtc->irq); | ||
335 | return 0; | ||
336 | } | ||
337 | |||
338 | static const struct dev_pm_ops jz4740_pm_ops = { | ||
339 | .suspend = jz4740_rtc_suspend, | ||
340 | .resume = jz4740_rtc_resume, | ||
341 | }; | ||
342 | #define JZ4740_RTC_PM_OPS (&jz4740_pm_ops) | ||
343 | |||
344 | #else | ||
345 | #define JZ4740_RTC_PM_OPS NULL | ||
346 | #endif /* CONFIG_PM */ | ||
347 | |||
321 | struct platform_driver jz4740_rtc_driver = { | 348 | struct platform_driver jz4740_rtc_driver = { |
322 | .probe = jz4740_rtc_probe, | 349 | .probe = jz4740_rtc_probe, |
323 | .remove = __devexit_p(jz4740_rtc_remove), | 350 | .remove = __devexit_p(jz4740_rtc_remove), |
324 | .driver = { | 351 | .driver = { |
325 | .name = "jz4740-rtc", | 352 | .name = "jz4740-rtc", |
326 | .owner = THIS_MODULE, | 353 | .owner = THIS_MODULE, |
354 | .pm = JZ4740_RTC_PM_OPS, | ||
327 | }, | 355 | }, |
328 | }; | 356 | }; |
329 | 357 | ||
diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c index 773851f338b8..075f1708deae 100644 --- a/drivers/rtc/rtc-lib.c +++ b/drivers/rtc/rtc-lib.c | |||
@@ -117,4 +117,32 @@ int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time) | |||
117 | } | 117 | } |
118 | EXPORT_SYMBOL(rtc_tm_to_time); | 118 | EXPORT_SYMBOL(rtc_tm_to_time); |
119 | 119 | ||
120 | /* | ||
121 | * Convert rtc_time to ktime | ||
122 | */ | ||
123 | ktime_t rtc_tm_to_ktime(struct rtc_time tm) | ||
124 | { | ||
125 | time_t time; | ||
126 | rtc_tm_to_time(&tm, &time); | ||
127 | return ktime_set(time, 0); | ||
128 | } | ||
129 | EXPORT_SYMBOL_GPL(rtc_tm_to_ktime); | ||
130 | |||
131 | /* | ||
132 | * Convert ktime to rtc_time | ||
133 | */ | ||
134 | struct rtc_time rtc_ktime_to_tm(ktime_t kt) | ||
135 | { | ||
136 | struct timespec ts; | ||
137 | struct rtc_time ret; | ||
138 | |||
139 | ts = ktime_to_timespec(kt); | ||
140 | /* Round up any ns */ | ||
141 | if (ts.tv_nsec) | ||
142 | ts.tv_sec++; | ||
143 | rtc_time_to_tm(ts.tv_sec, &ret); | ||
144 | return ret; | ||
145 | } | ||
146 | EXPORT_SYMBOL_GPL(rtc_ktime_to_tm); | ||
147 | |||
120 | MODULE_LICENSE("GPL"); | 148 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/rtc/rtc-lpc32xx.c b/drivers/rtc/rtc-lpc32xx.c new file mode 100644 index 000000000000..ae16250c762f --- /dev/null +++ b/drivers/rtc/rtc-lpc32xx.c | |||
@@ -0,0 +1,414 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 NXP Semiconductors | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * You should have received a copy of the GNU General Public License along | ||
10 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
11 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/spinlock.h> | ||
19 | #include <linux/rtc.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/io.h> | ||
22 | |||
23 | /* | ||
24 | * Clock and Power control register offsets | ||
25 | */ | ||
26 | #define LPC32XX_RTC_UCOUNT 0x00 | ||
27 | #define LPC32XX_RTC_DCOUNT 0x04 | ||
28 | #define LPC32XX_RTC_MATCH0 0x08 | ||
29 | #define LPC32XX_RTC_MATCH1 0x0C | ||
30 | #define LPC32XX_RTC_CTRL 0x10 | ||
31 | #define LPC32XX_RTC_INTSTAT 0x14 | ||
32 | #define LPC32XX_RTC_KEY 0x18 | ||
33 | #define LPC32XX_RTC_SRAM 0x80 | ||
34 | |||
35 | #define LPC32XX_RTC_CTRL_MATCH0 (1 << 0) | ||
36 | #define LPC32XX_RTC_CTRL_MATCH1 (1 << 1) | ||
37 | #define LPC32XX_RTC_CTRL_ONSW_MATCH0 (1 << 2) | ||
38 | #define LPC32XX_RTC_CTRL_ONSW_MATCH1 (1 << 3) | ||
39 | #define LPC32XX_RTC_CTRL_SW_RESET (1 << 4) | ||
40 | #define LPC32XX_RTC_CTRL_CNTR_DIS (1 << 6) | ||
41 | #define LPC32XX_RTC_CTRL_ONSW_FORCE_HI (1 << 7) | ||
42 | |||
43 | #define LPC32XX_RTC_INTSTAT_MATCH0 (1 << 0) | ||
44 | #define LPC32XX_RTC_INTSTAT_MATCH1 (1 << 1) | ||
45 | #define LPC32XX_RTC_INTSTAT_ONSW (1 << 2) | ||
46 | |||
47 | #define LPC32XX_RTC_KEY_ONSW_LOADVAL 0xB5C13F27 | ||
48 | |||
49 | #define RTC_NAME "rtc-lpc32xx" | ||
50 | |||
51 | #define rtc_readl(dev, reg) \ | ||
52 | __raw_readl((dev)->rtc_base + (reg)) | ||
53 | #define rtc_writel(dev, reg, val) \ | ||
54 | __raw_writel((val), (dev)->rtc_base + (reg)) | ||
55 | |||
56 | struct lpc32xx_rtc { | ||
57 | void __iomem *rtc_base; | ||
58 | int irq; | ||
59 | unsigned char alarm_enabled; | ||
60 | struct rtc_device *rtc; | ||
61 | spinlock_t lock; | ||
62 | }; | ||
63 | |||
64 | static int lpc32xx_rtc_read_time(struct device *dev, struct rtc_time *time) | ||
65 | { | ||
66 | unsigned long elapsed_sec; | ||
67 | struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); | ||
68 | |||
69 | elapsed_sec = rtc_readl(rtc, LPC32XX_RTC_UCOUNT); | ||
70 | rtc_time_to_tm(elapsed_sec, time); | ||
71 | |||
72 | return rtc_valid_tm(time); | ||
73 | } | ||
74 | |||
75 | static int lpc32xx_rtc_set_mmss(struct device *dev, unsigned long secs) | ||
76 | { | ||
77 | struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); | ||
78 | u32 tmp; | ||
79 | |||
80 | spin_lock_irq(&rtc->lock); | ||
81 | |||
82 | /* RTC must be disabled during count update */ | ||
83 | tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL); | ||
84 | rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp | LPC32XX_RTC_CTRL_CNTR_DIS); | ||
85 | rtc_writel(rtc, LPC32XX_RTC_UCOUNT, secs); | ||
86 | rtc_writel(rtc, LPC32XX_RTC_DCOUNT, 0xFFFFFFFF - secs); | ||
87 | rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp &= ~LPC32XX_RTC_CTRL_CNTR_DIS); | ||
88 | |||
89 | spin_unlock_irq(&rtc->lock); | ||
90 | |||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | static int lpc32xx_rtc_read_alarm(struct device *dev, | ||
95 | struct rtc_wkalrm *wkalrm) | ||
96 | { | ||
97 | struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); | ||
98 | |||
99 | rtc_time_to_tm(rtc_readl(rtc, LPC32XX_RTC_MATCH0), &wkalrm->time); | ||
100 | wkalrm->enabled = rtc->alarm_enabled; | ||
101 | wkalrm->pending = !!(rtc_readl(rtc, LPC32XX_RTC_INTSTAT) & | ||
102 | LPC32XX_RTC_INTSTAT_MATCH0); | ||
103 | |||
104 | return rtc_valid_tm(&wkalrm->time); | ||
105 | } | ||
106 | |||
107 | static int lpc32xx_rtc_set_alarm(struct device *dev, | ||
108 | struct rtc_wkalrm *wkalrm) | ||
109 | { | ||
110 | struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); | ||
111 | unsigned long alarmsecs; | ||
112 | u32 tmp; | ||
113 | int ret; | ||
114 | |||
115 | ret = rtc_tm_to_time(&wkalrm->time, &alarmsecs); | ||
116 | if (ret < 0) { | ||
117 | dev_warn(dev, "Failed to convert time: %d\n", ret); | ||
118 | return ret; | ||
119 | } | ||
120 | |||
121 | spin_lock_irq(&rtc->lock); | ||
122 | |||
123 | /* Disable alarm during update */ | ||
124 | tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL); | ||
125 | rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp & ~LPC32XX_RTC_CTRL_MATCH0); | ||
126 | |||
127 | rtc_writel(rtc, LPC32XX_RTC_MATCH0, alarmsecs); | ||
128 | |||
129 | rtc->alarm_enabled = wkalrm->enabled; | ||
130 | if (wkalrm->enabled) { | ||
131 | rtc_writel(rtc, LPC32XX_RTC_INTSTAT, | ||
132 | LPC32XX_RTC_INTSTAT_MATCH0); | ||
133 | rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp | | ||
134 | LPC32XX_RTC_CTRL_MATCH0); | ||
135 | } | ||
136 | |||
137 | spin_unlock_irq(&rtc->lock); | ||
138 | |||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | static int lpc32xx_rtc_alarm_irq_enable(struct device *dev, | ||
143 | unsigned int enabled) | ||
144 | { | ||
145 | struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); | ||
146 | u32 tmp; | ||
147 | |||
148 | spin_lock_irq(&rtc->lock); | ||
149 | tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL); | ||
150 | |||
151 | if (enabled) { | ||
152 | rtc->alarm_enabled = 1; | ||
153 | tmp |= LPC32XX_RTC_CTRL_MATCH0; | ||
154 | } else { | ||
155 | rtc->alarm_enabled = 0; | ||
156 | tmp &= ~LPC32XX_RTC_CTRL_MATCH0; | ||
157 | } | ||
158 | |||
159 | rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp); | ||
160 | spin_unlock_irq(&rtc->lock); | ||
161 | |||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static irqreturn_t lpc32xx_rtc_alarm_interrupt(int irq, void *dev) | ||
166 | { | ||
167 | struct lpc32xx_rtc *rtc = dev; | ||
168 | |||
169 | spin_lock(&rtc->lock); | ||
170 | |||
171 | /* Disable alarm interrupt */ | ||
172 | rtc_writel(rtc, LPC32XX_RTC_CTRL, | ||
173 | rtc_readl(rtc, LPC32XX_RTC_CTRL) & | ||
174 | ~LPC32XX_RTC_CTRL_MATCH0); | ||
175 | rtc->alarm_enabled = 0; | ||
176 | |||
177 | /* | ||
178 | * Write a large value to the match value so the RTC won't | ||
179 | * keep firing the match status | ||
180 | */ | ||
181 | rtc_writel(rtc, LPC32XX_RTC_MATCH0, 0xFFFFFFFF); | ||
182 | rtc_writel(rtc, LPC32XX_RTC_INTSTAT, LPC32XX_RTC_INTSTAT_MATCH0); | ||
183 | |||
184 | spin_unlock(&rtc->lock); | ||
185 | |||
186 | rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); | ||
187 | |||
188 | return IRQ_HANDLED; | ||
189 | } | ||
190 | |||
191 | static const struct rtc_class_ops lpc32xx_rtc_ops = { | ||
192 | .read_time = lpc32xx_rtc_read_time, | ||
193 | .set_mmss = lpc32xx_rtc_set_mmss, | ||
194 | .read_alarm = lpc32xx_rtc_read_alarm, | ||
195 | .set_alarm = lpc32xx_rtc_set_alarm, | ||
196 | .alarm_irq_enable = lpc32xx_rtc_alarm_irq_enable, | ||
197 | }; | ||
198 | |||
199 | static int __devinit lpc32xx_rtc_probe(struct platform_device *pdev) | ||
200 | { | ||
201 | struct resource *res; | ||
202 | struct lpc32xx_rtc *rtc; | ||
203 | resource_size_t size; | ||
204 | int rtcirq; | ||
205 | u32 tmp; | ||
206 | |||
207 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
208 | if (!res) { | ||
209 | dev_err(&pdev->dev, "Can't get memory resource\n"); | ||
210 | return -ENOENT; | ||
211 | } | ||
212 | |||
213 | rtcirq = platform_get_irq(pdev, 0); | ||
214 | if (rtcirq < 0 || rtcirq >= NR_IRQS) { | ||
215 | dev_warn(&pdev->dev, "Can't get interrupt resource\n"); | ||
216 | rtcirq = -1; | ||
217 | } | ||
218 | |||
219 | rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); | ||
220 | if (unlikely(!rtc)) { | ||
221 | dev_err(&pdev->dev, "Can't allocate memory\n"); | ||
222 | return -ENOMEM; | ||
223 | } | ||
224 | rtc->irq = rtcirq; | ||
225 | |||
226 | size = resource_size(res); | ||
227 | |||
228 | if (!devm_request_mem_region(&pdev->dev, res->start, size, | ||
229 | pdev->name)) { | ||
230 | dev_err(&pdev->dev, "RTC registers are not free\n"); | ||
231 | return -EBUSY; | ||
232 | } | ||
233 | |||
234 | rtc->rtc_base = devm_ioremap(&pdev->dev, res->start, size); | ||
235 | if (!rtc->rtc_base) { | ||
236 | dev_err(&pdev->dev, "Can't map memory\n"); | ||
237 | return -ENOMEM; | ||
238 | } | ||
239 | |||
240 | spin_lock_init(&rtc->lock); | ||
241 | |||
242 | /* | ||
243 | * The RTC is on a separate power domain and can keep it's state | ||
244 | * across a chip power cycle. If the RTC has never been previously | ||
245 | * setup, then set it up now for the first time. | ||
246 | */ | ||
247 | tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL); | ||
248 | if (rtc_readl(rtc, LPC32XX_RTC_KEY) != LPC32XX_RTC_KEY_ONSW_LOADVAL) { | ||
249 | tmp &= ~(LPC32XX_RTC_CTRL_SW_RESET | | ||
250 | LPC32XX_RTC_CTRL_CNTR_DIS | | ||
251 | LPC32XX_RTC_CTRL_MATCH0 | | ||
252 | LPC32XX_RTC_CTRL_MATCH1 | | ||
253 | LPC32XX_RTC_CTRL_ONSW_MATCH0 | | ||
254 | LPC32XX_RTC_CTRL_ONSW_MATCH1 | | ||
255 | LPC32XX_RTC_CTRL_ONSW_FORCE_HI); | ||
256 | rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp); | ||
257 | |||
258 | /* Clear latched interrupt states */ | ||
259 | rtc_writel(rtc, LPC32XX_RTC_MATCH0, 0xFFFFFFFF); | ||
260 | rtc_writel(rtc, LPC32XX_RTC_INTSTAT, | ||
261 | LPC32XX_RTC_INTSTAT_MATCH0 | | ||
262 | LPC32XX_RTC_INTSTAT_MATCH1 | | ||
263 | LPC32XX_RTC_INTSTAT_ONSW); | ||
264 | |||
265 | /* Write key value to RTC so it won't reload on reset */ | ||
266 | rtc_writel(rtc, LPC32XX_RTC_KEY, | ||
267 | LPC32XX_RTC_KEY_ONSW_LOADVAL); | ||
268 | } else { | ||
269 | rtc_writel(rtc, LPC32XX_RTC_CTRL, | ||
270 | tmp & ~LPC32XX_RTC_CTRL_MATCH0); | ||
271 | } | ||
272 | |||
273 | platform_set_drvdata(pdev, rtc); | ||
274 | |||
275 | rtc->rtc = rtc_device_register(RTC_NAME, &pdev->dev, &lpc32xx_rtc_ops, | ||
276 | THIS_MODULE); | ||
277 | if (IS_ERR(rtc->rtc)) { | ||
278 | dev_err(&pdev->dev, "Can't get RTC\n"); | ||
279 | platform_set_drvdata(pdev, NULL); | ||
280 | return PTR_ERR(rtc->rtc); | ||
281 | } | ||
282 | |||
283 | /* | ||
284 | * IRQ is enabled after device registration in case alarm IRQ | ||
285 | * is pending upon suspend exit. | ||
286 | */ | ||
287 | if (rtc->irq >= 0) { | ||
288 | if (devm_request_irq(&pdev->dev, rtc->irq, | ||
289 | lpc32xx_rtc_alarm_interrupt, | ||
290 | IRQF_DISABLED, pdev->name, rtc) < 0) { | ||
291 | dev_warn(&pdev->dev, "Can't request interrupt.\n"); | ||
292 | rtc->irq = -1; | ||
293 | } else { | ||
294 | device_init_wakeup(&pdev->dev, 1); | ||
295 | } | ||
296 | } | ||
297 | |||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | static int __devexit lpc32xx_rtc_remove(struct platform_device *pdev) | ||
302 | { | ||
303 | struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev); | ||
304 | |||
305 | if (rtc->irq >= 0) | ||
306 | device_init_wakeup(&pdev->dev, 0); | ||
307 | |||
308 | platform_set_drvdata(pdev, NULL); | ||
309 | rtc_device_unregister(rtc->rtc); | ||
310 | |||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | #ifdef CONFIG_PM | ||
315 | static int lpc32xx_rtc_suspend(struct device *dev) | ||
316 | { | ||
317 | struct platform_device *pdev = to_platform_device(dev); | ||
318 | struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev); | ||
319 | |||
320 | if (rtc->irq >= 0) { | ||
321 | if (device_may_wakeup(&pdev->dev)) | ||
322 | enable_irq_wake(rtc->irq); | ||
323 | else | ||
324 | disable_irq_wake(rtc->irq); | ||
325 | } | ||
326 | |||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | static int lpc32xx_rtc_resume(struct device *dev) | ||
331 | { | ||
332 | struct platform_device *pdev = to_platform_device(dev); | ||
333 | struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev); | ||
334 | |||
335 | if (rtc->irq >= 0 && device_may_wakeup(&pdev->dev)) | ||
336 | disable_irq_wake(rtc->irq); | ||
337 | |||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | /* Unconditionally disable the alarm */ | ||
342 | static int lpc32xx_rtc_freeze(struct device *dev) | ||
343 | { | ||
344 | struct platform_device *pdev = to_platform_device(dev); | ||
345 | struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev); | ||
346 | |||
347 | spin_lock_irq(&rtc->lock); | ||
348 | |||
349 | rtc_writel(rtc, LPC32XX_RTC_CTRL, | ||
350 | rtc_readl(rtc, LPC32XX_RTC_CTRL) & | ||
351 | ~LPC32XX_RTC_CTRL_MATCH0); | ||
352 | |||
353 | spin_unlock_irq(&rtc->lock); | ||
354 | |||
355 | return 0; | ||
356 | } | ||
357 | |||
358 | static int lpc32xx_rtc_thaw(struct device *dev) | ||
359 | { | ||
360 | struct platform_device *pdev = to_platform_device(dev); | ||
361 | struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev); | ||
362 | |||
363 | if (rtc->alarm_enabled) { | ||
364 | spin_lock_irq(&rtc->lock); | ||
365 | |||
366 | rtc_writel(rtc, LPC32XX_RTC_CTRL, | ||
367 | rtc_readl(rtc, LPC32XX_RTC_CTRL) | | ||
368 | LPC32XX_RTC_CTRL_MATCH0); | ||
369 | |||
370 | spin_unlock_irq(&rtc->lock); | ||
371 | } | ||
372 | |||
373 | return 0; | ||
374 | } | ||
375 | |||
376 | static const struct dev_pm_ops lpc32xx_rtc_pm_ops = { | ||
377 | .suspend = lpc32xx_rtc_suspend, | ||
378 | .resume = lpc32xx_rtc_resume, | ||
379 | .freeze = lpc32xx_rtc_freeze, | ||
380 | .thaw = lpc32xx_rtc_thaw, | ||
381 | .restore = lpc32xx_rtc_resume | ||
382 | }; | ||
383 | |||
384 | #define LPC32XX_RTC_PM_OPS (&lpc32xx_rtc_pm_ops) | ||
385 | #else | ||
386 | #define LPC32XX_RTC_PM_OPS NULL | ||
387 | #endif | ||
388 | |||
389 | static struct platform_driver lpc32xx_rtc_driver = { | ||
390 | .probe = lpc32xx_rtc_probe, | ||
391 | .remove = __devexit_p(lpc32xx_rtc_remove), | ||
392 | .driver = { | ||
393 | .name = RTC_NAME, | ||
394 | .owner = THIS_MODULE, | ||
395 | .pm = LPC32XX_RTC_PM_OPS | ||
396 | }, | ||
397 | }; | ||
398 | |||
399 | static int __init lpc32xx_rtc_init(void) | ||
400 | { | ||
401 | return platform_driver_register(&lpc32xx_rtc_driver); | ||
402 | } | ||
403 | module_init(lpc32xx_rtc_init); | ||
404 | |||
405 | static void __exit lpc32xx_rtc_exit(void) | ||
406 | { | ||
407 | platform_driver_unregister(&lpc32xx_rtc_driver); | ||
408 | } | ||
409 | module_exit(lpc32xx_rtc_exit); | ||
410 | |||
411 | MODULE_AUTHOR("Kevin Wells <wellsk40@gmail.com"); | ||
412 | MODULE_DESCRIPTION("RTC driver for the LPC32xx SoC"); | ||
413 | MODULE_LICENSE("GPL"); | ||
414 | MODULE_ALIAS("platform:rtc-lpc32xx"); | ||
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index d60557cae8ef..eda128fc1d38 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/rtc.h> | 21 | #include <linux/rtc.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/smp_lock.h> | 23 | #include <linux/mutex.h> |
24 | #include <linux/string.h> | 24 | #include <linux/string.h> |
25 | #ifdef CONFIG_RTC_DRV_M41T80_WDT | 25 | #ifdef CONFIG_RTC_DRV_M41T80_WDT |
26 | #include <linux/fs.h> | 26 | #include <linux/fs.h> |
@@ -68,6 +68,7 @@ | |||
68 | 68 | ||
69 | #define DRV_VERSION "0.05" | 69 | #define DRV_VERSION "0.05" |
70 | 70 | ||
71 | static DEFINE_MUTEX(m41t80_rtc_mutex); | ||
71 | static const struct i2c_device_id m41t80_id[] = { | 72 | static const struct i2c_device_id m41t80_id[] = { |
72 | { "m41t62", M41T80_FEATURE_SQ | M41T80_FEATURE_SQ_ALT }, | 73 | { "m41t62", M41T80_FEATURE_SQ | M41T80_FEATURE_SQ_ALT }, |
73 | { "m41t65", M41T80_FEATURE_HT | M41T80_FEATURE_WD }, | 74 | { "m41t65", M41T80_FEATURE_HT | M41T80_FEATURE_WD }, |
@@ -212,41 +213,27 @@ static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
212 | return m41t80_set_datetime(to_i2c_client(dev), tm); | 213 | return m41t80_set_datetime(to_i2c_client(dev), tm); |
213 | } | 214 | } |
214 | 215 | ||
215 | #if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE) | 216 | static int m41t80_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) |
216 | static int | ||
217 | m41t80_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | ||
218 | { | 217 | { |
219 | struct i2c_client *client = to_i2c_client(dev); | 218 | struct i2c_client *client = to_i2c_client(dev); |
220 | int rc; | 219 | int rc; |
221 | 220 | ||
222 | switch (cmd) { | ||
223 | case RTC_AIE_OFF: | ||
224 | case RTC_AIE_ON: | ||
225 | break; | ||
226 | default: | ||
227 | return -ENOIOCTLCMD; | ||
228 | } | ||
229 | |||
230 | rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON); | 221 | rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON); |
231 | if (rc < 0) | 222 | if (rc < 0) |
232 | goto err; | 223 | goto err; |
233 | switch (cmd) { | 224 | |
234 | case RTC_AIE_OFF: | 225 | if (enabled) |
235 | rc &= ~M41T80_ALMON_AFE; | ||
236 | break; | ||
237 | case RTC_AIE_ON: | ||
238 | rc |= M41T80_ALMON_AFE; | 226 | rc |= M41T80_ALMON_AFE; |
239 | break; | 227 | else |
240 | } | 228 | rc &= ~M41T80_ALMON_AFE; |
229 | |||
241 | if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, rc) < 0) | 230 | if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, rc) < 0) |
242 | goto err; | 231 | goto err; |
232 | |||
243 | return 0; | 233 | return 0; |
244 | err: | 234 | err: |
245 | return -EIO; | 235 | return -EIO; |
246 | } | 236 | } |
247 | #else | ||
248 | #define m41t80_rtc_ioctl NULL | ||
249 | #endif | ||
250 | 237 | ||
251 | static int m41t80_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t) | 238 | static int m41t80_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t) |
252 | { | 239 | { |
@@ -373,7 +360,7 @@ static struct rtc_class_ops m41t80_rtc_ops = { | |||
373 | .read_alarm = m41t80_rtc_read_alarm, | 360 | .read_alarm = m41t80_rtc_read_alarm, |
374 | .set_alarm = m41t80_rtc_set_alarm, | 361 | .set_alarm = m41t80_rtc_set_alarm, |
375 | .proc = m41t80_rtc_proc, | 362 | .proc = m41t80_rtc_proc, |
376 | .ioctl = m41t80_rtc_ioctl, | 363 | .alarm_irq_enable = m41t80_rtc_alarm_irq_enable, |
377 | }; | 364 | }; |
378 | 365 | ||
379 | #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) | 366 | #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) |
@@ -677,9 +664,9 @@ static long wdt_unlocked_ioctl(struct file *file, unsigned int cmd, | |||
677 | { | 664 | { |
678 | int ret; | 665 | int ret; |
679 | 666 | ||
680 | lock_kernel(); | 667 | mutex_lock(&m41t80_rtc_mutex); |
681 | ret = wdt_ioctl(file, cmd, arg); | 668 | ret = wdt_ioctl(file, cmd, arg); |
682 | unlock_kernel(); | 669 | mutex_unlock(&m41t80_rtc_mutex); |
683 | 670 | ||
684 | return ret; | 671 | return ret; |
685 | } | 672 | } |
@@ -693,16 +680,16 @@ static long wdt_unlocked_ioctl(struct file *file, unsigned int cmd, | |||
693 | static int wdt_open(struct inode *inode, struct file *file) | 680 | static int wdt_open(struct inode *inode, struct file *file) |
694 | { | 681 | { |
695 | if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) { | 682 | if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) { |
696 | lock_kernel(); | 683 | mutex_lock(&m41t80_rtc_mutex); |
697 | if (test_and_set_bit(0, &wdt_is_open)) { | 684 | if (test_and_set_bit(0, &wdt_is_open)) { |
698 | unlock_kernel(); | 685 | mutex_unlock(&m41t80_rtc_mutex); |
699 | return -EBUSY; | 686 | return -EBUSY; |
700 | } | 687 | } |
701 | /* | 688 | /* |
702 | * Activate | 689 | * Activate |
703 | */ | 690 | */ |
704 | wdt_is_open = 1; | 691 | wdt_is_open = 1; |
705 | unlock_kernel(); | 692 | mutex_unlock(&m41t80_rtc_mutex); |
706 | return nonseekable_open(inode, file); | 693 | return nonseekable_open(inode, file); |
707 | } | 694 | } |
708 | return -ENODEV; | 695 | return -ENODEV; |
@@ -748,6 +735,7 @@ static const struct file_operations wdt_fops = { | |||
748 | .write = wdt_write, | 735 | .write = wdt_write, |
749 | .open = wdt_open, | 736 | .open = wdt_open, |
750 | .release = wdt_release, | 737 | .release = wdt_release, |
738 | .llseek = no_llseek, | ||
751 | }; | 739 | }; |
752 | 740 | ||
753 | static struct miscdevice wdt_dev = { | 741 | static struct miscdevice wdt_dev = { |
@@ -795,6 +783,9 @@ static int m41t80_probe(struct i2c_client *client, | |||
795 | goto exit; | 783 | goto exit; |
796 | } | 784 | } |
797 | 785 | ||
786 | clientdata->features = id->driver_data; | ||
787 | i2c_set_clientdata(client, clientdata); | ||
788 | |||
798 | rtc = rtc_device_register(client->name, &client->dev, | 789 | rtc = rtc_device_register(client->name, &client->dev, |
799 | &m41t80_rtc_ops, THIS_MODULE); | 790 | &m41t80_rtc_ops, THIS_MODULE); |
800 | if (IS_ERR(rtc)) { | 791 | if (IS_ERR(rtc)) { |
@@ -804,8 +795,6 @@ static int m41t80_probe(struct i2c_client *client, | |||
804 | } | 795 | } |
805 | 796 | ||
806 | clientdata->rtc = rtc; | 797 | clientdata->rtc = rtc; |
807 | clientdata->features = id->driver_data; | ||
808 | i2c_set_clientdata(client, clientdata); | ||
809 | 798 | ||
810 | /* Make sure HT (Halt Update) bit is cleared */ | 799 | /* Make sure HT (Halt Update) bit is cleared */ |
811 | rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_HOUR); | 800 | rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_HOUR); |
diff --git a/drivers/rtc/rtc-m41t93.c b/drivers/rtc/rtc-m41t93.c new file mode 100644 index 000000000000..7317d3b9a3d5 --- /dev/null +++ b/drivers/rtc/rtc-m41t93.c | |||
@@ -0,0 +1,225 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Driver for ST M41T93 SPI RTC | ||
4 | * | ||
5 | * (c) 2010 Nikolaus Voss, Weinmann Medical GmbH | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/bcd.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/rtc.h> | ||
17 | #include <linux/spi/spi.h> | ||
18 | |||
19 | #define M41T93_REG_SSEC 0 | ||
20 | #define M41T93_REG_ST_SEC 1 | ||
21 | #define M41T93_REG_MIN 2 | ||
22 | #define M41T93_REG_CENT_HOUR 3 | ||
23 | #define M41T93_REG_WDAY 4 | ||
24 | #define M41T93_REG_DAY 5 | ||
25 | #define M41T93_REG_MON 6 | ||
26 | #define M41T93_REG_YEAR 7 | ||
27 | |||
28 | |||
29 | #define M41T93_REG_ALM_HOUR_HT 0xc | ||
30 | #define M41T93_REG_FLAGS 0xf | ||
31 | |||
32 | #define M41T93_FLAG_ST (1 << 7) | ||
33 | #define M41T93_FLAG_OF (1 << 2) | ||
34 | #define M41T93_FLAG_BL (1 << 4) | ||
35 | #define M41T93_FLAG_HT (1 << 6) | ||
36 | |||
37 | static inline int m41t93_set_reg(struct spi_device *spi, u8 addr, u8 data) | ||
38 | { | ||
39 | u8 buf[2]; | ||
40 | |||
41 | /* MSB must be '1' to write */ | ||
42 | buf[0] = addr | 0x80; | ||
43 | buf[1] = data; | ||
44 | |||
45 | return spi_write(spi, buf, sizeof(buf)); | ||
46 | } | ||
47 | |||
48 | static int m41t93_set_time(struct device *dev, struct rtc_time *tm) | ||
49 | { | ||
50 | struct spi_device *spi = to_spi_device(dev); | ||
51 | u8 buf[9] = {0x80}; /* write cmd + 8 data bytes */ | ||
52 | u8 * const data = &buf[1]; /* ptr to first data byte */ | ||
53 | |||
54 | dev_dbg(dev, "%s secs=%d, mins=%d, " | ||
55 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", | ||
56 | "write", tm->tm_sec, tm->tm_min, | ||
57 | tm->tm_hour, tm->tm_mday, | ||
58 | tm->tm_mon, tm->tm_year, tm->tm_wday); | ||
59 | |||
60 | if (tm->tm_year < 100) { | ||
61 | dev_warn(&spi->dev, "unsupported date (before 2000-01-01).\n"); | ||
62 | return -EINVAL; | ||
63 | } | ||
64 | |||
65 | data[M41T93_REG_SSEC] = 0; | ||
66 | data[M41T93_REG_ST_SEC] = bin2bcd(tm->tm_sec); | ||
67 | data[M41T93_REG_MIN] = bin2bcd(tm->tm_min); | ||
68 | data[M41T93_REG_CENT_HOUR] = bin2bcd(tm->tm_hour) | | ||
69 | ((tm->tm_year/100-1) << 6); | ||
70 | data[M41T93_REG_DAY] = bin2bcd(tm->tm_mday); | ||
71 | data[M41T93_REG_WDAY] = bin2bcd(tm->tm_wday + 1); | ||
72 | data[M41T93_REG_MON] = bin2bcd(tm->tm_mon + 1); | ||
73 | data[M41T93_REG_YEAR] = bin2bcd(tm->tm_year % 100); | ||
74 | |||
75 | return spi_write(spi, buf, sizeof(buf)); | ||
76 | } | ||
77 | |||
78 | |||
79 | static int m41t93_get_time(struct device *dev, struct rtc_time *tm) | ||
80 | { | ||
81 | struct spi_device *spi = to_spi_device(dev); | ||
82 | const u8 start_addr = 0; | ||
83 | u8 buf[8]; | ||
84 | int century_after_1900; | ||
85 | int tmp; | ||
86 | int ret = 0; | ||
87 | |||
88 | /* Check status of clock. Two states must be considered: | ||
89 | 1. halt bit (HT) is set: the clock is running but update of readout | ||
90 | registers has been disabled due to power failure. This is normal | ||
91 | case after poweron. Time is valid after resetting HT bit. | ||
92 | 2. oscillator fail bit (OF) is set. Oscillator has be stopped and | ||
93 | time is invalid: | ||
94 | a) OF can be immeditely reset. | ||
95 | b) OF cannot be immediately reset: oscillator has to be restarted. | ||
96 | */ | ||
97 | tmp = spi_w8r8(spi, M41T93_REG_ALM_HOUR_HT); | ||
98 | if (tmp < 0) | ||
99 | return tmp; | ||
100 | |||
101 | if (tmp & M41T93_FLAG_HT) { | ||
102 | dev_dbg(&spi->dev, "HT bit is set, reenable clock update.\n"); | ||
103 | m41t93_set_reg(spi, M41T93_REG_ALM_HOUR_HT, | ||
104 | tmp & ~M41T93_FLAG_HT); | ||
105 | } | ||
106 | |||
107 | tmp = spi_w8r8(spi, M41T93_REG_FLAGS); | ||
108 | if (tmp < 0) | ||
109 | return tmp; | ||
110 | |||
111 | if (tmp & M41T93_FLAG_OF) { | ||
112 | ret = -EINVAL; | ||
113 | dev_warn(&spi->dev, "OF bit is set, resetting.\n"); | ||
114 | m41t93_set_reg(spi, M41T93_REG_FLAGS, tmp & ~M41T93_FLAG_OF); | ||
115 | |||
116 | tmp = spi_w8r8(spi, M41T93_REG_FLAGS); | ||
117 | if (tmp < 0) | ||
118 | return tmp; | ||
119 | else if (tmp & M41T93_FLAG_OF) { | ||
120 | u8 reset_osc = buf[M41T93_REG_ST_SEC] | M41T93_FLAG_ST; | ||
121 | |||
122 | dev_warn(&spi->dev, | ||
123 | "OF bit is still set, kickstarting clock.\n"); | ||
124 | m41t93_set_reg(spi, M41T93_REG_ST_SEC, reset_osc); | ||
125 | reset_osc &= ~M41T93_FLAG_ST; | ||
126 | m41t93_set_reg(spi, M41T93_REG_ST_SEC, reset_osc); | ||
127 | } | ||
128 | } | ||
129 | |||
130 | if (tmp & M41T93_FLAG_BL) | ||
131 | dev_warn(&spi->dev, "BL bit is set, replace battery.\n"); | ||
132 | |||
133 | /* read actual time/date */ | ||
134 | tmp = spi_write_then_read(spi, &start_addr, 1, buf, sizeof(buf)); | ||
135 | if (tmp < 0) | ||
136 | return tmp; | ||
137 | |||
138 | tm->tm_sec = bcd2bin(buf[M41T93_REG_ST_SEC]); | ||
139 | tm->tm_min = bcd2bin(buf[M41T93_REG_MIN]); | ||
140 | tm->tm_hour = bcd2bin(buf[M41T93_REG_CENT_HOUR] & 0x3f); | ||
141 | tm->tm_mday = bcd2bin(buf[M41T93_REG_DAY]); | ||
142 | tm->tm_mon = bcd2bin(buf[M41T93_REG_MON]) - 1; | ||
143 | tm->tm_wday = bcd2bin(buf[M41T93_REG_WDAY] & 0x0f) - 1; | ||
144 | |||
145 | century_after_1900 = (buf[M41T93_REG_CENT_HOUR] >> 6) + 1; | ||
146 | tm->tm_year = bcd2bin(buf[M41T93_REG_YEAR]) + century_after_1900 * 100; | ||
147 | |||
148 | dev_dbg(dev, "%s secs=%d, mins=%d, " | ||
149 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", | ||
150 | "read", tm->tm_sec, tm->tm_min, | ||
151 | tm->tm_hour, tm->tm_mday, | ||
152 | tm->tm_mon, tm->tm_year, tm->tm_wday); | ||
153 | |||
154 | return ret < 0 ? ret : rtc_valid_tm(tm); | ||
155 | } | ||
156 | |||
157 | |||
158 | static const struct rtc_class_ops m41t93_rtc_ops = { | ||
159 | .read_time = m41t93_get_time, | ||
160 | .set_time = m41t93_set_time, | ||
161 | }; | ||
162 | |||
163 | static struct spi_driver m41t93_driver; | ||
164 | |||
165 | static int __devinit m41t93_probe(struct spi_device *spi) | ||
166 | { | ||
167 | struct rtc_device *rtc; | ||
168 | int res; | ||
169 | |||
170 | spi->bits_per_word = 8; | ||
171 | spi_setup(spi); | ||
172 | |||
173 | res = spi_w8r8(spi, M41T93_REG_WDAY); | ||
174 | if (res < 0 || (res & 0xf8) != 0) { | ||
175 | dev_err(&spi->dev, "not found 0x%x.\n", res); | ||
176 | return -ENODEV; | ||
177 | } | ||
178 | |||
179 | rtc = rtc_device_register(m41t93_driver.driver.name, | ||
180 | &spi->dev, &m41t93_rtc_ops, THIS_MODULE); | ||
181 | if (IS_ERR(rtc)) | ||
182 | return PTR_ERR(rtc); | ||
183 | |||
184 | dev_set_drvdata(&spi->dev, rtc); | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | |||
190 | static int __devexit m41t93_remove(struct spi_device *spi) | ||
191 | { | ||
192 | struct rtc_device *rtc = spi_get_drvdata(spi); | ||
193 | |||
194 | if (rtc) | ||
195 | rtc_device_unregister(rtc); | ||
196 | |||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | static struct spi_driver m41t93_driver = { | ||
201 | .driver = { | ||
202 | .name = "rtc-m41t93", | ||
203 | .bus = &spi_bus_type, | ||
204 | .owner = THIS_MODULE, | ||
205 | }, | ||
206 | .probe = m41t93_probe, | ||
207 | .remove = __devexit_p(m41t93_remove), | ||
208 | }; | ||
209 | |||
210 | static __init int m41t93_init(void) | ||
211 | { | ||
212 | return spi_register_driver(&m41t93_driver); | ||
213 | } | ||
214 | module_init(m41t93_init); | ||
215 | |||
216 | static __exit void m41t93_exit(void) | ||
217 | { | ||
218 | spi_unregister_driver(&m41t93_driver); | ||
219 | } | ||
220 | module_exit(m41t93_exit); | ||
221 | |||
222 | MODULE_AUTHOR("Nikolaus Voss <n.voss@weinmann.de>"); | ||
223 | MODULE_DESCRIPTION("Driver for ST M41T93 SPI RTC"); | ||
224 | MODULE_LICENSE("GPL"); | ||
225 | MODULE_ALIAS("spi:rtc-m41t93"); | ||
diff --git a/drivers/rtc/rtc-m41t94.c b/drivers/rtc/rtc-m41t94.c index c8c97a4169d4..e259ed76ae85 100644 --- a/drivers/rtc/rtc-m41t94.c +++ b/drivers/rtc/rtc-m41t94.c | |||
@@ -136,7 +136,7 @@ static int __devinit m41t94_probe(struct spi_device *spi) | |||
136 | 136 | ||
137 | static int __devexit m41t94_remove(struct spi_device *spi) | 137 | static int __devexit m41t94_remove(struct spi_device *spi) |
138 | { | 138 | { |
139 | struct rtc_device *rtc = platform_get_drvdata(spi); | 139 | struct rtc_device *rtc = spi_get_drvdata(spi); |
140 | 140 | ||
141 | if (rtc) | 141 | if (rtc) |
142 | rtc_device_unregister(rtc); | 142 | rtc_device_unregister(rtc); |
diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c index a99a0b554eb8..3978f4caf724 100644 --- a/drivers/rtc/rtc-m48t59.c +++ b/drivers/rtc/rtc-m48t59.c | |||
@@ -263,30 +263,21 @@ static int m48t59_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
263 | /* | 263 | /* |
264 | * Handle commands from user-space | 264 | * Handle commands from user-space |
265 | */ | 265 | */ |
266 | static int m48t59_rtc_ioctl(struct device *dev, unsigned int cmd, | 266 | static int m48t59_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) |
267 | unsigned long arg) | ||
268 | { | 267 | { |
269 | struct platform_device *pdev = to_platform_device(dev); | 268 | struct platform_device *pdev = to_platform_device(dev); |
270 | struct m48t59_plat_data *pdata = pdev->dev.platform_data; | 269 | struct m48t59_plat_data *pdata = pdev->dev.platform_data; |
271 | struct m48t59_private *m48t59 = platform_get_drvdata(pdev); | 270 | struct m48t59_private *m48t59 = platform_get_drvdata(pdev); |
272 | unsigned long flags; | 271 | unsigned long flags; |
273 | int ret = 0; | ||
274 | 272 | ||
275 | spin_lock_irqsave(&m48t59->lock, flags); | 273 | spin_lock_irqsave(&m48t59->lock, flags); |
276 | switch (cmd) { | 274 | if (enabled) |
277 | case RTC_AIE_OFF: /* alarm interrupt off */ | ||
278 | M48T59_WRITE(0x00, M48T59_INTR); | ||
279 | break; | ||
280 | case RTC_AIE_ON: /* alarm interrupt on */ | ||
281 | M48T59_WRITE(M48T59_INTR_AFE, M48T59_INTR); | 275 | M48T59_WRITE(M48T59_INTR_AFE, M48T59_INTR); |
282 | break; | 276 | else |
283 | default: | 277 | M48T59_WRITE(0x00, M48T59_INTR); |
284 | ret = -ENOIOCTLCMD; | ||
285 | break; | ||
286 | } | ||
287 | spin_unlock_irqrestore(&m48t59->lock, flags); | 278 | spin_unlock_irqrestore(&m48t59->lock, flags); |
288 | 279 | ||
289 | return ret; | 280 | return 0; |
290 | } | 281 | } |
291 | 282 | ||
292 | static int m48t59_rtc_proc(struct device *dev, struct seq_file *seq) | 283 | static int m48t59_rtc_proc(struct device *dev, struct seq_file *seq) |
@@ -330,12 +321,12 @@ static irqreturn_t m48t59_rtc_interrupt(int irq, void *dev_id) | |||
330 | } | 321 | } |
331 | 322 | ||
332 | static const struct rtc_class_ops m48t59_rtc_ops = { | 323 | static const struct rtc_class_ops m48t59_rtc_ops = { |
333 | .ioctl = m48t59_rtc_ioctl, | ||
334 | .read_time = m48t59_rtc_read_time, | 324 | .read_time = m48t59_rtc_read_time, |
335 | .set_time = m48t59_rtc_set_time, | 325 | .set_time = m48t59_rtc_set_time, |
336 | .read_alarm = m48t59_rtc_readalarm, | 326 | .read_alarm = m48t59_rtc_readalarm, |
337 | .set_alarm = m48t59_rtc_setalarm, | 327 | .set_alarm = m48t59_rtc_setalarm, |
338 | .proc = m48t59_rtc_proc, | 328 | .proc = m48t59_rtc_proc, |
329 | .alarm_irq_enable = m48t59_rtc_alarm_irq_enable, | ||
339 | }; | 330 | }; |
340 | 331 | ||
341 | static const struct rtc_class_ops m48t02_rtc_ops = { | 332 | static const struct rtc_class_ops m48t02_rtc_ops = { |
diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c index 657403ebd54a..0ec3f588a255 100644 --- a/drivers/rtc/rtc-max6902.c +++ b/drivers/rtc/rtc-max6902.c | |||
@@ -139,12 +139,13 @@ static int __devinit max6902_probe(struct spi_device *spi) | |||
139 | if (IS_ERR(rtc)) | 139 | if (IS_ERR(rtc)) |
140 | return PTR_ERR(rtc); | 140 | return PTR_ERR(rtc); |
141 | 141 | ||
142 | dev_set_drvdata(&spi->dev, rtc); | ||
142 | return 0; | 143 | return 0; |
143 | } | 144 | } |
144 | 145 | ||
145 | static int __devexit max6902_remove(struct spi_device *spi) | 146 | static int __devexit max6902_remove(struct spi_device *spi) |
146 | { | 147 | { |
147 | struct rtc_device *rtc = platform_get_drvdata(spi); | 148 | struct rtc_device *rtc = dev_get_drvdata(&spi->dev); |
148 | 149 | ||
149 | rtc_device_unregister(rtc); | 150 | rtc_device_unregister(rtc); |
150 | return 0; | 151 | return 0; |
diff --git a/drivers/rtc/rtc-max8925.c b/drivers/rtc/rtc-max8925.c index 174036dda786..3bc046f427e0 100644 --- a/drivers/rtc/rtc-max8925.c +++ b/drivers/rtc/rtc-max8925.c | |||
@@ -257,6 +257,10 @@ static int __devinit max8925_rtc_probe(struct platform_device *pdev) | |||
257 | goto out_irq; | 257 | goto out_irq; |
258 | } | 258 | } |
259 | 259 | ||
260 | dev_set_drvdata(&pdev->dev, info); | ||
261 | /* XXX - isn't this redundant? */ | ||
262 | platform_set_drvdata(pdev, info); | ||
263 | |||
260 | info->rtc_dev = rtc_device_register("max8925-rtc", &pdev->dev, | 264 | info->rtc_dev = rtc_device_register("max8925-rtc", &pdev->dev, |
261 | &max8925_rtc_ops, THIS_MODULE); | 265 | &max8925_rtc_ops, THIS_MODULE); |
262 | ret = PTR_ERR(info->rtc_dev); | 266 | ret = PTR_ERR(info->rtc_dev); |
@@ -265,11 +269,9 @@ static int __devinit max8925_rtc_probe(struct platform_device *pdev) | |||
265 | goto out_rtc; | 269 | goto out_rtc; |
266 | } | 270 | } |
267 | 271 | ||
268 | dev_set_drvdata(&pdev->dev, info); | ||
269 | platform_set_drvdata(pdev, info); | ||
270 | |||
271 | return 0; | 272 | return 0; |
272 | out_rtc: | 273 | out_rtc: |
274 | platform_set_drvdata(pdev, NULL); | ||
273 | free_irq(chip->irq_base + MAX8925_IRQ_RTC_ALARM0, info); | 275 | free_irq(chip->irq_base + MAX8925_IRQ_RTC_ALARM0, info); |
274 | out_irq: | 276 | out_irq: |
275 | kfree(info); | 277 | kfree(info); |
diff --git a/drivers/rtc/rtc-max8998.c b/drivers/rtc/rtc-max8998.c new file mode 100644 index 000000000000..2e48aa604273 --- /dev/null +++ b/drivers/rtc/rtc-max8998.c | |||
@@ -0,0 +1,345 @@ | |||
1 | /* | ||
2 | * RTC driver for Maxim MAX8998 | ||
3 | * | ||
4 | * Copyright (C) 2010 Samsung Electronics Co.Ltd | ||
5 | * Author: Minkyu Kang <mk7.kang@samsung.com> | ||
6 | * Author: Joonyoung Shim <jy0922.shim@samsung.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/i2c.h> | ||
17 | #include <linux/slab.h> | ||
18 | #include <linux/bcd.h> | ||
19 | #include <linux/rtc.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/mfd/max8998.h> | ||
22 | #include <linux/mfd/max8998-private.h> | ||
23 | #include <linux/delay.h> | ||
24 | |||
25 | #define MAX8998_RTC_SEC 0x00 | ||
26 | #define MAX8998_RTC_MIN 0x01 | ||
27 | #define MAX8998_RTC_HOUR 0x02 | ||
28 | #define MAX8998_RTC_WEEKDAY 0x03 | ||
29 | #define MAX8998_RTC_DATE 0x04 | ||
30 | #define MAX8998_RTC_MONTH 0x05 | ||
31 | #define MAX8998_RTC_YEAR1 0x06 | ||
32 | #define MAX8998_RTC_YEAR2 0x07 | ||
33 | #define MAX8998_ALARM0_SEC 0x08 | ||
34 | #define MAX8998_ALARM0_MIN 0x09 | ||
35 | #define MAX8998_ALARM0_HOUR 0x0a | ||
36 | #define MAX8998_ALARM0_WEEKDAY 0x0b | ||
37 | #define MAX8998_ALARM0_DATE 0x0c | ||
38 | #define MAX8998_ALARM0_MONTH 0x0d | ||
39 | #define MAX8998_ALARM0_YEAR1 0x0e | ||
40 | #define MAX8998_ALARM0_YEAR2 0x0f | ||
41 | #define MAX8998_ALARM1_SEC 0x10 | ||
42 | #define MAX8998_ALARM1_MIN 0x11 | ||
43 | #define MAX8998_ALARM1_HOUR 0x12 | ||
44 | #define MAX8998_ALARM1_WEEKDAY 0x13 | ||
45 | #define MAX8998_ALARM1_DATE 0x14 | ||
46 | #define MAX8998_ALARM1_MONTH 0x15 | ||
47 | #define MAX8998_ALARM1_YEAR1 0x16 | ||
48 | #define MAX8998_ALARM1_YEAR2 0x17 | ||
49 | #define MAX8998_ALARM0_CONF 0x18 | ||
50 | #define MAX8998_ALARM1_CONF 0x19 | ||
51 | #define MAX8998_RTC_STATUS 0x1a | ||
52 | #define MAX8998_WTSR_SMPL_CNTL 0x1b | ||
53 | #define MAX8998_TEST 0x1f | ||
54 | |||
55 | #define HOUR_12 (1 << 7) | ||
56 | #define HOUR_PM (1 << 5) | ||
57 | #define ALARM0_STATUS (1 << 1) | ||
58 | #define ALARM1_STATUS (1 << 2) | ||
59 | |||
60 | enum { | ||
61 | RTC_SEC = 0, | ||
62 | RTC_MIN, | ||
63 | RTC_HOUR, | ||
64 | RTC_WEEKDAY, | ||
65 | RTC_DATE, | ||
66 | RTC_MONTH, | ||
67 | RTC_YEAR1, | ||
68 | RTC_YEAR2, | ||
69 | }; | ||
70 | |||
71 | struct max8998_rtc_info { | ||
72 | struct device *dev; | ||
73 | struct max8998_dev *max8998; | ||
74 | struct i2c_client *rtc; | ||
75 | struct rtc_device *rtc_dev; | ||
76 | int irq; | ||
77 | bool lp3974_bug_workaround; | ||
78 | }; | ||
79 | |||
80 | static void max8998_data_to_tm(u8 *data, struct rtc_time *tm) | ||
81 | { | ||
82 | tm->tm_sec = bcd2bin(data[RTC_SEC]); | ||
83 | tm->tm_min = bcd2bin(data[RTC_MIN]); | ||
84 | if (data[RTC_HOUR] & HOUR_12) { | ||
85 | tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x1f); | ||
86 | if (data[RTC_HOUR] & HOUR_PM) | ||
87 | tm->tm_hour += 12; | ||
88 | } else | ||
89 | tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x3f); | ||
90 | |||
91 | tm->tm_wday = data[RTC_WEEKDAY] & 0x07; | ||
92 | tm->tm_mday = bcd2bin(data[RTC_DATE]); | ||
93 | tm->tm_mon = bcd2bin(data[RTC_MONTH]); | ||
94 | tm->tm_year = bcd2bin(data[RTC_YEAR1]) + bcd2bin(data[RTC_YEAR2]) * 100; | ||
95 | tm->tm_year -= 1900; | ||
96 | } | ||
97 | |||
98 | static void max8998_tm_to_data(struct rtc_time *tm, u8 *data) | ||
99 | { | ||
100 | data[RTC_SEC] = bin2bcd(tm->tm_sec); | ||
101 | data[RTC_MIN] = bin2bcd(tm->tm_min); | ||
102 | data[RTC_HOUR] = bin2bcd(tm->tm_hour); | ||
103 | data[RTC_WEEKDAY] = tm->tm_wday; | ||
104 | data[RTC_DATE] = bin2bcd(tm->tm_mday); | ||
105 | data[RTC_MONTH] = bin2bcd(tm->tm_mon); | ||
106 | data[RTC_YEAR1] = bin2bcd(tm->tm_year % 100); | ||
107 | data[RTC_YEAR2] = bin2bcd((tm->tm_year + 1900) / 100); | ||
108 | } | ||
109 | |||
110 | static int max8998_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
111 | { | ||
112 | struct max8998_rtc_info *info = dev_get_drvdata(dev); | ||
113 | u8 data[8]; | ||
114 | int ret; | ||
115 | |||
116 | ret = max8998_bulk_read(info->rtc, MAX8998_RTC_SEC, 8, data); | ||
117 | if (ret < 0) | ||
118 | return ret; | ||
119 | |||
120 | max8998_data_to_tm(data, tm); | ||
121 | |||
122 | return rtc_valid_tm(tm); | ||
123 | } | ||
124 | |||
125 | static int max8998_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
126 | { | ||
127 | struct max8998_rtc_info *info = dev_get_drvdata(dev); | ||
128 | u8 data[8]; | ||
129 | int ret; | ||
130 | |||
131 | max8998_tm_to_data(tm, data); | ||
132 | |||
133 | ret = max8998_bulk_write(info->rtc, MAX8998_RTC_SEC, 8, data); | ||
134 | |||
135 | if (info->lp3974_bug_workaround) | ||
136 | msleep(2000); | ||
137 | |||
138 | return ret; | ||
139 | } | ||
140 | |||
141 | static int max8998_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
142 | { | ||
143 | struct max8998_rtc_info *info = dev_get_drvdata(dev); | ||
144 | u8 data[8]; | ||
145 | u8 val; | ||
146 | int ret; | ||
147 | |||
148 | ret = max8998_bulk_read(info->rtc, MAX8998_ALARM0_SEC, 8, data); | ||
149 | if (ret < 0) | ||
150 | return ret; | ||
151 | |||
152 | max8998_data_to_tm(data, &alrm->time); | ||
153 | |||
154 | ret = max8998_read_reg(info->rtc, MAX8998_ALARM0_CONF, &val); | ||
155 | if (ret < 0) | ||
156 | return ret; | ||
157 | |||
158 | alrm->enabled = !!val; | ||
159 | |||
160 | ret = max8998_read_reg(info->rtc, MAX8998_RTC_STATUS, &val); | ||
161 | if (ret < 0) | ||
162 | return ret; | ||
163 | |||
164 | if (val & ALARM0_STATUS) | ||
165 | alrm->pending = 1; | ||
166 | else | ||
167 | alrm->pending = 0; | ||
168 | |||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | static int max8998_rtc_stop_alarm(struct max8998_rtc_info *info) | ||
173 | { | ||
174 | int ret = max8998_write_reg(info->rtc, MAX8998_ALARM0_CONF, 0); | ||
175 | |||
176 | if (info->lp3974_bug_workaround) | ||
177 | msleep(2000); | ||
178 | |||
179 | return ret; | ||
180 | } | ||
181 | |||
182 | static int max8998_rtc_start_alarm(struct max8998_rtc_info *info) | ||
183 | { | ||
184 | int ret; | ||
185 | u8 alarm0_conf = 0x77; | ||
186 | |||
187 | /* LP3974 with delay bug chips has rtc alarm bugs with "MONTH" field */ | ||
188 | if (info->lp3974_bug_workaround) | ||
189 | alarm0_conf = 0x57; | ||
190 | |||
191 | ret = max8998_write_reg(info->rtc, MAX8998_ALARM0_CONF, alarm0_conf); | ||
192 | |||
193 | if (info->lp3974_bug_workaround) | ||
194 | msleep(2000); | ||
195 | |||
196 | return ret; | ||
197 | } | ||
198 | |||
199 | static int max8998_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
200 | { | ||
201 | struct max8998_rtc_info *info = dev_get_drvdata(dev); | ||
202 | u8 data[8]; | ||
203 | int ret; | ||
204 | |||
205 | max8998_tm_to_data(&alrm->time, data); | ||
206 | |||
207 | ret = max8998_rtc_stop_alarm(info); | ||
208 | if (ret < 0) | ||
209 | return ret; | ||
210 | |||
211 | ret = max8998_bulk_write(info->rtc, MAX8998_ALARM0_SEC, 8, data); | ||
212 | if (ret < 0) | ||
213 | return ret; | ||
214 | |||
215 | if (info->lp3974_bug_workaround) | ||
216 | msleep(2000); | ||
217 | |||
218 | if (alrm->enabled) | ||
219 | ret = max8998_rtc_start_alarm(info); | ||
220 | |||
221 | return ret; | ||
222 | } | ||
223 | |||
224 | static int max8998_rtc_alarm_irq_enable(struct device *dev, | ||
225 | unsigned int enabled) | ||
226 | { | ||
227 | struct max8998_rtc_info *info = dev_get_drvdata(dev); | ||
228 | |||
229 | if (enabled) | ||
230 | return max8998_rtc_start_alarm(info); | ||
231 | else | ||
232 | return max8998_rtc_stop_alarm(info); | ||
233 | } | ||
234 | |||
235 | static irqreturn_t max8998_rtc_alarm_irq(int irq, void *data) | ||
236 | { | ||
237 | struct max8998_rtc_info *info = data; | ||
238 | |||
239 | rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF); | ||
240 | |||
241 | return IRQ_HANDLED; | ||
242 | } | ||
243 | |||
244 | static const struct rtc_class_ops max8998_rtc_ops = { | ||
245 | .read_time = max8998_rtc_read_time, | ||
246 | .set_time = max8998_rtc_set_time, | ||
247 | .read_alarm = max8998_rtc_read_alarm, | ||
248 | .set_alarm = max8998_rtc_set_alarm, | ||
249 | .alarm_irq_enable = max8998_rtc_alarm_irq_enable, | ||
250 | }; | ||
251 | |||
252 | static int __devinit max8998_rtc_probe(struct platform_device *pdev) | ||
253 | { | ||
254 | struct max8998_dev *max8998 = dev_get_drvdata(pdev->dev.parent); | ||
255 | struct max8998_platform_data *pdata = dev_get_platdata(max8998->dev); | ||
256 | struct max8998_rtc_info *info; | ||
257 | int ret; | ||
258 | |||
259 | info = kzalloc(sizeof(struct max8998_rtc_info), GFP_KERNEL); | ||
260 | if (!info) | ||
261 | return -ENOMEM; | ||
262 | |||
263 | info->dev = &pdev->dev; | ||
264 | info->max8998 = max8998; | ||
265 | info->rtc = max8998->rtc; | ||
266 | info->irq = max8998->irq_base + MAX8998_IRQ_ALARM0; | ||
267 | |||
268 | platform_set_drvdata(pdev, info); | ||
269 | |||
270 | info->rtc_dev = rtc_device_register("max8998-rtc", &pdev->dev, | ||
271 | &max8998_rtc_ops, THIS_MODULE); | ||
272 | |||
273 | if (IS_ERR(info->rtc_dev)) { | ||
274 | ret = PTR_ERR(info->rtc_dev); | ||
275 | dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); | ||
276 | goto out_rtc; | ||
277 | } | ||
278 | |||
279 | ret = request_threaded_irq(info->irq, NULL, max8998_rtc_alarm_irq, 0, | ||
280 | "rtc-alarm0", info); | ||
281 | |||
282 | if (ret < 0) | ||
283 | dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", | ||
284 | info->irq, ret); | ||
285 | |||
286 | dev_info(&pdev->dev, "RTC CHIP NAME: %s\n", pdev->id_entry->name); | ||
287 | if (pdata->rtc_delay) { | ||
288 | info->lp3974_bug_workaround = true; | ||
289 | dev_warn(&pdev->dev, "LP3974 with RTC REGERR option." | ||
290 | " RTC updates will be extremely slow.\n"); | ||
291 | } | ||
292 | |||
293 | return 0; | ||
294 | |||
295 | out_rtc: | ||
296 | platform_set_drvdata(pdev, NULL); | ||
297 | kfree(info); | ||
298 | return ret; | ||
299 | } | ||
300 | |||
301 | static int __devexit max8998_rtc_remove(struct platform_device *pdev) | ||
302 | { | ||
303 | struct max8998_rtc_info *info = platform_get_drvdata(pdev); | ||
304 | |||
305 | if (info) { | ||
306 | free_irq(info->irq, info); | ||
307 | rtc_device_unregister(info->rtc_dev); | ||
308 | kfree(info); | ||
309 | } | ||
310 | |||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | static const struct platform_device_id max8998_rtc_id[] = { | ||
315 | { "max8998-rtc", TYPE_MAX8998 }, | ||
316 | { "lp3974-rtc", TYPE_LP3974 }, | ||
317 | { } | ||
318 | }; | ||
319 | |||
320 | static struct platform_driver max8998_rtc_driver = { | ||
321 | .driver = { | ||
322 | .name = "max8998-rtc", | ||
323 | .owner = THIS_MODULE, | ||
324 | }, | ||
325 | .probe = max8998_rtc_probe, | ||
326 | .remove = __devexit_p(max8998_rtc_remove), | ||
327 | .id_table = max8998_rtc_id, | ||
328 | }; | ||
329 | |||
330 | static int __init max8998_rtc_init(void) | ||
331 | { | ||
332 | return platform_driver_register(&max8998_rtc_driver); | ||
333 | } | ||
334 | module_init(max8998_rtc_init); | ||
335 | |||
336 | static void __exit max8998_rtc_exit(void) | ||
337 | { | ||
338 | platform_driver_unregister(&max8998_rtc_driver); | ||
339 | } | ||
340 | module_exit(max8998_rtc_exit); | ||
341 | |||
342 | MODULE_AUTHOR("Minkyu Kang <mk7.kang@samsung.com>"); | ||
343 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); | ||
344 | MODULE_DESCRIPTION("Maxim MAX8998 RTC driver"); | ||
345 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-mc13783.c b/drivers/rtc/rtc-mc13783.c deleted file mode 100644 index 675bfb515367..000000000000 --- a/drivers/rtc/rtc-mc13783.c +++ /dev/null | |||
@@ -1,428 +0,0 @@ | |||
1 | /* | ||
2 | * Real Time Clock driver for Freescale MC13783 PMIC | ||
3 | * | ||
4 | * (C) 2009 Sascha Hauer, Pengutronix | ||
5 | * (C) 2009 Uwe Kleine-Koenig, Pengutronix | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/mfd/mc13783.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/rtc.h> | ||
18 | |||
19 | #define DRIVER_NAME "mc13783-rtc" | ||
20 | |||
21 | #define MC13783_RTCTOD 20 | ||
22 | #define MC13783_RTCTODA 21 | ||
23 | #define MC13783_RTCDAY 22 | ||
24 | #define MC13783_RTCDAYA 23 | ||
25 | |||
26 | struct mc13783_rtc { | ||
27 | struct rtc_device *rtc; | ||
28 | struct mc13783 *mc13783; | ||
29 | int valid; | ||
30 | }; | ||
31 | |||
32 | static int mc13783_rtc_irq_enable_unlocked(struct device *dev, | ||
33 | unsigned int enabled, int irq) | ||
34 | { | ||
35 | struct mc13783_rtc *priv = dev_get_drvdata(dev); | ||
36 | int (*func)(struct mc13783 *mc13783, int irq); | ||
37 | |||
38 | if (!priv->valid) | ||
39 | return -ENODATA; | ||
40 | |||
41 | func = enabled ? mc13783_irq_unmask : mc13783_irq_mask; | ||
42 | return func(priv->mc13783, irq); | ||
43 | } | ||
44 | |||
45 | static int mc13783_rtc_irq_enable(struct device *dev, | ||
46 | unsigned int enabled, int irq) | ||
47 | { | ||
48 | struct mc13783_rtc *priv = dev_get_drvdata(dev); | ||
49 | int ret; | ||
50 | |||
51 | mc13783_lock(priv->mc13783); | ||
52 | |||
53 | ret = mc13783_rtc_irq_enable_unlocked(dev, enabled, irq); | ||
54 | |||
55 | mc13783_unlock(priv->mc13783); | ||
56 | |||
57 | return ret; | ||
58 | } | ||
59 | |||
60 | static int mc13783_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
61 | { | ||
62 | struct mc13783_rtc *priv = dev_get_drvdata(dev); | ||
63 | unsigned int seconds, days1, days2; | ||
64 | unsigned long s1970; | ||
65 | int ret; | ||
66 | |||
67 | mc13783_lock(priv->mc13783); | ||
68 | |||
69 | if (!priv->valid) { | ||
70 | ret = -ENODATA; | ||
71 | goto out; | ||
72 | } | ||
73 | |||
74 | ret = mc13783_reg_read(priv->mc13783, MC13783_RTCDAY, &days1); | ||
75 | if (unlikely(ret)) | ||
76 | goto out; | ||
77 | |||
78 | ret = mc13783_reg_read(priv->mc13783, MC13783_RTCTOD, &seconds); | ||
79 | if (unlikely(ret)) | ||
80 | goto out; | ||
81 | |||
82 | ret = mc13783_reg_read(priv->mc13783, MC13783_RTCDAY, &days2); | ||
83 | out: | ||
84 | mc13783_unlock(priv->mc13783); | ||
85 | |||
86 | if (ret) | ||
87 | return ret; | ||
88 | |||
89 | if (days2 == days1 + 1) { | ||
90 | if (seconds >= 86400 / 2) | ||
91 | days2 = days1; | ||
92 | else | ||
93 | days1 = days2; | ||
94 | } | ||
95 | |||
96 | if (days1 != days2) | ||
97 | return -EIO; | ||
98 | |||
99 | s1970 = days1 * 86400 + seconds; | ||
100 | |||
101 | rtc_time_to_tm(s1970, tm); | ||
102 | |||
103 | return rtc_valid_tm(tm); | ||
104 | } | ||
105 | |||
106 | static int mc13783_rtc_set_mmss(struct device *dev, unsigned long secs) | ||
107 | { | ||
108 | struct mc13783_rtc *priv = dev_get_drvdata(dev); | ||
109 | unsigned int seconds, days; | ||
110 | unsigned int alarmseconds; | ||
111 | int ret; | ||
112 | |||
113 | seconds = secs % 86400; | ||
114 | days = secs / 86400; | ||
115 | |||
116 | mc13783_lock(priv->mc13783); | ||
117 | |||
118 | /* | ||
119 | * temporarily invalidate alarm to prevent triggering it when the day is | ||
120 | * already updated while the time isn't yet. | ||
121 | */ | ||
122 | ret = mc13783_reg_read(priv->mc13783, MC13783_RTCTODA, &alarmseconds); | ||
123 | if (unlikely(ret)) | ||
124 | goto out; | ||
125 | |||
126 | if (alarmseconds < 86400) { | ||
127 | ret = mc13783_reg_write(priv->mc13783, | ||
128 | MC13783_RTCTODA, 0x1ffff); | ||
129 | if (unlikely(ret)) | ||
130 | goto out; | ||
131 | } | ||
132 | |||
133 | /* | ||
134 | * write seconds=0 to prevent a day switch between writing days | ||
135 | * and seconds below | ||
136 | */ | ||
137 | ret = mc13783_reg_write(priv->mc13783, MC13783_RTCTOD, 0); | ||
138 | if (unlikely(ret)) | ||
139 | goto out; | ||
140 | |||
141 | ret = mc13783_reg_write(priv->mc13783, MC13783_RTCDAY, days); | ||
142 | if (unlikely(ret)) | ||
143 | goto out; | ||
144 | |||
145 | ret = mc13783_reg_write(priv->mc13783, MC13783_RTCTOD, seconds); | ||
146 | if (unlikely(ret)) | ||
147 | goto out; | ||
148 | |||
149 | /* restore alarm */ | ||
150 | if (alarmseconds < 86400) { | ||
151 | ret = mc13783_reg_write(priv->mc13783, | ||
152 | MC13783_RTCTODA, alarmseconds); | ||
153 | if (unlikely(ret)) | ||
154 | goto out; | ||
155 | } | ||
156 | |||
157 | ret = mc13783_irq_ack(priv->mc13783, MC13783_IRQ_RTCRST); | ||
158 | if (unlikely(ret)) | ||
159 | goto out; | ||
160 | |||
161 | ret = mc13783_irq_unmask(priv->mc13783, MC13783_IRQ_RTCRST); | ||
162 | out: | ||
163 | priv->valid = !ret; | ||
164 | |||
165 | mc13783_unlock(priv->mc13783); | ||
166 | |||
167 | return ret; | ||
168 | } | ||
169 | |||
170 | static int mc13783_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | ||
171 | { | ||
172 | struct mc13783_rtc *priv = dev_get_drvdata(dev); | ||
173 | unsigned seconds, days; | ||
174 | unsigned long s1970; | ||
175 | int enabled, pending; | ||
176 | int ret; | ||
177 | |||
178 | mc13783_lock(priv->mc13783); | ||
179 | |||
180 | ret = mc13783_reg_read(priv->mc13783, MC13783_RTCTODA, &seconds); | ||
181 | if (unlikely(ret)) | ||
182 | goto out; | ||
183 | if (seconds >= 86400) { | ||
184 | ret = -ENODATA; | ||
185 | goto out; | ||
186 | } | ||
187 | |||
188 | ret = mc13783_reg_read(priv->mc13783, MC13783_RTCDAY, &days); | ||
189 | if (unlikely(ret)) | ||
190 | goto out; | ||
191 | |||
192 | ret = mc13783_irq_status(priv->mc13783, MC13783_IRQ_TODA, | ||
193 | &enabled, &pending); | ||
194 | |||
195 | out: | ||
196 | mc13783_unlock(priv->mc13783); | ||
197 | |||
198 | if (ret) | ||
199 | return ret; | ||
200 | |||
201 | alarm->enabled = enabled; | ||
202 | alarm->pending = pending; | ||
203 | |||
204 | s1970 = days * 86400 + seconds; | ||
205 | |||
206 | rtc_time_to_tm(s1970, &alarm->time); | ||
207 | dev_dbg(dev, "%s: %lu\n", __func__, s1970); | ||
208 | |||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | static int mc13783_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) | ||
213 | { | ||
214 | struct mc13783_rtc *priv = dev_get_drvdata(dev); | ||
215 | unsigned long s1970; | ||
216 | unsigned seconds, days; | ||
217 | int ret; | ||
218 | |||
219 | mc13783_lock(priv->mc13783); | ||
220 | |||
221 | /* disable alarm to prevent false triggering */ | ||
222 | ret = mc13783_reg_write(priv->mc13783, MC13783_RTCTODA, 0x1ffff); | ||
223 | if (unlikely(ret)) | ||
224 | goto out; | ||
225 | |||
226 | ret = mc13783_irq_ack(priv->mc13783, MC13783_IRQ_TODA); | ||
227 | if (unlikely(ret)) | ||
228 | goto out; | ||
229 | |||
230 | ret = rtc_tm_to_time(&alarm->time, &s1970); | ||
231 | if (unlikely(ret)) | ||
232 | goto out; | ||
233 | |||
234 | dev_dbg(dev, "%s: o%2.s %lu\n", __func__, alarm->enabled ? "n" : "ff", | ||
235 | s1970); | ||
236 | |||
237 | ret = mc13783_rtc_irq_enable_unlocked(dev, alarm->enabled, | ||
238 | MC13783_IRQ_TODA); | ||
239 | if (unlikely(ret)) | ||
240 | goto out; | ||
241 | |||
242 | seconds = s1970 % 86400; | ||
243 | days = s1970 / 86400; | ||
244 | |||
245 | ret = mc13783_reg_write(priv->mc13783, MC13783_RTCDAYA, days); | ||
246 | if (unlikely(ret)) | ||
247 | goto out; | ||
248 | |||
249 | ret = mc13783_reg_write(priv->mc13783, MC13783_RTCTODA, seconds); | ||
250 | |||
251 | out: | ||
252 | mc13783_unlock(priv->mc13783); | ||
253 | |||
254 | return ret; | ||
255 | } | ||
256 | |||
257 | static irqreturn_t mc13783_rtc_alarm_handler(int irq, void *dev) | ||
258 | { | ||
259 | struct mc13783_rtc *priv = dev; | ||
260 | struct mc13783 *mc13783 = priv->mc13783; | ||
261 | |||
262 | dev_dbg(&priv->rtc->dev, "Alarm\n"); | ||
263 | |||
264 | rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_AF); | ||
265 | |||
266 | mc13783_irq_ack(mc13783, irq); | ||
267 | |||
268 | return IRQ_HANDLED; | ||
269 | } | ||
270 | |||
271 | static irqreturn_t mc13783_rtc_update_handler(int irq, void *dev) | ||
272 | { | ||
273 | struct mc13783_rtc *priv = dev; | ||
274 | struct mc13783 *mc13783 = priv->mc13783; | ||
275 | |||
276 | dev_dbg(&priv->rtc->dev, "1HZ\n"); | ||
277 | |||
278 | rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_UF); | ||
279 | |||
280 | mc13783_irq_ack(mc13783, irq); | ||
281 | |||
282 | return IRQ_HANDLED; | ||
283 | } | ||
284 | |||
285 | static int mc13783_rtc_update_irq_enable(struct device *dev, | ||
286 | unsigned int enabled) | ||
287 | { | ||
288 | return mc13783_rtc_irq_enable(dev, enabled, MC13783_IRQ_1HZ); | ||
289 | } | ||
290 | |||
291 | static int mc13783_rtc_alarm_irq_enable(struct device *dev, | ||
292 | unsigned int enabled) | ||
293 | { | ||
294 | return mc13783_rtc_irq_enable(dev, enabled, MC13783_IRQ_TODA); | ||
295 | } | ||
296 | |||
297 | static const struct rtc_class_ops mc13783_rtc_ops = { | ||
298 | .read_time = mc13783_rtc_read_time, | ||
299 | .set_mmss = mc13783_rtc_set_mmss, | ||
300 | .read_alarm = mc13783_rtc_read_alarm, | ||
301 | .set_alarm = mc13783_rtc_set_alarm, | ||
302 | .alarm_irq_enable = mc13783_rtc_alarm_irq_enable, | ||
303 | .update_irq_enable = mc13783_rtc_update_irq_enable, | ||
304 | }; | ||
305 | |||
306 | static irqreturn_t mc13783_rtc_reset_handler(int irq, void *dev) | ||
307 | { | ||
308 | struct mc13783_rtc *priv = dev; | ||
309 | struct mc13783 *mc13783 = priv->mc13783; | ||
310 | |||
311 | dev_dbg(&priv->rtc->dev, "RTCRST\n"); | ||
312 | priv->valid = 0; | ||
313 | |||
314 | mc13783_irq_mask(mc13783, irq); | ||
315 | |||
316 | return IRQ_HANDLED; | ||
317 | } | ||
318 | |||
319 | static int __devinit mc13783_rtc_probe(struct platform_device *pdev) | ||
320 | { | ||
321 | int ret; | ||
322 | struct mc13783_rtc *priv; | ||
323 | struct mc13783 *mc13783; | ||
324 | int rtcrst_pending; | ||
325 | |||
326 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
327 | if (!priv) | ||
328 | return -ENOMEM; | ||
329 | |||
330 | mc13783 = dev_get_drvdata(pdev->dev.parent); | ||
331 | priv->mc13783 = mc13783; | ||
332 | |||
333 | platform_set_drvdata(pdev, priv); | ||
334 | |||
335 | mc13783_lock(mc13783); | ||
336 | |||
337 | ret = mc13783_irq_request(mc13783, MC13783_IRQ_RTCRST, | ||
338 | mc13783_rtc_reset_handler, DRIVER_NAME, priv); | ||
339 | if (ret) | ||
340 | goto err_reset_irq_request; | ||
341 | |||
342 | ret = mc13783_irq_status(mc13783, MC13783_IRQ_RTCRST, | ||
343 | NULL, &rtcrst_pending); | ||
344 | if (ret) | ||
345 | goto err_reset_irq_status; | ||
346 | |||
347 | priv->valid = !rtcrst_pending; | ||
348 | |||
349 | ret = mc13783_irq_request_nounmask(mc13783, MC13783_IRQ_1HZ, | ||
350 | mc13783_rtc_update_handler, DRIVER_NAME, priv); | ||
351 | if (ret) | ||
352 | goto err_update_irq_request; | ||
353 | |||
354 | ret = mc13783_irq_request_nounmask(mc13783, MC13783_IRQ_TODA, | ||
355 | mc13783_rtc_alarm_handler, DRIVER_NAME, priv); | ||
356 | if (ret) | ||
357 | goto err_alarm_irq_request; | ||
358 | |||
359 | priv->rtc = rtc_device_register(pdev->name, | ||
360 | &pdev->dev, &mc13783_rtc_ops, THIS_MODULE); | ||
361 | if (IS_ERR(priv->rtc)) { | ||
362 | ret = PTR_ERR(priv->rtc); | ||
363 | |||
364 | mc13783_irq_free(mc13783, MC13783_IRQ_TODA, priv); | ||
365 | err_alarm_irq_request: | ||
366 | |||
367 | mc13783_irq_free(mc13783, MC13783_IRQ_1HZ, priv); | ||
368 | err_update_irq_request: | ||
369 | |||
370 | err_reset_irq_status: | ||
371 | |||
372 | mc13783_irq_free(mc13783, MC13783_IRQ_RTCRST, priv); | ||
373 | err_reset_irq_request: | ||
374 | |||
375 | platform_set_drvdata(pdev, NULL); | ||
376 | kfree(priv); | ||
377 | } | ||
378 | |||
379 | mc13783_unlock(mc13783); | ||
380 | |||
381 | return ret; | ||
382 | } | ||
383 | |||
384 | static int __devexit mc13783_rtc_remove(struct platform_device *pdev) | ||
385 | { | ||
386 | struct mc13783_rtc *priv = platform_get_drvdata(pdev); | ||
387 | |||
388 | mc13783_lock(priv->mc13783); | ||
389 | |||
390 | rtc_device_unregister(priv->rtc); | ||
391 | |||
392 | mc13783_irq_free(priv->mc13783, MC13783_IRQ_TODA, priv); | ||
393 | mc13783_irq_free(priv->mc13783, MC13783_IRQ_1HZ, priv); | ||
394 | mc13783_irq_free(priv->mc13783, MC13783_IRQ_RTCRST, priv); | ||
395 | |||
396 | mc13783_unlock(priv->mc13783); | ||
397 | |||
398 | platform_set_drvdata(pdev, NULL); | ||
399 | |||
400 | kfree(priv); | ||
401 | |||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | static struct platform_driver mc13783_rtc_driver = { | ||
406 | .remove = __devexit_p(mc13783_rtc_remove), | ||
407 | .driver = { | ||
408 | .name = DRIVER_NAME, | ||
409 | .owner = THIS_MODULE, | ||
410 | }, | ||
411 | }; | ||
412 | |||
413 | static int __init mc13783_rtc_init(void) | ||
414 | { | ||
415 | return platform_driver_probe(&mc13783_rtc_driver, &mc13783_rtc_probe); | ||
416 | } | ||
417 | module_init(mc13783_rtc_init); | ||
418 | |||
419 | static void __exit mc13783_rtc_exit(void) | ||
420 | { | ||
421 | platform_driver_unregister(&mc13783_rtc_driver); | ||
422 | } | ||
423 | module_exit(mc13783_rtc_exit); | ||
424 | |||
425 | MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); | ||
426 | MODULE_DESCRIPTION("RTC driver for Freescale MC13783 PMIC"); | ||
427 | MODULE_LICENSE("GPL v2"); | ||
428 | MODULE_ALIAS("platform:" DRIVER_NAME); | ||
diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c new file mode 100644 index 000000000000..a1a278bc340d --- /dev/null +++ b/drivers/rtc/rtc-mc13xxx.c | |||
@@ -0,0 +1,435 @@ | |||
1 | /* | ||
2 | * Real Time Clock driver for Freescale MC13XXX PMIC | ||
3 | * | ||
4 | * (C) 2009 Sascha Hauer, Pengutronix | ||
5 | * (C) 2009 Uwe Kleine-Koenig, Pengutronix | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/mfd/mc13xxx.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/rtc.h> | ||
18 | |||
19 | #define DRIVER_NAME "mc13xxx-rtc" | ||
20 | |||
21 | #define MC13XXX_RTCTOD 20 | ||
22 | #define MC13XXX_RTCTODA 21 | ||
23 | #define MC13XXX_RTCDAY 22 | ||
24 | #define MC13XXX_RTCDAYA 23 | ||
25 | |||
26 | struct mc13xxx_rtc { | ||
27 | struct rtc_device *rtc; | ||
28 | struct mc13xxx *mc13xxx; | ||
29 | int valid; | ||
30 | }; | ||
31 | |||
32 | static int mc13xxx_rtc_irq_enable_unlocked(struct device *dev, | ||
33 | unsigned int enabled, int irq) | ||
34 | { | ||
35 | struct mc13xxx_rtc *priv = dev_get_drvdata(dev); | ||
36 | int (*func)(struct mc13xxx *mc13xxx, int irq); | ||
37 | |||
38 | if (!priv->valid) | ||
39 | return -ENODATA; | ||
40 | |||
41 | func = enabled ? mc13xxx_irq_unmask : mc13xxx_irq_mask; | ||
42 | return func(priv->mc13xxx, irq); | ||
43 | } | ||
44 | |||
45 | static int mc13xxx_rtc_irq_enable(struct device *dev, | ||
46 | unsigned int enabled, int irq) | ||
47 | { | ||
48 | struct mc13xxx_rtc *priv = dev_get_drvdata(dev); | ||
49 | int ret; | ||
50 | |||
51 | mc13xxx_lock(priv->mc13xxx); | ||
52 | |||
53 | ret = mc13xxx_rtc_irq_enable_unlocked(dev, enabled, irq); | ||
54 | |||
55 | mc13xxx_unlock(priv->mc13xxx); | ||
56 | |||
57 | return ret; | ||
58 | } | ||
59 | |||
60 | static int mc13xxx_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
61 | { | ||
62 | struct mc13xxx_rtc *priv = dev_get_drvdata(dev); | ||
63 | unsigned int seconds, days1, days2; | ||
64 | unsigned long s1970; | ||
65 | int ret; | ||
66 | |||
67 | mc13xxx_lock(priv->mc13xxx); | ||
68 | |||
69 | if (!priv->valid) { | ||
70 | ret = -ENODATA; | ||
71 | goto out; | ||
72 | } | ||
73 | |||
74 | ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days1); | ||
75 | if (unlikely(ret)) | ||
76 | goto out; | ||
77 | |||
78 | ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTOD, &seconds); | ||
79 | if (unlikely(ret)) | ||
80 | goto out; | ||
81 | |||
82 | ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days2); | ||
83 | out: | ||
84 | mc13xxx_unlock(priv->mc13xxx); | ||
85 | |||
86 | if (ret) | ||
87 | return ret; | ||
88 | |||
89 | if (days2 == days1 + 1) { | ||
90 | if (seconds >= 86400 / 2) | ||
91 | days2 = days1; | ||
92 | else | ||
93 | days1 = days2; | ||
94 | } | ||
95 | |||
96 | if (days1 != days2) | ||
97 | return -EIO; | ||
98 | |||
99 | s1970 = days1 * 86400 + seconds; | ||
100 | |||
101 | rtc_time_to_tm(s1970, tm); | ||
102 | |||
103 | return rtc_valid_tm(tm); | ||
104 | } | ||
105 | |||
106 | static int mc13xxx_rtc_set_mmss(struct device *dev, unsigned long secs) | ||
107 | { | ||
108 | struct mc13xxx_rtc *priv = dev_get_drvdata(dev); | ||
109 | unsigned int seconds, days; | ||
110 | unsigned int alarmseconds; | ||
111 | int ret; | ||
112 | |||
113 | seconds = secs % 86400; | ||
114 | days = secs / 86400; | ||
115 | |||
116 | mc13xxx_lock(priv->mc13xxx); | ||
117 | |||
118 | /* | ||
119 | * temporarily invalidate alarm to prevent triggering it when the day is | ||
120 | * already updated while the time isn't yet. | ||
121 | */ | ||
122 | ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTODA, &alarmseconds); | ||
123 | if (unlikely(ret)) | ||
124 | goto out; | ||
125 | |||
126 | if (alarmseconds < 86400) { | ||
127 | ret = mc13xxx_reg_write(priv->mc13xxx, | ||
128 | MC13XXX_RTCTODA, 0x1ffff); | ||
129 | if (unlikely(ret)) | ||
130 | goto out; | ||
131 | } | ||
132 | |||
133 | /* | ||
134 | * write seconds=0 to prevent a day switch between writing days | ||
135 | * and seconds below | ||
136 | */ | ||
137 | ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTOD, 0); | ||
138 | if (unlikely(ret)) | ||
139 | goto out; | ||
140 | |||
141 | ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCDAY, days); | ||
142 | if (unlikely(ret)) | ||
143 | goto out; | ||
144 | |||
145 | ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTOD, seconds); | ||
146 | if (unlikely(ret)) | ||
147 | goto out; | ||
148 | |||
149 | /* restore alarm */ | ||
150 | if (alarmseconds < 86400) { | ||
151 | ret = mc13xxx_reg_write(priv->mc13xxx, | ||
152 | MC13XXX_RTCTODA, alarmseconds); | ||
153 | if (unlikely(ret)) | ||
154 | goto out; | ||
155 | } | ||
156 | |||
157 | ret = mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_RTCRST); | ||
158 | if (unlikely(ret)) | ||
159 | goto out; | ||
160 | |||
161 | ret = mc13xxx_irq_unmask(priv->mc13xxx, MC13XXX_IRQ_RTCRST); | ||
162 | out: | ||
163 | priv->valid = !ret; | ||
164 | |||
165 | mc13xxx_unlock(priv->mc13xxx); | ||
166 | |||
167 | return ret; | ||
168 | } | ||
169 | |||
170 | static int mc13xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | ||
171 | { | ||
172 | struct mc13xxx_rtc *priv = dev_get_drvdata(dev); | ||
173 | unsigned seconds, days; | ||
174 | unsigned long s1970; | ||
175 | int enabled, pending; | ||
176 | int ret; | ||
177 | |||
178 | mc13xxx_lock(priv->mc13xxx); | ||
179 | |||
180 | ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTODA, &seconds); | ||
181 | if (unlikely(ret)) | ||
182 | goto out; | ||
183 | if (seconds >= 86400) { | ||
184 | ret = -ENODATA; | ||
185 | goto out; | ||
186 | } | ||
187 | |||
188 | ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days); | ||
189 | if (unlikely(ret)) | ||
190 | goto out; | ||
191 | |||
192 | ret = mc13xxx_irq_status(priv->mc13xxx, MC13XXX_IRQ_TODA, | ||
193 | &enabled, &pending); | ||
194 | |||
195 | out: | ||
196 | mc13xxx_unlock(priv->mc13xxx); | ||
197 | |||
198 | if (ret) | ||
199 | return ret; | ||
200 | |||
201 | alarm->enabled = enabled; | ||
202 | alarm->pending = pending; | ||
203 | |||
204 | s1970 = days * 86400 + seconds; | ||
205 | |||
206 | rtc_time_to_tm(s1970, &alarm->time); | ||
207 | dev_dbg(dev, "%s: %lu\n", __func__, s1970); | ||
208 | |||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | static int mc13xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) | ||
213 | { | ||
214 | struct mc13xxx_rtc *priv = dev_get_drvdata(dev); | ||
215 | unsigned long s1970; | ||
216 | unsigned seconds, days; | ||
217 | int ret; | ||
218 | |||
219 | mc13xxx_lock(priv->mc13xxx); | ||
220 | |||
221 | /* disable alarm to prevent false triggering */ | ||
222 | ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTODA, 0x1ffff); | ||
223 | if (unlikely(ret)) | ||
224 | goto out; | ||
225 | |||
226 | ret = mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_TODA); | ||
227 | if (unlikely(ret)) | ||
228 | goto out; | ||
229 | |||
230 | ret = rtc_tm_to_time(&alarm->time, &s1970); | ||
231 | if (unlikely(ret)) | ||
232 | goto out; | ||
233 | |||
234 | dev_dbg(dev, "%s: o%2.s %lu\n", __func__, alarm->enabled ? "n" : "ff", | ||
235 | s1970); | ||
236 | |||
237 | ret = mc13xxx_rtc_irq_enable_unlocked(dev, alarm->enabled, | ||
238 | MC13XXX_IRQ_TODA); | ||
239 | if (unlikely(ret)) | ||
240 | goto out; | ||
241 | |||
242 | seconds = s1970 % 86400; | ||
243 | days = s1970 / 86400; | ||
244 | |||
245 | ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCDAYA, days); | ||
246 | if (unlikely(ret)) | ||
247 | goto out; | ||
248 | |||
249 | ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTODA, seconds); | ||
250 | |||
251 | out: | ||
252 | mc13xxx_unlock(priv->mc13xxx); | ||
253 | |||
254 | return ret; | ||
255 | } | ||
256 | |||
257 | static irqreturn_t mc13xxx_rtc_alarm_handler(int irq, void *dev) | ||
258 | { | ||
259 | struct mc13xxx_rtc *priv = dev; | ||
260 | struct mc13xxx *mc13xxx = priv->mc13xxx; | ||
261 | |||
262 | dev_dbg(&priv->rtc->dev, "Alarm\n"); | ||
263 | |||
264 | rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_AF); | ||
265 | |||
266 | mc13xxx_irq_ack(mc13xxx, irq); | ||
267 | |||
268 | return IRQ_HANDLED; | ||
269 | } | ||
270 | |||
271 | static irqreturn_t mc13xxx_rtc_update_handler(int irq, void *dev) | ||
272 | { | ||
273 | struct mc13xxx_rtc *priv = dev; | ||
274 | struct mc13xxx *mc13xxx = priv->mc13xxx; | ||
275 | |||
276 | dev_dbg(&priv->rtc->dev, "1HZ\n"); | ||
277 | |||
278 | rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_UF); | ||
279 | |||
280 | mc13xxx_irq_ack(mc13xxx, irq); | ||
281 | |||
282 | return IRQ_HANDLED; | ||
283 | } | ||
284 | |||
285 | static int mc13xxx_rtc_alarm_irq_enable(struct device *dev, | ||
286 | unsigned int enabled) | ||
287 | { | ||
288 | return mc13xxx_rtc_irq_enable(dev, enabled, MC13XXX_IRQ_TODA); | ||
289 | } | ||
290 | |||
291 | static const struct rtc_class_ops mc13xxx_rtc_ops = { | ||
292 | .read_time = mc13xxx_rtc_read_time, | ||
293 | .set_mmss = mc13xxx_rtc_set_mmss, | ||
294 | .read_alarm = mc13xxx_rtc_read_alarm, | ||
295 | .set_alarm = mc13xxx_rtc_set_alarm, | ||
296 | .alarm_irq_enable = mc13xxx_rtc_alarm_irq_enable, | ||
297 | }; | ||
298 | |||
299 | static irqreturn_t mc13xxx_rtc_reset_handler(int irq, void *dev) | ||
300 | { | ||
301 | struct mc13xxx_rtc *priv = dev; | ||
302 | struct mc13xxx *mc13xxx = priv->mc13xxx; | ||
303 | |||
304 | dev_dbg(&priv->rtc->dev, "RTCRST\n"); | ||
305 | priv->valid = 0; | ||
306 | |||
307 | mc13xxx_irq_mask(mc13xxx, irq); | ||
308 | |||
309 | return IRQ_HANDLED; | ||
310 | } | ||
311 | |||
312 | static int __devinit mc13xxx_rtc_probe(struct platform_device *pdev) | ||
313 | { | ||
314 | int ret; | ||
315 | struct mc13xxx_rtc *priv; | ||
316 | struct mc13xxx *mc13xxx; | ||
317 | int rtcrst_pending; | ||
318 | |||
319 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
320 | if (!priv) | ||
321 | return -ENOMEM; | ||
322 | |||
323 | mc13xxx = dev_get_drvdata(pdev->dev.parent); | ||
324 | priv->mc13xxx = mc13xxx; | ||
325 | |||
326 | platform_set_drvdata(pdev, priv); | ||
327 | |||
328 | mc13xxx_lock(mc13xxx); | ||
329 | |||
330 | ret = mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_RTCRST, | ||
331 | mc13xxx_rtc_reset_handler, DRIVER_NAME, priv); | ||
332 | if (ret) | ||
333 | goto err_reset_irq_request; | ||
334 | |||
335 | ret = mc13xxx_irq_status(mc13xxx, MC13XXX_IRQ_RTCRST, | ||
336 | NULL, &rtcrst_pending); | ||
337 | if (ret) | ||
338 | goto err_reset_irq_status; | ||
339 | |||
340 | priv->valid = !rtcrst_pending; | ||
341 | |||
342 | ret = mc13xxx_irq_request_nounmask(mc13xxx, MC13XXX_IRQ_1HZ, | ||
343 | mc13xxx_rtc_update_handler, DRIVER_NAME, priv); | ||
344 | if (ret) | ||
345 | goto err_update_irq_request; | ||
346 | |||
347 | ret = mc13xxx_irq_request_nounmask(mc13xxx, MC13XXX_IRQ_TODA, | ||
348 | mc13xxx_rtc_alarm_handler, DRIVER_NAME, priv); | ||
349 | if (ret) | ||
350 | goto err_alarm_irq_request; | ||
351 | |||
352 | mc13xxx_unlock(mc13xxx); | ||
353 | |||
354 | priv->rtc = rtc_device_register(pdev->name, | ||
355 | &pdev->dev, &mc13xxx_rtc_ops, THIS_MODULE); | ||
356 | if (IS_ERR(priv->rtc)) { | ||
357 | ret = PTR_ERR(priv->rtc); | ||
358 | |||
359 | mc13xxx_lock(mc13xxx); | ||
360 | |||
361 | mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_TODA, priv); | ||
362 | err_alarm_irq_request: | ||
363 | |||
364 | mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_1HZ, priv); | ||
365 | err_update_irq_request: | ||
366 | |||
367 | err_reset_irq_status: | ||
368 | |||
369 | mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_RTCRST, priv); | ||
370 | err_reset_irq_request: | ||
371 | |||
372 | mc13xxx_unlock(mc13xxx); | ||
373 | |||
374 | platform_set_drvdata(pdev, NULL); | ||
375 | kfree(priv); | ||
376 | } | ||
377 | |||
378 | return ret; | ||
379 | } | ||
380 | |||
381 | static int __devexit mc13xxx_rtc_remove(struct platform_device *pdev) | ||
382 | { | ||
383 | struct mc13xxx_rtc *priv = platform_get_drvdata(pdev); | ||
384 | |||
385 | mc13xxx_lock(priv->mc13xxx); | ||
386 | |||
387 | rtc_device_unregister(priv->rtc); | ||
388 | |||
389 | mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_TODA, priv); | ||
390 | mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_1HZ, priv); | ||
391 | mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_RTCRST, priv); | ||
392 | |||
393 | mc13xxx_unlock(priv->mc13xxx); | ||
394 | |||
395 | platform_set_drvdata(pdev, NULL); | ||
396 | |||
397 | kfree(priv); | ||
398 | |||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | const struct platform_device_id mc13xxx_rtc_idtable[] = { | ||
403 | { | ||
404 | .name = "mc13783-rtc", | ||
405 | }, { | ||
406 | .name = "mc13892-rtc", | ||
407 | }, | ||
408 | { } | ||
409 | }; | ||
410 | |||
411 | static struct platform_driver mc13xxx_rtc_driver = { | ||
412 | .id_table = mc13xxx_rtc_idtable, | ||
413 | .remove = __devexit_p(mc13xxx_rtc_remove), | ||
414 | .driver = { | ||
415 | .name = DRIVER_NAME, | ||
416 | .owner = THIS_MODULE, | ||
417 | }, | ||
418 | }; | ||
419 | |||
420 | static int __init mc13xxx_rtc_init(void) | ||
421 | { | ||
422 | return platform_driver_probe(&mc13xxx_rtc_driver, &mc13xxx_rtc_probe); | ||
423 | } | ||
424 | module_init(mc13xxx_rtc_init); | ||
425 | |||
426 | static void __exit mc13xxx_rtc_exit(void) | ||
427 | { | ||
428 | platform_driver_unregister(&mc13xxx_rtc_driver); | ||
429 | } | ||
430 | module_exit(mc13xxx_rtc_exit); | ||
431 | |||
432 | MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); | ||
433 | MODULE_DESCRIPTION("RTC driver for Freescale MC13XXX PMIC"); | ||
434 | MODULE_LICENSE("GPL v2"); | ||
435 | MODULE_ALIAS("platform:" DRIVER_NAME); | ||
diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index dfcdf0901d21..09ccd8d3ba2a 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c | |||
@@ -240,36 +240,15 @@ static int mpc5121_rtc_alarm_irq_enable(struct device *dev, | |||
240 | return 0; | 240 | return 0; |
241 | } | 241 | } |
242 | 242 | ||
243 | static int mpc5121_rtc_update_irq_enable(struct device *dev, | ||
244 | unsigned int enabled) | ||
245 | { | ||
246 | struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev); | ||
247 | struct mpc5121_rtc_regs __iomem *regs = rtc->regs; | ||
248 | int val; | ||
249 | |||
250 | val = in_8(®s->int_enable); | ||
251 | |||
252 | if (enabled) | ||
253 | val = (val & ~0x8) | 0x1; | ||
254 | else | ||
255 | val &= ~0x1; | ||
256 | |||
257 | out_8(®s->int_enable, val); | ||
258 | |||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | static const struct rtc_class_ops mpc5121_rtc_ops = { | 243 | static const struct rtc_class_ops mpc5121_rtc_ops = { |
263 | .read_time = mpc5121_rtc_read_time, | 244 | .read_time = mpc5121_rtc_read_time, |
264 | .set_time = mpc5121_rtc_set_time, | 245 | .set_time = mpc5121_rtc_set_time, |
265 | .read_alarm = mpc5121_rtc_read_alarm, | 246 | .read_alarm = mpc5121_rtc_read_alarm, |
266 | .set_alarm = mpc5121_rtc_set_alarm, | 247 | .set_alarm = mpc5121_rtc_set_alarm, |
267 | .alarm_irq_enable = mpc5121_rtc_alarm_irq_enable, | 248 | .alarm_irq_enable = mpc5121_rtc_alarm_irq_enable, |
268 | .update_irq_enable = mpc5121_rtc_update_irq_enable, | ||
269 | }; | 249 | }; |
270 | 250 | ||
271 | static int __devinit mpc5121_rtc_probe(struct platform_device *op, | 251 | static int __devinit mpc5121_rtc_probe(struct platform_device *op) |
272 | const struct of_device_id *match) | ||
273 | { | 252 | { |
274 | struct mpc5121_rtc_data *rtc; | 253 | struct mpc5121_rtc_data *rtc; |
275 | int err = 0; | 254 | int err = 0; |
@@ -364,7 +343,7 @@ static struct of_device_id mpc5121_rtc_match[] __devinitdata = { | |||
364 | {}, | 343 | {}, |
365 | }; | 344 | }; |
366 | 345 | ||
367 | static struct of_platform_driver mpc5121_rtc_driver = { | 346 | static struct platform_driver mpc5121_rtc_driver = { |
368 | .driver = { | 347 | .driver = { |
369 | .name = "mpc5121-rtc", | 348 | .name = "mpc5121-rtc", |
370 | .owner = THIS_MODULE, | 349 | .owner = THIS_MODULE, |
@@ -376,13 +355,13 @@ static struct of_platform_driver mpc5121_rtc_driver = { | |||
376 | 355 | ||
377 | static int __init mpc5121_rtc_init(void) | 356 | static int __init mpc5121_rtc_init(void) |
378 | { | 357 | { |
379 | return of_register_platform_driver(&mpc5121_rtc_driver); | 358 | return platform_driver_register(&mpc5121_rtc_driver); |
380 | } | 359 | } |
381 | module_init(mpc5121_rtc_init); | 360 | module_init(mpc5121_rtc_init); |
382 | 361 | ||
383 | static void __exit mpc5121_rtc_exit(void) | 362 | static void __exit mpc5121_rtc_exit(void) |
384 | { | 363 | { |
385 | of_unregister_platform_driver(&mpc5121_rtc_driver); | 364 | platform_driver_unregister(&mpc5121_rtc_driver); |
386 | } | 365 | } |
387 | module_exit(mpc5121_rtc_exit); | 366 | module_exit(mpc5121_rtc_exit); |
388 | 367 | ||
diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c new file mode 100644 index 000000000000..0cec5650d56a --- /dev/null +++ b/drivers/rtc/rtc-mrst.c | |||
@@ -0,0 +1,553 @@ | |||
1 | /* | ||
2 | * rtc-mrst.c: Driver for Moorestown virtual RTC | ||
3 | * | ||
4 | * (C) Copyright 2009 Intel Corporation | ||
5 | * Author: Jacob Pan (jacob.jun.pan@intel.com) | ||
6 | * Feng Tang (feng.tang@intel.com) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; version 2 | ||
11 | * of the License. | ||
12 | * | ||
13 | * Note: | ||
14 | * VRTC is emulated by system controller firmware, the real HW | ||
15 | * RTC is located in the PMIC device. SCU FW shadows PMIC RTC | ||
16 | * in a memory mapped IO space that is visible to the host IA | ||
17 | * processor. | ||
18 | * | ||
19 | * This driver is based upon drivers/rtc/rtc-cmos.c | ||
20 | */ | ||
21 | |||
22 | /* | ||
23 | * Note: | ||
24 | * * vRTC only supports binary mode and 24H mode | ||
25 | * * vRTC only support PIE and AIE, no UIE, and its PIE only happens | ||
26 | * at 23:59:59pm everyday, no support for adjustable frequency | ||
27 | * * Alarm function is also limited to hr/min/sec. | ||
28 | */ | ||
29 | |||
30 | #include <linux/mod_devicetable.h> | ||
31 | #include <linux/platform_device.h> | ||
32 | #include <linux/interrupt.h> | ||
33 | #include <linux/spinlock.h> | ||
34 | #include <linux/kernel.h> | ||
35 | #include <linux/module.h> | ||
36 | #include <linux/init.h> | ||
37 | #include <linux/sfi.h> | ||
38 | |||
39 | #include <asm-generic/rtc.h> | ||
40 | #include <asm/intel_scu_ipc.h> | ||
41 | #include <asm/mrst.h> | ||
42 | #include <asm/mrst-vrtc.h> | ||
43 | |||
44 | struct mrst_rtc { | ||
45 | struct rtc_device *rtc; | ||
46 | struct device *dev; | ||
47 | int irq; | ||
48 | struct resource *iomem; | ||
49 | |||
50 | u8 enabled_wake; | ||
51 | u8 suspend_ctrl; | ||
52 | }; | ||
53 | |||
54 | static const char driver_name[] = "rtc_mrst"; | ||
55 | |||
56 | #define RTC_IRQMASK (RTC_PF | RTC_AF) | ||
57 | |||
58 | static inline int is_intr(u8 rtc_intr) | ||
59 | { | ||
60 | if (!(rtc_intr & RTC_IRQF)) | ||
61 | return 0; | ||
62 | return rtc_intr & RTC_IRQMASK; | ||
63 | } | ||
64 | |||
65 | static inline unsigned char vrtc_is_updating(void) | ||
66 | { | ||
67 | unsigned char uip; | ||
68 | unsigned long flags; | ||
69 | |||
70 | spin_lock_irqsave(&rtc_lock, flags); | ||
71 | uip = (vrtc_cmos_read(RTC_FREQ_SELECT) & RTC_UIP); | ||
72 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
73 | return uip; | ||
74 | } | ||
75 | |||
76 | /* | ||
77 | * rtc_time's year contains the increment over 1900, but vRTC's YEAR | ||
78 | * register can't be programmed to value larger than 0x64, so vRTC | ||
79 | * driver chose to use 1960 (1970 is UNIX time start point) as the base, | ||
80 | * and does the translation at read/write time. | ||
81 | * | ||
82 | * Why not just use 1970 as the offset? it's because using 1960 will | ||
83 | * make it consistent in leap year setting for both vrtc and low-level | ||
84 | * physical rtc devices. | ||
85 | */ | ||
86 | static int mrst_read_time(struct device *dev, struct rtc_time *time) | ||
87 | { | ||
88 | unsigned long flags; | ||
89 | |||
90 | if (vrtc_is_updating()) | ||
91 | mdelay(20); | ||
92 | |||
93 | spin_lock_irqsave(&rtc_lock, flags); | ||
94 | time->tm_sec = vrtc_cmos_read(RTC_SECONDS); | ||
95 | time->tm_min = vrtc_cmos_read(RTC_MINUTES); | ||
96 | time->tm_hour = vrtc_cmos_read(RTC_HOURS); | ||
97 | time->tm_mday = vrtc_cmos_read(RTC_DAY_OF_MONTH); | ||
98 | time->tm_mon = vrtc_cmos_read(RTC_MONTH); | ||
99 | time->tm_year = vrtc_cmos_read(RTC_YEAR); | ||
100 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
101 | |||
102 | /* Adjust for the 1960/1900 */ | ||
103 | time->tm_year += 60; | ||
104 | time->tm_mon--; | ||
105 | return RTC_24H; | ||
106 | } | ||
107 | |||
108 | static int mrst_set_time(struct device *dev, struct rtc_time *time) | ||
109 | { | ||
110 | int ret; | ||
111 | unsigned long flags; | ||
112 | unsigned char mon, day, hrs, min, sec; | ||
113 | unsigned int yrs; | ||
114 | |||
115 | yrs = time->tm_year; | ||
116 | mon = time->tm_mon + 1; /* tm_mon starts at zero */ | ||
117 | day = time->tm_mday; | ||
118 | hrs = time->tm_hour; | ||
119 | min = time->tm_min; | ||
120 | sec = time->tm_sec; | ||
121 | |||
122 | if (yrs < 70 || yrs > 138) | ||
123 | return -EINVAL; | ||
124 | yrs -= 60; | ||
125 | |||
126 | spin_lock_irqsave(&rtc_lock, flags); | ||
127 | |||
128 | vrtc_cmos_write(yrs, RTC_YEAR); | ||
129 | vrtc_cmos_write(mon, RTC_MONTH); | ||
130 | vrtc_cmos_write(day, RTC_DAY_OF_MONTH); | ||
131 | vrtc_cmos_write(hrs, RTC_HOURS); | ||
132 | vrtc_cmos_write(min, RTC_MINUTES); | ||
133 | vrtc_cmos_write(sec, RTC_SECONDS); | ||
134 | |||
135 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
136 | |||
137 | ret = intel_scu_ipc_simple_command(IPCMSG_VRTC, IPC_CMD_VRTC_SETTIME); | ||
138 | return ret; | ||
139 | } | ||
140 | |||
141 | static int mrst_read_alarm(struct device *dev, struct rtc_wkalrm *t) | ||
142 | { | ||
143 | struct mrst_rtc *mrst = dev_get_drvdata(dev); | ||
144 | unsigned char rtc_control; | ||
145 | |||
146 | if (mrst->irq <= 0) | ||
147 | return -EIO; | ||
148 | |||
149 | /* Basic alarms only support hour, minute, and seconds fields. | ||
150 | * Some also support day and month, for alarms up to a year in | ||
151 | * the future. | ||
152 | */ | ||
153 | t->time.tm_mday = -1; | ||
154 | t->time.tm_mon = -1; | ||
155 | t->time.tm_year = -1; | ||
156 | |||
157 | /* vRTC only supports binary mode */ | ||
158 | spin_lock_irq(&rtc_lock); | ||
159 | t->time.tm_sec = vrtc_cmos_read(RTC_SECONDS_ALARM); | ||
160 | t->time.tm_min = vrtc_cmos_read(RTC_MINUTES_ALARM); | ||
161 | t->time.tm_hour = vrtc_cmos_read(RTC_HOURS_ALARM); | ||
162 | |||
163 | rtc_control = vrtc_cmos_read(RTC_CONTROL); | ||
164 | spin_unlock_irq(&rtc_lock); | ||
165 | |||
166 | t->enabled = !!(rtc_control & RTC_AIE); | ||
167 | t->pending = 0; | ||
168 | |||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | static void mrst_checkintr(struct mrst_rtc *mrst, unsigned char rtc_control) | ||
173 | { | ||
174 | unsigned char rtc_intr; | ||
175 | |||
176 | /* | ||
177 | * NOTE after changing RTC_xIE bits we always read INTR_FLAGS; | ||
178 | * allegedly some older rtcs need that to handle irqs properly | ||
179 | */ | ||
180 | rtc_intr = vrtc_cmos_read(RTC_INTR_FLAGS); | ||
181 | rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; | ||
182 | if (is_intr(rtc_intr)) | ||
183 | rtc_update_irq(mrst->rtc, 1, rtc_intr); | ||
184 | } | ||
185 | |||
186 | static void mrst_irq_enable(struct mrst_rtc *mrst, unsigned char mask) | ||
187 | { | ||
188 | unsigned char rtc_control; | ||
189 | |||
190 | /* | ||
191 | * Flush any pending IRQ status, notably for update irqs, | ||
192 | * before we enable new IRQs | ||
193 | */ | ||
194 | rtc_control = vrtc_cmos_read(RTC_CONTROL); | ||
195 | mrst_checkintr(mrst, rtc_control); | ||
196 | |||
197 | rtc_control |= mask; | ||
198 | vrtc_cmos_write(rtc_control, RTC_CONTROL); | ||
199 | |||
200 | mrst_checkintr(mrst, rtc_control); | ||
201 | } | ||
202 | |||
203 | static void mrst_irq_disable(struct mrst_rtc *mrst, unsigned char mask) | ||
204 | { | ||
205 | unsigned char rtc_control; | ||
206 | |||
207 | rtc_control = vrtc_cmos_read(RTC_CONTROL); | ||
208 | rtc_control &= ~mask; | ||
209 | vrtc_cmos_write(rtc_control, RTC_CONTROL); | ||
210 | mrst_checkintr(mrst, rtc_control); | ||
211 | } | ||
212 | |||
213 | static int mrst_set_alarm(struct device *dev, struct rtc_wkalrm *t) | ||
214 | { | ||
215 | struct mrst_rtc *mrst = dev_get_drvdata(dev); | ||
216 | unsigned char hrs, min, sec; | ||
217 | int ret = 0; | ||
218 | |||
219 | if (!mrst->irq) | ||
220 | return -EIO; | ||
221 | |||
222 | hrs = t->time.tm_hour; | ||
223 | min = t->time.tm_min; | ||
224 | sec = t->time.tm_sec; | ||
225 | |||
226 | spin_lock_irq(&rtc_lock); | ||
227 | /* Next rtc irq must not be from previous alarm setting */ | ||
228 | mrst_irq_disable(mrst, RTC_AIE); | ||
229 | |||
230 | /* Update alarm */ | ||
231 | vrtc_cmos_write(hrs, RTC_HOURS_ALARM); | ||
232 | vrtc_cmos_write(min, RTC_MINUTES_ALARM); | ||
233 | vrtc_cmos_write(sec, RTC_SECONDS_ALARM); | ||
234 | |||
235 | spin_unlock_irq(&rtc_lock); | ||
236 | |||
237 | ret = intel_scu_ipc_simple_command(IPCMSG_VRTC, IPC_CMD_VRTC_SETALARM); | ||
238 | if (ret) | ||
239 | return ret; | ||
240 | |||
241 | spin_lock_irq(&rtc_lock); | ||
242 | if (t->enabled) | ||
243 | mrst_irq_enable(mrst, RTC_AIE); | ||
244 | |||
245 | spin_unlock_irq(&rtc_lock); | ||
246 | |||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | /* Currently, the vRTC doesn't support UIE ON/OFF */ | ||
251 | static int mrst_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | ||
252 | { | ||
253 | struct mrst_rtc *mrst = dev_get_drvdata(dev); | ||
254 | unsigned long flags; | ||
255 | |||
256 | spin_lock_irqsave(&rtc_lock, flags); | ||
257 | if (enabled) | ||
258 | mrst_irq_enable(mrst, RTC_AIE); | ||
259 | else | ||
260 | mrst_irq_disable(mrst, RTC_AIE); | ||
261 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | |||
266 | #if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE) | ||
267 | |||
268 | static int mrst_procfs(struct device *dev, struct seq_file *seq) | ||
269 | { | ||
270 | unsigned char rtc_control, valid; | ||
271 | |||
272 | spin_lock_irq(&rtc_lock); | ||
273 | rtc_control = vrtc_cmos_read(RTC_CONTROL); | ||
274 | valid = vrtc_cmos_read(RTC_VALID); | ||
275 | spin_unlock_irq(&rtc_lock); | ||
276 | |||
277 | return seq_printf(seq, | ||
278 | "periodic_IRQ\t: %s\n" | ||
279 | "alarm\t\t: %s\n" | ||
280 | "BCD\t\t: no\n" | ||
281 | "periodic_freq\t: daily (not adjustable)\n", | ||
282 | (rtc_control & RTC_PIE) ? "on" : "off", | ||
283 | (rtc_control & RTC_AIE) ? "on" : "off"); | ||
284 | } | ||
285 | |||
286 | #else | ||
287 | #define mrst_procfs NULL | ||
288 | #endif | ||
289 | |||
290 | static const struct rtc_class_ops mrst_rtc_ops = { | ||
291 | .read_time = mrst_read_time, | ||
292 | .set_time = mrst_set_time, | ||
293 | .read_alarm = mrst_read_alarm, | ||
294 | .set_alarm = mrst_set_alarm, | ||
295 | .proc = mrst_procfs, | ||
296 | .alarm_irq_enable = mrst_rtc_alarm_irq_enable, | ||
297 | }; | ||
298 | |||
299 | static struct mrst_rtc mrst_rtc; | ||
300 | |||
301 | /* | ||
302 | * When vRTC IRQ is captured by SCU FW, FW will clear the AIE bit in | ||
303 | * Reg B, so no need for this driver to clear it | ||
304 | */ | ||
305 | static irqreturn_t mrst_rtc_irq(int irq, void *p) | ||
306 | { | ||
307 | u8 irqstat; | ||
308 | |||
309 | spin_lock(&rtc_lock); | ||
310 | /* This read will clear all IRQ flags inside Reg C */ | ||
311 | irqstat = vrtc_cmos_read(RTC_INTR_FLAGS); | ||
312 | spin_unlock(&rtc_lock); | ||
313 | |||
314 | irqstat &= RTC_IRQMASK | RTC_IRQF; | ||
315 | if (is_intr(irqstat)) { | ||
316 | rtc_update_irq(p, 1, irqstat); | ||
317 | return IRQ_HANDLED; | ||
318 | } | ||
319 | return IRQ_NONE; | ||
320 | } | ||
321 | |||
322 | static int __devinit | ||
323 | vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq) | ||
324 | { | ||
325 | int retval = 0; | ||
326 | unsigned char rtc_control; | ||
327 | |||
328 | /* There can be only one ... */ | ||
329 | if (mrst_rtc.dev) | ||
330 | return -EBUSY; | ||
331 | |||
332 | if (!iomem) | ||
333 | return -ENODEV; | ||
334 | |||
335 | iomem = request_mem_region(iomem->start, | ||
336 | iomem->end + 1 - iomem->start, | ||
337 | driver_name); | ||
338 | if (!iomem) { | ||
339 | dev_dbg(dev, "i/o mem already in use.\n"); | ||
340 | return -EBUSY; | ||
341 | } | ||
342 | |||
343 | mrst_rtc.irq = rtc_irq; | ||
344 | mrst_rtc.iomem = iomem; | ||
345 | mrst_rtc.dev = dev; | ||
346 | dev_set_drvdata(dev, &mrst_rtc); | ||
347 | |||
348 | mrst_rtc.rtc = rtc_device_register(driver_name, dev, | ||
349 | &mrst_rtc_ops, THIS_MODULE); | ||
350 | if (IS_ERR(mrst_rtc.rtc)) { | ||
351 | retval = PTR_ERR(mrst_rtc.rtc); | ||
352 | goto cleanup0; | ||
353 | } | ||
354 | |||
355 | rename_region(iomem, dev_name(&mrst_rtc.rtc->dev)); | ||
356 | |||
357 | spin_lock_irq(&rtc_lock); | ||
358 | mrst_irq_disable(&mrst_rtc, RTC_PIE | RTC_AIE); | ||
359 | rtc_control = vrtc_cmos_read(RTC_CONTROL); | ||
360 | spin_unlock_irq(&rtc_lock); | ||
361 | |||
362 | if (!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY))) | ||
363 | dev_dbg(dev, "TODO: support more than 24-hr BCD mode\n"); | ||
364 | |||
365 | if (rtc_irq) { | ||
366 | retval = request_irq(rtc_irq, mrst_rtc_irq, | ||
367 | IRQF_DISABLED, dev_name(&mrst_rtc.rtc->dev), | ||
368 | mrst_rtc.rtc); | ||
369 | if (retval < 0) { | ||
370 | dev_dbg(dev, "IRQ %d is already in use, err %d\n", | ||
371 | rtc_irq, retval); | ||
372 | goto cleanup1; | ||
373 | } | ||
374 | } | ||
375 | dev_dbg(dev, "initialised\n"); | ||
376 | return 0; | ||
377 | |||
378 | cleanup1: | ||
379 | rtc_device_unregister(mrst_rtc.rtc); | ||
380 | cleanup0: | ||
381 | dev_set_drvdata(dev, NULL); | ||
382 | mrst_rtc.dev = NULL; | ||
383 | release_mem_region(iomem->start, resource_size(iomem)); | ||
384 | dev_err(dev, "rtc-mrst: unable to initialise\n"); | ||
385 | return retval; | ||
386 | } | ||
387 | |||
388 | static void rtc_mrst_do_shutdown(void) | ||
389 | { | ||
390 | spin_lock_irq(&rtc_lock); | ||
391 | mrst_irq_disable(&mrst_rtc, RTC_IRQMASK); | ||
392 | spin_unlock_irq(&rtc_lock); | ||
393 | } | ||
394 | |||
395 | static void __devexit rtc_mrst_do_remove(struct device *dev) | ||
396 | { | ||
397 | struct mrst_rtc *mrst = dev_get_drvdata(dev); | ||
398 | struct resource *iomem; | ||
399 | |||
400 | rtc_mrst_do_shutdown(); | ||
401 | |||
402 | if (mrst->irq) | ||
403 | free_irq(mrst->irq, mrst->rtc); | ||
404 | |||
405 | rtc_device_unregister(mrst->rtc); | ||
406 | mrst->rtc = NULL; | ||
407 | |||
408 | iomem = mrst->iomem; | ||
409 | release_mem_region(iomem->start, resource_size(iomem)); | ||
410 | mrst->iomem = NULL; | ||
411 | |||
412 | mrst->dev = NULL; | ||
413 | dev_set_drvdata(dev, NULL); | ||
414 | } | ||
415 | |||
416 | #ifdef CONFIG_PM | ||
417 | static int mrst_suspend(struct device *dev, pm_message_t mesg) | ||
418 | { | ||
419 | struct mrst_rtc *mrst = dev_get_drvdata(dev); | ||
420 | unsigned char tmp; | ||
421 | |||
422 | /* Only the alarm might be a wakeup event source */ | ||
423 | spin_lock_irq(&rtc_lock); | ||
424 | mrst->suspend_ctrl = tmp = vrtc_cmos_read(RTC_CONTROL); | ||
425 | if (tmp & (RTC_PIE | RTC_AIE)) { | ||
426 | unsigned char mask; | ||
427 | |||
428 | if (device_may_wakeup(dev)) | ||
429 | mask = RTC_IRQMASK & ~RTC_AIE; | ||
430 | else | ||
431 | mask = RTC_IRQMASK; | ||
432 | tmp &= ~mask; | ||
433 | vrtc_cmos_write(tmp, RTC_CONTROL); | ||
434 | |||
435 | mrst_checkintr(mrst, tmp); | ||
436 | } | ||
437 | spin_unlock_irq(&rtc_lock); | ||
438 | |||
439 | if (tmp & RTC_AIE) { | ||
440 | mrst->enabled_wake = 1; | ||
441 | enable_irq_wake(mrst->irq); | ||
442 | } | ||
443 | |||
444 | dev_dbg(&mrst_rtc.rtc->dev, "suspend%s, ctrl %02x\n", | ||
445 | (tmp & RTC_AIE) ? ", alarm may wake" : "", | ||
446 | tmp); | ||
447 | |||
448 | return 0; | ||
449 | } | ||
450 | |||
451 | /* | ||
452 | * We want RTC alarms to wake us from the deep power saving state | ||
453 | */ | ||
454 | static inline int mrst_poweroff(struct device *dev) | ||
455 | { | ||
456 | return mrst_suspend(dev, PMSG_HIBERNATE); | ||
457 | } | ||
458 | |||
459 | static int mrst_resume(struct device *dev) | ||
460 | { | ||
461 | struct mrst_rtc *mrst = dev_get_drvdata(dev); | ||
462 | unsigned char tmp = mrst->suspend_ctrl; | ||
463 | |||
464 | /* Re-enable any irqs previously active */ | ||
465 | if (tmp & RTC_IRQMASK) { | ||
466 | unsigned char mask; | ||
467 | |||
468 | if (mrst->enabled_wake) { | ||
469 | disable_irq_wake(mrst->irq); | ||
470 | mrst->enabled_wake = 0; | ||
471 | } | ||
472 | |||
473 | spin_lock_irq(&rtc_lock); | ||
474 | do { | ||
475 | vrtc_cmos_write(tmp, RTC_CONTROL); | ||
476 | |||
477 | mask = vrtc_cmos_read(RTC_INTR_FLAGS); | ||
478 | mask &= (tmp & RTC_IRQMASK) | RTC_IRQF; | ||
479 | if (!is_intr(mask)) | ||
480 | break; | ||
481 | |||
482 | rtc_update_irq(mrst->rtc, 1, mask); | ||
483 | tmp &= ~RTC_AIE; | ||
484 | } while (mask & RTC_AIE); | ||
485 | spin_unlock_irq(&rtc_lock); | ||
486 | } | ||
487 | |||
488 | dev_dbg(&mrst_rtc.rtc->dev, "resume, ctrl %02x\n", tmp); | ||
489 | |||
490 | return 0; | ||
491 | } | ||
492 | |||
493 | #else | ||
494 | #define mrst_suspend NULL | ||
495 | #define mrst_resume NULL | ||
496 | |||
497 | static inline int mrst_poweroff(struct device *dev) | ||
498 | { | ||
499 | return -ENOSYS; | ||
500 | } | ||
501 | |||
502 | #endif | ||
503 | |||
504 | static int __devinit vrtc_mrst_platform_probe(struct platform_device *pdev) | ||
505 | { | ||
506 | return vrtc_mrst_do_probe(&pdev->dev, | ||
507 | platform_get_resource(pdev, IORESOURCE_MEM, 0), | ||
508 | platform_get_irq(pdev, 0)); | ||
509 | } | ||
510 | |||
511 | static int __devexit vrtc_mrst_platform_remove(struct platform_device *pdev) | ||
512 | { | ||
513 | rtc_mrst_do_remove(&pdev->dev); | ||
514 | return 0; | ||
515 | } | ||
516 | |||
517 | static void vrtc_mrst_platform_shutdown(struct platform_device *pdev) | ||
518 | { | ||
519 | if (system_state == SYSTEM_POWER_OFF && !mrst_poweroff(&pdev->dev)) | ||
520 | return; | ||
521 | |||
522 | rtc_mrst_do_shutdown(); | ||
523 | } | ||
524 | |||
525 | MODULE_ALIAS("platform:vrtc_mrst"); | ||
526 | |||
527 | static struct platform_driver vrtc_mrst_platform_driver = { | ||
528 | .probe = vrtc_mrst_platform_probe, | ||
529 | .remove = __devexit_p(vrtc_mrst_platform_remove), | ||
530 | .shutdown = vrtc_mrst_platform_shutdown, | ||
531 | .driver = { | ||
532 | .name = (char *) driver_name, | ||
533 | .suspend = mrst_suspend, | ||
534 | .resume = mrst_resume, | ||
535 | } | ||
536 | }; | ||
537 | |||
538 | static int __init vrtc_mrst_init(void) | ||
539 | { | ||
540 | return platform_driver_register(&vrtc_mrst_platform_driver); | ||
541 | } | ||
542 | |||
543 | static void __exit vrtc_mrst_exit(void) | ||
544 | { | ||
545 | platform_driver_unregister(&vrtc_mrst_platform_driver); | ||
546 | } | ||
547 | |||
548 | module_init(vrtc_mrst_init); | ||
549 | module_exit(vrtc_mrst_exit); | ||
550 | |||
551 | MODULE_AUTHOR("Jacob Pan; Feng Tang"); | ||
552 | MODULE_DESCRIPTION("Driver for Moorestown virtual RTC"); | ||
553 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-msm6242.c b/drivers/rtc/rtc-msm6242.c index b2fff0ca49f8..fcb113c11122 100644 --- a/drivers/rtc/rtc-msm6242.c +++ b/drivers/rtc/rtc-msm6242.c | |||
@@ -82,7 +82,7 @@ static inline unsigned int msm6242_read(struct msm6242_priv *priv, | |||
82 | static inline void msm6242_write(struct msm6242_priv *priv, unsigned int val, | 82 | static inline void msm6242_write(struct msm6242_priv *priv, unsigned int val, |
83 | unsigned int reg) | 83 | unsigned int reg) |
84 | { | 84 | { |
85 | return __raw_writel(val, &priv->regs[reg]); | 85 | __raw_writel(val, &priv->regs[reg]); |
86 | } | 86 | } |
87 | 87 | ||
88 | static inline void msm6242_set(struct msm6242_priv *priv, unsigned int val, | 88 | static inline void msm6242_set(struct msm6242_priv *priv, unsigned int val, |
@@ -214,6 +214,7 @@ static int __init msm6242_rtc_probe(struct platform_device *dev) | |||
214 | error = -ENOMEM; | 214 | error = -ENOMEM; |
215 | goto out_free_priv; | 215 | goto out_free_priv; |
216 | } | 216 | } |
217 | platform_set_drvdata(dev, priv); | ||
217 | 218 | ||
218 | rtc = rtc_device_register("rtc-msm6242", &dev->dev, &msm6242_rtc_ops, | 219 | rtc = rtc_device_register("rtc-msm6242", &dev->dev, &msm6242_rtc_ops, |
219 | THIS_MODULE); | 220 | THIS_MODULE); |
@@ -223,10 +224,10 @@ static int __init msm6242_rtc_probe(struct platform_device *dev) | |||
223 | } | 224 | } |
224 | 225 | ||
225 | priv->rtc = rtc; | 226 | priv->rtc = rtc; |
226 | platform_set_drvdata(dev, priv); | ||
227 | return 0; | 227 | return 0; |
228 | 228 | ||
229 | out_unmap: | 229 | out_unmap: |
230 | platform_set_drvdata(dev, NULL); | ||
230 | iounmap(priv->regs); | 231 | iounmap(priv->regs); |
231 | out_free_priv: | 232 | out_free_priv: |
232 | kfree(priv); | 233 | kfree(priv); |
diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c index bcca47298554..60627a764514 100644 --- a/drivers/rtc/rtc-mv.c +++ b/drivers/rtc/rtc-mv.c | |||
@@ -169,25 +169,19 @@ static int mv_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
169 | return 0; | 169 | return 0; |
170 | } | 170 | } |
171 | 171 | ||
172 | static int mv_rtc_ioctl(struct device *dev, unsigned int cmd, | 172 | static int mv_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) |
173 | unsigned long arg) | ||
174 | { | 173 | { |
175 | struct platform_device *pdev = to_platform_device(dev); | 174 | struct platform_device *pdev = to_platform_device(dev); |
176 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 175 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
177 | void __iomem *ioaddr = pdata->ioaddr; | 176 | void __iomem *ioaddr = pdata->ioaddr; |
178 | 177 | ||
179 | if (pdata->irq < 0) | 178 | if (pdata->irq < 0) |
180 | return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */ | 179 | return -EINVAL; /* fall back into rtc-dev's emulation */ |
181 | switch (cmd) { | 180 | |
182 | case RTC_AIE_OFF: | 181 | if (enabled) |
183 | writel(0, ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS); | ||
184 | break; | ||
185 | case RTC_AIE_ON: | ||
186 | writel(1, ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS); | 182 | writel(1, ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS); |
187 | break; | 183 | else |
188 | default: | 184 | writel(0, ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS); |
189 | return -ENOIOCTLCMD; | ||
190 | } | ||
191 | return 0; | 185 | return 0; |
192 | } | 186 | } |
193 | 187 | ||
@@ -216,7 +210,7 @@ static const struct rtc_class_ops mv_rtc_alarm_ops = { | |||
216 | .set_time = mv_rtc_set_time, | 210 | .set_time = mv_rtc_set_time, |
217 | .read_alarm = mv_rtc_read_alarm, | 211 | .read_alarm = mv_rtc_read_alarm, |
218 | .set_alarm = mv_rtc_set_alarm, | 212 | .set_alarm = mv_rtc_set_alarm, |
219 | .ioctl = mv_rtc_ioctl, | 213 | .alarm_irq_enable = mv_rtc_alarm_irq_enable, |
220 | }; | 214 | }; |
221 | 215 | ||
222 | static int __devinit mv_rtc_probe(struct platform_device *pdev) | 216 | static int __devinit mv_rtc_probe(struct platform_device *pdev) |
diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index 0b06c1e03fd5..39e41fbdf08b 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c | |||
@@ -55,12 +55,6 @@ static const u32 PIE_BIT_DEF[MAX_PIE_NUM][2] = { | |||
55 | { MAX_PIE_FREQ, RTC_SAM7_BIT }, | 55 | { MAX_PIE_FREQ, RTC_SAM7_BIT }, |
56 | }; | 56 | }; |
57 | 57 | ||
58 | /* Those are the bits from a classic RTC we want to mimic */ | ||
59 | #define RTC_IRQF 0x80 /* any of the following 3 is active */ | ||
60 | #define RTC_PF 0x40 /* Periodic interrupt */ | ||
61 | #define RTC_AF 0x20 /* Alarm interrupt */ | ||
62 | #define RTC_UF 0x10 /* Update interrupt for 1Hz RTC */ | ||
63 | |||
64 | #define MXC_RTC_TIME 0 | 58 | #define MXC_RTC_TIME 0 |
65 | #define MXC_RTC_ALARM 1 | 59 | #define MXC_RTC_ALARM 1 |
66 | 60 | ||
@@ -274,12 +268,6 @@ static int mxc_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | |||
274 | return 0; | 268 | return 0; |
275 | } | 269 | } |
276 | 270 | ||
277 | static int mxc_rtc_update_irq_enable(struct device *dev, unsigned int enabled) | ||
278 | { | ||
279 | mxc_rtc_irq_enable(dev, RTC_1HZ_BIT, enabled); | ||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | /* | 271 | /* |
284 | * This function reads the current RTC time into tm in Gregorian date. | 272 | * This function reads the current RTC time into tm in Gregorian date. |
285 | */ | 273 | */ |
@@ -368,7 +356,6 @@ static struct rtc_class_ops mxc_rtc_ops = { | |||
368 | .read_alarm = mxc_rtc_read_alarm, | 356 | .read_alarm = mxc_rtc_read_alarm, |
369 | .set_alarm = mxc_rtc_set_alarm, | 357 | .set_alarm = mxc_rtc_set_alarm, |
370 | .alarm_irq_enable = mxc_rtc_alarm_irq_enable, | 358 | .alarm_irq_enable = mxc_rtc_alarm_irq_enable, |
371 | .update_irq_enable = mxc_rtc_update_irq_enable, | ||
372 | }; | 359 | }; |
373 | 360 | ||
374 | static int __init mxc_rtc_probe(struct platform_device *pdev) | 361 | static int __init mxc_rtc_probe(struct platform_device *pdev) |
@@ -425,14 +412,6 @@ static int __init mxc_rtc_probe(struct platform_device *pdev) | |||
425 | goto exit_put_clk; | 412 | goto exit_put_clk; |
426 | } | 413 | } |
427 | 414 | ||
428 | rtc = rtc_device_register(pdev->name, &pdev->dev, &mxc_rtc_ops, | ||
429 | THIS_MODULE); | ||
430 | if (IS_ERR(rtc)) { | ||
431 | ret = PTR_ERR(rtc); | ||
432 | goto exit_put_clk; | ||
433 | } | ||
434 | |||
435 | pdata->rtc = rtc; | ||
436 | platform_set_drvdata(pdev, pdata); | 415 | platform_set_drvdata(pdev, pdata); |
437 | 416 | ||
438 | /* Configure and enable the RTC */ | 417 | /* Configure and enable the RTC */ |
@@ -445,8 +424,19 @@ static int __init mxc_rtc_probe(struct platform_device *pdev) | |||
445 | pdata->irq = -1; | 424 | pdata->irq = -1; |
446 | } | 425 | } |
447 | 426 | ||
427 | rtc = rtc_device_register(pdev->name, &pdev->dev, &mxc_rtc_ops, | ||
428 | THIS_MODULE); | ||
429 | if (IS_ERR(rtc)) { | ||
430 | ret = PTR_ERR(rtc); | ||
431 | goto exit_clr_drvdata; | ||
432 | } | ||
433 | |||
434 | pdata->rtc = rtc; | ||
435 | |||
448 | return 0; | 436 | return 0; |
449 | 437 | ||
438 | exit_clr_drvdata: | ||
439 | platform_set_drvdata(pdev, NULL); | ||
450 | exit_put_clk: | 440 | exit_put_clk: |
451 | clk_disable(pdata->clk); | 441 | clk_disable(pdata->clk); |
452 | clk_put(pdata->clk); | 442 | clk_put(pdata->clk); |
diff --git a/drivers/rtc/rtc-nuc900.c b/drivers/rtc/rtc-nuc900.c index 62de66af0a68..781068d62f23 100644 --- a/drivers/rtc/rtc-nuc900.c +++ b/drivers/rtc/rtc-nuc900.c | |||
@@ -134,20 +134,6 @@ static void nuc900_rtc_bin2bcd(struct device *dev, struct rtc_time *settm, | |||
134 | gettm->bcd_hour = bin2bcd(settm->tm_hour) << 16; | 134 | gettm->bcd_hour = bin2bcd(settm->tm_hour) << 16; |
135 | } | 135 | } |
136 | 136 | ||
137 | static int nuc900_update_irq_enable(struct device *dev, unsigned int enabled) | ||
138 | { | ||
139 | struct nuc900_rtc *rtc = dev_get_drvdata(dev); | ||
140 | |||
141 | if (enabled) | ||
142 | __raw_writel(__raw_readl(rtc->rtc_reg + REG_RTC_RIER)| | ||
143 | (TICKINTENB), rtc->rtc_reg + REG_RTC_RIER); | ||
144 | else | ||
145 | __raw_writel(__raw_readl(rtc->rtc_reg + REG_RTC_RIER)& | ||
146 | (~TICKINTENB), rtc->rtc_reg + REG_RTC_RIER); | ||
147 | |||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | static int nuc900_alarm_irq_enable(struct device *dev, unsigned int enabled) | 137 | static int nuc900_alarm_irq_enable(struct device *dev, unsigned int enabled) |
152 | { | 138 | { |
153 | struct nuc900_rtc *rtc = dev_get_drvdata(dev); | 139 | struct nuc900_rtc *rtc = dev_get_drvdata(dev); |
@@ -234,7 +220,6 @@ static struct rtc_class_ops nuc900_rtc_ops = { | |||
234 | .read_alarm = nuc900_rtc_read_alarm, | 220 | .read_alarm = nuc900_rtc_read_alarm, |
235 | .set_alarm = nuc900_rtc_set_alarm, | 221 | .set_alarm = nuc900_rtc_set_alarm, |
236 | .alarm_irq_enable = nuc900_alarm_irq_enable, | 222 | .alarm_irq_enable = nuc900_alarm_irq_enable, |
237 | .update_irq_enable = nuc900_update_irq_enable, | ||
238 | }; | 223 | }; |
239 | 224 | ||
240 | static int __devinit nuc900_rtc_probe(struct platform_device *pdev) | 225 | static int __devinit nuc900_rtc_probe(struct platform_device *pdev) |
@@ -274,7 +259,7 @@ static int __devinit nuc900_rtc_probe(struct platform_device *pdev) | |||
274 | nuc900_rtc->rtcdev = rtc_device_register(pdev->name, &pdev->dev, | 259 | nuc900_rtc->rtcdev = rtc_device_register(pdev->name, &pdev->dev, |
275 | &nuc900_rtc_ops, THIS_MODULE); | 260 | &nuc900_rtc_ops, THIS_MODULE); |
276 | if (IS_ERR(nuc900_rtc->rtcdev)) { | 261 | if (IS_ERR(nuc900_rtc->rtcdev)) { |
277 | dev_err(&pdev->dev, "rtc device register faild\n"); | 262 | dev_err(&pdev->dev, "rtc device register failed\n"); |
278 | err = PTR_ERR(nuc900_rtc->rtcdev); | 263 | err = PTR_ERR(nuc900_rtc->rtcdev); |
279 | goto fail3; | 264 | goto fail3; |
280 | } | 265 | } |
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index 64d9727b7229..bcae8dd41496 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c | |||
@@ -34,7 +34,8 @@ | |||
34 | * Board-specific wiring options include using split power mode with | 34 | * Board-specific wiring options include using split power mode with |
35 | * RTC_OFF_NOFF used as the reset signal (so the RTC won't be reset), | 35 | * RTC_OFF_NOFF used as the reset signal (so the RTC won't be reset), |
36 | * and wiring RTC_WAKE_INT (so the RTC alarm can wake the system from | 36 | * and wiring RTC_WAKE_INT (so the RTC alarm can wake the system from |
37 | * low power modes). See the BOARD-SPECIFIC CUSTOMIZATION comment. | 37 | * low power modes) for OMAP1 boards (OMAP-L138 has this built into |
38 | * the SoC). See the BOARD-SPECIFIC CUSTOMIZATION comment. | ||
38 | */ | 39 | */ |
39 | 40 | ||
40 | #define OMAP_RTC_BASE 0xfffb4800 | 41 | #define OMAP_RTC_BASE 0xfffb4800 |
@@ -134,42 +135,17 @@ static irqreturn_t rtc_irq(int irq, void *rtc) | |||
134 | return IRQ_HANDLED; | 135 | return IRQ_HANDLED; |
135 | } | 136 | } |
136 | 137 | ||
137 | #ifdef CONFIG_RTC_INTF_DEV | 138 | static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) |
138 | |||
139 | static int | ||
140 | omap_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | ||
141 | { | 139 | { |
142 | u8 reg; | 140 | u8 reg; |
143 | 141 | ||
144 | switch (cmd) { | ||
145 | case RTC_AIE_OFF: | ||
146 | case RTC_AIE_ON: | ||
147 | case RTC_UIE_OFF: | ||
148 | case RTC_UIE_ON: | ||
149 | break; | ||
150 | default: | ||
151 | return -ENOIOCTLCMD; | ||
152 | } | ||
153 | |||
154 | local_irq_disable(); | 142 | local_irq_disable(); |
155 | rtc_wait_not_busy(); | 143 | rtc_wait_not_busy(); |
156 | reg = rtc_read(OMAP_RTC_INTERRUPTS_REG); | 144 | reg = rtc_read(OMAP_RTC_INTERRUPTS_REG); |
157 | switch (cmd) { | 145 | if (enabled) |
158 | /* AIE = Alarm Interrupt Enable */ | ||
159 | case RTC_AIE_OFF: | ||
160 | reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM; | ||
161 | break; | ||
162 | case RTC_AIE_ON: | ||
163 | reg |= OMAP_RTC_INTERRUPTS_IT_ALARM; | 146 | reg |= OMAP_RTC_INTERRUPTS_IT_ALARM; |
164 | break; | 147 | else |
165 | /* UIE = Update Interrupt Enable (1/second) */ | 148 | reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM; |
166 | case RTC_UIE_OFF: | ||
167 | reg &= ~OMAP_RTC_INTERRUPTS_IT_TIMER; | ||
168 | break; | ||
169 | case RTC_UIE_ON: | ||
170 | reg |= OMAP_RTC_INTERRUPTS_IT_TIMER; | ||
171 | break; | ||
172 | } | ||
173 | rtc_wait_not_busy(); | 149 | rtc_wait_not_busy(); |
174 | rtc_write(reg, OMAP_RTC_INTERRUPTS_REG); | 150 | rtc_write(reg, OMAP_RTC_INTERRUPTS_REG); |
175 | local_irq_enable(); | 151 | local_irq_enable(); |
@@ -177,10 +153,6 @@ omap_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | |||
177 | return 0; | 153 | return 0; |
178 | } | 154 | } |
179 | 155 | ||
180 | #else | ||
181 | #define omap_rtc_ioctl NULL | ||
182 | #endif | ||
183 | |||
184 | /* this hardware doesn't support "don't care" alarm fields */ | 156 | /* this hardware doesn't support "don't care" alarm fields */ |
185 | static int tm2bcd(struct rtc_time *tm) | 157 | static int tm2bcd(struct rtc_time *tm) |
186 | { | 158 | { |
@@ -303,11 +275,11 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
303 | } | 275 | } |
304 | 276 | ||
305 | static struct rtc_class_ops omap_rtc_ops = { | 277 | static struct rtc_class_ops omap_rtc_ops = { |
306 | .ioctl = omap_rtc_ioctl, | ||
307 | .read_time = omap_rtc_read_time, | 278 | .read_time = omap_rtc_read_time, |
308 | .set_time = omap_rtc_set_time, | 279 | .set_time = omap_rtc_set_time, |
309 | .read_alarm = omap_rtc_read_alarm, | 280 | .read_alarm = omap_rtc_read_alarm, |
310 | .set_alarm = omap_rtc_set_alarm, | 281 | .set_alarm = omap_rtc_set_alarm, |
282 | .alarm_irq_enable = omap_rtc_alarm_irq_enable, | ||
311 | }; | 283 | }; |
312 | 284 | ||
313 | static int omap_rtc_alarm; | 285 | static int omap_rtc_alarm; |
@@ -401,16 +373,17 @@ static int __init omap_rtc_probe(struct platform_device *pdev) | |||
401 | 373 | ||
402 | /* BOARD-SPECIFIC CUSTOMIZATION CAN GO HERE: | 374 | /* BOARD-SPECIFIC CUSTOMIZATION CAN GO HERE: |
403 | * | 375 | * |
404 | * - Boards wired so that RTC_WAKE_INT does something, and muxed | 376 | * - Device wake-up capability setting should come through chip |
405 | * right (W13_1610_RTC_WAKE_INT is the default after chip reset), | 377 | * init logic. OMAP1 boards should initialize the "wakeup capable" |
406 | * should initialize the device wakeup flag appropriately. | 378 | * flag in the platform device if the board is wired right for |
379 | * being woken up by RTC alarm. For OMAP-L138, this capability | ||
380 | * is built into the SoC by the "Deep Sleep" capability. | ||
407 | * | 381 | * |
408 | * - Boards wired so RTC_ON_nOFF is used as the reset signal, | 382 | * - Boards wired so RTC_ON_nOFF is used as the reset signal, |
409 | * rather than nPWRON_RESET, should forcibly enable split | 383 | * rather than nPWRON_RESET, should forcibly enable split |
410 | * power mode. (Some chip errata report that RTC_CTRL_SPLIT | 384 | * power mode. (Some chip errata report that RTC_CTRL_SPLIT |
411 | * is write-only, and always reads as zero...) | 385 | * is write-only, and always reads as zero...) |
412 | */ | 386 | */ |
413 | device_init_wakeup(&pdev->dev, 0); | ||
414 | 387 | ||
415 | if (new_ctrl & (u8) OMAP_RTC_CTRL_SPLIT) | 388 | if (new_ctrl & (u8) OMAP_RTC_CTRL_SPLIT) |
416 | pr_info("%s: split power mode\n", pdev->name); | 389 | pr_info("%s: split power mode\n", pdev->name); |
@@ -421,19 +394,20 @@ static int __init omap_rtc_probe(struct platform_device *pdev) | |||
421 | return 0; | 394 | return 0; |
422 | 395 | ||
423 | fail2: | 396 | fail2: |
424 | free_irq(omap_rtc_timer, NULL); | 397 | free_irq(omap_rtc_timer, rtc); |
425 | fail1: | 398 | fail1: |
426 | rtc_device_unregister(rtc); | 399 | rtc_device_unregister(rtc); |
427 | fail0: | 400 | fail0: |
428 | iounmap(rtc_base); | 401 | iounmap(rtc_base); |
429 | fail: | 402 | fail: |
430 | release_resource(mem); | 403 | release_mem_region(mem->start, resource_size(mem)); |
431 | return -EIO; | 404 | return -EIO; |
432 | } | 405 | } |
433 | 406 | ||
434 | static int __exit omap_rtc_remove(struct platform_device *pdev) | 407 | static int __exit omap_rtc_remove(struct platform_device *pdev) |
435 | { | 408 | { |
436 | struct rtc_device *rtc = platform_get_drvdata(pdev); | 409 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
410 | struct resource *mem = dev_get_drvdata(&rtc->dev); | ||
437 | 411 | ||
438 | device_init_wakeup(&pdev->dev, 0); | 412 | device_init_wakeup(&pdev->dev, 0); |
439 | 413 | ||
@@ -445,8 +419,9 @@ static int __exit omap_rtc_remove(struct platform_device *pdev) | |||
445 | if (omap_rtc_timer != omap_rtc_alarm) | 419 | if (omap_rtc_timer != omap_rtc_alarm) |
446 | free_irq(omap_rtc_alarm, rtc); | 420 | free_irq(omap_rtc_alarm, rtc); |
447 | 421 | ||
448 | release_resource(dev_get_drvdata(&rtc->dev)); | ||
449 | rtc_device_unregister(rtc); | 422 | rtc_device_unregister(rtc); |
423 | iounmap(rtc_base); | ||
424 | release_mem_region(mem->start, resource_size(mem)); | ||
450 | return 0; | 425 | return 0; |
451 | } | 426 | } |
452 | 427 | ||
diff --git a/drivers/rtc/rtc-pcap.c b/drivers/rtc/rtc-pcap.c index 25c0b3fd44f1..cd4f198cc2ef 100644 --- a/drivers/rtc/rtc-pcap.c +++ b/drivers/rtc/rtc-pcap.c | |||
@@ -131,18 +131,12 @@ static int pcap_rtc_alarm_irq_enable(struct device *dev, unsigned int en) | |||
131 | return pcap_rtc_irq_enable(dev, PCAP_IRQ_TODA, en); | 131 | return pcap_rtc_irq_enable(dev, PCAP_IRQ_TODA, en); |
132 | } | 132 | } |
133 | 133 | ||
134 | static int pcap_rtc_update_irq_enable(struct device *dev, unsigned int en) | ||
135 | { | ||
136 | return pcap_rtc_irq_enable(dev, PCAP_IRQ_1HZ, en); | ||
137 | } | ||
138 | |||
139 | static const struct rtc_class_ops pcap_rtc_ops = { | 134 | static const struct rtc_class_ops pcap_rtc_ops = { |
140 | .read_time = pcap_rtc_read_time, | 135 | .read_time = pcap_rtc_read_time, |
141 | .read_alarm = pcap_rtc_read_alarm, | 136 | .read_alarm = pcap_rtc_read_alarm, |
142 | .set_alarm = pcap_rtc_set_alarm, | 137 | .set_alarm = pcap_rtc_set_alarm, |
143 | .set_mmss = pcap_rtc_set_mmss, | 138 | .set_mmss = pcap_rtc_set_mmss, |
144 | .alarm_irq_enable = pcap_rtc_alarm_irq_enable, | 139 | .alarm_irq_enable = pcap_rtc_alarm_irq_enable, |
145 | .update_irq_enable = pcap_rtc_update_irq_enable, | ||
146 | }; | 140 | }; |
147 | 141 | ||
148 | static int __devinit pcap_rtc_probe(struct platform_device *pdev) | 142 | static int __devinit pcap_rtc_probe(struct platform_device *pdev) |
@@ -157,6 +151,8 @@ static int __devinit pcap_rtc_probe(struct platform_device *pdev) | |||
157 | 151 | ||
158 | pcap_rtc->pcap = dev_get_drvdata(pdev->dev.parent); | 152 | pcap_rtc->pcap = dev_get_drvdata(pdev->dev.parent); |
159 | 153 | ||
154 | platform_set_drvdata(pdev, pcap_rtc); | ||
155 | |||
160 | pcap_rtc->rtc = rtc_device_register("pcap", &pdev->dev, | 156 | pcap_rtc->rtc = rtc_device_register("pcap", &pdev->dev, |
161 | &pcap_rtc_ops, THIS_MODULE); | 157 | &pcap_rtc_ops, THIS_MODULE); |
162 | if (IS_ERR(pcap_rtc->rtc)) { | 158 | if (IS_ERR(pcap_rtc->rtc)) { |
@@ -164,7 +160,6 @@ static int __devinit pcap_rtc_probe(struct platform_device *pdev) | |||
164 | goto fail_rtc; | 160 | goto fail_rtc; |
165 | } | 161 | } |
166 | 162 | ||
167 | platform_set_drvdata(pdev, pcap_rtc); | ||
168 | 163 | ||
169 | timer_irq = pcap_to_irq(pcap_rtc->pcap, PCAP_IRQ_1HZ); | 164 | timer_irq = pcap_to_irq(pcap_rtc->pcap, PCAP_IRQ_1HZ); |
170 | alarm_irq = pcap_to_irq(pcap_rtc->pcap, PCAP_IRQ_TODA); | 165 | alarm_irq = pcap_to_irq(pcap_rtc->pcap, PCAP_IRQ_TODA); |
@@ -183,6 +178,7 @@ fail_alarm: | |||
183 | fail_timer: | 178 | fail_timer: |
184 | rtc_device_unregister(pcap_rtc->rtc); | 179 | rtc_device_unregister(pcap_rtc->rtc); |
185 | fail_rtc: | 180 | fail_rtc: |
181 | platform_set_drvdata(pdev, NULL); | ||
186 | kfree(pcap_rtc); | 182 | kfree(pcap_rtc); |
187 | return err; | 183 | return err; |
188 | } | 184 | } |
diff --git a/drivers/rtc/rtc-pcf50633.c b/drivers/rtc/rtc-pcf50633.c index 16edf94ab42f..0c423892923c 100644 --- a/drivers/rtc/rtc-pcf50633.c +++ b/drivers/rtc/rtc-pcf50633.c | |||
@@ -58,7 +58,6 @@ struct pcf50633_time { | |||
58 | 58 | ||
59 | struct pcf50633_rtc { | 59 | struct pcf50633_rtc { |
60 | int alarm_enabled; | 60 | int alarm_enabled; |
61 | int second_enabled; | ||
62 | int alarm_pending; | 61 | int alarm_pending; |
63 | 62 | ||
64 | struct pcf50633 *pcf; | 63 | struct pcf50633 *pcf; |
@@ -106,25 +105,6 @@ pcf50633_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | |||
106 | return 0; | 105 | return 0; |
107 | } | 106 | } |
108 | 107 | ||
109 | static int | ||
110 | pcf50633_rtc_update_irq_enable(struct device *dev, unsigned int enabled) | ||
111 | { | ||
112 | struct pcf50633_rtc *rtc = dev_get_drvdata(dev); | ||
113 | int err; | ||
114 | |||
115 | if (enabled) | ||
116 | err = pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_SECOND); | ||
117 | else | ||
118 | err = pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_SECOND); | ||
119 | |||
120 | if (err < 0) | ||
121 | return err; | ||
122 | |||
123 | rtc->second_enabled = enabled; | ||
124 | |||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | static int pcf50633_rtc_read_time(struct device *dev, struct rtc_time *tm) | 108 | static int pcf50633_rtc_read_time(struct device *dev, struct rtc_time *tm) |
129 | { | 109 | { |
130 | struct pcf50633_rtc *rtc; | 110 | struct pcf50633_rtc *rtc; |
@@ -162,7 +142,7 @@ static int pcf50633_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
162 | { | 142 | { |
163 | struct pcf50633_rtc *rtc; | 143 | struct pcf50633_rtc *rtc; |
164 | struct pcf50633_time pcf_tm; | 144 | struct pcf50633_time pcf_tm; |
165 | int second_masked, alarm_masked, ret = 0; | 145 | int alarm_masked, ret = 0; |
166 | 146 | ||
167 | rtc = dev_get_drvdata(dev); | 147 | rtc = dev_get_drvdata(dev); |
168 | 148 | ||
@@ -181,11 +161,8 @@ static int pcf50633_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
181 | pcf_tm.time[PCF50633_TI_SEC]); | 161 | pcf_tm.time[PCF50633_TI_SEC]); |
182 | 162 | ||
183 | 163 | ||
184 | second_masked = pcf50633_irq_mask_get(rtc->pcf, PCF50633_IRQ_SECOND); | ||
185 | alarm_masked = pcf50633_irq_mask_get(rtc->pcf, PCF50633_IRQ_ALARM); | 164 | alarm_masked = pcf50633_irq_mask_get(rtc->pcf, PCF50633_IRQ_ALARM); |
186 | 165 | ||
187 | if (!second_masked) | ||
188 | pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_SECOND); | ||
189 | if (!alarm_masked) | 166 | if (!alarm_masked) |
190 | pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_ALARM); | 167 | pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_ALARM); |
191 | 168 | ||
@@ -194,8 +171,6 @@ static int pcf50633_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
194 | PCF50633_TI_EXTENT, | 171 | PCF50633_TI_EXTENT, |
195 | &pcf_tm.time[0]); | 172 | &pcf_tm.time[0]); |
196 | 173 | ||
197 | if (!second_masked) | ||
198 | pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_SECOND); | ||
199 | if (!alarm_masked) | 174 | if (!alarm_masked) |
200 | pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_ALARM); | 175 | pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_ALARM); |
201 | 176 | ||
@@ -262,23 +237,15 @@ static struct rtc_class_ops pcf50633_rtc_ops = { | |||
262 | .set_time = pcf50633_rtc_set_time, | 237 | .set_time = pcf50633_rtc_set_time, |
263 | .read_alarm = pcf50633_rtc_read_alarm, | 238 | .read_alarm = pcf50633_rtc_read_alarm, |
264 | .set_alarm = pcf50633_rtc_set_alarm, | 239 | .set_alarm = pcf50633_rtc_set_alarm, |
265 | .alarm_irq_enable = pcf50633_rtc_alarm_irq_enable, | 240 | .alarm_irq_enable = pcf50633_rtc_alarm_irq_enable, |
266 | .update_irq_enable = pcf50633_rtc_update_irq_enable, | ||
267 | }; | 241 | }; |
268 | 242 | ||
269 | static void pcf50633_rtc_irq(int irq, void *data) | 243 | static void pcf50633_rtc_irq(int irq, void *data) |
270 | { | 244 | { |
271 | struct pcf50633_rtc *rtc = data; | 245 | struct pcf50633_rtc *rtc = data; |
272 | 246 | ||
273 | switch (irq) { | 247 | rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); |
274 | case PCF50633_IRQ_ALARM: | 248 | rtc->alarm_pending = 1; |
275 | rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); | ||
276 | rtc->alarm_pending = 1; | ||
277 | break; | ||
278 | case PCF50633_IRQ_SECOND: | ||
279 | rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF); | ||
280 | break; | ||
281 | } | ||
282 | } | 249 | } |
283 | 250 | ||
284 | static int __devinit pcf50633_rtc_probe(struct platform_device *pdev) | 251 | static int __devinit pcf50633_rtc_probe(struct platform_device *pdev) |
@@ -302,9 +269,6 @@ static int __devinit pcf50633_rtc_probe(struct platform_device *pdev) | |||
302 | 269 | ||
303 | pcf50633_register_irq(rtc->pcf, PCF50633_IRQ_ALARM, | 270 | pcf50633_register_irq(rtc->pcf, PCF50633_IRQ_ALARM, |
304 | pcf50633_rtc_irq, rtc); | 271 | pcf50633_rtc_irq, rtc); |
305 | pcf50633_register_irq(rtc->pcf, PCF50633_IRQ_SECOND, | ||
306 | pcf50633_rtc_irq, rtc); | ||
307 | |||
308 | return 0; | 272 | return 0; |
309 | } | 273 | } |
310 | 274 | ||
@@ -315,7 +279,6 @@ static int __devexit pcf50633_rtc_remove(struct platform_device *pdev) | |||
315 | rtc = platform_get_drvdata(pdev); | 279 | rtc = platform_get_drvdata(pdev); |
316 | 280 | ||
317 | pcf50633_free_irq(rtc->pcf, PCF50633_IRQ_ALARM); | 281 | pcf50633_free_irq(rtc->pcf, PCF50633_IRQ_ALARM); |
318 | pcf50633_free_irq(rtc->pcf, PCF50633_IRQ_SECOND); | ||
319 | 282 | ||
320 | rtc_device_unregister(rtc->rtc_dev); | 283 | rtc_device_unregister(rtc->rtc_dev); |
321 | kfree(rtc); | 284 | kfree(rtc); |
diff --git a/drivers/rtc/rtc-pl030.c b/drivers/rtc/rtc-pl030.c index bbdb2f02798a..1d28d4451dae 100644 --- a/drivers/rtc/rtc-pl030.c +++ b/drivers/rtc/rtc-pl030.c | |||
@@ -35,11 +35,6 @@ static irqreturn_t pl030_interrupt(int irq, void *dev_id) | |||
35 | return IRQ_HANDLED; | 35 | return IRQ_HANDLED; |
36 | } | 36 | } |
37 | 37 | ||
38 | static int pl030_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | ||
39 | { | ||
40 | return -ENOIOCTLCMD; | ||
41 | } | ||
42 | |||
43 | static int pl030_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | 38 | static int pl030_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
44 | { | 39 | { |
45 | struct pl030_rtc *rtc = dev_get_drvdata(dev); | 40 | struct pl030_rtc *rtc = dev_get_drvdata(dev); |
@@ -96,14 +91,13 @@ static int pl030_set_time(struct device *dev, struct rtc_time *tm) | |||
96 | } | 91 | } |
97 | 92 | ||
98 | static const struct rtc_class_ops pl030_ops = { | 93 | static const struct rtc_class_ops pl030_ops = { |
99 | .ioctl = pl030_ioctl, | ||
100 | .read_time = pl030_read_time, | 94 | .read_time = pl030_read_time, |
101 | .set_time = pl030_set_time, | 95 | .set_time = pl030_set_time, |
102 | .read_alarm = pl030_read_alarm, | 96 | .read_alarm = pl030_read_alarm, |
103 | .set_alarm = pl030_set_alarm, | 97 | .set_alarm = pl030_set_alarm, |
104 | }; | 98 | }; |
105 | 99 | ||
106 | static int pl030_probe(struct amba_device *dev, struct amba_id *id) | 100 | static int pl030_probe(struct amba_device *dev, const struct amba_id *id) |
107 | { | 101 | { |
108 | struct pl030_rtc *rtc; | 102 | struct pl030_rtc *rtc; |
109 | int ret; | 103 | int ret; |
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index b7a6690e5b35..ff1b84bd9bb5 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c | |||
@@ -293,57 +293,6 @@ static int pl031_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
293 | return ret; | 293 | return ret; |
294 | } | 294 | } |
295 | 295 | ||
296 | /* Periodic interrupt is only available in ST variants. */ | ||
297 | static int pl031_irq_set_state(struct device *dev, int enabled) | ||
298 | { | ||
299 | struct pl031_local *ldata = dev_get_drvdata(dev); | ||
300 | |||
301 | if (enabled == 1) { | ||
302 | /* Clear any pending timer interrupt. */ | ||
303 | writel(RTC_BIT_PI, ldata->base + RTC_ICR); | ||
304 | |||
305 | writel(readl(ldata->base + RTC_IMSC) | RTC_BIT_PI, | ||
306 | ldata->base + RTC_IMSC); | ||
307 | |||
308 | /* Now start the timer */ | ||
309 | writel(readl(ldata->base + RTC_TCR) | RTC_TCR_EN, | ||
310 | ldata->base + RTC_TCR); | ||
311 | |||
312 | } else { | ||
313 | writel(readl(ldata->base + RTC_IMSC) & (~RTC_BIT_PI), | ||
314 | ldata->base + RTC_IMSC); | ||
315 | |||
316 | /* Also stop the timer */ | ||
317 | writel(readl(ldata->base + RTC_TCR) & (~RTC_TCR_EN), | ||
318 | ldata->base + RTC_TCR); | ||
319 | } | ||
320 | /* Wait at least 1 RTC32 clock cycle to ensure next access | ||
321 | * to RTC_TCR will succeed. | ||
322 | */ | ||
323 | udelay(40); | ||
324 | |||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | static int pl031_irq_set_freq(struct device *dev, int freq) | ||
329 | { | ||
330 | struct pl031_local *ldata = dev_get_drvdata(dev); | ||
331 | |||
332 | /* Cant set timer if it is already enabled */ | ||
333 | if (readl(ldata->base + RTC_TCR) & RTC_TCR_EN) { | ||
334 | dev_err(dev, "can't change frequency while timer enabled\n"); | ||
335 | return -EINVAL; | ||
336 | } | ||
337 | |||
338 | /* If self start bit in RTC_TCR is set timer will start here, | ||
339 | * but we never set that bit. Instead we start the timer when | ||
340 | * set_state is called with enabled == 1. | ||
341 | */ | ||
342 | writel(RTC_TIMER_FREQ / freq, ldata->base + RTC_TLR); | ||
343 | |||
344 | return 0; | ||
345 | } | ||
346 | |||
347 | static int pl031_remove(struct amba_device *adev) | 296 | static int pl031_remove(struct amba_device *adev) |
348 | { | 297 | { |
349 | struct pl031_local *ldata = dev_get_drvdata(&adev->dev); | 298 | struct pl031_local *ldata = dev_get_drvdata(&adev->dev); |
@@ -358,7 +307,7 @@ static int pl031_remove(struct amba_device *adev) | |||
358 | return 0; | 307 | return 0; |
359 | } | 308 | } |
360 | 309 | ||
361 | static int pl031_probe(struct amba_device *adev, struct amba_id *id) | 310 | static int pl031_probe(struct amba_device *adev, const struct amba_id *id) |
362 | { | 311 | { |
363 | int ret; | 312 | int ret; |
364 | struct pl031_local *ldata; | 313 | struct pl031_local *ldata; |
@@ -440,8 +389,6 @@ static struct rtc_class_ops stv1_pl031_ops = { | |||
440 | .read_alarm = pl031_read_alarm, | 389 | .read_alarm = pl031_read_alarm, |
441 | .set_alarm = pl031_set_alarm, | 390 | .set_alarm = pl031_set_alarm, |
442 | .alarm_irq_enable = pl031_alarm_irq_enable, | 391 | .alarm_irq_enable = pl031_alarm_irq_enable, |
443 | .irq_set_state = pl031_irq_set_state, | ||
444 | .irq_set_freq = pl031_irq_set_freq, | ||
445 | }; | 392 | }; |
446 | 393 | ||
447 | /* And the second ST derivative */ | 394 | /* And the second ST derivative */ |
@@ -451,8 +398,6 @@ static struct rtc_class_ops stv2_pl031_ops = { | |||
451 | .read_alarm = pl031_stv2_read_alarm, | 398 | .read_alarm = pl031_stv2_read_alarm, |
452 | .set_alarm = pl031_stv2_set_alarm, | 399 | .set_alarm = pl031_stv2_set_alarm, |
453 | .alarm_irq_enable = pl031_alarm_irq_enable, | 400 | .alarm_irq_enable = pl031_alarm_irq_enable, |
454 | .irq_set_state = pl031_irq_set_state, | ||
455 | .irq_set_freq = pl031_irq_set_freq, | ||
456 | }; | 401 | }; |
457 | 402 | ||
458 | static struct amba_id pl031_ids[] = { | 403 | static struct amba_id pl031_ids[] = { |
diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c index c086fc30a84c..0a59fda5c09d 100644 --- a/drivers/rtc/rtc-proc.c +++ b/drivers/rtc/rtc-proc.c | |||
@@ -69,6 +69,14 @@ static int rtc_proc_show(struct seq_file *seq, void *offset) | |||
69 | alrm.enabled ? "yes" : "no"); | 69 | alrm.enabled ? "yes" : "no"); |
70 | seq_printf(seq, "alrm_pending\t: %s\n", | 70 | seq_printf(seq, "alrm_pending\t: %s\n", |
71 | alrm.pending ? "yes" : "no"); | 71 | alrm.pending ? "yes" : "no"); |
72 | seq_printf(seq, "update IRQ enabled\t: %s\n", | ||
73 | (rtc->uie_rtctimer.enabled) ? "yes" : "no"); | ||
74 | seq_printf(seq, "periodic IRQ enabled\t: %s\n", | ||
75 | (rtc->pie_enabled) ? "yes" : "no"); | ||
76 | seq_printf(seq, "periodic IRQ frequency\t: %d\n", | ||
77 | rtc->irq_freq); | ||
78 | seq_printf(seq, "max user IRQ frequency\t: %d\n", | ||
79 | rtc->max_user_freq); | ||
72 | } | 80 | } |
73 | 81 | ||
74 | seq_printf(seq, "24hr\t\t: yes\n"); | 82 | seq_printf(seq, "24hr\t\t: yes\n"); |
@@ -81,12 +89,16 @@ static int rtc_proc_show(struct seq_file *seq, void *offset) | |||
81 | 89 | ||
82 | static int rtc_proc_open(struct inode *inode, struct file *file) | 90 | static int rtc_proc_open(struct inode *inode, struct file *file) |
83 | { | 91 | { |
92 | int ret; | ||
84 | struct rtc_device *rtc = PDE(inode)->data; | 93 | struct rtc_device *rtc = PDE(inode)->data; |
85 | 94 | ||
86 | if (!try_module_get(THIS_MODULE)) | 95 | if (!try_module_get(THIS_MODULE)) |
87 | return -ENODEV; | 96 | return -ENODEV; |
88 | 97 | ||
89 | return single_open(file, rtc_proc_show, rtc); | 98 | ret = single_open(file, rtc_proc_show, rtc); |
99 | if (ret) | ||
100 | module_put(THIS_MODULE); | ||
101 | return ret; | ||
90 | } | 102 | } |
91 | 103 | ||
92 | static int rtc_proc_release(struct inode *inode, struct file *file) | 104 | static int rtc_proc_release(struct inode *inode, struct file *file) |
diff --git a/drivers/rtc/rtc-puv3.c b/drivers/rtc/rtc-puv3.c new file mode 100644 index 000000000000..46f14b82f3ab --- /dev/null +++ b/drivers/rtc/rtc-puv3.c | |||
@@ -0,0 +1,359 @@ | |||
1 | /* | ||
2 | * RTC driver code specific to PKUnity SoC and UniCore ISA | ||
3 | * | ||
4 | * Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn> | ||
5 | * Copyright (C) 2001-2010 Guan Xuetao | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/fs.h> | ||
14 | #include <linux/string.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/rtc.h> | ||
19 | #include <linux/bcd.h> | ||
20 | #include <linux/clk.h> | ||
21 | #include <linux/log2.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/uaccess.h> | ||
24 | #include <linux/io.h> | ||
25 | |||
26 | #include <asm/irq.h> | ||
27 | #include <mach/hardware.h> | ||
28 | |||
29 | static struct resource *puv3_rtc_mem; | ||
30 | |||
31 | static int puv3_rtc_alarmno = IRQ_RTCAlarm; | ||
32 | static int puv3_rtc_tickno = IRQ_RTC; | ||
33 | |||
34 | static DEFINE_SPINLOCK(puv3_rtc_pie_lock); | ||
35 | |||
36 | /* IRQ Handlers */ | ||
37 | static irqreturn_t puv3_rtc_alarmirq(int irq, void *id) | ||
38 | { | ||
39 | struct rtc_device *rdev = id; | ||
40 | |||
41 | writel(readl(RTC_RTSR) | RTC_RTSR_AL, RTC_RTSR); | ||
42 | rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF); | ||
43 | return IRQ_HANDLED; | ||
44 | } | ||
45 | |||
46 | static irqreturn_t puv3_rtc_tickirq(int irq, void *id) | ||
47 | { | ||
48 | struct rtc_device *rdev = id; | ||
49 | |||
50 | writel(readl(RTC_RTSR) | RTC_RTSR_HZ, RTC_RTSR); | ||
51 | rtc_update_irq(rdev, 1, RTC_PF | RTC_IRQF); | ||
52 | return IRQ_HANDLED; | ||
53 | } | ||
54 | |||
55 | /* Update control registers */ | ||
56 | static void puv3_rtc_setaie(int to) | ||
57 | { | ||
58 | unsigned int tmp; | ||
59 | |||
60 | pr_debug("%s: aie=%d\n", __func__, to); | ||
61 | |||
62 | tmp = readl(RTC_RTSR) & ~RTC_RTSR_ALE; | ||
63 | |||
64 | if (to) | ||
65 | tmp |= RTC_RTSR_ALE; | ||
66 | |||
67 | writel(tmp, RTC_RTSR); | ||
68 | } | ||
69 | |||
70 | static int puv3_rtc_setpie(struct device *dev, int enabled) | ||
71 | { | ||
72 | unsigned int tmp; | ||
73 | |||
74 | pr_debug("%s: pie=%d\n", __func__, enabled); | ||
75 | |||
76 | spin_lock_irq(&puv3_rtc_pie_lock); | ||
77 | tmp = readl(RTC_RTSR) & ~RTC_RTSR_HZE; | ||
78 | |||
79 | if (enabled) | ||
80 | tmp |= RTC_RTSR_HZE; | ||
81 | |||
82 | writel(tmp, RTC_RTSR); | ||
83 | spin_unlock_irq(&puv3_rtc_pie_lock); | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | /* Time read/write */ | ||
89 | static int puv3_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) | ||
90 | { | ||
91 | rtc_time_to_tm(readl(RTC_RCNR), rtc_tm); | ||
92 | |||
93 | pr_debug("read time %02x.%02x.%02x %02x/%02x/%02x\n", | ||
94 | rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday, | ||
95 | rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec); | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | static int puv3_rtc_settime(struct device *dev, struct rtc_time *tm) | ||
101 | { | ||
102 | unsigned long rtc_count = 0; | ||
103 | |||
104 | pr_debug("set time %02d.%02d.%02d %02d/%02d/%02d\n", | ||
105 | tm->tm_year, tm->tm_mon, tm->tm_mday, | ||
106 | tm->tm_hour, tm->tm_min, tm->tm_sec); | ||
107 | |||
108 | rtc_tm_to_time(tm, &rtc_count); | ||
109 | writel(rtc_count, RTC_RCNR); | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static int puv3_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
115 | { | ||
116 | struct rtc_time *alm_tm = &alrm->time; | ||
117 | |||
118 | rtc_time_to_tm(readl(RTC_RTAR), alm_tm); | ||
119 | |||
120 | alrm->enabled = readl(RTC_RTSR) & RTC_RTSR_ALE; | ||
121 | |||
122 | pr_debug("read alarm %02x %02x.%02x.%02x %02x/%02x/%02x\n", | ||
123 | alrm->enabled, | ||
124 | alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday, | ||
125 | alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec); | ||
126 | |||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | static int puv3_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
131 | { | ||
132 | struct rtc_time *tm = &alrm->time; | ||
133 | unsigned long rtcalarm_count = 0; | ||
134 | |||
135 | pr_debug("puv3_rtc_setalarm: %d, %02x/%02x/%02x %02x.%02x.%02x\n", | ||
136 | alrm->enabled, | ||
137 | tm->tm_mday & 0xff, tm->tm_mon & 0xff, tm->tm_year & 0xff, | ||
138 | tm->tm_hour & 0xff, tm->tm_min & 0xff, tm->tm_sec); | ||
139 | |||
140 | rtc_tm_to_time(tm, &rtcalarm_count); | ||
141 | writel(rtcalarm_count, RTC_RTAR); | ||
142 | |||
143 | puv3_rtc_setaie(alrm->enabled); | ||
144 | |||
145 | if (alrm->enabled) | ||
146 | enable_irq_wake(puv3_rtc_alarmno); | ||
147 | else | ||
148 | disable_irq_wake(puv3_rtc_alarmno); | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static int puv3_rtc_proc(struct device *dev, struct seq_file *seq) | ||
154 | { | ||
155 | seq_printf(seq, "periodic_IRQ\t: %s\n", | ||
156 | (readl(RTC_RTSR) & RTC_RTSR_HZE) ? "yes" : "no"); | ||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | static int puv3_rtc_open(struct device *dev) | ||
161 | { | ||
162 | struct platform_device *pdev = to_platform_device(dev); | ||
163 | struct rtc_device *rtc_dev = platform_get_drvdata(pdev); | ||
164 | int ret; | ||
165 | |||
166 | ret = request_irq(puv3_rtc_alarmno, puv3_rtc_alarmirq, | ||
167 | IRQF_DISABLED, "pkunity-rtc alarm", rtc_dev); | ||
168 | |||
169 | if (ret) { | ||
170 | dev_err(dev, "IRQ%d error %d\n", puv3_rtc_alarmno, ret); | ||
171 | return ret; | ||
172 | } | ||
173 | |||
174 | ret = request_irq(puv3_rtc_tickno, puv3_rtc_tickirq, | ||
175 | IRQF_DISABLED, "pkunity-rtc tick", rtc_dev); | ||
176 | |||
177 | if (ret) { | ||
178 | dev_err(dev, "IRQ%d error %d\n", puv3_rtc_tickno, ret); | ||
179 | goto tick_err; | ||
180 | } | ||
181 | |||
182 | return ret; | ||
183 | |||
184 | tick_err: | ||
185 | free_irq(puv3_rtc_alarmno, rtc_dev); | ||
186 | return ret; | ||
187 | } | ||
188 | |||
189 | static void puv3_rtc_release(struct device *dev) | ||
190 | { | ||
191 | struct platform_device *pdev = to_platform_device(dev); | ||
192 | struct rtc_device *rtc_dev = platform_get_drvdata(pdev); | ||
193 | |||
194 | /* do not clear AIE here, it may be needed for wake */ | ||
195 | puv3_rtc_setpie(dev, 0); | ||
196 | free_irq(puv3_rtc_alarmno, rtc_dev); | ||
197 | free_irq(puv3_rtc_tickno, rtc_dev); | ||
198 | } | ||
199 | |||
200 | static const struct rtc_class_ops puv3_rtcops = { | ||
201 | .open = puv3_rtc_open, | ||
202 | .release = puv3_rtc_release, | ||
203 | .read_time = puv3_rtc_gettime, | ||
204 | .set_time = puv3_rtc_settime, | ||
205 | .read_alarm = puv3_rtc_getalarm, | ||
206 | .set_alarm = puv3_rtc_setalarm, | ||
207 | .proc = puv3_rtc_proc, | ||
208 | }; | ||
209 | |||
210 | static void puv3_rtc_enable(struct platform_device *pdev, int en) | ||
211 | { | ||
212 | if (!en) { | ||
213 | writel(readl(RTC_RTSR) & ~RTC_RTSR_HZE, RTC_RTSR); | ||
214 | } else { | ||
215 | /* re-enable the device, and check it is ok */ | ||
216 | if ((readl(RTC_RTSR) & RTC_RTSR_HZE) == 0) { | ||
217 | dev_info(&pdev->dev, "rtc disabled, re-enabling\n"); | ||
218 | writel(readl(RTC_RTSR) | RTC_RTSR_HZE, RTC_RTSR); | ||
219 | } | ||
220 | } | ||
221 | } | ||
222 | |||
223 | static int puv3_rtc_remove(struct platform_device *dev) | ||
224 | { | ||
225 | struct rtc_device *rtc = platform_get_drvdata(dev); | ||
226 | |||
227 | platform_set_drvdata(dev, NULL); | ||
228 | rtc_device_unregister(rtc); | ||
229 | |||
230 | puv3_rtc_setpie(&dev->dev, 0); | ||
231 | puv3_rtc_setaie(0); | ||
232 | |||
233 | release_resource(puv3_rtc_mem); | ||
234 | kfree(puv3_rtc_mem); | ||
235 | |||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | static int puv3_rtc_probe(struct platform_device *pdev) | ||
240 | { | ||
241 | struct rtc_device *rtc; | ||
242 | struct resource *res; | ||
243 | int ret; | ||
244 | |||
245 | pr_debug("%s: probe=%p\n", __func__, pdev); | ||
246 | |||
247 | /* find the IRQs */ | ||
248 | puv3_rtc_tickno = platform_get_irq(pdev, 1); | ||
249 | if (puv3_rtc_tickno < 0) { | ||
250 | dev_err(&pdev->dev, "no irq for rtc tick\n"); | ||
251 | return -ENOENT; | ||
252 | } | ||
253 | |||
254 | puv3_rtc_alarmno = platform_get_irq(pdev, 0); | ||
255 | if (puv3_rtc_alarmno < 0) { | ||
256 | dev_err(&pdev->dev, "no irq for alarm\n"); | ||
257 | return -ENOENT; | ||
258 | } | ||
259 | |||
260 | pr_debug("PKUnity_rtc: tick irq %d, alarm irq %d\n", | ||
261 | puv3_rtc_tickno, puv3_rtc_alarmno); | ||
262 | |||
263 | /* get the memory region */ | ||
264 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
265 | if (res == NULL) { | ||
266 | dev_err(&pdev->dev, "failed to get memory region resource\n"); | ||
267 | return -ENOENT; | ||
268 | } | ||
269 | |||
270 | puv3_rtc_mem = request_mem_region(res->start, | ||
271 | res->end-res->start+1, | ||
272 | pdev->name); | ||
273 | |||
274 | if (puv3_rtc_mem == NULL) { | ||
275 | dev_err(&pdev->dev, "failed to reserve memory region\n"); | ||
276 | ret = -ENOENT; | ||
277 | goto err_nores; | ||
278 | } | ||
279 | |||
280 | puv3_rtc_enable(pdev, 1); | ||
281 | |||
282 | /* register RTC and exit */ | ||
283 | rtc = rtc_device_register("pkunity", &pdev->dev, &puv3_rtcops, | ||
284 | THIS_MODULE); | ||
285 | |||
286 | if (IS_ERR(rtc)) { | ||
287 | dev_err(&pdev->dev, "cannot attach rtc\n"); | ||
288 | ret = PTR_ERR(rtc); | ||
289 | goto err_nortc; | ||
290 | } | ||
291 | |||
292 | /* platform setup code should have handled this; sigh */ | ||
293 | if (!device_can_wakeup(&pdev->dev)) | ||
294 | device_init_wakeup(&pdev->dev, 1); | ||
295 | |||
296 | platform_set_drvdata(pdev, rtc); | ||
297 | return 0; | ||
298 | |||
299 | err_nortc: | ||
300 | puv3_rtc_enable(pdev, 0); | ||
301 | release_resource(puv3_rtc_mem); | ||
302 | |||
303 | err_nores: | ||
304 | return ret; | ||
305 | } | ||
306 | |||
307 | #ifdef CONFIG_PM | ||
308 | |||
309 | static int ticnt_save; | ||
310 | |||
311 | static int puv3_rtc_suspend(struct platform_device *pdev, pm_message_t state) | ||
312 | { | ||
313 | /* save RTAR for anyone using periodic interrupts */ | ||
314 | ticnt_save = readl(RTC_RTAR); | ||
315 | puv3_rtc_enable(pdev, 0); | ||
316 | return 0; | ||
317 | } | ||
318 | |||
319 | static int puv3_rtc_resume(struct platform_device *pdev) | ||
320 | { | ||
321 | puv3_rtc_enable(pdev, 1); | ||
322 | writel(ticnt_save, RTC_RTAR); | ||
323 | return 0; | ||
324 | } | ||
325 | #else | ||
326 | #define puv3_rtc_suspend NULL | ||
327 | #define puv3_rtc_resume NULL | ||
328 | #endif | ||
329 | |||
330 | static struct platform_driver puv3_rtcdrv = { | ||
331 | .probe = puv3_rtc_probe, | ||
332 | .remove = __devexit_p(puv3_rtc_remove), | ||
333 | .suspend = puv3_rtc_suspend, | ||
334 | .resume = puv3_rtc_resume, | ||
335 | .driver = { | ||
336 | .name = "PKUnity-v3-RTC", | ||
337 | .owner = THIS_MODULE, | ||
338 | } | ||
339 | }; | ||
340 | |||
341 | static char __initdata banner[] = "PKUnity-v3 RTC, (c) 2009 PKUnity Co.\n"; | ||
342 | |||
343 | static int __init puv3_rtc_init(void) | ||
344 | { | ||
345 | printk(banner); | ||
346 | return platform_driver_register(&puv3_rtcdrv); | ||
347 | } | ||
348 | |||
349 | static void __exit puv3_rtc_exit(void) | ||
350 | { | ||
351 | platform_driver_unregister(&puv3_rtcdrv); | ||
352 | } | ||
353 | |||
354 | module_init(puv3_rtc_init); | ||
355 | module_exit(puv3_rtc_exit); | ||
356 | |||
357 | MODULE_DESCRIPTION("RTC Driver for the PKUnity v3 chip"); | ||
358 | MODULE_AUTHOR("Hu Dongliang"); | ||
359 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c index 29e867a1aaa8..fc9f4991574b 100644 --- a/drivers/rtc/rtc-pxa.c +++ b/drivers/rtc/rtc-pxa.c | |||
@@ -209,32 +209,6 @@ static void pxa_rtc_release(struct device *dev) | |||
209 | free_irq(pxa_rtc->irq_1Hz, dev); | 209 | free_irq(pxa_rtc->irq_1Hz, dev); |
210 | } | 210 | } |
211 | 211 | ||
212 | static int pxa_periodic_irq_set_freq(struct device *dev, int freq) | ||
213 | { | ||
214 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | ||
215 | int period_ms; | ||
216 | |||
217 | if (freq < 1 || freq > MAXFREQ_PERIODIC) | ||
218 | return -EINVAL; | ||
219 | |||
220 | period_ms = 1000 / freq; | ||
221 | rtc_writel(pxa_rtc, PIAR, period_ms); | ||
222 | |||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | static int pxa_periodic_irq_set_state(struct device *dev, int enabled) | ||
227 | { | ||
228 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | ||
229 | |||
230 | if (enabled) | ||
231 | rtsr_set_bits(pxa_rtc, RTSR_PIALE | RTSR_PICE); | ||
232 | else | ||
233 | rtsr_clear_bits(pxa_rtc, RTSR_PIALE | RTSR_PICE); | ||
234 | |||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | static int pxa_alarm_irq_enable(struct device *dev, unsigned int enabled) | 212 | static int pxa_alarm_irq_enable(struct device *dev, unsigned int enabled) |
239 | { | 213 | { |
240 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | 214 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); |
@@ -250,21 +224,6 @@ static int pxa_alarm_irq_enable(struct device *dev, unsigned int enabled) | |||
250 | return 0; | 224 | return 0; |
251 | } | 225 | } |
252 | 226 | ||
253 | static int pxa_update_irq_enable(struct device *dev, unsigned int enabled) | ||
254 | { | ||
255 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | ||
256 | |||
257 | spin_lock_irq(&pxa_rtc->lock); | ||
258 | |||
259 | if (enabled) | ||
260 | rtsr_set_bits(pxa_rtc, RTSR_HZE); | ||
261 | else | ||
262 | rtsr_clear_bits(pxa_rtc, RTSR_HZE); | ||
263 | |||
264 | spin_unlock_irq(&pxa_rtc->lock); | ||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | static int pxa_rtc_read_time(struct device *dev, struct rtc_time *tm) | 227 | static int pxa_rtc_read_time(struct device *dev, struct rtc_time *tm) |
269 | { | 228 | { |
270 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | 229 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); |
@@ -346,10 +305,7 @@ static const struct rtc_class_ops pxa_rtc_ops = { | |||
346 | .read_alarm = pxa_rtc_read_alarm, | 305 | .read_alarm = pxa_rtc_read_alarm, |
347 | .set_alarm = pxa_rtc_set_alarm, | 306 | .set_alarm = pxa_rtc_set_alarm, |
348 | .alarm_irq_enable = pxa_alarm_irq_enable, | 307 | .alarm_irq_enable = pxa_alarm_irq_enable, |
349 | .update_irq_enable = pxa_update_irq_enable, | ||
350 | .proc = pxa_rtc_proc, | 308 | .proc = pxa_rtc_proc, |
351 | .irq_set_state = pxa_periodic_irq_set_state, | ||
352 | .irq_set_freq = pxa_periodic_irq_set_freq, | ||
353 | }; | 309 | }; |
354 | 310 | ||
355 | static int __init pxa_rtc_probe(struct platform_device *pdev) | 311 | static int __init pxa_rtc_probe(struct platform_device *pdev) |
diff --git a/drivers/rtc/rtc-rp5c01.c b/drivers/rtc/rtc-rp5c01.c index 36eb66184461..359da6d020b9 100644 --- a/drivers/rtc/rtc-rp5c01.c +++ b/drivers/rtc/rtc-rp5c01.c | |||
@@ -76,7 +76,7 @@ static inline unsigned int rp5c01_read(struct rp5c01_priv *priv, | |||
76 | static inline void rp5c01_write(struct rp5c01_priv *priv, unsigned int val, | 76 | static inline void rp5c01_write(struct rp5c01_priv *priv, unsigned int val, |
77 | unsigned int reg) | 77 | unsigned int reg) |
78 | { | 78 | { |
79 | return __raw_writel(val, &priv->regs[reg]); | 79 | __raw_writel(val, &priv->regs[reg]); |
80 | } | 80 | } |
81 | 81 | ||
82 | static void rp5c01_lock(struct rp5c01_priv *priv) | 82 | static void rp5c01_lock(struct rp5c01_priv *priv) |
@@ -249,15 +249,15 @@ static int __init rp5c01_rtc_probe(struct platform_device *dev) | |||
249 | 249 | ||
250 | spin_lock_init(&priv->lock); | 250 | spin_lock_init(&priv->lock); |
251 | 251 | ||
252 | platform_set_drvdata(dev, priv); | ||
253 | |||
252 | rtc = rtc_device_register("rtc-rp5c01", &dev->dev, &rp5c01_rtc_ops, | 254 | rtc = rtc_device_register("rtc-rp5c01", &dev->dev, &rp5c01_rtc_ops, |
253 | THIS_MODULE); | 255 | THIS_MODULE); |
254 | if (IS_ERR(rtc)) { | 256 | if (IS_ERR(rtc)) { |
255 | error = PTR_ERR(rtc); | 257 | error = PTR_ERR(rtc); |
256 | goto out_unmap; | 258 | goto out_unmap; |
257 | } | 259 | } |
258 | |||
259 | priv->rtc = rtc; | 260 | priv->rtc = rtc; |
260 | platform_set_drvdata(dev, priv); | ||
261 | 261 | ||
262 | error = sysfs_create_bin_file(&dev->dev.kobj, &priv->nvram_attr); | 262 | error = sysfs_create_bin_file(&dev->dev.kobj, &priv->nvram_attr); |
263 | if (error) | 263 | if (error) |
@@ -268,6 +268,7 @@ static int __init rp5c01_rtc_probe(struct platform_device *dev) | |||
268 | out_unregister: | 268 | out_unregister: |
269 | rtc_device_unregister(rtc); | 269 | rtc_device_unregister(rtc); |
270 | out_unmap: | 270 | out_unmap: |
271 | platform_set_drvdata(dev, NULL); | ||
271 | iounmap(priv->regs); | 272 | iounmap(priv->regs); |
272 | out_free_priv: | 273 | out_free_priv: |
273 | kfree(priv); | 274 | kfree(priv); |
diff --git a/drivers/rtc/rtc-rs5c313.c b/drivers/rtc/rtc-rs5c313.c index e6ea3f5ee1eb..e3ff179b99ca 100644 --- a/drivers/rtc/rtc-rs5c313.c +++ b/drivers/rtc/rtc-rs5c313.c | |||
@@ -80,21 +80,21 @@ | |||
80 | /* SCSPTR1 data */ | 80 | /* SCSPTR1 data */ |
81 | unsigned char scsptr1_data; | 81 | unsigned char scsptr1_data; |
82 | 82 | ||
83 | #define RS5C313_CEENABLE ctrl_outb(RS5C313_CE_RTCCE, RS5C313_CE); | 83 | #define RS5C313_CEENABLE __raw_writeb(RS5C313_CE_RTCCE, RS5C313_CE); |
84 | #define RS5C313_CEDISABLE ctrl_outb(0x00, RS5C313_CE) | 84 | #define RS5C313_CEDISABLE __raw_writeb(0x00, RS5C313_CE) |
85 | #define RS5C313_MISCOP ctrl_outb(0x02, 0xB0000008) | 85 | #define RS5C313_MISCOP __raw_writeb(0x02, 0xB0000008) |
86 | 86 | ||
87 | static void rs5c313_init_port(void) | 87 | static void rs5c313_init_port(void) |
88 | { | 88 | { |
89 | /* Set SCK as I/O port and Initialize SCSPTR1 data & I/O port. */ | 89 | /* Set SCK as I/O port and Initialize SCSPTR1 data & I/O port. */ |
90 | ctrl_outb(ctrl_inb(SCSMR1) & ~SCSMR1_CA, SCSMR1); | 90 | __raw_writeb(__raw_readb(SCSMR1) & ~SCSMR1_CA, SCSMR1); |
91 | ctrl_outb(ctrl_inb(SCSCR1) & ~SCSCR1_CKE, SCSCR1); | 91 | __raw_writeb(__raw_readb(SCSCR1) & ~SCSCR1_CKE, SCSCR1); |
92 | 92 | ||
93 | /* And Initialize SCL for RS5C313 clock */ | 93 | /* And Initialize SCL for RS5C313 clock */ |
94 | scsptr1_data = ctrl_inb(SCSPTR1) | SCL; /* SCL:H */ | 94 | scsptr1_data = __raw_readb(SCSPTR1) | SCL; /* SCL:H */ |
95 | ctrl_outb(scsptr1_data, SCSPTR1); | 95 | __raw_writeb(scsptr1_data, SCSPTR1); |
96 | scsptr1_data = ctrl_inb(SCSPTR1) | SCL_OEN; /* SCL output enable */ | 96 | scsptr1_data = __raw_readb(SCSPTR1) | SCL_OEN; /* SCL output enable */ |
97 | ctrl_outb(scsptr1_data, SCSPTR1); | 97 | __raw_writeb(scsptr1_data, SCSPTR1); |
98 | RS5C313_CEDISABLE; /* CE:L */ | 98 | RS5C313_CEDISABLE; /* CE:L */ |
99 | } | 99 | } |
100 | 100 | ||
@@ -106,21 +106,21 @@ static void rs5c313_write_data(unsigned char data) | |||
106 | /* SDA:Write Data */ | 106 | /* SDA:Write Data */ |
107 | scsptr1_data = (scsptr1_data & ~SDA) | | 107 | scsptr1_data = (scsptr1_data & ~SDA) | |
108 | ((((0x80 >> i) & data) >> (7 - i)) << 2); | 108 | ((((0x80 >> i) & data) >> (7 - i)) << 2); |
109 | ctrl_outb(scsptr1_data, SCSPTR1); | 109 | __raw_writeb(scsptr1_data, SCSPTR1); |
110 | if (i == 0) { | 110 | if (i == 0) { |
111 | scsptr1_data |= SDA_OEN; /* SDA:output enable */ | 111 | scsptr1_data |= SDA_OEN; /* SDA:output enable */ |
112 | ctrl_outb(scsptr1_data, SCSPTR1); | 112 | __raw_writeb(scsptr1_data, SCSPTR1); |
113 | } | 113 | } |
114 | ndelay(700); | 114 | ndelay(700); |
115 | scsptr1_data &= ~SCL; /* SCL:L */ | 115 | scsptr1_data &= ~SCL; /* SCL:L */ |
116 | ctrl_outb(scsptr1_data, SCSPTR1); | 116 | __raw_writeb(scsptr1_data, SCSPTR1); |
117 | ndelay(700); | 117 | ndelay(700); |
118 | scsptr1_data |= SCL; /* SCL:H */ | 118 | scsptr1_data |= SCL; /* SCL:H */ |
119 | ctrl_outb(scsptr1_data, SCSPTR1); | 119 | __raw_writeb(scsptr1_data, SCSPTR1); |
120 | } | 120 | } |
121 | 121 | ||
122 | scsptr1_data &= ~SDA_OEN; /* SDA:output disable */ | 122 | scsptr1_data &= ~SDA_OEN; /* SDA:output disable */ |
123 | ctrl_outb(scsptr1_data, SCSPTR1); | 123 | __raw_writeb(scsptr1_data, SCSPTR1); |
124 | } | 124 | } |
125 | 125 | ||
126 | static unsigned char rs5c313_read_data(void) | 126 | static unsigned char rs5c313_read_data(void) |
@@ -131,12 +131,12 @@ static unsigned char rs5c313_read_data(void) | |||
131 | for (i = 0; i < 8; i++) { | 131 | for (i = 0; i < 8; i++) { |
132 | ndelay(700); | 132 | ndelay(700); |
133 | /* SDA:Read Data */ | 133 | /* SDA:Read Data */ |
134 | data |= ((ctrl_inb(SCSPTR1) & SDA) >> 2) << (7 - i); | 134 | data |= ((__raw_readb(SCSPTR1) & SDA) >> 2) << (7 - i); |
135 | scsptr1_data &= ~SCL; /* SCL:L */ | 135 | scsptr1_data &= ~SCL; /* SCL:L */ |
136 | ctrl_outb(scsptr1_data, SCSPTR1); | 136 | __raw_writeb(scsptr1_data, SCSPTR1); |
137 | ndelay(700); | 137 | ndelay(700); |
138 | scsptr1_data |= SCL; /* SCL:H */ | 138 | scsptr1_data |= SCL; /* SCL:H */ |
139 | ctrl_outb(scsptr1_data, SCSPTR1); | 139 | __raw_writeb(scsptr1_data, SCSPTR1); |
140 | } | 140 | } |
141 | return data & 0x0F; | 141 | return data & 0x0F; |
142 | } | 142 | } |
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index 90cf0a6ff23e..85c1b848dd72 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c | |||
@@ -207,7 +207,7 @@ static int rs5c372_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
207 | static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm) | 207 | static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm) |
208 | { | 208 | { |
209 | struct rs5c372 *rs5c = i2c_get_clientdata(client); | 209 | struct rs5c372 *rs5c = i2c_get_clientdata(client); |
210 | unsigned char buf[8]; | 210 | unsigned char buf[7]; |
211 | int addr; | 211 | int addr; |
212 | 212 | ||
213 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d " | 213 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d " |
@@ -281,10 +281,8 @@ static int rs5c372_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
281 | return rs5c372_set_datetime(to_i2c_client(dev), tm); | 281 | return rs5c372_set_datetime(to_i2c_client(dev), tm); |
282 | } | 282 | } |
283 | 283 | ||
284 | #if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE) | ||
285 | 284 | ||
286 | static int | 285 | static int rs5c_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) |
287 | rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | ||
288 | { | 286 | { |
289 | struct i2c_client *client = to_i2c_client(dev); | 287 | struct i2c_client *client = to_i2c_client(dev); |
290 | struct rs5c372 *rs5c = i2c_get_clientdata(client); | 288 | struct rs5c372 *rs5c = i2c_get_clientdata(client); |
@@ -292,45 +290,19 @@ rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | |||
292 | int status, addr; | 290 | int status, addr; |
293 | 291 | ||
294 | buf = rs5c->regs[RS5C_REG_CTRL1]; | 292 | buf = rs5c->regs[RS5C_REG_CTRL1]; |
295 | switch (cmd) { | 293 | |
296 | case RTC_UIE_OFF: | 294 | if (!rs5c->has_irq) |
297 | case RTC_UIE_ON: | 295 | return -EINVAL; |
298 | /* some 327a modes use a different IRQ pin for 1Hz irqs */ | ||
299 | if (rs5c->type == rtc_rs5c372a | ||
300 | && (buf & RS5C372A_CTRL1_SL1)) | ||
301 | return -ENOIOCTLCMD; | ||
302 | case RTC_AIE_OFF: | ||
303 | case RTC_AIE_ON: | ||
304 | /* these irq management calls only make sense for chips | ||
305 | * which are wired up to an IRQ. | ||
306 | */ | ||
307 | if (!rs5c->has_irq) | ||
308 | return -ENOIOCTLCMD; | ||
309 | break; | ||
310 | default: | ||
311 | return -ENOIOCTLCMD; | ||
312 | } | ||
313 | 296 | ||
314 | status = rs5c_get_regs(rs5c); | 297 | status = rs5c_get_regs(rs5c); |
315 | if (status < 0) | 298 | if (status < 0) |
316 | return status; | 299 | return status; |
317 | 300 | ||
318 | addr = RS5C_ADDR(RS5C_REG_CTRL1); | 301 | addr = RS5C_ADDR(RS5C_REG_CTRL1); |
319 | switch (cmd) { | 302 | if (enabled) |
320 | case RTC_AIE_OFF: /* alarm off */ | ||
321 | buf &= ~RS5C_CTRL1_AALE; | ||
322 | break; | ||
323 | case RTC_AIE_ON: /* alarm on */ | ||
324 | buf |= RS5C_CTRL1_AALE; | 303 | buf |= RS5C_CTRL1_AALE; |
325 | break; | 304 | else |
326 | case RTC_UIE_OFF: /* update off */ | 305 | buf &= ~RS5C_CTRL1_AALE; |
327 | buf &= ~RS5C_CTRL1_CT_MASK; | ||
328 | break; | ||
329 | case RTC_UIE_ON: /* update on */ | ||
330 | buf &= ~RS5C_CTRL1_CT_MASK; | ||
331 | buf |= RS5C_CTRL1_CT4; | ||
332 | break; | ||
333 | } | ||
334 | 306 | ||
335 | if (i2c_smbus_write_byte_data(client, addr, buf) < 0) { | 307 | if (i2c_smbus_write_byte_data(client, addr, buf) < 0) { |
336 | printk(KERN_WARNING "%s: can't update alarm\n", | 308 | printk(KERN_WARNING "%s: can't update alarm\n", |
@@ -342,10 +314,6 @@ rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | |||
342 | return status; | 314 | return status; |
343 | } | 315 | } |
344 | 316 | ||
345 | #else | ||
346 | #define rs5c_rtc_ioctl NULL | ||
347 | #endif | ||
348 | |||
349 | 317 | ||
350 | /* NOTE: Since RTC_WKALM_{RD,SET} were originally defined for EFI, | 318 | /* NOTE: Since RTC_WKALM_{RD,SET} were originally defined for EFI, |
351 | * which only exposes a polled programming interface; and since | 319 | * which only exposes a polled programming interface; and since |
@@ -461,11 +429,11 @@ static int rs5c372_rtc_proc(struct device *dev, struct seq_file *seq) | |||
461 | 429 | ||
462 | static const struct rtc_class_ops rs5c372_rtc_ops = { | 430 | static const struct rtc_class_ops rs5c372_rtc_ops = { |
463 | .proc = rs5c372_rtc_proc, | 431 | .proc = rs5c372_rtc_proc, |
464 | .ioctl = rs5c_rtc_ioctl, | ||
465 | .read_time = rs5c372_rtc_read_time, | 432 | .read_time = rs5c372_rtc_read_time, |
466 | .set_time = rs5c372_rtc_set_time, | 433 | .set_time = rs5c372_rtc_set_time, |
467 | .read_alarm = rs5c_read_alarm, | 434 | .read_alarm = rs5c_read_alarm, |
468 | .set_alarm = rs5c_set_alarm, | 435 | .set_alarm = rs5c_set_alarm, |
436 | .alarm_irq_enable = rs5c_rtc_alarm_irq_enable, | ||
469 | }; | 437 | }; |
470 | 438 | ||
471 | #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) | 439 | #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) |
diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c new file mode 100644 index 000000000000..ea09ff211dc6 --- /dev/null +++ b/drivers/rtc/rtc-rv3029c2.c | |||
@@ -0,0 +1,454 @@ | |||
1 | /* | ||
2 | * Micro Crystal RV-3029C2 rtc class driver | ||
3 | * | ||
4 | * Author: Gregory Hermant <gregory.hermant@calao-systems.com> | ||
5 | * | ||
6 | * based on previously existing rtc class drivers | ||
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 | * NOTE: Currently this driver only supports the bare minimum for read | ||
13 | * and write the RTC and alarms. The extra features provided by this chip | ||
14 | * (trickle charger, eeprom, T° compensation) are unavailable. | ||
15 | */ | ||
16 | |||
17 | #include <linux/module.h> | ||
18 | #include <linux/i2c.h> | ||
19 | #include <linux/bcd.h> | ||
20 | #include <linux/rtc.h> | ||
21 | |||
22 | /* Register map */ | ||
23 | /* control section */ | ||
24 | #define RV3029C2_ONOFF_CTRL 0x00 | ||
25 | #define RV3029C2_IRQ_CTRL 0x01 | ||
26 | #define RV3029C2_IRQ_CTRL_AIE (1 << 0) | ||
27 | #define RV3029C2_IRQ_FLAGS 0x02 | ||
28 | #define RV3029C2_IRQ_FLAGS_AF (1 << 0) | ||
29 | #define RV3029C2_STATUS 0x03 | ||
30 | #define RV3029C2_STATUS_VLOW1 (1 << 2) | ||
31 | #define RV3029C2_STATUS_VLOW2 (1 << 3) | ||
32 | #define RV3029C2_STATUS_SR (1 << 4) | ||
33 | #define RV3029C2_STATUS_PON (1 << 5) | ||
34 | #define RV3029C2_STATUS_EEBUSY (1 << 7) | ||
35 | #define RV3029C2_RST_CTRL 0x04 | ||
36 | #define RV3029C2_CONTROL_SECTION_LEN 0x05 | ||
37 | |||
38 | /* watch section */ | ||
39 | #define RV3029C2_W_SEC 0x08 | ||
40 | #define RV3029C2_W_MINUTES 0x09 | ||
41 | #define RV3029C2_W_HOURS 0x0A | ||
42 | #define RV3029C2_REG_HR_12_24 (1<<6) /* 24h/12h mode */ | ||
43 | #define RV3029C2_REG_HR_PM (1<<5) /* PM/AM bit in 12h mode */ | ||
44 | #define RV3029C2_W_DATE 0x0B | ||
45 | #define RV3029C2_W_DAYS 0x0C | ||
46 | #define RV3029C2_W_MONTHS 0x0D | ||
47 | #define RV3029C2_W_YEARS 0x0E | ||
48 | #define RV3029C2_WATCH_SECTION_LEN 0x07 | ||
49 | |||
50 | /* alarm section */ | ||
51 | #define RV3029C2_A_SC 0x10 | ||
52 | #define RV3029C2_A_MN 0x11 | ||
53 | #define RV3029C2_A_HR 0x12 | ||
54 | #define RV3029C2_A_DT 0x13 | ||
55 | #define RV3029C2_A_DW 0x14 | ||
56 | #define RV3029C2_A_MO 0x15 | ||
57 | #define RV3029C2_A_YR 0x16 | ||
58 | #define RV3029C2_ALARM_SECTION_LEN 0x07 | ||
59 | |||
60 | /* timer section */ | ||
61 | #define RV3029C2_TIMER_LOW 0x18 | ||
62 | #define RV3029C2_TIMER_HIGH 0x19 | ||
63 | |||
64 | /* temperature section */ | ||
65 | #define RV3029C2_TEMP_PAGE 0x20 | ||
66 | |||
67 | /* eeprom data section */ | ||
68 | #define RV3029C2_E2P_EEDATA1 0x28 | ||
69 | #define RV3029C2_E2P_EEDATA2 0x29 | ||
70 | |||
71 | /* eeprom control section */ | ||
72 | #define RV3029C2_CONTROL_E2P_EECTRL 0x30 | ||
73 | #define RV3029C2_TRICKLE_1K (1<<0) /* 1K resistance */ | ||
74 | #define RV3029C2_TRICKLE_5K (1<<1) /* 5K resistance */ | ||
75 | #define RV3029C2_TRICKLE_20K (1<<2) /* 20K resistance */ | ||
76 | #define RV3029C2_TRICKLE_80K (1<<3) /* 80K resistance */ | ||
77 | #define RV3029C2_CONTROL_E2P_XTALOFFSET 0x31 | ||
78 | #define RV3029C2_CONTROL_E2P_QCOEF 0x32 | ||
79 | #define RV3029C2_CONTROL_E2P_TURNOVER 0x33 | ||
80 | |||
81 | /* user ram section */ | ||
82 | #define RV3029C2_USR1_RAM_PAGE 0x38 | ||
83 | #define RV3029C2_USR1_SECTION_LEN 0x04 | ||
84 | #define RV3029C2_USR2_RAM_PAGE 0x3C | ||
85 | #define RV3029C2_USR2_SECTION_LEN 0x04 | ||
86 | |||
87 | static int | ||
88 | rv3029c2_i2c_read_regs(struct i2c_client *client, u8 reg, u8 *buf, | ||
89 | unsigned len) | ||
90 | { | ||
91 | int ret; | ||
92 | |||
93 | if ((reg > RV3029C2_USR1_RAM_PAGE + 7) || | ||
94 | (reg + len > RV3029C2_USR1_RAM_PAGE + 8)) | ||
95 | return -EINVAL; | ||
96 | |||
97 | ret = i2c_smbus_read_i2c_block_data(client, reg, len, buf); | ||
98 | if (ret < 0) | ||
99 | return ret; | ||
100 | if (ret < len) | ||
101 | return -EIO; | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static int | ||
106 | rv3029c2_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[], | ||
107 | unsigned len) | ||
108 | { | ||
109 | if ((reg > RV3029C2_USR1_RAM_PAGE + 7) || | ||
110 | (reg + len > RV3029C2_USR1_RAM_PAGE + 8)) | ||
111 | return -EINVAL; | ||
112 | |||
113 | return i2c_smbus_write_i2c_block_data(client, reg, len, buf); | ||
114 | } | ||
115 | |||
116 | static int | ||
117 | rv3029c2_i2c_get_sr(struct i2c_client *client, u8 *buf) | ||
118 | { | ||
119 | int ret = rv3029c2_i2c_read_regs(client, RV3029C2_STATUS, buf, 1); | ||
120 | |||
121 | if (ret < 0) | ||
122 | return -EIO; | ||
123 | dev_dbg(&client->dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]); | ||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static int | ||
128 | rv3029c2_i2c_set_sr(struct i2c_client *client, u8 val) | ||
129 | { | ||
130 | u8 buf[1]; | ||
131 | int sr; | ||
132 | |||
133 | buf[0] = val; | ||
134 | sr = rv3029c2_i2c_write_regs(client, RV3029C2_STATUS, buf, 1); | ||
135 | dev_dbg(&client->dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]); | ||
136 | if (sr < 0) | ||
137 | return -EIO; | ||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | static int | ||
142 | rv3029c2_i2c_read_time(struct i2c_client *client, struct rtc_time *tm) | ||
143 | { | ||
144 | u8 buf[1]; | ||
145 | int ret; | ||
146 | u8 regs[RV3029C2_WATCH_SECTION_LEN] = { 0, }; | ||
147 | |||
148 | ret = rv3029c2_i2c_get_sr(client, buf); | ||
149 | if (ret < 0) { | ||
150 | dev_err(&client->dev, "%s: reading SR failed\n", __func__); | ||
151 | return -EIO; | ||
152 | } | ||
153 | |||
154 | ret = rv3029c2_i2c_read_regs(client, RV3029C2_W_SEC , regs, | ||
155 | RV3029C2_WATCH_SECTION_LEN); | ||
156 | if (ret < 0) { | ||
157 | dev_err(&client->dev, "%s: reading RTC section failed\n", | ||
158 | __func__); | ||
159 | return ret; | ||
160 | } | ||
161 | |||
162 | tm->tm_sec = bcd2bin(regs[RV3029C2_W_SEC-RV3029C2_W_SEC]); | ||
163 | tm->tm_min = bcd2bin(regs[RV3029C2_W_MINUTES-RV3029C2_W_SEC]); | ||
164 | |||
165 | /* HR field has a more complex interpretation */ | ||
166 | { | ||
167 | const u8 _hr = regs[RV3029C2_W_HOURS-RV3029C2_W_SEC]; | ||
168 | if (_hr & RV3029C2_REG_HR_12_24) { | ||
169 | /* 12h format */ | ||
170 | tm->tm_hour = bcd2bin(_hr & 0x1f); | ||
171 | if (_hr & RV3029C2_REG_HR_PM) /* PM flag set */ | ||
172 | tm->tm_hour += 12; | ||
173 | } else /* 24h format */ | ||
174 | tm->tm_hour = bcd2bin(_hr & 0x3f); | ||
175 | } | ||
176 | |||
177 | tm->tm_mday = bcd2bin(regs[RV3029C2_W_DATE-RV3029C2_W_SEC]); | ||
178 | tm->tm_mon = bcd2bin(regs[RV3029C2_W_MONTHS-RV3029C2_W_SEC]) - 1; | ||
179 | tm->tm_year = bcd2bin(regs[RV3029C2_W_YEARS-RV3029C2_W_SEC]) + 100; | ||
180 | tm->tm_wday = bcd2bin(regs[RV3029C2_W_DAYS-RV3029C2_W_SEC]) - 1; | ||
181 | |||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | static int rv3029c2_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
186 | { | ||
187 | return rv3029c2_i2c_read_time(to_i2c_client(dev), tm); | ||
188 | } | ||
189 | |||
190 | static int | ||
191 | rv3029c2_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm) | ||
192 | { | ||
193 | struct rtc_time *const tm = &alarm->time; | ||
194 | int ret; | ||
195 | u8 regs[8]; | ||
196 | |||
197 | ret = rv3029c2_i2c_get_sr(client, regs); | ||
198 | if (ret < 0) { | ||
199 | dev_err(&client->dev, "%s: reading SR failed\n", __func__); | ||
200 | return -EIO; | ||
201 | } | ||
202 | |||
203 | ret = rv3029c2_i2c_read_regs(client, RV3029C2_A_SC, regs, | ||
204 | RV3029C2_ALARM_SECTION_LEN); | ||
205 | |||
206 | if (ret < 0) { | ||
207 | dev_err(&client->dev, "%s: reading alarm section failed\n", | ||
208 | __func__); | ||
209 | return ret; | ||
210 | } | ||
211 | |||
212 | tm->tm_sec = bcd2bin(regs[RV3029C2_A_SC-RV3029C2_A_SC] & 0x7f); | ||
213 | tm->tm_min = bcd2bin(regs[RV3029C2_A_MN-RV3029C2_A_SC] & 0x7f); | ||
214 | tm->tm_hour = bcd2bin(regs[RV3029C2_A_HR-RV3029C2_A_SC] & 0x3f); | ||
215 | tm->tm_mday = bcd2bin(regs[RV3029C2_A_DT-RV3029C2_A_SC] & 0x3f); | ||
216 | tm->tm_mon = bcd2bin(regs[RV3029C2_A_MO-RV3029C2_A_SC] & 0x1f) - 1; | ||
217 | tm->tm_year = bcd2bin(regs[RV3029C2_A_YR-RV3029C2_A_SC] & 0x7f) + 100; | ||
218 | tm->tm_wday = bcd2bin(regs[RV3029C2_A_DW-RV3029C2_A_SC] & 0x07) - 1; | ||
219 | |||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | static int | ||
224 | rv3029c2_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | ||
225 | { | ||
226 | return rv3029c2_i2c_read_alarm(to_i2c_client(dev), alarm); | ||
227 | } | ||
228 | |||
229 | static int rv3029c2_rtc_i2c_alarm_set_irq(struct i2c_client *client, | ||
230 | int enable) | ||
231 | { | ||
232 | int ret; | ||
233 | u8 buf[1]; | ||
234 | |||
235 | /* enable AIE irq */ | ||
236 | ret = rv3029c2_i2c_read_regs(client, RV3029C2_IRQ_CTRL, buf, 1); | ||
237 | if (ret < 0) { | ||
238 | dev_err(&client->dev, "can't read INT reg\n"); | ||
239 | return ret; | ||
240 | } | ||
241 | if (enable) | ||
242 | buf[0] |= RV3029C2_IRQ_CTRL_AIE; | ||
243 | else | ||
244 | buf[0] &= ~RV3029C2_IRQ_CTRL_AIE; | ||
245 | |||
246 | ret = rv3029c2_i2c_write_regs(client, RV3029C2_IRQ_CTRL, buf, 1); | ||
247 | if (ret < 0) { | ||
248 | dev_err(&client->dev, "can't set INT reg\n"); | ||
249 | return ret; | ||
250 | } | ||
251 | |||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | static int rv3029c2_rtc_i2c_set_alarm(struct i2c_client *client, | ||
256 | struct rtc_wkalrm *alarm) | ||
257 | { | ||
258 | struct rtc_time *const tm = &alarm->time; | ||
259 | int ret; | ||
260 | u8 regs[8]; | ||
261 | |||
262 | /* | ||
263 | * The clock has an 8 bit wide bcd-coded register (they never learn) | ||
264 | * for the year. tm_year is an offset from 1900 and we are interested | ||
265 | * in the 2000-2099 range, so any value less than 100 is invalid. | ||
266 | */ | ||
267 | if (tm->tm_year < 100) | ||
268 | return -EINVAL; | ||
269 | |||
270 | ret = rv3029c2_i2c_get_sr(client, regs); | ||
271 | if (ret < 0) { | ||
272 | dev_err(&client->dev, "%s: reading SR failed\n", __func__); | ||
273 | return -EIO; | ||
274 | } | ||
275 | regs[RV3029C2_A_SC-RV3029C2_A_SC] = bin2bcd(tm->tm_sec & 0x7f); | ||
276 | regs[RV3029C2_A_MN-RV3029C2_A_SC] = bin2bcd(tm->tm_min & 0x7f); | ||
277 | regs[RV3029C2_A_HR-RV3029C2_A_SC] = bin2bcd(tm->tm_hour & 0x3f); | ||
278 | regs[RV3029C2_A_DT-RV3029C2_A_SC] = bin2bcd(tm->tm_mday & 0x3f); | ||
279 | regs[RV3029C2_A_MO-RV3029C2_A_SC] = bin2bcd((tm->tm_mon & 0x1f) - 1); | ||
280 | regs[RV3029C2_A_DW-RV3029C2_A_SC] = bin2bcd((tm->tm_wday & 7) - 1); | ||
281 | regs[RV3029C2_A_YR-RV3029C2_A_SC] = bin2bcd((tm->tm_year & 0x7f) - 100); | ||
282 | |||
283 | ret = rv3029c2_i2c_write_regs(client, RV3029C2_A_SC, regs, | ||
284 | RV3029C2_ALARM_SECTION_LEN); | ||
285 | if (ret < 0) | ||
286 | return ret; | ||
287 | |||
288 | if (alarm->enabled) { | ||
289 | u8 buf[1]; | ||
290 | |||
291 | /* clear AF flag */ | ||
292 | ret = rv3029c2_i2c_read_regs(client, RV3029C2_IRQ_FLAGS, | ||
293 | buf, 1); | ||
294 | if (ret < 0) { | ||
295 | dev_err(&client->dev, "can't read alarm flag\n"); | ||
296 | return ret; | ||
297 | } | ||
298 | buf[0] &= ~RV3029C2_IRQ_FLAGS_AF; | ||
299 | ret = rv3029c2_i2c_write_regs(client, RV3029C2_IRQ_FLAGS, | ||
300 | buf, 1); | ||
301 | if (ret < 0) { | ||
302 | dev_err(&client->dev, "can't set alarm flag\n"); | ||
303 | return ret; | ||
304 | } | ||
305 | /* enable AIE irq */ | ||
306 | ret = rv3029c2_rtc_i2c_alarm_set_irq(client, 1); | ||
307 | if (ret) | ||
308 | return ret; | ||
309 | |||
310 | dev_dbg(&client->dev, "alarm IRQ armed\n"); | ||
311 | } else { | ||
312 | /* disable AIE irq */ | ||
313 | ret = rv3029c2_rtc_i2c_alarm_set_irq(client, 1); | ||
314 | if (ret) | ||
315 | return ret; | ||
316 | |||
317 | dev_dbg(&client->dev, "alarm IRQ disabled\n"); | ||
318 | } | ||
319 | |||
320 | return 0; | ||
321 | } | ||
322 | |||
323 | static int rv3029c2_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) | ||
324 | { | ||
325 | return rv3029c2_rtc_i2c_set_alarm(to_i2c_client(dev), alarm); | ||
326 | } | ||
327 | |||
328 | static int | ||
329 | rv3029c2_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm) | ||
330 | { | ||
331 | u8 regs[8]; | ||
332 | int ret; | ||
333 | |||
334 | /* | ||
335 | * The clock has an 8 bit wide bcd-coded register (they never learn) | ||
336 | * for the year. tm_year is an offset from 1900 and we are interested | ||
337 | * in the 2000-2099 range, so any value less than 100 is invalid. | ||
338 | */ | ||
339 | if (tm->tm_year < 100) | ||
340 | return -EINVAL; | ||
341 | |||
342 | regs[RV3029C2_W_SEC-RV3029C2_W_SEC] = bin2bcd(tm->tm_sec); | ||
343 | regs[RV3029C2_W_MINUTES-RV3029C2_W_SEC] = bin2bcd(tm->tm_min); | ||
344 | regs[RV3029C2_W_HOURS-RV3029C2_W_SEC] = bin2bcd(tm->tm_hour); | ||
345 | regs[RV3029C2_W_DATE-RV3029C2_W_SEC] = bin2bcd(tm->tm_mday); | ||
346 | regs[RV3029C2_W_MONTHS-RV3029C2_W_SEC] = bin2bcd(tm->tm_mon+1); | ||
347 | regs[RV3029C2_W_DAYS-RV3029C2_W_SEC] = bin2bcd((tm->tm_wday & 7)+1); | ||
348 | regs[RV3029C2_W_YEARS-RV3029C2_W_SEC] = bin2bcd(tm->tm_year - 100); | ||
349 | |||
350 | ret = rv3029c2_i2c_write_regs(client, RV3029C2_W_SEC, regs, | ||
351 | RV3029C2_WATCH_SECTION_LEN); | ||
352 | if (ret < 0) | ||
353 | return ret; | ||
354 | |||
355 | ret = rv3029c2_i2c_get_sr(client, regs); | ||
356 | if (ret < 0) { | ||
357 | dev_err(&client->dev, "%s: reading SR failed\n", __func__); | ||
358 | return ret; | ||
359 | } | ||
360 | /* clear PON bit */ | ||
361 | ret = rv3029c2_i2c_set_sr(client, (regs[0] & ~RV3029C2_STATUS_PON)); | ||
362 | if (ret < 0) { | ||
363 | dev_err(&client->dev, "%s: reading SR failed\n", __func__); | ||
364 | return ret; | ||
365 | } | ||
366 | |||
367 | return 0; | ||
368 | } | ||
369 | |||
370 | static int rv3029c2_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
371 | { | ||
372 | return rv3029c2_i2c_set_time(to_i2c_client(dev), tm); | ||
373 | } | ||
374 | |||
375 | static const struct rtc_class_ops rv3029c2_rtc_ops = { | ||
376 | .read_time = rv3029c2_rtc_read_time, | ||
377 | .set_time = rv3029c2_rtc_set_time, | ||
378 | .read_alarm = rv3029c2_rtc_read_alarm, | ||
379 | .set_alarm = rv3029c2_rtc_set_alarm, | ||
380 | }; | ||
381 | |||
382 | static struct i2c_device_id rv3029c2_id[] = { | ||
383 | { "rv3029c2", 0 }, | ||
384 | { } | ||
385 | }; | ||
386 | MODULE_DEVICE_TABLE(i2c, rv3029c2_id); | ||
387 | |||
388 | static int __devinit | ||
389 | rv3029c2_probe(struct i2c_client *client, const struct i2c_device_id *id) | ||
390 | { | ||
391 | struct rtc_device *rtc; | ||
392 | int rc = 0; | ||
393 | u8 buf[1]; | ||
394 | |||
395 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_EMUL)) | ||
396 | return -ENODEV; | ||
397 | |||
398 | rtc = rtc_device_register(client->name, | ||
399 | &client->dev, &rv3029c2_rtc_ops, | ||
400 | THIS_MODULE); | ||
401 | |||
402 | if (IS_ERR(rtc)) | ||
403 | return PTR_ERR(rtc); | ||
404 | |||
405 | i2c_set_clientdata(client, rtc); | ||
406 | |||
407 | rc = rv3029c2_i2c_get_sr(client, buf); | ||
408 | if (rc < 0) { | ||
409 | dev_err(&client->dev, "reading status failed\n"); | ||
410 | goto exit_unregister; | ||
411 | } | ||
412 | |||
413 | return 0; | ||
414 | |||
415 | exit_unregister: | ||
416 | rtc_device_unregister(rtc); | ||
417 | |||
418 | return rc; | ||
419 | } | ||
420 | |||
421 | static int __devexit rv3029c2_remove(struct i2c_client *client) | ||
422 | { | ||
423 | struct rtc_device *rtc = i2c_get_clientdata(client); | ||
424 | |||
425 | rtc_device_unregister(rtc); | ||
426 | |||
427 | return 0; | ||
428 | } | ||
429 | |||
430 | static struct i2c_driver rv3029c2_driver = { | ||
431 | .driver = { | ||
432 | .name = "rtc-rv3029c2", | ||
433 | }, | ||
434 | .probe = rv3029c2_probe, | ||
435 | .remove = __devexit_p(rv3029c2_remove), | ||
436 | .id_table = rv3029c2_id, | ||
437 | }; | ||
438 | |||
439 | static int __init rv3029c2_init(void) | ||
440 | { | ||
441 | return i2c_add_driver(&rv3029c2_driver); | ||
442 | } | ||
443 | |||
444 | static void __exit rv3029c2_exit(void) | ||
445 | { | ||
446 | i2c_del_driver(&rv3029c2_driver); | ||
447 | } | ||
448 | |||
449 | module_init(rv3029c2_init); | ||
450 | module_exit(rv3029c2_exit); | ||
451 | |||
452 | MODULE_AUTHOR("Gregory Hermant <gregory.hermant@calao-systems.com>"); | ||
453 | MODULE_DESCRIPTION("Micro Crystal RV3029C2 RTC driver"); | ||
454 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c index 1146e3522d3c..fde172fb2abe 100644 --- a/drivers/rtc/rtc-rx8025.c +++ b/drivers/rtc/rtc-rx8025.c | |||
@@ -424,37 +424,12 @@ static int rx8025_alarm_irq_enable(struct device *dev, unsigned int enabled) | |||
424 | return 0; | 424 | return 0; |
425 | } | 425 | } |
426 | 426 | ||
427 | static int rx8025_irq_set_state(struct device *dev, int enabled) | ||
428 | { | ||
429 | struct i2c_client *client = to_i2c_client(dev); | ||
430 | struct rx8025_data *rx8025 = i2c_get_clientdata(client); | ||
431 | int ctrl1; | ||
432 | int err; | ||
433 | |||
434 | if (client->irq <= 0) | ||
435 | return -ENXIO; | ||
436 | |||
437 | ctrl1 = rx8025->ctrl1 & ~RX8025_BIT_CTRL1_CT; | ||
438 | if (enabled) | ||
439 | ctrl1 |= RX8025_BIT_CTRL1_CT_1HZ; | ||
440 | if (ctrl1 != rx8025->ctrl1) { | ||
441 | rx8025->ctrl1 = ctrl1; | ||
442 | err = rx8025_write_reg(rx8025->client, RX8025_REG_CTRL1, | ||
443 | rx8025->ctrl1); | ||
444 | if (err) | ||
445 | return err; | ||
446 | } | ||
447 | |||
448 | return 0; | ||
449 | } | ||
450 | |||
451 | static struct rtc_class_ops rx8025_rtc_ops = { | 427 | static struct rtc_class_ops rx8025_rtc_ops = { |
452 | .read_time = rx8025_get_time, | 428 | .read_time = rx8025_get_time, |
453 | .set_time = rx8025_set_time, | 429 | .set_time = rx8025_set_time, |
454 | .read_alarm = rx8025_read_alarm, | 430 | .read_alarm = rx8025_read_alarm, |
455 | .set_alarm = rx8025_set_alarm, | 431 | .set_alarm = rx8025_set_alarm, |
456 | .alarm_irq_enable = rx8025_alarm_irq_enable, | 432 | .alarm_irq_enable = rx8025_alarm_irq_enable, |
457 | .irq_set_state = rx8025_irq_set_state, | ||
458 | }; | 433 | }; |
459 | 434 | ||
460 | /* | 435 | /* |
@@ -650,7 +625,7 @@ static int __devexit rx8025_remove(struct i2c_client *client) | |||
650 | mutex_unlock(lock); | 625 | mutex_unlock(lock); |
651 | 626 | ||
652 | free_irq(client->irq, client); | 627 | free_irq(client->irq, client); |
653 | flush_scheduled_work(); | 628 | cancel_work_sync(&rx8025->work); |
654 | } | 629 | } |
655 | 630 | ||
656 | rx8025_sysfs_unregister(&client->dev); | 631 | rx8025_sysfs_unregister(&client->dev); |
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index f57a87f4ae96..16512ecae31a 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -46,6 +46,7 @@ static struct clk *rtc_clk; | |||
46 | static void __iomem *s3c_rtc_base; | 46 | static void __iomem *s3c_rtc_base; |
47 | static int s3c_rtc_alarmno = NO_IRQ; | 47 | static int s3c_rtc_alarmno = NO_IRQ; |
48 | static int s3c_rtc_tickno = NO_IRQ; | 48 | static int s3c_rtc_tickno = NO_IRQ; |
49 | static bool wake_en; | ||
49 | static enum s3c_cpu_type s3c_rtc_cpu_type; | 50 | static enum s3c_cpu_type s3c_rtc_cpu_type; |
50 | 51 | ||
51 | static DEFINE_SPINLOCK(s3c_rtc_pie_lock); | 52 | static DEFINE_SPINLOCK(s3c_rtc_pie_lock); |
@@ -77,47 +78,18 @@ static irqreturn_t s3c_rtc_tickirq(int irq, void *id) | |||
77 | } | 78 | } |
78 | 79 | ||
79 | /* Update control registers */ | 80 | /* Update control registers */ |
80 | static void s3c_rtc_setaie(int to) | 81 | static int s3c_rtc_setaie(struct device *dev, unsigned int enabled) |
81 | { | 82 | { |
82 | unsigned int tmp; | 83 | unsigned int tmp; |
83 | 84 | ||
84 | pr_debug("%s: aie=%d\n", __func__, to); | 85 | pr_debug("%s: aie=%d\n", __func__, enabled); |
85 | 86 | ||
86 | tmp = readb(s3c_rtc_base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; | 87 | tmp = readb(s3c_rtc_base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; |
87 | 88 | ||
88 | if (to) | 89 | if (enabled) |
89 | tmp |= S3C2410_RTCALM_ALMEN; | 90 | tmp |= S3C2410_RTCALM_ALMEN; |
90 | 91 | ||
91 | writeb(tmp, s3c_rtc_base + S3C2410_RTCALM); | 92 | writeb(tmp, s3c_rtc_base + S3C2410_RTCALM); |
92 | } | ||
93 | |||
94 | static int s3c_rtc_setpie(struct device *dev, int enabled) | ||
95 | { | ||
96 | unsigned int tmp; | ||
97 | |||
98 | pr_debug("%s: pie=%d\n", __func__, enabled); | ||
99 | |||
100 | spin_lock_irq(&s3c_rtc_pie_lock); | ||
101 | |||
102 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { | ||
103 | tmp = readb(s3c_rtc_base + S3C2410_RTCCON); | ||
104 | tmp &= ~S3C64XX_RTCCON_TICEN; | ||
105 | |||
106 | if (enabled) | ||
107 | tmp |= S3C64XX_RTCCON_TICEN; | ||
108 | |||
109 | writew(tmp, s3c_rtc_base + S3C2410_RTCCON); | ||
110 | } else { | ||
111 | tmp = readb(s3c_rtc_base + S3C2410_TICNT); | ||
112 | tmp &= ~S3C2410_TICNT_ENABLE; | ||
113 | |||
114 | if (enabled) | ||
115 | tmp |= S3C2410_TICNT_ENABLE; | ||
116 | |||
117 | writeb(tmp, s3c_rtc_base + S3C2410_TICNT); | ||
118 | } | ||
119 | |||
120 | spin_unlock_irq(&s3c_rtc_pie_lock); | ||
121 | 93 | ||
122 | return 0; | 94 | return 0; |
123 | } | 95 | } |
@@ -171,8 +143,8 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) | |||
171 | goto retry_get_time; | 143 | goto retry_get_time; |
172 | } | 144 | } |
173 | 145 | ||
174 | pr_debug("read time %02x.%02x.%02x %02x/%02x/%02x\n", | 146 | pr_debug("read time %04d.%02d.%02d %02d:%02d:%02d\n", |
175 | rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday, | 147 | 1900 + rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday, |
176 | rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec); | 148 | rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec); |
177 | 149 | ||
178 | rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec); | 150 | rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec); |
@@ -185,7 +157,7 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) | |||
185 | rtc_tm->tm_year += 100; | 157 | rtc_tm->tm_year += 100; |
186 | rtc_tm->tm_mon -= 1; | 158 | rtc_tm->tm_mon -= 1; |
187 | 159 | ||
188 | return 0; | 160 | return rtc_valid_tm(rtc_tm); |
189 | } | 161 | } |
190 | 162 | ||
191 | static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) | 163 | static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) |
@@ -193,8 +165,8 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) | |||
193 | void __iomem *base = s3c_rtc_base; | 165 | void __iomem *base = s3c_rtc_base; |
194 | int year = tm->tm_year - 100; | 166 | int year = tm->tm_year - 100; |
195 | 167 | ||
196 | pr_debug("set time %02d.%02d.%02d %02d/%02d/%02d\n", | 168 | pr_debug("set time %04d.%02d.%02d %02d:%02d:%02d\n", |
197 | tm->tm_year, tm->tm_mon, tm->tm_mday, | 169 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, |
198 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 170 | tm->tm_hour, tm->tm_min, tm->tm_sec); |
199 | 171 | ||
200 | /* we get around y2k by simply not supporting it */ | 172 | /* we get around y2k by simply not supporting it */ |
@@ -231,9 +203,9 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
231 | 203 | ||
232 | alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0; | 204 | alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0; |
233 | 205 | ||
234 | pr_debug("read alarm %02x %02x.%02x.%02x %02x/%02x/%02x\n", | 206 | pr_debug("read alarm %d, %04d.%02d.%02d %02d:%02d:%02d\n", |
235 | alm_en, | 207 | alm_en, |
236 | alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday, | 208 | 1900 + alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday, |
237 | alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec); | 209 | alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec); |
238 | 210 | ||
239 | 211 | ||
@@ -242,34 +214,34 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
242 | if (alm_en & S3C2410_RTCALM_SECEN) | 214 | if (alm_en & S3C2410_RTCALM_SECEN) |
243 | alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec); | 215 | alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec); |
244 | else | 216 | else |
245 | alm_tm->tm_sec = 0xff; | 217 | alm_tm->tm_sec = -1; |
246 | 218 | ||
247 | if (alm_en & S3C2410_RTCALM_MINEN) | 219 | if (alm_en & S3C2410_RTCALM_MINEN) |
248 | alm_tm->tm_min = bcd2bin(alm_tm->tm_min); | 220 | alm_tm->tm_min = bcd2bin(alm_tm->tm_min); |
249 | else | 221 | else |
250 | alm_tm->tm_min = 0xff; | 222 | alm_tm->tm_min = -1; |
251 | 223 | ||
252 | if (alm_en & S3C2410_RTCALM_HOUREN) | 224 | if (alm_en & S3C2410_RTCALM_HOUREN) |
253 | alm_tm->tm_hour = bcd2bin(alm_tm->tm_hour); | 225 | alm_tm->tm_hour = bcd2bin(alm_tm->tm_hour); |
254 | else | 226 | else |
255 | alm_tm->tm_hour = 0xff; | 227 | alm_tm->tm_hour = -1; |
256 | 228 | ||
257 | if (alm_en & S3C2410_RTCALM_DAYEN) | 229 | if (alm_en & S3C2410_RTCALM_DAYEN) |
258 | alm_tm->tm_mday = bcd2bin(alm_tm->tm_mday); | 230 | alm_tm->tm_mday = bcd2bin(alm_tm->tm_mday); |
259 | else | 231 | else |
260 | alm_tm->tm_mday = 0xff; | 232 | alm_tm->tm_mday = -1; |
261 | 233 | ||
262 | if (alm_en & S3C2410_RTCALM_MONEN) { | 234 | if (alm_en & S3C2410_RTCALM_MONEN) { |
263 | alm_tm->tm_mon = bcd2bin(alm_tm->tm_mon); | 235 | alm_tm->tm_mon = bcd2bin(alm_tm->tm_mon); |
264 | alm_tm->tm_mon -= 1; | 236 | alm_tm->tm_mon -= 1; |
265 | } else { | 237 | } else { |
266 | alm_tm->tm_mon = 0xff; | 238 | alm_tm->tm_mon = -1; |
267 | } | 239 | } |
268 | 240 | ||
269 | if (alm_en & S3C2410_RTCALM_YEAREN) | 241 | if (alm_en & S3C2410_RTCALM_YEAREN) |
270 | alm_tm->tm_year = bcd2bin(alm_tm->tm_year); | 242 | alm_tm->tm_year = bcd2bin(alm_tm->tm_year); |
271 | else | 243 | else |
272 | alm_tm->tm_year = 0xffff; | 244 | alm_tm->tm_year = -1; |
273 | 245 | ||
274 | return 0; | 246 | return 0; |
275 | } | 247 | } |
@@ -280,10 +252,10 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
280 | void __iomem *base = s3c_rtc_base; | 252 | void __iomem *base = s3c_rtc_base; |
281 | unsigned int alrm_en; | 253 | unsigned int alrm_en; |
282 | 254 | ||
283 | pr_debug("s3c_rtc_setalarm: %d, %02x/%02x/%02x %02x.%02x.%02x\n", | 255 | pr_debug("s3c_rtc_setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n", |
284 | alrm->enabled, | 256 | alrm->enabled, |
285 | tm->tm_mday & 0xff, tm->tm_mon & 0xff, tm->tm_year & 0xff, | 257 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, |
286 | tm->tm_hour & 0xff, tm->tm_min & 0xff, tm->tm_sec); | 258 | tm->tm_hour, tm->tm_min, tm->tm_sec); |
287 | 259 | ||
288 | 260 | ||
289 | alrm_en = readb(base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN; | 261 | alrm_en = readb(base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN; |
@@ -308,7 +280,7 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
308 | 280 | ||
309 | writeb(alrm_en, base + S3C2410_RTCALM); | 281 | writeb(alrm_en, base + S3C2410_RTCALM); |
310 | 282 | ||
311 | s3c_rtc_setaie(alrm->enabled); | 283 | s3c_rtc_setaie(dev, alrm->enabled); |
312 | 284 | ||
313 | return 0; | 285 | return 0; |
314 | } | 286 | } |
@@ -318,7 +290,7 @@ static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) | |||
318 | unsigned int ticnt; | 290 | unsigned int ticnt; |
319 | 291 | ||
320 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { | 292 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { |
321 | ticnt = readb(s3c_rtc_base + S3C2410_RTCCON); | 293 | ticnt = readw(s3c_rtc_base + S3C2410_RTCCON); |
322 | ticnt &= S3C64XX_RTCCON_TICEN; | 294 | ticnt &= S3C64XX_RTCCON_TICEN; |
323 | } else { | 295 | } else { |
324 | ticnt = readb(s3c_rtc_base + S3C2410_TICNT); | 296 | ticnt = readb(s3c_rtc_base + S3C2410_TICNT); |
@@ -365,7 +337,6 @@ static void s3c_rtc_release(struct device *dev) | |||
365 | 337 | ||
366 | /* do not clear AIE here, it may be needed for wake */ | 338 | /* do not clear AIE here, it may be needed for wake */ |
367 | 339 | ||
368 | s3c_rtc_setpie(dev, 0); | ||
369 | free_irq(s3c_rtc_alarmno, rtc_dev); | 340 | free_irq(s3c_rtc_alarmno, rtc_dev); |
370 | free_irq(s3c_rtc_tickno, rtc_dev); | 341 | free_irq(s3c_rtc_tickno, rtc_dev); |
371 | } | 342 | } |
@@ -377,9 +348,8 @@ static const struct rtc_class_ops s3c_rtcops = { | |||
377 | .set_time = s3c_rtc_settime, | 348 | .set_time = s3c_rtc_settime, |
378 | .read_alarm = s3c_rtc_getalarm, | 349 | .read_alarm = s3c_rtc_getalarm, |
379 | .set_alarm = s3c_rtc_setalarm, | 350 | .set_alarm = s3c_rtc_setalarm, |
380 | .irq_set_freq = s3c_rtc_setfreq, | 351 | .proc = s3c_rtc_proc, |
381 | .irq_set_state = s3c_rtc_setpie, | 352 | .alarm_irq_enable = s3c_rtc_setaie, |
382 | .proc = s3c_rtc_proc, | ||
383 | }; | 353 | }; |
384 | 354 | ||
385 | static void s3c_rtc_enable(struct platform_device *pdev, int en) | 355 | static void s3c_rtc_enable(struct platform_device *pdev, int en) |
@@ -391,11 +361,11 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en) | |||
391 | return; | 361 | return; |
392 | 362 | ||
393 | if (!en) { | 363 | if (!en) { |
394 | tmp = readb(base + S3C2410_RTCCON); | 364 | tmp = readw(base + S3C2410_RTCCON); |
395 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) | 365 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) |
396 | tmp &= ~S3C64XX_RTCCON_TICEN; | 366 | tmp &= ~S3C64XX_RTCCON_TICEN; |
397 | tmp &= ~S3C2410_RTCCON_RTCEN; | 367 | tmp &= ~S3C2410_RTCCON_RTCEN; |
398 | writeb(tmp, base + S3C2410_RTCCON); | 368 | writew(tmp, base + S3C2410_RTCCON); |
399 | 369 | ||
400 | if (s3c_rtc_cpu_type == TYPE_S3C2410) { | 370 | if (s3c_rtc_cpu_type == TYPE_S3C2410) { |
401 | tmp = readb(base + S3C2410_TICNT); | 371 | tmp = readb(base + S3C2410_TICNT); |
@@ -405,25 +375,28 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en) | |||
405 | } else { | 375 | } else { |
406 | /* re-enable the device, and check it is ok */ | 376 | /* re-enable the device, and check it is ok */ |
407 | 377 | ||
408 | if ((readb(base+S3C2410_RTCCON) & S3C2410_RTCCON_RTCEN) == 0){ | 378 | if ((readw(base+S3C2410_RTCCON) & S3C2410_RTCCON_RTCEN) == 0) { |
409 | dev_info(&pdev->dev, "rtc disabled, re-enabling\n"); | 379 | dev_info(&pdev->dev, "rtc disabled, re-enabling\n"); |
410 | 380 | ||
411 | tmp = readb(base + S3C2410_RTCCON); | 381 | tmp = readw(base + S3C2410_RTCCON); |
412 | writeb(tmp|S3C2410_RTCCON_RTCEN, base+S3C2410_RTCCON); | 382 | writew(tmp | S3C2410_RTCCON_RTCEN, |
383 | base + S3C2410_RTCCON); | ||
413 | } | 384 | } |
414 | 385 | ||
415 | if ((readb(base + S3C2410_RTCCON) & S3C2410_RTCCON_CNTSEL)){ | 386 | if ((readw(base + S3C2410_RTCCON) & S3C2410_RTCCON_CNTSEL)) { |
416 | dev_info(&pdev->dev, "removing RTCCON_CNTSEL\n"); | 387 | dev_info(&pdev->dev, "removing RTCCON_CNTSEL\n"); |
417 | 388 | ||
418 | tmp = readb(base + S3C2410_RTCCON); | 389 | tmp = readw(base + S3C2410_RTCCON); |
419 | writeb(tmp& ~S3C2410_RTCCON_CNTSEL, base+S3C2410_RTCCON); | 390 | writew(tmp & ~S3C2410_RTCCON_CNTSEL, |
391 | base + S3C2410_RTCCON); | ||
420 | } | 392 | } |
421 | 393 | ||
422 | if ((readb(base + S3C2410_RTCCON) & S3C2410_RTCCON_CLKRST)){ | 394 | if ((readw(base + S3C2410_RTCCON) & S3C2410_RTCCON_CLKRST)) { |
423 | dev_info(&pdev->dev, "removing RTCCON_CLKRST\n"); | 395 | dev_info(&pdev->dev, "removing RTCCON_CLKRST\n"); |
424 | 396 | ||
425 | tmp = readb(base + S3C2410_RTCCON); | 397 | tmp = readw(base + S3C2410_RTCCON); |
426 | writeb(tmp & ~S3C2410_RTCCON_CLKRST, base+S3C2410_RTCCON); | 398 | writew(tmp & ~S3C2410_RTCCON_CLKRST, |
399 | base + S3C2410_RTCCON); | ||
427 | } | 400 | } |
428 | } | 401 | } |
429 | } | 402 | } |
@@ -435,8 +408,7 @@ static int __devexit s3c_rtc_remove(struct platform_device *dev) | |||
435 | platform_set_drvdata(dev, NULL); | 408 | platform_set_drvdata(dev, NULL); |
436 | rtc_device_unregister(rtc); | 409 | rtc_device_unregister(rtc); |
437 | 410 | ||
438 | s3c_rtc_setpie(&dev->dev, 0); | 411 | s3c_rtc_setaie(&dev->dev, 0); |
439 | s3c_rtc_setaie(0); | ||
440 | 412 | ||
441 | clk_disable(rtc_clk); | 413 | clk_disable(rtc_clk); |
442 | clk_put(rtc_clk); | 414 | clk_put(rtc_clk); |
@@ -452,8 +424,8 @@ static int __devexit s3c_rtc_remove(struct platform_device *dev) | |||
452 | static int __devinit s3c_rtc_probe(struct platform_device *pdev) | 424 | static int __devinit s3c_rtc_probe(struct platform_device *pdev) |
453 | { | 425 | { |
454 | struct rtc_device *rtc; | 426 | struct rtc_device *rtc; |
427 | struct rtc_time rtc_tm; | ||
455 | struct resource *res; | 428 | struct resource *res; |
456 | unsigned int tmp, i; | ||
457 | int ret; | 429 | int ret; |
458 | 430 | ||
459 | pr_debug("%s: probe=%p\n", __func__, pdev); | 431 | pr_debug("%s: probe=%p\n", __func__, pdev); |
@@ -514,8 +486,8 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) | |||
514 | 486 | ||
515 | s3c_rtc_enable(pdev, 1); | 487 | s3c_rtc_enable(pdev, 1); |
516 | 488 | ||
517 | pr_debug("s3c2410_rtc: RTCCON=%02x\n", | 489 | pr_debug("s3c2410_rtc: RTCCON=%02x\n", |
518 | readb(s3c_rtc_base + S3C2410_RTCCON)); | 490 | readw(s3c_rtc_base + S3C2410_RTCCON)); |
519 | 491 | ||
520 | device_init_wakeup(&pdev->dev, 1); | 492 | device_init_wakeup(&pdev->dev, 1); |
521 | 493 | ||
@@ -534,11 +506,19 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) | |||
534 | 506 | ||
535 | /* Check RTC Time */ | 507 | /* Check RTC Time */ |
536 | 508 | ||
537 | for (i = S3C2410_RTCSEC; i <= S3C2410_RTCYEAR; i += 0x4) { | 509 | s3c_rtc_gettime(NULL, &rtc_tm); |
538 | tmp = readb(s3c_rtc_base + i); | 510 | |
511 | if (rtc_valid_tm(&rtc_tm)) { | ||
512 | rtc_tm.tm_year = 100; | ||
513 | rtc_tm.tm_mon = 0; | ||
514 | rtc_tm.tm_mday = 1; | ||
515 | rtc_tm.tm_hour = 0; | ||
516 | rtc_tm.tm_min = 0; | ||
517 | rtc_tm.tm_sec = 0; | ||
539 | 518 | ||
540 | if ((tmp & 0xf) > 0x9 || ((tmp >> 4) & 0xf) > 0x9) | 519 | s3c_rtc_settime(NULL, &rtc_tm); |
541 | writeb(0, s3c_rtc_base + i); | 520 | |
521 | dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n"); | ||
542 | } | 522 | } |
543 | 523 | ||
544 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) | 524 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) |
@@ -578,13 +558,17 @@ static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) | |||
578 | /* save TICNT for anyone using periodic interrupts */ | 558 | /* save TICNT for anyone using periodic interrupts */ |
579 | ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); | 559 | ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); |
580 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { | 560 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { |
581 | ticnt_en_save = readb(s3c_rtc_base + S3C2410_RTCCON); | 561 | ticnt_en_save = readw(s3c_rtc_base + S3C2410_RTCCON); |
582 | ticnt_en_save &= S3C64XX_RTCCON_TICEN; | 562 | ticnt_en_save &= S3C64XX_RTCCON_TICEN; |
583 | } | 563 | } |
584 | s3c_rtc_enable(pdev, 0); | 564 | s3c_rtc_enable(pdev, 0); |
585 | 565 | ||
586 | if (device_may_wakeup(&pdev->dev)) | 566 | if (device_may_wakeup(&pdev->dev) && !wake_en) { |
587 | enable_irq_wake(s3c_rtc_alarmno); | 567 | if (enable_irq_wake(s3c_rtc_alarmno) == 0) |
568 | wake_en = true; | ||
569 | else | ||
570 | dev_err(&pdev->dev, "enable_irq_wake failed\n"); | ||
571 | } | ||
588 | 572 | ||
589 | return 0; | 573 | return 0; |
590 | } | 574 | } |
@@ -596,12 +580,14 @@ static int s3c_rtc_resume(struct platform_device *pdev) | |||
596 | s3c_rtc_enable(pdev, 1); | 580 | s3c_rtc_enable(pdev, 1); |
597 | writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); | 581 | writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); |
598 | if (s3c_rtc_cpu_type == TYPE_S3C64XX && ticnt_en_save) { | 582 | if (s3c_rtc_cpu_type == TYPE_S3C64XX && ticnt_en_save) { |
599 | tmp = readb(s3c_rtc_base + S3C2410_RTCCON); | 583 | tmp = readw(s3c_rtc_base + S3C2410_RTCCON); |
600 | writeb(tmp | ticnt_en_save, s3c_rtc_base + S3C2410_RTCCON); | 584 | writew(tmp | ticnt_en_save, s3c_rtc_base + S3C2410_RTCCON); |
601 | } | 585 | } |
602 | 586 | ||
603 | if (device_may_wakeup(&pdev->dev)) | 587 | if (device_may_wakeup(&pdev->dev) && wake_en) { |
604 | disable_irq_wake(s3c_rtc_alarmno); | 588 | disable_irq_wake(s3c_rtc_alarmno); |
589 | wake_en = false; | ||
590 | } | ||
605 | 591 | ||
606 | return 0; | 592 | return 0; |
607 | } | 593 | } |
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index e4a44b641702..0b40bb88a884 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c | |||
@@ -39,11 +39,10 @@ | |||
39 | #include <mach/regs-ost.h> | 39 | #include <mach/regs-ost.h> |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | #define RTC_DEF_DIVIDER 32768 - 1 | 42 | #define RTC_DEF_DIVIDER (32768 - 1) |
43 | #define RTC_DEF_TRIM 0 | 43 | #define RTC_DEF_TRIM 0 |
44 | 44 | ||
45 | static unsigned long rtc_freq = 1024; | 45 | static const unsigned long RTC_FREQ = 1024; |
46 | static unsigned long timer_freq; | ||
47 | static struct rtc_time rtc_alarm; | 46 | static struct rtc_time rtc_alarm; |
48 | static DEFINE_SPINLOCK(sa1100_rtc_lock); | 47 | static DEFINE_SPINLOCK(sa1100_rtc_lock); |
49 | 48 | ||
@@ -61,7 +60,8 @@ static inline int rtc_periodic_alarm(struct rtc_time *tm) | |||
61 | * Calculate the next alarm time given the requested alarm time mask | 60 | * Calculate the next alarm time given the requested alarm time mask |
62 | * and the current time. | 61 | * and the current time. |
63 | */ | 62 | */ |
64 | static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc_time *alrm) | 63 | static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, |
64 | struct rtc_time *alrm) | ||
65 | { | 65 | { |
66 | unsigned long next_time; | 66 | unsigned long next_time; |
67 | unsigned long now_time; | 67 | unsigned long now_time; |
@@ -116,7 +116,23 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) | |||
116 | rtsr = RTSR; | 116 | rtsr = RTSR; |
117 | /* clear interrupt sources */ | 117 | /* clear interrupt sources */ |
118 | RTSR = 0; | 118 | RTSR = 0; |
119 | RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2); | 119 | /* Fix for a nasty initialization problem the in SA11xx RTSR register. |
120 | * See also the comments in sa1100_rtc_probe(). */ | ||
121 | if (rtsr & (RTSR_ALE | RTSR_HZE)) { | ||
122 | /* This is the original code, before there was the if test | ||
123 | * above. This code does not clear interrupts that were not | ||
124 | * enabled. */ | ||
125 | RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2); | ||
126 | } else { | ||
127 | /* For some reason, it is possible to enter this routine | ||
128 | * without interruptions enabled, it has been tested with | ||
129 | * several units (Bug in SA11xx chip?). | ||
130 | * | ||
131 | * This situation leads to an infinite "loop" of interrupt | ||
132 | * routine calling and as a result the processor seems to | ||
133 | * lock on its first call to open(). */ | ||
134 | RTSR = RTSR_AL | RTSR_HZ; | ||
135 | } | ||
120 | 136 | ||
121 | /* clear alarm interrupt if it has occurred */ | 137 | /* clear alarm interrupt if it has occurred */ |
122 | if (rtsr & RTSR_AL) | 138 | if (rtsr & RTSR_AL) |
@@ -139,80 +155,29 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) | |||
139 | return IRQ_HANDLED; | 155 | return IRQ_HANDLED; |
140 | } | 156 | } |
141 | 157 | ||
142 | static int rtc_timer1_count; | ||
143 | |||
144 | static irqreturn_t timer1_interrupt(int irq, void *dev_id) | ||
145 | { | ||
146 | struct platform_device *pdev = to_platform_device(dev_id); | ||
147 | struct rtc_device *rtc = platform_get_drvdata(pdev); | ||
148 | |||
149 | /* | ||
150 | * If we match for the first time, rtc_timer1_count will be 1. | ||
151 | * Otherwise, we wrapped around (very unlikely but | ||
152 | * still possible) so compute the amount of missed periods. | ||
153 | * The match reg is updated only when the data is actually retrieved | ||
154 | * to avoid unnecessary interrupts. | ||
155 | */ | ||
156 | OSSR = OSSR_M1; /* clear match on timer1 */ | ||
157 | |||
158 | rtc_update_irq(rtc, rtc_timer1_count, RTC_PF | RTC_IRQF); | ||
159 | |||
160 | if (rtc_timer1_count == 1) | ||
161 | rtc_timer1_count = (rtc_freq * ((1 << 30) / (timer_freq >> 2))); | ||
162 | |||
163 | return IRQ_HANDLED; | ||
164 | } | ||
165 | |||
166 | static int sa1100_rtc_read_callback(struct device *dev, int data) | ||
167 | { | ||
168 | if (data & RTC_PF) { | ||
169 | /* interpolate missed periods and set match for the next */ | ||
170 | unsigned long period = timer_freq / rtc_freq; | ||
171 | unsigned long oscr = OSCR; | ||
172 | unsigned long osmr1 = OSMR1; | ||
173 | unsigned long missed = (oscr - osmr1)/period; | ||
174 | data += missed << 8; | ||
175 | OSSR = OSSR_M1; /* clear match on timer 1 */ | ||
176 | OSMR1 = osmr1 + (missed + 1)*period; | ||
177 | /* Ensure we didn't miss another match in the mean time. | ||
178 | * Here we compare (match - OSCR) 8 instead of 0 -- | ||
179 | * see comment in pxa_timer_interrupt() for explanation. | ||
180 | */ | ||
181 | while( (signed long)((osmr1 = OSMR1) - OSCR) <= 8 ) { | ||
182 | data += 0x100; | ||
183 | OSSR = OSSR_M1; /* clear match on timer 1 */ | ||
184 | OSMR1 = osmr1 + period; | ||
185 | } | ||
186 | } | ||
187 | return data; | ||
188 | } | ||
189 | |||
190 | static int sa1100_rtc_open(struct device *dev) | 158 | static int sa1100_rtc_open(struct device *dev) |
191 | { | 159 | { |
192 | int ret; | 160 | int ret; |
161 | struct platform_device *plat_dev = to_platform_device(dev); | ||
162 | struct rtc_device *rtc = platform_get_drvdata(plat_dev); | ||
193 | 163 | ||
194 | ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, IRQF_DISABLED, | 164 | ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, IRQF_DISABLED, |
195 | "rtc 1Hz", dev); | 165 | "rtc 1Hz", dev); |
196 | if (ret) { | 166 | if (ret) { |
197 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz); | 167 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz); |
198 | goto fail_ui; | 168 | goto fail_ui; |
199 | } | 169 | } |
200 | ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, IRQF_DISABLED, | 170 | ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, IRQF_DISABLED, |
201 | "rtc Alrm", dev); | 171 | "rtc Alrm", dev); |
202 | if (ret) { | 172 | if (ret) { |
203 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm); | 173 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm); |
204 | goto fail_ai; | 174 | goto fail_ai; |
205 | } | 175 | } |
206 | ret = request_irq(IRQ_OST1, timer1_interrupt, IRQF_DISABLED, | 176 | rtc->max_user_freq = RTC_FREQ; |
207 | "rtc timer", dev); | 177 | rtc_irq_set_freq(rtc, NULL, RTC_FREQ); |
208 | if (ret) { | 178 | |
209 | dev_err(dev, "IRQ %d already in use.\n", IRQ_OST1); | ||
210 | goto fail_pi; | ||
211 | } | ||
212 | return 0; | 179 | return 0; |
213 | 180 | ||
214 | fail_pi: | ||
215 | free_irq(IRQ_RTCAlrm, dev); | ||
216 | fail_ai: | 181 | fail_ai: |
217 | free_irq(IRQ_RTC1Hz, dev); | 182 | free_irq(IRQ_RTC1Hz, dev); |
218 | fail_ui: | 183 | fail_ui: |
@@ -227,57 +192,19 @@ static void sa1100_rtc_release(struct device *dev) | |||
227 | OSSR = OSSR_M1; | 192 | OSSR = OSSR_M1; |
228 | spin_unlock_irq(&sa1100_rtc_lock); | 193 | spin_unlock_irq(&sa1100_rtc_lock); |
229 | 194 | ||
230 | free_irq(IRQ_OST1, dev); | ||
231 | free_irq(IRQ_RTCAlrm, dev); | 195 | free_irq(IRQ_RTCAlrm, dev); |
232 | free_irq(IRQ_RTC1Hz, dev); | 196 | free_irq(IRQ_RTC1Hz, dev); |
233 | } | 197 | } |
234 | 198 | ||
235 | 199 | static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | |
236 | static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, | ||
237 | unsigned long arg) | ||
238 | { | 200 | { |
239 | switch(cmd) { | 201 | spin_lock_irq(&sa1100_rtc_lock); |
240 | case RTC_AIE_OFF: | 202 | if (enabled) |
241 | spin_lock_irq(&sa1100_rtc_lock); | ||
242 | RTSR &= ~RTSR_ALE; | ||
243 | spin_unlock_irq(&sa1100_rtc_lock); | ||
244 | return 0; | ||
245 | case RTC_AIE_ON: | ||
246 | spin_lock_irq(&sa1100_rtc_lock); | ||
247 | RTSR |= RTSR_ALE; | 203 | RTSR |= RTSR_ALE; |
248 | spin_unlock_irq(&sa1100_rtc_lock); | 204 | else |
249 | return 0; | 205 | RTSR &= ~RTSR_ALE; |
250 | case RTC_UIE_OFF: | 206 | spin_unlock_irq(&sa1100_rtc_lock); |
251 | spin_lock_irq(&sa1100_rtc_lock); | 207 | return 0; |
252 | RTSR &= ~RTSR_HZE; | ||
253 | spin_unlock_irq(&sa1100_rtc_lock); | ||
254 | return 0; | ||
255 | case RTC_UIE_ON: | ||
256 | spin_lock_irq(&sa1100_rtc_lock); | ||
257 | RTSR |= RTSR_HZE; | ||
258 | spin_unlock_irq(&sa1100_rtc_lock); | ||
259 | return 0; | ||
260 | case RTC_PIE_OFF: | ||
261 | spin_lock_irq(&sa1100_rtc_lock); | ||
262 | OIER &= ~OIER_E1; | ||
263 | spin_unlock_irq(&sa1100_rtc_lock); | ||
264 | return 0; | ||
265 | case RTC_PIE_ON: | ||
266 | spin_lock_irq(&sa1100_rtc_lock); | ||
267 | OSMR1 = timer_freq / rtc_freq + OSCR; | ||
268 | OIER |= OIER_E1; | ||
269 | rtc_timer1_count = 1; | ||
270 | spin_unlock_irq(&sa1100_rtc_lock); | ||
271 | return 0; | ||
272 | case RTC_IRQP_READ: | ||
273 | return put_user(rtc_freq, (unsigned long *)arg); | ||
274 | case RTC_IRQP_SET: | ||
275 | if (arg < 1 || arg > timer_freq) | ||
276 | return -EINVAL; | ||
277 | rtc_freq = arg; | ||
278 | return 0; | ||
279 | } | ||
280 | return -ENOIOCTLCMD; | ||
281 | } | 208 | } |
282 | 209 | ||
283 | static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm) | 210 | static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm) |
@@ -327,34 +254,27 @@ static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
327 | 254 | ||
328 | static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq) | 255 | static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq) |
329 | { | 256 | { |
330 | seq_printf(seq, "trim/divider\t: 0x%08x\n", (u32) RTTR); | 257 | seq_printf(seq, "trim/divider\t\t: 0x%08x\n", (u32) RTTR); |
331 | seq_printf(seq, "update_IRQ\t: %s\n", | 258 | seq_printf(seq, "RTSR\t\t\t: 0x%08x\n", (u32)RTSR); |
332 | (RTSR & RTSR_HZE) ? "yes" : "no"); | ||
333 | seq_printf(seq, "periodic_IRQ\t: %s\n", | ||
334 | (OIER & OIER_E1) ? "yes" : "no"); | ||
335 | seq_printf(seq, "periodic_freq\t: %ld\n", rtc_freq); | ||
336 | 259 | ||
337 | return 0; | 260 | return 0; |
338 | } | 261 | } |
339 | 262 | ||
340 | static const struct rtc_class_ops sa1100_rtc_ops = { | 263 | static const struct rtc_class_ops sa1100_rtc_ops = { |
341 | .open = sa1100_rtc_open, | 264 | .open = sa1100_rtc_open, |
342 | .read_callback = sa1100_rtc_read_callback, | ||
343 | .release = sa1100_rtc_release, | 265 | .release = sa1100_rtc_release, |
344 | .ioctl = sa1100_rtc_ioctl, | ||
345 | .read_time = sa1100_rtc_read_time, | 266 | .read_time = sa1100_rtc_read_time, |
346 | .set_time = sa1100_rtc_set_time, | 267 | .set_time = sa1100_rtc_set_time, |
347 | .read_alarm = sa1100_rtc_read_alarm, | 268 | .read_alarm = sa1100_rtc_read_alarm, |
348 | .set_alarm = sa1100_rtc_set_alarm, | 269 | .set_alarm = sa1100_rtc_set_alarm, |
349 | .proc = sa1100_rtc_proc, | 270 | .proc = sa1100_rtc_proc, |
271 | .alarm_irq_enable = sa1100_rtc_alarm_irq_enable, | ||
350 | }; | 272 | }; |
351 | 273 | ||
352 | static int sa1100_rtc_probe(struct platform_device *pdev) | 274 | static int sa1100_rtc_probe(struct platform_device *pdev) |
353 | { | 275 | { |
354 | struct rtc_device *rtc; | 276 | struct rtc_device *rtc; |
355 | 277 | ||
356 | timer_freq = get_clock_tick_rate(); | ||
357 | |||
358 | /* | 278 | /* |
359 | * According to the manual we should be able to let RTTR be zero | 279 | * According to the manual we should be able to let RTTR be zero |
360 | * and then a default diviser for a 32.768KHz clock is used. | 280 | * and then a default diviser for a 32.768KHz clock is used. |
@@ -364,7 +284,8 @@ static int sa1100_rtc_probe(struct platform_device *pdev) | |||
364 | */ | 284 | */ |
365 | if (RTTR == 0) { | 285 | if (RTTR == 0) { |
366 | RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); | 286 | RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); |
367 | dev_warn(&pdev->dev, "warning: initializing default clock divider/trim value\n"); | 287 | dev_warn(&pdev->dev, "warning: " |
288 | "initializing default clock divider/trim value\n"); | ||
368 | /* The current RTC value probably doesn't make sense either */ | 289 | /* The current RTC value probably doesn't make sense either */ |
369 | RCNR = 0; | 290 | RCNR = 0; |
370 | } | 291 | } |
@@ -372,13 +293,37 @@ static int sa1100_rtc_probe(struct platform_device *pdev) | |||
372 | device_init_wakeup(&pdev->dev, 1); | 293 | device_init_wakeup(&pdev->dev, 1); |
373 | 294 | ||
374 | rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, | 295 | rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, |
375 | THIS_MODULE); | 296 | THIS_MODULE); |
376 | 297 | ||
377 | if (IS_ERR(rtc)) | 298 | if (IS_ERR(rtc)) |
378 | return PTR_ERR(rtc); | 299 | return PTR_ERR(rtc); |
379 | 300 | ||
380 | platform_set_drvdata(pdev, rtc); | 301 | platform_set_drvdata(pdev, rtc); |
381 | 302 | ||
303 | /* Fix for a nasty initialization problem the in SA11xx RTSR register. | ||
304 | * See also the comments in sa1100_rtc_interrupt(). | ||
305 | * | ||
306 | * Sometimes bit 1 of the RTSR (RTSR_HZ) will wake up 1, which means an | ||
307 | * interrupt pending, even though interrupts were never enabled. | ||
308 | * In this case, this bit it must be reset before enabling | ||
309 | * interruptions to avoid a nonexistent interrupt to occur. | ||
310 | * | ||
311 | * In principle, the same problem would apply to bit 0, although it has | ||
312 | * never been observed to happen. | ||
313 | * | ||
314 | * This issue is addressed both here and in sa1100_rtc_interrupt(). | ||
315 | * If the issue is not addressed here, in the times when the processor | ||
316 | * wakes up with the bit set there will be one spurious interrupt. | ||
317 | * | ||
318 | * The issue is also dealt with in sa1100_rtc_interrupt() to be on the | ||
319 | * safe side, once the condition that lead to this strange | ||
320 | * initialization is unknown and could in principle happen during | ||
321 | * normal processing. | ||
322 | * | ||
323 | * Notice that clearing bit 1 and 0 is accomplished by writting ONES to | ||
324 | * the corresponding bits in RTSR. */ | ||
325 | RTSR = RTSR_AL | RTSR_HZ; | ||
326 | |||
382 | return 0; | 327 | return 0; |
383 | } | 328 | } |
384 | 329 | ||
@@ -386,7 +331,7 @@ static int sa1100_rtc_remove(struct platform_device *pdev) | |||
386 | { | 331 | { |
387 | struct rtc_device *rtc = platform_get_drvdata(pdev); | 332 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
388 | 333 | ||
389 | if (rtc) | 334 | if (rtc) |
390 | rtc_device_unregister(rtc); | 335 | rtc_device_unregister(rtc); |
391 | 336 | ||
392 | return 0; | 337 | return 0; |
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index 5efbd5990ff8..6ac55fd48413 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c | |||
@@ -344,29 +344,10 @@ static inline void sh_rtc_setcie(struct device *dev, unsigned int enable) | |||
344 | spin_unlock_irq(&rtc->lock); | 344 | spin_unlock_irq(&rtc->lock); |
345 | } | 345 | } |
346 | 346 | ||
347 | static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | 347 | static int sh_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) |
348 | { | 348 | { |
349 | struct sh_rtc *rtc = dev_get_drvdata(dev); | 349 | sh_rtc_setaie(dev, enabled); |
350 | unsigned int ret = 0; | 350 | return 0; |
351 | |||
352 | switch (cmd) { | ||
353 | case RTC_AIE_OFF: | ||
354 | case RTC_AIE_ON: | ||
355 | sh_rtc_setaie(dev, cmd == RTC_AIE_ON); | ||
356 | break; | ||
357 | case RTC_UIE_OFF: | ||
358 | rtc->periodic_freq &= ~PF_OXS; | ||
359 | sh_rtc_setcie(dev, 0); | ||
360 | break; | ||
361 | case RTC_UIE_ON: | ||
362 | rtc->periodic_freq |= PF_OXS; | ||
363 | sh_rtc_setcie(dev, 1); | ||
364 | break; | ||
365 | default: | ||
366 | ret = -ENOIOCTLCMD; | ||
367 | } | ||
368 | |||
369 | return ret; | ||
370 | } | 351 | } |
371 | 352 | ||
372 | static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm) | 353 | static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm) |
@@ -596,14 +577,12 @@ static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | |||
596 | } | 577 | } |
597 | 578 | ||
598 | static struct rtc_class_ops sh_rtc_ops = { | 579 | static struct rtc_class_ops sh_rtc_ops = { |
599 | .ioctl = sh_rtc_ioctl, | ||
600 | .read_time = sh_rtc_read_time, | 580 | .read_time = sh_rtc_read_time, |
601 | .set_time = sh_rtc_set_time, | 581 | .set_time = sh_rtc_set_time, |
602 | .read_alarm = sh_rtc_read_alarm, | 582 | .read_alarm = sh_rtc_read_alarm, |
603 | .set_alarm = sh_rtc_set_alarm, | 583 | .set_alarm = sh_rtc_set_alarm, |
604 | .irq_set_state = sh_rtc_irq_set_state, | ||
605 | .irq_set_freq = sh_rtc_irq_set_freq, | ||
606 | .proc = sh_rtc_proc, | 584 | .proc = sh_rtc_proc, |
585 | .alarm_irq_enable = sh_rtc_alarm_irq_enable, | ||
607 | }; | 586 | }; |
608 | 587 | ||
609 | static int __init sh_rtc_probe(struct platform_device *pdev) | 588 | static int __init sh_rtc_probe(struct platform_device *pdev) |
@@ -761,7 +740,7 @@ err_unmap: | |||
761 | clk_put(rtc->clk); | 740 | clk_put(rtc->clk); |
762 | iounmap(rtc->regbase); | 741 | iounmap(rtc->regbase); |
763 | err_badmap: | 742 | err_badmap: |
764 | release_resource(rtc->res); | 743 | release_mem_region(rtc->res->start, rtc->regsize); |
765 | err_badres: | 744 | err_badres: |
766 | kfree(rtc); | 745 | kfree(rtc); |
767 | 746 | ||
@@ -786,7 +765,7 @@ static int __exit sh_rtc_remove(struct platform_device *pdev) | |||
786 | } | 765 | } |
787 | 766 | ||
788 | iounmap(rtc->regbase); | 767 | iounmap(rtc->regbase); |
789 | release_resource(rtc->res); | 768 | release_mem_region(rtc->res->start, rtc->regsize); |
790 | 769 | ||
791 | clk_disable(rtc->clk); | 770 | clk_disable(rtc->clk); |
792 | clk_put(rtc->clk); | 771 | clk_put(rtc->clk); |
@@ -803,11 +782,11 @@ static void sh_rtc_set_irq_wake(struct device *dev, int enabled) | |||
803 | struct platform_device *pdev = to_platform_device(dev); | 782 | struct platform_device *pdev = to_platform_device(dev); |
804 | struct sh_rtc *rtc = platform_get_drvdata(pdev); | 783 | struct sh_rtc *rtc = platform_get_drvdata(pdev); |
805 | 784 | ||
806 | set_irq_wake(rtc->periodic_irq, enabled); | 785 | irq_set_irq_wake(rtc->periodic_irq, enabled); |
807 | 786 | ||
808 | if (rtc->carry_irq > 0) { | 787 | if (rtc->carry_irq > 0) { |
809 | set_irq_wake(rtc->carry_irq, enabled); | 788 | irq_set_irq_wake(rtc->carry_irq, enabled); |
810 | set_irq_wake(rtc->alarm_irq, enabled); | 789 | irq_set_irq_wake(rtc->alarm_irq, enabled); |
811 | } | 790 | } |
812 | } | 791 | } |
813 | 792 | ||
diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c new file mode 100644 index 000000000000..893bac2bb21b --- /dev/null +++ b/drivers/rtc/rtc-spear.c | |||
@@ -0,0 +1,534 @@ | |||
1 | /* | ||
2 | * drivers/rtc/rtc-spear.c | ||
3 | * | ||
4 | * Copyright (C) 2010 ST Microelectronics | ||
5 | * Rajeev Kumar<rajeev-dlh.kumar@st.com> | ||
6 | * | ||
7 | * This file is licensed under the terms of the GNU General Public | ||
8 | * License version 2. This program is licensed "as is" without any | ||
9 | * warranty of any kind, whether express or implied. | ||
10 | */ | ||
11 | |||
12 | #include <linux/bcd.h> | ||
13 | #include <linux/clk.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/irq.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/rtc.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/spinlock.h> | ||
23 | |||
24 | /* RTC registers */ | ||
25 | #define TIME_REG 0x00 | ||
26 | #define DATE_REG 0x04 | ||
27 | #define ALARM_TIME_REG 0x08 | ||
28 | #define ALARM_DATE_REG 0x0C | ||
29 | #define CTRL_REG 0x10 | ||
30 | #define STATUS_REG 0x14 | ||
31 | |||
32 | /* TIME_REG & ALARM_TIME_REG */ | ||
33 | #define SECONDS_UNITS (0xf<<0) /* seconds units position */ | ||
34 | #define SECONDS_TENS (0x7<<4) /* seconds tens position */ | ||
35 | #define MINUTES_UNITS (0xf<<8) /* minutes units position */ | ||
36 | #define MINUTES_TENS (0x7<<12) /* minutes tens position */ | ||
37 | #define HOURS_UNITS (0xf<<16) /* hours units position */ | ||
38 | #define HOURS_TENS (0x3<<20) /* hours tens position */ | ||
39 | |||
40 | /* DATE_REG & ALARM_DATE_REG */ | ||
41 | #define DAYS_UNITS (0xf<<0) /* days units position */ | ||
42 | #define DAYS_TENS (0x3<<4) /* days tens position */ | ||
43 | #define MONTHS_UNITS (0xf<<8) /* months units position */ | ||
44 | #define MONTHS_TENS (0x1<<12) /* months tens position */ | ||
45 | #define YEARS_UNITS (0xf<<16) /* years units position */ | ||
46 | #define YEARS_TENS (0xf<<20) /* years tens position */ | ||
47 | #define YEARS_HUNDREDS (0xf<<24) /* years hundereds position */ | ||
48 | #define YEARS_MILLENIUMS (0xf<<28) /* years millenium position */ | ||
49 | |||
50 | /* MASK SHIFT TIME_REG & ALARM_TIME_REG*/ | ||
51 | #define SECOND_SHIFT 0x00 /* seconds units */ | ||
52 | #define MINUTE_SHIFT 0x08 /* minutes units position */ | ||
53 | #define HOUR_SHIFT 0x10 /* hours units position */ | ||
54 | #define MDAY_SHIFT 0x00 /* Month day shift */ | ||
55 | #define MONTH_SHIFT 0x08 /* Month shift */ | ||
56 | #define YEAR_SHIFT 0x10 /* Year shift */ | ||
57 | |||
58 | #define SECOND_MASK 0x7F | ||
59 | #define MIN_MASK 0x7F | ||
60 | #define HOUR_MASK 0x3F | ||
61 | #define DAY_MASK 0x3F | ||
62 | #define MONTH_MASK 0x7F | ||
63 | #define YEAR_MASK 0xFFFF | ||
64 | |||
65 | /* date reg equal to time reg, for debug only */ | ||
66 | #define TIME_BYP (1<<9) | ||
67 | #define INT_ENABLE (1<<31) /* interrupt enable */ | ||
68 | |||
69 | /* STATUS_REG */ | ||
70 | #define CLK_UNCONNECTED (1<<0) | ||
71 | #define PEND_WR_TIME (1<<2) | ||
72 | #define PEND_WR_DATE (1<<3) | ||
73 | #define LOST_WR_TIME (1<<4) | ||
74 | #define LOST_WR_DATE (1<<5) | ||
75 | #define RTC_INT_MASK (1<<31) | ||
76 | #define STATUS_BUSY (PEND_WR_TIME | PEND_WR_DATE) | ||
77 | #define STATUS_FAIL (LOST_WR_TIME | LOST_WR_DATE) | ||
78 | |||
79 | struct spear_rtc_config { | ||
80 | struct clk *clk; | ||
81 | spinlock_t lock; | ||
82 | void __iomem *ioaddr; | ||
83 | }; | ||
84 | |||
85 | static inline void spear_rtc_clear_interrupt(struct spear_rtc_config *config) | ||
86 | { | ||
87 | unsigned int val; | ||
88 | unsigned long flags; | ||
89 | |||
90 | spin_lock_irqsave(&config->lock, flags); | ||
91 | val = readl(config->ioaddr + STATUS_REG); | ||
92 | val |= RTC_INT_MASK; | ||
93 | writel(val, config->ioaddr + STATUS_REG); | ||
94 | spin_unlock_irqrestore(&config->lock, flags); | ||
95 | } | ||
96 | |||
97 | static inline void spear_rtc_enable_interrupt(struct spear_rtc_config *config) | ||
98 | { | ||
99 | unsigned int val; | ||
100 | |||
101 | val = readl(config->ioaddr + CTRL_REG); | ||
102 | if (!(val & INT_ENABLE)) { | ||
103 | spear_rtc_clear_interrupt(config); | ||
104 | val |= INT_ENABLE; | ||
105 | writel(val, config->ioaddr + CTRL_REG); | ||
106 | } | ||
107 | } | ||
108 | |||
109 | static inline void spear_rtc_disable_interrupt(struct spear_rtc_config *config) | ||
110 | { | ||
111 | unsigned int val; | ||
112 | |||
113 | val = readl(config->ioaddr + CTRL_REG); | ||
114 | if (val & INT_ENABLE) { | ||
115 | val &= ~INT_ENABLE; | ||
116 | writel(val, config->ioaddr + CTRL_REG); | ||
117 | } | ||
118 | } | ||
119 | |||
120 | static inline int is_write_complete(struct spear_rtc_config *config) | ||
121 | { | ||
122 | int ret = 0; | ||
123 | unsigned long flags; | ||
124 | |||
125 | spin_lock_irqsave(&config->lock, flags); | ||
126 | if ((readl(config->ioaddr + STATUS_REG)) & STATUS_FAIL) | ||
127 | ret = -EIO; | ||
128 | spin_unlock_irqrestore(&config->lock, flags); | ||
129 | |||
130 | return ret; | ||
131 | } | ||
132 | |||
133 | static void rtc_wait_not_busy(struct spear_rtc_config *config) | ||
134 | { | ||
135 | int status, count = 0; | ||
136 | unsigned long flags; | ||
137 | |||
138 | /* Assuming BUSY may stay active for 80 msec) */ | ||
139 | for (count = 0; count < 80; count++) { | ||
140 | spin_lock_irqsave(&config->lock, flags); | ||
141 | status = readl(config->ioaddr + STATUS_REG); | ||
142 | spin_unlock_irqrestore(&config->lock, flags); | ||
143 | if ((status & STATUS_BUSY) == 0) | ||
144 | break; | ||
145 | /* check status busy, after each msec */ | ||
146 | msleep(1); | ||
147 | } | ||
148 | } | ||
149 | |||
150 | static irqreturn_t spear_rtc_irq(int irq, void *dev_id) | ||
151 | { | ||
152 | struct rtc_device *rtc = (struct rtc_device *)dev_id; | ||
153 | struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); | ||
154 | unsigned long flags, events = 0; | ||
155 | unsigned int irq_data; | ||
156 | |||
157 | spin_lock_irqsave(&config->lock, flags); | ||
158 | irq_data = readl(config->ioaddr + STATUS_REG); | ||
159 | spin_unlock_irqrestore(&config->lock, flags); | ||
160 | |||
161 | if ((irq_data & RTC_INT_MASK)) { | ||
162 | spear_rtc_clear_interrupt(config); | ||
163 | events = RTC_IRQF | RTC_AF; | ||
164 | rtc_update_irq(rtc, 1, events); | ||
165 | return IRQ_HANDLED; | ||
166 | } else | ||
167 | return IRQ_NONE; | ||
168 | |||
169 | } | ||
170 | |||
171 | static int tm2bcd(struct rtc_time *tm) | ||
172 | { | ||
173 | if (rtc_valid_tm(tm) != 0) | ||
174 | return -EINVAL; | ||
175 | tm->tm_sec = bin2bcd(tm->tm_sec); | ||
176 | tm->tm_min = bin2bcd(tm->tm_min); | ||
177 | tm->tm_hour = bin2bcd(tm->tm_hour); | ||
178 | tm->tm_mday = bin2bcd(tm->tm_mday); | ||
179 | tm->tm_mon = bin2bcd(tm->tm_mon + 1); | ||
180 | tm->tm_year = bin2bcd(tm->tm_year); | ||
181 | |||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | static void bcd2tm(struct rtc_time *tm) | ||
186 | { | ||
187 | tm->tm_sec = bcd2bin(tm->tm_sec); | ||
188 | tm->tm_min = bcd2bin(tm->tm_min); | ||
189 | tm->tm_hour = bcd2bin(tm->tm_hour); | ||
190 | tm->tm_mday = bcd2bin(tm->tm_mday); | ||
191 | tm->tm_mon = bcd2bin(tm->tm_mon) - 1; | ||
192 | /* epoch == 1900 */ | ||
193 | tm->tm_year = bcd2bin(tm->tm_year); | ||
194 | } | ||
195 | |||
196 | /* | ||
197 | * spear_rtc_read_time - set the time | ||
198 | * @dev: rtc device in use | ||
199 | * @tm: holds date and time | ||
200 | * | ||
201 | * This function read time and date. On success it will return 0 | ||
202 | * otherwise -ve error is returned. | ||
203 | */ | ||
204 | static int spear_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
205 | { | ||
206 | struct platform_device *pdev = to_platform_device(dev); | ||
207 | struct rtc_device *rtc = platform_get_drvdata(pdev); | ||
208 | struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); | ||
209 | unsigned int time, date; | ||
210 | |||
211 | /* we don't report wday/yday/isdst ... */ | ||
212 | rtc_wait_not_busy(config); | ||
213 | |||
214 | time = readl(config->ioaddr + TIME_REG); | ||
215 | date = readl(config->ioaddr + DATE_REG); | ||
216 | tm->tm_sec = (time >> SECOND_SHIFT) & SECOND_MASK; | ||
217 | tm->tm_min = (time >> MINUTE_SHIFT) & MIN_MASK; | ||
218 | tm->tm_hour = (time >> HOUR_SHIFT) & HOUR_MASK; | ||
219 | tm->tm_mday = (date >> MDAY_SHIFT) & DAY_MASK; | ||
220 | tm->tm_mon = (date >> MONTH_SHIFT) & MONTH_MASK; | ||
221 | tm->tm_year = (date >> YEAR_SHIFT) & YEAR_MASK; | ||
222 | |||
223 | bcd2tm(tm); | ||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | /* | ||
228 | * spear_rtc_set_time - set the time | ||
229 | * @dev: rtc device in use | ||
230 | * @tm: holds date and time | ||
231 | * | ||
232 | * This function set time and date. On success it will return 0 | ||
233 | * otherwise -ve error is returned. | ||
234 | */ | ||
235 | static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
236 | { | ||
237 | struct platform_device *pdev = to_platform_device(dev); | ||
238 | struct rtc_device *rtc = platform_get_drvdata(pdev); | ||
239 | struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); | ||
240 | unsigned int time, date, err = 0; | ||
241 | |||
242 | if (tm2bcd(tm) < 0) | ||
243 | return -EINVAL; | ||
244 | |||
245 | rtc_wait_not_busy(config); | ||
246 | time = (tm->tm_sec << SECOND_SHIFT) | (tm->tm_min << MINUTE_SHIFT) | | ||
247 | (tm->tm_hour << HOUR_SHIFT); | ||
248 | date = (tm->tm_mday << MDAY_SHIFT) | (tm->tm_mon << MONTH_SHIFT) | | ||
249 | (tm->tm_year << YEAR_SHIFT); | ||
250 | writel(time, config->ioaddr + TIME_REG); | ||
251 | writel(date, config->ioaddr + DATE_REG); | ||
252 | err = is_write_complete(config); | ||
253 | if (err < 0) | ||
254 | return err; | ||
255 | |||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | /* | ||
260 | * spear_rtc_read_alarm - read the alarm time | ||
261 | * @dev: rtc device in use | ||
262 | * @alm: holds alarm date and time | ||
263 | * | ||
264 | * This function read alarm time and date. On success it will return 0 | ||
265 | * otherwise -ve error is returned. | ||
266 | */ | ||
267 | static int spear_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | ||
268 | { | ||
269 | struct platform_device *pdev = to_platform_device(dev); | ||
270 | struct rtc_device *rtc = platform_get_drvdata(pdev); | ||
271 | struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); | ||
272 | unsigned int time, date; | ||
273 | |||
274 | rtc_wait_not_busy(config); | ||
275 | |||
276 | time = readl(config->ioaddr + ALARM_TIME_REG); | ||
277 | date = readl(config->ioaddr + ALARM_DATE_REG); | ||
278 | alm->time.tm_sec = (time >> SECOND_SHIFT) & SECOND_MASK; | ||
279 | alm->time.tm_min = (time >> MINUTE_SHIFT) & MIN_MASK; | ||
280 | alm->time.tm_hour = (time >> HOUR_SHIFT) & HOUR_MASK; | ||
281 | alm->time.tm_mday = (date >> MDAY_SHIFT) & DAY_MASK; | ||
282 | alm->time.tm_mon = (date >> MONTH_SHIFT) & MONTH_MASK; | ||
283 | alm->time.tm_year = (date >> YEAR_SHIFT) & YEAR_MASK; | ||
284 | |||
285 | bcd2tm(&alm->time); | ||
286 | alm->enabled = readl(config->ioaddr + CTRL_REG) & INT_ENABLE; | ||
287 | |||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * spear_rtc_set_alarm - set the alarm time | ||
293 | * @dev: rtc device in use | ||
294 | * @alm: holds alarm date and time | ||
295 | * | ||
296 | * This function set alarm time and date. On success it will return 0 | ||
297 | * otherwise -ve error is returned. | ||
298 | */ | ||
299 | static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | ||
300 | { | ||
301 | struct platform_device *pdev = to_platform_device(dev); | ||
302 | struct rtc_device *rtc = platform_get_drvdata(pdev); | ||
303 | struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); | ||
304 | unsigned int time, date, err = 0; | ||
305 | |||
306 | if (tm2bcd(&alm->time) < 0) | ||
307 | return -EINVAL; | ||
308 | |||
309 | rtc_wait_not_busy(config); | ||
310 | |||
311 | time = (alm->time.tm_sec << SECOND_SHIFT) | (alm->time.tm_min << | ||
312 | MINUTE_SHIFT) | (alm->time.tm_hour << HOUR_SHIFT); | ||
313 | date = (alm->time.tm_mday << MDAY_SHIFT) | (alm->time.tm_mon << | ||
314 | MONTH_SHIFT) | (alm->time.tm_year << YEAR_SHIFT); | ||
315 | |||
316 | writel(time, config->ioaddr + ALARM_TIME_REG); | ||
317 | writel(date, config->ioaddr + ALARM_DATE_REG); | ||
318 | err = is_write_complete(config); | ||
319 | if (err < 0) | ||
320 | return err; | ||
321 | |||
322 | if (alm->enabled) | ||
323 | spear_rtc_enable_interrupt(config); | ||
324 | else | ||
325 | spear_rtc_disable_interrupt(config); | ||
326 | |||
327 | return 0; | ||
328 | } | ||
329 | static struct rtc_class_ops spear_rtc_ops = { | ||
330 | .read_time = spear_rtc_read_time, | ||
331 | .set_time = spear_rtc_set_time, | ||
332 | .read_alarm = spear_rtc_read_alarm, | ||
333 | .set_alarm = spear_rtc_set_alarm, | ||
334 | }; | ||
335 | |||
336 | static int __devinit spear_rtc_probe(struct platform_device *pdev) | ||
337 | { | ||
338 | struct resource *res; | ||
339 | struct rtc_device *rtc; | ||
340 | struct spear_rtc_config *config; | ||
341 | unsigned int status = 0; | ||
342 | int irq; | ||
343 | |||
344 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
345 | if (!res) { | ||
346 | dev_err(&pdev->dev, "no resource defined\n"); | ||
347 | return -EBUSY; | ||
348 | } | ||
349 | if (!request_mem_region(res->start, resource_size(res), pdev->name)) { | ||
350 | dev_err(&pdev->dev, "rtc region already claimed\n"); | ||
351 | return -EBUSY; | ||
352 | } | ||
353 | |||
354 | config = kzalloc(sizeof(*config), GFP_KERNEL); | ||
355 | if (!config) { | ||
356 | dev_err(&pdev->dev, "out of memory\n"); | ||
357 | status = -ENOMEM; | ||
358 | goto err_release_region; | ||
359 | } | ||
360 | |||
361 | config->clk = clk_get(&pdev->dev, NULL); | ||
362 | if (IS_ERR(config->clk)) { | ||
363 | status = PTR_ERR(config->clk); | ||
364 | goto err_kfree; | ||
365 | } | ||
366 | |||
367 | status = clk_enable(config->clk); | ||
368 | if (status < 0) | ||
369 | goto err_clk_put; | ||
370 | |||
371 | config->ioaddr = ioremap(res->start, resource_size(res)); | ||
372 | if (!config->ioaddr) { | ||
373 | dev_err(&pdev->dev, "ioremap fail\n"); | ||
374 | status = -ENOMEM; | ||
375 | goto err_disable_clock; | ||
376 | } | ||
377 | |||
378 | spin_lock_init(&config->lock); | ||
379 | |||
380 | rtc = rtc_device_register(pdev->name, &pdev->dev, &spear_rtc_ops, | ||
381 | THIS_MODULE); | ||
382 | if (IS_ERR(rtc)) { | ||
383 | dev_err(&pdev->dev, "can't register RTC device, err %ld\n", | ||
384 | PTR_ERR(rtc)); | ||
385 | status = PTR_ERR(rtc); | ||
386 | goto err_iounmap; | ||
387 | } | ||
388 | |||
389 | platform_set_drvdata(pdev, rtc); | ||
390 | dev_set_drvdata(&rtc->dev, config); | ||
391 | |||
392 | /* alarm irqs */ | ||
393 | irq = platform_get_irq(pdev, 0); | ||
394 | if (irq < 0) { | ||
395 | dev_err(&pdev->dev, "no update irq?\n"); | ||
396 | status = irq; | ||
397 | goto err_clear_platdata; | ||
398 | } | ||
399 | |||
400 | status = request_irq(irq, spear_rtc_irq, 0, pdev->name, rtc); | ||
401 | if (status) { | ||
402 | dev_err(&pdev->dev, "Alarm interrupt IRQ%d already \ | ||
403 | claimed\n", irq); | ||
404 | goto err_clear_platdata; | ||
405 | } | ||
406 | |||
407 | if (!device_can_wakeup(&pdev->dev)) | ||
408 | device_init_wakeup(&pdev->dev, 1); | ||
409 | |||
410 | return 0; | ||
411 | |||
412 | err_clear_platdata: | ||
413 | platform_set_drvdata(pdev, NULL); | ||
414 | dev_set_drvdata(&rtc->dev, NULL); | ||
415 | rtc_device_unregister(rtc); | ||
416 | err_iounmap: | ||
417 | iounmap(config->ioaddr); | ||
418 | err_disable_clock: | ||
419 | clk_disable(config->clk); | ||
420 | err_clk_put: | ||
421 | clk_put(config->clk); | ||
422 | err_kfree: | ||
423 | kfree(config); | ||
424 | err_release_region: | ||
425 | release_mem_region(res->start, resource_size(res)); | ||
426 | |||
427 | return status; | ||
428 | } | ||
429 | |||
430 | static int __devexit spear_rtc_remove(struct platform_device *pdev) | ||
431 | { | ||
432 | struct rtc_device *rtc = platform_get_drvdata(pdev); | ||
433 | struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); | ||
434 | int irq; | ||
435 | struct resource *res; | ||
436 | |||
437 | /* leave rtc running, but disable irqs */ | ||
438 | spear_rtc_disable_interrupt(config); | ||
439 | device_init_wakeup(&pdev->dev, 0); | ||
440 | irq = platform_get_irq(pdev, 0); | ||
441 | if (irq) | ||
442 | free_irq(irq, pdev); | ||
443 | clk_disable(config->clk); | ||
444 | clk_put(config->clk); | ||
445 | iounmap(config->ioaddr); | ||
446 | kfree(config); | ||
447 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
448 | if (res) | ||
449 | release_mem_region(res->start, resource_size(res)); | ||
450 | platform_set_drvdata(pdev, NULL); | ||
451 | dev_set_drvdata(&rtc->dev, NULL); | ||
452 | rtc_device_unregister(rtc); | ||
453 | |||
454 | return 0; | ||
455 | } | ||
456 | |||
457 | #ifdef CONFIG_PM | ||
458 | |||
459 | static int spear_rtc_suspend(struct platform_device *pdev, pm_message_t state) | ||
460 | { | ||
461 | struct rtc_device *rtc = platform_get_drvdata(pdev); | ||
462 | struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); | ||
463 | int irq; | ||
464 | |||
465 | irq = platform_get_irq(pdev, 0); | ||
466 | if (device_may_wakeup(&pdev->dev)) | ||
467 | enable_irq_wake(irq); | ||
468 | else { | ||
469 | spear_rtc_disable_interrupt(config); | ||
470 | clk_disable(config->clk); | ||
471 | } | ||
472 | |||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | static int spear_rtc_resume(struct platform_device *pdev) | ||
477 | { | ||
478 | struct rtc_device *rtc = platform_get_drvdata(pdev); | ||
479 | struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); | ||
480 | int irq; | ||
481 | |||
482 | irq = platform_get_irq(pdev, 0); | ||
483 | |||
484 | if (device_may_wakeup(&pdev->dev)) | ||
485 | disable_irq_wake(irq); | ||
486 | else { | ||
487 | clk_enable(config->clk); | ||
488 | spear_rtc_enable_interrupt(config); | ||
489 | } | ||
490 | |||
491 | return 0; | ||
492 | } | ||
493 | |||
494 | #else | ||
495 | #define spear_rtc_suspend NULL | ||
496 | #define spear_rtc_resume NULL | ||
497 | #endif | ||
498 | |||
499 | static void spear_rtc_shutdown(struct platform_device *pdev) | ||
500 | { | ||
501 | struct rtc_device *rtc = platform_get_drvdata(pdev); | ||
502 | struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); | ||
503 | |||
504 | spear_rtc_disable_interrupt(config); | ||
505 | clk_disable(config->clk); | ||
506 | } | ||
507 | |||
508 | static struct platform_driver spear_rtc_driver = { | ||
509 | .probe = spear_rtc_probe, | ||
510 | .remove = __devexit_p(spear_rtc_remove), | ||
511 | .suspend = spear_rtc_suspend, | ||
512 | .resume = spear_rtc_resume, | ||
513 | .shutdown = spear_rtc_shutdown, | ||
514 | .driver = { | ||
515 | .name = "rtc-spear", | ||
516 | }, | ||
517 | }; | ||
518 | |||
519 | static int __init rtc_init(void) | ||
520 | { | ||
521 | return platform_driver_register(&spear_rtc_driver); | ||
522 | } | ||
523 | module_init(rtc_init); | ||
524 | |||
525 | static void __exit rtc_exit(void) | ||
526 | { | ||
527 | platform_driver_unregister(&spear_rtc_driver); | ||
528 | } | ||
529 | module_exit(rtc_exit); | ||
530 | |||
531 | MODULE_ALIAS("platform:rtc-spear"); | ||
532 | MODULE_AUTHOR("Rajeev Kumar <rajeev-dlh.kumar@st.com>"); | ||
533 | MODULE_DESCRIPTION("ST SPEAr Realtime Clock Driver (RTC)"); | ||
534 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c index 7e7d0c806f2d..572e9534b591 100644 --- a/drivers/rtc/rtc-stmp3xxx.c +++ b/drivers/rtc/rtc-stmp3xxx.c | |||
@@ -115,19 +115,6 @@ static int stmp3xxx_alarm_irq_enable(struct device *dev, unsigned int enabled) | |||
115 | return 0; | 115 | return 0; |
116 | } | 116 | } |
117 | 117 | ||
118 | static int stmp3xxx_update_irq_enable(struct device *dev, unsigned int enabled) | ||
119 | { | ||
120 | struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); | ||
121 | |||
122 | if (enabled) | ||
123 | stmp3xxx_setl(BM_RTC_CTRL_ONEMSEC_IRQ_EN, | ||
124 | rtc_data->io + HW_RTC_CTRL); | ||
125 | else | ||
126 | stmp3xxx_clearl(BM_RTC_CTRL_ONEMSEC_IRQ_EN, | ||
127 | rtc_data->io + HW_RTC_CTRL); | ||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | static int stmp3xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | 118 | static int stmp3xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) |
132 | { | 119 | { |
133 | struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); | 120 | struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); |
@@ -149,8 +136,6 @@ static int stmp3xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
149 | static struct rtc_class_ops stmp3xxx_rtc_ops = { | 136 | static struct rtc_class_ops stmp3xxx_rtc_ops = { |
150 | .alarm_irq_enable = | 137 | .alarm_irq_enable = |
151 | stmp3xxx_alarm_irq_enable, | 138 | stmp3xxx_alarm_irq_enable, |
152 | .update_irq_enable = | ||
153 | stmp3xxx_update_irq_enable, | ||
154 | .read_time = stmp3xxx_rtc_gettime, | 139 | .read_time = stmp3xxx_rtc_gettime, |
155 | .set_mmss = stmp3xxx_rtc_set_mmss, | 140 | .set_mmss = stmp3xxx_rtc_set_mmss, |
156 | .read_alarm = stmp3xxx_rtc_read_alarm, | 141 | .read_alarm = stmp3xxx_rtc_read_alarm, |
diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c new file mode 100644 index 000000000000..2fc31aac3f4e --- /dev/null +++ b/drivers/rtc/rtc-tegra.c | |||
@@ -0,0 +1,488 @@ | |||
1 | /* | ||
2 | * An RTC driver for the NVIDIA Tegra 200 series internal RTC. | ||
3 | * | ||
4 | * Copyright (c) 2010, NVIDIA Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/irq.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/rtc.h> | ||
28 | #include <linux/platform_device.h> | ||
29 | |||
30 | /* set to 1 = busy every eight 32kHz clocks during copy of sec+msec to AHB */ | ||
31 | #define TEGRA_RTC_REG_BUSY 0x004 | ||
32 | #define TEGRA_RTC_REG_SECONDS 0x008 | ||
33 | /* when msec is read, the seconds are buffered into shadow seconds. */ | ||
34 | #define TEGRA_RTC_REG_SHADOW_SECONDS 0x00c | ||
35 | #define TEGRA_RTC_REG_MILLI_SECONDS 0x010 | ||
36 | #define TEGRA_RTC_REG_SECONDS_ALARM0 0x014 | ||
37 | #define TEGRA_RTC_REG_SECONDS_ALARM1 0x018 | ||
38 | #define TEGRA_RTC_REG_MILLI_SECONDS_ALARM0 0x01c | ||
39 | #define TEGRA_RTC_REG_INTR_MASK 0x028 | ||
40 | /* write 1 bits to clear status bits */ | ||
41 | #define TEGRA_RTC_REG_INTR_STATUS 0x02c | ||
42 | |||
43 | /* bits in INTR_MASK */ | ||
44 | #define TEGRA_RTC_INTR_MASK_MSEC_CDN_ALARM (1<<4) | ||
45 | #define TEGRA_RTC_INTR_MASK_SEC_CDN_ALARM (1<<3) | ||
46 | #define TEGRA_RTC_INTR_MASK_MSEC_ALARM (1<<2) | ||
47 | #define TEGRA_RTC_INTR_MASK_SEC_ALARM1 (1<<1) | ||
48 | #define TEGRA_RTC_INTR_MASK_SEC_ALARM0 (1<<0) | ||
49 | |||
50 | /* bits in INTR_STATUS */ | ||
51 | #define TEGRA_RTC_INTR_STATUS_MSEC_CDN_ALARM (1<<4) | ||
52 | #define TEGRA_RTC_INTR_STATUS_SEC_CDN_ALARM (1<<3) | ||
53 | #define TEGRA_RTC_INTR_STATUS_MSEC_ALARM (1<<2) | ||
54 | #define TEGRA_RTC_INTR_STATUS_SEC_ALARM1 (1<<1) | ||
55 | #define TEGRA_RTC_INTR_STATUS_SEC_ALARM0 (1<<0) | ||
56 | |||
57 | struct tegra_rtc_info { | ||
58 | struct platform_device *pdev; | ||
59 | struct rtc_device *rtc_dev; | ||
60 | void __iomem *rtc_base; /* NULL if not initialized. */ | ||
61 | int tegra_rtc_irq; /* alarm and periodic irq */ | ||
62 | spinlock_t tegra_rtc_lock; | ||
63 | }; | ||
64 | |||
65 | /* RTC hardware is busy when it is updating its values over AHB once | ||
66 | * every eight 32kHz clocks (~250uS). | ||
67 | * outside of these updates the CPU is free to write. | ||
68 | * CPU is always free to read. | ||
69 | */ | ||
70 | static inline u32 tegra_rtc_check_busy(struct tegra_rtc_info *info) | ||
71 | { | ||
72 | return readl(info->rtc_base + TEGRA_RTC_REG_BUSY) & 1; | ||
73 | } | ||
74 | |||
75 | /* Wait for hardware to be ready for writing. | ||
76 | * This function tries to maximize the amount of time before the next update. | ||
77 | * It does this by waiting for the RTC to become busy with its periodic update, | ||
78 | * then returning once the RTC first becomes not busy. | ||
79 | * This periodic update (where the seconds and milliseconds are copied to the | ||
80 | * AHB side) occurs every eight 32kHz clocks (~250uS). | ||
81 | * The behavior of this function allows us to make some assumptions without | ||
82 | * introducing a race, because 250uS is plenty of time to read/write a value. | ||
83 | */ | ||
84 | static int tegra_rtc_wait_while_busy(struct device *dev) | ||
85 | { | ||
86 | struct tegra_rtc_info *info = dev_get_drvdata(dev); | ||
87 | |||
88 | int retries = 500; /* ~490 us is the worst case, ~250 us is best. */ | ||
89 | |||
90 | /* first wait for the RTC to become busy. this is when it | ||
91 | * posts its updated seconds+msec registers to AHB side. */ | ||
92 | while (tegra_rtc_check_busy(info)) { | ||
93 | if (!retries--) | ||
94 | goto retry_failed; | ||
95 | udelay(1); | ||
96 | } | ||
97 | |||
98 | /* now we have about 250 us to manipulate registers */ | ||
99 | return 0; | ||
100 | |||
101 | retry_failed: | ||
102 | dev_err(dev, "write failed:retry count exceeded.\n"); | ||
103 | return -ETIMEDOUT; | ||
104 | } | ||
105 | |||
106 | static int tegra_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
107 | { | ||
108 | struct tegra_rtc_info *info = dev_get_drvdata(dev); | ||
109 | unsigned long sec, msec; | ||
110 | unsigned long sl_irq_flags; | ||
111 | |||
112 | /* RTC hardware copies seconds to shadow seconds when a read | ||
113 | * of milliseconds occurs. use a lock to keep other threads out. */ | ||
114 | spin_lock_irqsave(&info->tegra_rtc_lock, sl_irq_flags); | ||
115 | |||
116 | msec = readl(info->rtc_base + TEGRA_RTC_REG_MILLI_SECONDS); | ||
117 | sec = readl(info->rtc_base + TEGRA_RTC_REG_SHADOW_SECONDS); | ||
118 | |||
119 | spin_unlock_irqrestore(&info->tegra_rtc_lock, sl_irq_flags); | ||
120 | |||
121 | rtc_time_to_tm(sec, tm); | ||
122 | |||
123 | dev_vdbg(dev, "time read as %lu. %d/%d/%d %d:%02u:%02u\n", | ||
124 | sec, | ||
125 | tm->tm_mon + 1, | ||
126 | tm->tm_mday, | ||
127 | tm->tm_year + 1900, | ||
128 | tm->tm_hour, | ||
129 | tm->tm_min, | ||
130 | tm->tm_sec | ||
131 | ); | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static int tegra_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
137 | { | ||
138 | struct tegra_rtc_info *info = dev_get_drvdata(dev); | ||
139 | unsigned long sec; | ||
140 | int ret; | ||
141 | |||
142 | /* convert tm to seconds. */ | ||
143 | ret = rtc_valid_tm(tm); | ||
144 | if (ret) | ||
145 | return ret; | ||
146 | |||
147 | rtc_tm_to_time(tm, &sec); | ||
148 | |||
149 | dev_vdbg(dev, "time set to %lu. %d/%d/%d %d:%02u:%02u\n", | ||
150 | sec, | ||
151 | tm->tm_mon+1, | ||
152 | tm->tm_mday, | ||
153 | tm->tm_year+1900, | ||
154 | tm->tm_hour, | ||
155 | tm->tm_min, | ||
156 | tm->tm_sec | ||
157 | ); | ||
158 | |||
159 | /* seconds only written if wait succeeded. */ | ||
160 | ret = tegra_rtc_wait_while_busy(dev); | ||
161 | if (!ret) | ||
162 | writel(sec, info->rtc_base + TEGRA_RTC_REG_SECONDS); | ||
163 | |||
164 | dev_vdbg(dev, "time read back as %d\n", | ||
165 | readl(info->rtc_base + TEGRA_RTC_REG_SECONDS)); | ||
166 | |||
167 | return ret; | ||
168 | } | ||
169 | |||
170 | static int tegra_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | ||
171 | { | ||
172 | struct tegra_rtc_info *info = dev_get_drvdata(dev); | ||
173 | unsigned long sec; | ||
174 | unsigned tmp; | ||
175 | |||
176 | sec = readl(info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0); | ||
177 | |||
178 | if (sec == 0) { | ||
179 | /* alarm is disabled. */ | ||
180 | alarm->enabled = 0; | ||
181 | alarm->time.tm_mon = -1; | ||
182 | alarm->time.tm_mday = -1; | ||
183 | alarm->time.tm_year = -1; | ||
184 | alarm->time.tm_hour = -1; | ||
185 | alarm->time.tm_min = -1; | ||
186 | alarm->time.tm_sec = -1; | ||
187 | } else { | ||
188 | /* alarm is enabled. */ | ||
189 | alarm->enabled = 1; | ||
190 | rtc_time_to_tm(sec, &alarm->time); | ||
191 | } | ||
192 | |||
193 | tmp = readl(info->rtc_base + TEGRA_RTC_REG_INTR_STATUS); | ||
194 | alarm->pending = (tmp & TEGRA_RTC_INTR_STATUS_SEC_ALARM0) != 0; | ||
195 | |||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | static int tegra_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | ||
200 | { | ||
201 | struct tegra_rtc_info *info = dev_get_drvdata(dev); | ||
202 | unsigned status; | ||
203 | unsigned long sl_irq_flags; | ||
204 | |||
205 | tegra_rtc_wait_while_busy(dev); | ||
206 | spin_lock_irqsave(&info->tegra_rtc_lock, sl_irq_flags); | ||
207 | |||
208 | /* read the original value, and OR in the flag. */ | ||
209 | status = readl(info->rtc_base + TEGRA_RTC_REG_INTR_MASK); | ||
210 | if (enabled) | ||
211 | status |= TEGRA_RTC_INTR_MASK_SEC_ALARM0; /* set it */ | ||
212 | else | ||
213 | status &= ~TEGRA_RTC_INTR_MASK_SEC_ALARM0; /* clear it */ | ||
214 | |||
215 | writel(status, info->rtc_base + TEGRA_RTC_REG_INTR_MASK); | ||
216 | |||
217 | spin_unlock_irqrestore(&info->tegra_rtc_lock, sl_irq_flags); | ||
218 | |||
219 | return 0; | ||
220 | } | ||
221 | |||
222 | static int tegra_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) | ||
223 | { | ||
224 | struct tegra_rtc_info *info = dev_get_drvdata(dev); | ||
225 | unsigned long sec; | ||
226 | |||
227 | if (alarm->enabled) | ||
228 | rtc_tm_to_time(&alarm->time, &sec); | ||
229 | else | ||
230 | sec = 0; | ||
231 | |||
232 | tegra_rtc_wait_while_busy(dev); | ||
233 | writel(sec, info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0); | ||
234 | dev_vdbg(dev, "alarm read back as %d\n", | ||
235 | readl(info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0)); | ||
236 | |||
237 | /* if successfully written and alarm is enabled ... */ | ||
238 | if (sec) { | ||
239 | tegra_rtc_alarm_irq_enable(dev, 1); | ||
240 | |||
241 | dev_vdbg(dev, "alarm set as %lu. %d/%d/%d %d:%02u:%02u\n", | ||
242 | sec, | ||
243 | alarm->time.tm_mon+1, | ||
244 | alarm->time.tm_mday, | ||
245 | alarm->time.tm_year+1900, | ||
246 | alarm->time.tm_hour, | ||
247 | alarm->time.tm_min, | ||
248 | alarm->time.tm_sec); | ||
249 | } else { | ||
250 | /* disable alarm if 0 or write error. */ | ||
251 | dev_vdbg(dev, "alarm disabled\n"); | ||
252 | tegra_rtc_alarm_irq_enable(dev, 0); | ||
253 | } | ||
254 | |||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | static int tegra_rtc_proc(struct device *dev, struct seq_file *seq) | ||
259 | { | ||
260 | if (!dev || !dev->driver) | ||
261 | return 0; | ||
262 | |||
263 | return seq_printf(seq, "name\t\t: %s\n", dev_name(dev)); | ||
264 | } | ||
265 | |||
266 | static irqreturn_t tegra_rtc_irq_handler(int irq, void *data) | ||
267 | { | ||
268 | struct device *dev = data; | ||
269 | struct tegra_rtc_info *info = dev_get_drvdata(dev); | ||
270 | unsigned long events = 0; | ||
271 | unsigned status; | ||
272 | unsigned long sl_irq_flags; | ||
273 | |||
274 | status = readl(info->rtc_base + TEGRA_RTC_REG_INTR_STATUS); | ||
275 | if (status) { | ||
276 | /* clear the interrupt masks and status on any irq. */ | ||
277 | tegra_rtc_wait_while_busy(dev); | ||
278 | spin_lock_irqsave(&info->tegra_rtc_lock, sl_irq_flags); | ||
279 | writel(0, info->rtc_base + TEGRA_RTC_REG_INTR_MASK); | ||
280 | writel(status, info->rtc_base + TEGRA_RTC_REG_INTR_STATUS); | ||
281 | spin_unlock_irqrestore(&info->tegra_rtc_lock, sl_irq_flags); | ||
282 | } | ||
283 | |||
284 | /* check if Alarm */ | ||
285 | if ((status & TEGRA_RTC_INTR_STATUS_SEC_ALARM0)) | ||
286 | events |= RTC_IRQF | RTC_AF; | ||
287 | |||
288 | /* check if Periodic */ | ||
289 | if ((status & TEGRA_RTC_INTR_STATUS_SEC_CDN_ALARM)) | ||
290 | events |= RTC_IRQF | RTC_PF; | ||
291 | |||
292 | rtc_update_irq(info->rtc_dev, 1, events); | ||
293 | |||
294 | return IRQ_HANDLED; | ||
295 | } | ||
296 | |||
297 | static struct rtc_class_ops tegra_rtc_ops = { | ||
298 | .read_time = tegra_rtc_read_time, | ||
299 | .set_time = tegra_rtc_set_time, | ||
300 | .read_alarm = tegra_rtc_read_alarm, | ||
301 | .set_alarm = tegra_rtc_set_alarm, | ||
302 | .proc = tegra_rtc_proc, | ||
303 | .alarm_irq_enable = tegra_rtc_alarm_irq_enable, | ||
304 | }; | ||
305 | |||
306 | static int __devinit tegra_rtc_probe(struct platform_device *pdev) | ||
307 | { | ||
308 | struct tegra_rtc_info *info; | ||
309 | struct resource *res; | ||
310 | int ret; | ||
311 | |||
312 | info = kzalloc(sizeof(struct tegra_rtc_info), GFP_KERNEL); | ||
313 | if (!info) | ||
314 | return -ENOMEM; | ||
315 | |||
316 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
317 | if (!res) { | ||
318 | dev_err(&pdev->dev, | ||
319 | "Unable to allocate resources for device.\n"); | ||
320 | ret = -EBUSY; | ||
321 | goto err_free_info; | ||
322 | } | ||
323 | |||
324 | if (!request_mem_region(res->start, resource_size(res), pdev->name)) { | ||
325 | dev_err(&pdev->dev, | ||
326 | "Unable to request mem region for device.\n"); | ||
327 | ret = -EBUSY; | ||
328 | goto err_free_info; | ||
329 | } | ||
330 | |||
331 | info->tegra_rtc_irq = platform_get_irq(pdev, 0); | ||
332 | if (info->tegra_rtc_irq <= 0) { | ||
333 | ret = -EBUSY; | ||
334 | goto err_release_mem_region; | ||
335 | } | ||
336 | |||
337 | info->rtc_base = ioremap_nocache(res->start, resource_size(res)); | ||
338 | if (!info->rtc_base) { | ||
339 | dev_err(&pdev->dev, "Unable to grab IOs for device.\n"); | ||
340 | ret = -EBUSY; | ||
341 | goto err_release_mem_region; | ||
342 | } | ||
343 | |||
344 | /* set context info. */ | ||
345 | info->pdev = pdev; | ||
346 | info->tegra_rtc_lock = __SPIN_LOCK_UNLOCKED(info->tegra_rtc_lock); | ||
347 | |||
348 | platform_set_drvdata(pdev, info); | ||
349 | |||
350 | /* clear out the hardware. */ | ||
351 | writel(0, info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0); | ||
352 | writel(0xffffffff, info->rtc_base + TEGRA_RTC_REG_INTR_STATUS); | ||
353 | writel(0, info->rtc_base + TEGRA_RTC_REG_INTR_MASK); | ||
354 | |||
355 | device_init_wakeup(&pdev->dev, 1); | ||
356 | |||
357 | info->rtc_dev = rtc_device_register( | ||
358 | pdev->name, &pdev->dev, &tegra_rtc_ops, THIS_MODULE); | ||
359 | if (IS_ERR(info->rtc_dev)) { | ||
360 | ret = PTR_ERR(info->rtc_dev); | ||
361 | info->rtc_dev = NULL; | ||
362 | dev_err(&pdev->dev, | ||
363 | "Unable to register device (err=%d).\n", | ||
364 | ret); | ||
365 | goto err_iounmap; | ||
366 | } | ||
367 | |||
368 | ret = request_irq(info->tegra_rtc_irq, tegra_rtc_irq_handler, | ||
369 | IRQF_TRIGGER_HIGH, "rtc alarm", &pdev->dev); | ||
370 | if (ret) { | ||
371 | dev_err(&pdev->dev, | ||
372 | "Unable to request interrupt for device (err=%d).\n", | ||
373 | ret); | ||
374 | goto err_dev_unreg; | ||
375 | } | ||
376 | |||
377 | dev_notice(&pdev->dev, "Tegra internal Real Time Clock\n"); | ||
378 | |||
379 | return 0; | ||
380 | |||
381 | err_dev_unreg: | ||
382 | rtc_device_unregister(info->rtc_dev); | ||
383 | err_iounmap: | ||
384 | iounmap(info->rtc_base); | ||
385 | err_release_mem_region: | ||
386 | release_mem_region(res->start, resource_size(res)); | ||
387 | err_free_info: | ||
388 | kfree(info); | ||
389 | |||
390 | return ret; | ||
391 | } | ||
392 | |||
393 | static int __devexit tegra_rtc_remove(struct platform_device *pdev) | ||
394 | { | ||
395 | struct tegra_rtc_info *info = platform_get_drvdata(pdev); | ||
396 | struct resource *res; | ||
397 | |||
398 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
399 | if (!res) | ||
400 | return -EBUSY; | ||
401 | |||
402 | free_irq(info->tegra_rtc_irq, &pdev->dev); | ||
403 | rtc_device_unregister(info->rtc_dev); | ||
404 | iounmap(info->rtc_base); | ||
405 | release_mem_region(res->start, resource_size(res)); | ||
406 | kfree(info); | ||
407 | |||
408 | platform_set_drvdata(pdev, NULL); | ||
409 | |||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | #ifdef CONFIG_PM | ||
414 | static int tegra_rtc_suspend(struct platform_device *pdev, pm_message_t state) | ||
415 | { | ||
416 | struct device *dev = &pdev->dev; | ||
417 | struct tegra_rtc_info *info = platform_get_drvdata(pdev); | ||
418 | |||
419 | tegra_rtc_wait_while_busy(dev); | ||
420 | |||
421 | /* only use ALARM0 as a wake source. */ | ||
422 | writel(0xffffffff, info->rtc_base + TEGRA_RTC_REG_INTR_STATUS); | ||
423 | writel(TEGRA_RTC_INTR_STATUS_SEC_ALARM0, | ||
424 | info->rtc_base + TEGRA_RTC_REG_INTR_MASK); | ||
425 | |||
426 | dev_vdbg(dev, "alarm sec = %d\n", | ||
427 | readl(info->rtc_base + TEGRA_RTC_REG_SECONDS_ALARM0)); | ||
428 | |||
429 | dev_vdbg(dev, "Suspend (device_may_wakeup=%d) irq:%d\n", | ||
430 | device_may_wakeup(dev), info->tegra_rtc_irq); | ||
431 | |||
432 | /* leave the alarms on as a wake source. */ | ||
433 | if (device_may_wakeup(dev)) | ||
434 | enable_irq_wake(info->tegra_rtc_irq); | ||
435 | |||
436 | return 0; | ||
437 | } | ||
438 | |||
439 | static int tegra_rtc_resume(struct platform_device *pdev) | ||
440 | { | ||
441 | struct device *dev = &pdev->dev; | ||
442 | struct tegra_rtc_info *info = platform_get_drvdata(pdev); | ||
443 | |||
444 | dev_vdbg(dev, "Resume (device_may_wakeup=%d)\n", | ||
445 | device_may_wakeup(dev)); | ||
446 | /* alarms were left on as a wake source, turn them off. */ | ||
447 | if (device_may_wakeup(dev)) | ||
448 | disable_irq_wake(info->tegra_rtc_irq); | ||
449 | |||
450 | return 0; | ||
451 | } | ||
452 | #endif | ||
453 | |||
454 | static void tegra_rtc_shutdown(struct platform_device *pdev) | ||
455 | { | ||
456 | dev_vdbg(&pdev->dev, "disabling interrupts.\n"); | ||
457 | tegra_rtc_alarm_irq_enable(&pdev->dev, 0); | ||
458 | } | ||
459 | |||
460 | MODULE_ALIAS("platform:tegra_rtc"); | ||
461 | static struct platform_driver tegra_rtc_driver = { | ||
462 | .remove = __devexit_p(tegra_rtc_remove), | ||
463 | .shutdown = tegra_rtc_shutdown, | ||
464 | .driver = { | ||
465 | .name = "tegra_rtc", | ||
466 | .owner = THIS_MODULE, | ||
467 | }, | ||
468 | #ifdef CONFIG_PM | ||
469 | .suspend = tegra_rtc_suspend, | ||
470 | .resume = tegra_rtc_resume, | ||
471 | #endif | ||
472 | }; | ||
473 | |||
474 | static int __init tegra_rtc_init(void) | ||
475 | { | ||
476 | return platform_driver_probe(&tegra_rtc_driver, tegra_rtc_probe); | ||
477 | } | ||
478 | module_init(tegra_rtc_init); | ||
479 | |||
480 | static void __exit tegra_rtc_exit(void) | ||
481 | { | ||
482 | platform_driver_unregister(&tegra_rtc_driver); | ||
483 | } | ||
484 | module_exit(tegra_rtc_exit); | ||
485 | |||
486 | MODULE_AUTHOR("Jon Mayo <jmayo@nvidia.com>"); | ||
487 | MODULE_DESCRIPTION("driver for Tegra internal RTC"); | ||
488 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c index 51725f7755b0..7e96254bd365 100644 --- a/drivers/rtc/rtc-test.c +++ b/drivers/rtc/rtc-test.c | |||
@@ -50,24 +50,9 @@ static int test_rtc_proc(struct device *dev, struct seq_file *seq) | |||
50 | return 0; | 50 | return 0; |
51 | } | 51 | } |
52 | 52 | ||
53 | static int test_rtc_ioctl(struct device *dev, unsigned int cmd, | 53 | static int test_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) |
54 | unsigned long arg) | ||
55 | { | 54 | { |
56 | /* We do support interrupts, they're generated | 55 | return 0; |
57 | * using the sysfs interface. | ||
58 | */ | ||
59 | switch (cmd) { | ||
60 | case RTC_PIE_ON: | ||
61 | case RTC_PIE_OFF: | ||
62 | case RTC_UIE_ON: | ||
63 | case RTC_UIE_OFF: | ||
64 | case RTC_AIE_ON: | ||
65 | case RTC_AIE_OFF: | ||
66 | return 0; | ||
67 | |||
68 | default: | ||
69 | return -ENOIOCTLCMD; | ||
70 | } | ||
71 | } | 56 | } |
72 | 57 | ||
73 | static const struct rtc_class_ops test_rtc_ops = { | 58 | static const struct rtc_class_ops test_rtc_ops = { |
@@ -76,7 +61,7 @@ static const struct rtc_class_ops test_rtc_ops = { | |||
76 | .read_alarm = test_rtc_read_alarm, | 61 | .read_alarm = test_rtc_read_alarm, |
77 | .set_alarm = test_rtc_set_alarm, | 62 | .set_alarm = test_rtc_set_alarm, |
78 | .set_mmss = test_rtc_set_mmss, | 63 | .set_mmss = test_rtc_set_mmss, |
79 | .ioctl = test_rtc_ioctl, | 64 | .alarm_irq_enable = test_rtc_alarm_irq_enable, |
80 | }; | 65 | }; |
81 | 66 | ||
82 | static ssize_t test_irq_show(struct device *dev, | 67 | static ssize_t test_irq_show(struct device *dev, |
@@ -93,11 +78,16 @@ static ssize_t test_irq_store(struct device *dev, | |||
93 | struct rtc_device *rtc = platform_get_drvdata(plat_dev); | 78 | struct rtc_device *rtc = platform_get_drvdata(plat_dev); |
94 | 79 | ||
95 | retval = count; | 80 | retval = count; |
96 | if (strncmp(buf, "tick", 4) == 0) | 81 | if (strncmp(buf, "tick", 4) == 0 && rtc->pie_enabled) |
97 | rtc_update_irq(rtc, 1, RTC_PF | RTC_IRQF); | 82 | rtc_update_irq(rtc, 1, RTC_PF | RTC_IRQF); |
98 | else if (strncmp(buf, "alarm", 5) == 0) | 83 | else if (strncmp(buf, "alarm", 5) == 0) { |
99 | rtc_update_irq(rtc, 1, RTC_AF | RTC_IRQF); | 84 | struct rtc_wkalrm alrm; |
100 | else if (strncmp(buf, "update", 6) == 0) | 85 | int err = rtc_read_alarm(rtc, &alrm); |
86 | |||
87 | if (!err && alrm.enabled) | ||
88 | rtc_update_irq(rtc, 1, RTC_AF | RTC_IRQF); | ||
89 | |||
90 | } else if (strncmp(buf, "update", 6) == 0 && rtc->uie_rtctimer.enabled) | ||
101 | rtc_update_irq(rtc, 1, RTC_UF | RTC_IRQF); | 91 | rtc_update_irq(rtc, 1, RTC_UF | RTC_IRQF); |
102 | else | 92 | else |
103 | retval = -EINVAL; | 93 | retval = -EINVAL; |
diff --git a/drivers/rtc/rtc-tile.c b/drivers/rtc/rtc-tile.c new file mode 100644 index 000000000000..eb65dafee66e --- /dev/null +++ b/drivers/rtc/rtc-tile.c | |||
@@ -0,0 +1,162 @@ | |||
1 | /* | ||
2 | * Copyright 2011 Tilera Corporation. All Rights Reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation, version 2. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, but | ||
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
11 | * NON INFRINGEMENT. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * Tilera-specific RTC driver. | ||
15 | */ | ||
16 | |||
17 | #include <linux/module.h> | ||
18 | #include <linux/device.h> | ||
19 | #include <linux/rtc.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | |||
22 | /* Platform device pointer. */ | ||
23 | static struct platform_device *tile_rtc_platform_device; | ||
24 | |||
25 | /* | ||
26 | * RTC read routine. Gets time info from RTC chip via hypervisor syscall. | ||
27 | */ | ||
28 | static int read_rtc_time(struct device *dev, struct rtc_time *tm) | ||
29 | { | ||
30 | HV_RTCTime hvtm = hv_get_rtc(); | ||
31 | |||
32 | tm->tm_sec = hvtm.tm_sec; | ||
33 | tm->tm_min = hvtm.tm_min; | ||
34 | tm->tm_hour = hvtm.tm_hour; | ||
35 | tm->tm_mday = hvtm.tm_mday; | ||
36 | tm->tm_mon = hvtm.tm_mon; | ||
37 | tm->tm_year = hvtm.tm_year; | ||
38 | tm->tm_wday = 0; | ||
39 | tm->tm_yday = 0; | ||
40 | tm->tm_isdst = 0; | ||
41 | |||
42 | if (rtc_valid_tm(tm) < 0) | ||
43 | dev_warn(dev, "Read invalid date/time from RTC\n"); | ||
44 | |||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | /* | ||
49 | * RTC write routine. Sends time info to hypervisor via syscall, to be | ||
50 | * written to RTC chip. | ||
51 | */ | ||
52 | static int set_rtc_time(struct device *dev, struct rtc_time *tm) | ||
53 | { | ||
54 | HV_RTCTime hvtm; | ||
55 | |||
56 | hvtm.tm_sec = tm->tm_sec; | ||
57 | hvtm.tm_min = tm->tm_min; | ||
58 | hvtm.tm_hour = tm->tm_hour; | ||
59 | hvtm.tm_mday = tm->tm_mday; | ||
60 | hvtm.tm_mon = tm->tm_mon; | ||
61 | hvtm.tm_year = tm->tm_year; | ||
62 | |||
63 | hv_set_rtc(hvtm); | ||
64 | |||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | /* | ||
69 | * RTC read/write ops. | ||
70 | */ | ||
71 | static const struct rtc_class_ops tile_rtc_ops = { | ||
72 | .read_time = read_rtc_time, | ||
73 | .set_time = set_rtc_time, | ||
74 | }; | ||
75 | |||
76 | /* | ||
77 | * Device probe routine. | ||
78 | */ | ||
79 | static int __devinit tile_rtc_probe(struct platform_device *dev) | ||
80 | { | ||
81 | struct rtc_device *rtc; | ||
82 | |||
83 | rtc = rtc_device_register("tile", | ||
84 | &dev->dev, &tile_rtc_ops, THIS_MODULE); | ||
85 | |||
86 | if (IS_ERR(rtc)) | ||
87 | return PTR_ERR(rtc); | ||
88 | |||
89 | platform_set_drvdata(dev, rtc); | ||
90 | |||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | /* | ||
95 | * Device cleanup routine. | ||
96 | */ | ||
97 | static int __devexit tile_rtc_remove(struct platform_device *dev) | ||
98 | { | ||
99 | struct rtc_device *rtc = platform_get_drvdata(dev); | ||
100 | |||
101 | if (rtc) | ||
102 | rtc_device_unregister(rtc); | ||
103 | |||
104 | platform_set_drvdata(dev, NULL); | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static struct platform_driver tile_rtc_platform_driver = { | ||
110 | .driver = { | ||
111 | .name = "rtc-tile", | ||
112 | .owner = THIS_MODULE, | ||
113 | }, | ||
114 | .probe = tile_rtc_probe, | ||
115 | .remove = __devexit_p(tile_rtc_remove), | ||
116 | }; | ||
117 | |||
118 | /* | ||
119 | * Driver init routine. | ||
120 | */ | ||
121 | static int __init tile_rtc_driver_init(void) | ||
122 | { | ||
123 | int err; | ||
124 | |||
125 | err = platform_driver_register(&tile_rtc_platform_driver); | ||
126 | if (err) | ||
127 | return err; | ||
128 | |||
129 | tile_rtc_platform_device = platform_device_alloc("rtc-tile", 0); | ||
130 | if (tile_rtc_platform_device == NULL) { | ||
131 | err = -ENOMEM; | ||
132 | goto exit_driver_unregister; | ||
133 | } | ||
134 | |||
135 | err = platform_device_add(tile_rtc_platform_device); | ||
136 | if (err) | ||
137 | goto exit_device_put; | ||
138 | |||
139 | return 0; | ||
140 | |||
141 | exit_device_put: | ||
142 | platform_device_put(tile_rtc_platform_device); | ||
143 | |||
144 | exit_driver_unregister: | ||
145 | platform_driver_unregister(&tile_rtc_platform_driver); | ||
146 | return err; | ||
147 | } | ||
148 | |||
149 | /* | ||
150 | * Driver cleanup routine. | ||
151 | */ | ||
152 | static void __exit tile_rtc_driver_exit(void) | ||
153 | { | ||
154 | platform_driver_unregister(&tile_rtc_platform_driver); | ||
155 | } | ||
156 | |||
157 | module_init(tile_rtc_driver_init); | ||
158 | module_exit(tile_rtc_driver_exit); | ||
159 | |||
160 | MODULE_DESCRIPTION("Tilera-specific Real Time Clock Driver"); | ||
161 | MODULE_LICENSE("GPL"); | ||
162 | MODULE_ALIAS("platform:rtc-tile"); | ||
diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index ed1b86828124..f9a2799c44d6 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c | |||
@@ -213,18 +213,6 @@ static int twl_rtc_alarm_irq_enable(struct device *dev, unsigned enabled) | |||
213 | return ret; | 213 | return ret; |
214 | } | 214 | } |
215 | 215 | ||
216 | static int twl_rtc_update_irq_enable(struct device *dev, unsigned enabled) | ||
217 | { | ||
218 | int ret; | ||
219 | |||
220 | if (enabled) | ||
221 | ret = set_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M); | ||
222 | else | ||
223 | ret = mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M); | ||
224 | |||
225 | return ret; | ||
226 | } | ||
227 | |||
228 | /* | 216 | /* |
229 | * Gets current TWL RTC time and date parameters. | 217 | * Gets current TWL RTC time and date parameters. |
230 | * | 218 | * |
@@ -433,7 +421,6 @@ static struct rtc_class_ops twl_rtc_ops = { | |||
433 | .read_alarm = twl_rtc_read_alarm, | 421 | .read_alarm = twl_rtc_read_alarm, |
434 | .set_alarm = twl_rtc_set_alarm, | 422 | .set_alarm = twl_rtc_set_alarm, |
435 | .alarm_irq_enable = twl_rtc_alarm_irq_enable, | 423 | .alarm_irq_enable = twl_rtc_alarm_irq_enable, |
436 | .update_irq_enable = twl_rtc_update_irq_enable, | ||
437 | }; | 424 | }; |
438 | 425 | ||
439 | /*----------------------------------------------------------------------*/ | 426 | /*----------------------------------------------------------------------*/ |
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index c3244244e8cf..c5698cda366a 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c | |||
@@ -207,59 +207,9 @@ static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | |||
207 | return 0; | 207 | return 0; |
208 | } | 208 | } |
209 | 209 | ||
210 | static int vr41xx_rtc_irq_set_freq(struct device *dev, int freq) | ||
211 | { | ||
212 | u64 count; | ||
213 | |||
214 | if (!is_power_of_2(freq)) | ||
215 | return -EINVAL; | ||
216 | count = RTC_FREQUENCY; | ||
217 | do_div(count, freq); | ||
218 | |||
219 | spin_lock_irq(&rtc_lock); | ||
220 | |||
221 | periodic_count = count; | ||
222 | rtc1_write(RTCL1LREG, periodic_count); | ||
223 | rtc1_write(RTCL1HREG, periodic_count >> 16); | ||
224 | |||
225 | spin_unlock_irq(&rtc_lock); | ||
226 | |||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | static int vr41xx_rtc_irq_set_state(struct device *dev, int enabled) | ||
231 | { | ||
232 | if (enabled) | ||
233 | enable_irq(pie_irq); | ||
234 | else | ||
235 | disable_irq(pie_irq); | ||
236 | |||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | 210 | static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) |
241 | { | 211 | { |
242 | switch (cmd) { | 212 | switch (cmd) { |
243 | case RTC_AIE_ON: | ||
244 | spin_lock_irq(&rtc_lock); | ||
245 | |||
246 | if (!alarm_enabled) { | ||
247 | enable_irq(aie_irq); | ||
248 | alarm_enabled = 1; | ||
249 | } | ||
250 | |||
251 | spin_unlock_irq(&rtc_lock); | ||
252 | break; | ||
253 | case RTC_AIE_OFF: | ||
254 | spin_lock_irq(&rtc_lock); | ||
255 | |||
256 | if (alarm_enabled) { | ||
257 | disable_irq(aie_irq); | ||
258 | alarm_enabled = 0; | ||
259 | } | ||
260 | |||
261 | spin_unlock_irq(&rtc_lock); | ||
262 | break; | ||
263 | case RTC_EPOCH_READ: | 213 | case RTC_EPOCH_READ: |
264 | return put_user(epoch, (unsigned long __user *)arg); | 214 | return put_user(epoch, (unsigned long __user *)arg); |
265 | case RTC_EPOCH_SET: | 215 | case RTC_EPOCH_SET: |
@@ -275,6 +225,24 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long | |||
275 | return 0; | 225 | return 0; |
276 | } | 226 | } |
277 | 227 | ||
228 | static int vr41xx_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | ||
229 | { | ||
230 | spin_lock_irq(&rtc_lock); | ||
231 | if (enabled) { | ||
232 | if (!alarm_enabled) { | ||
233 | enable_irq(aie_irq); | ||
234 | alarm_enabled = 1; | ||
235 | } | ||
236 | } else { | ||
237 | if (alarm_enabled) { | ||
238 | disable_irq(aie_irq); | ||
239 | alarm_enabled = 0; | ||
240 | } | ||
241 | } | ||
242 | spin_unlock_irq(&rtc_lock); | ||
243 | return 0; | ||
244 | } | ||
245 | |||
278 | static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id) | 246 | static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id) |
279 | { | 247 | { |
280 | struct platform_device *pdev = (struct platform_device *)dev_id; | 248 | struct platform_device *pdev = (struct platform_device *)dev_id; |
@@ -310,8 +278,6 @@ static const struct rtc_class_ops vr41xx_rtc_ops = { | |||
310 | .set_time = vr41xx_rtc_set_time, | 278 | .set_time = vr41xx_rtc_set_time, |
311 | .read_alarm = vr41xx_rtc_read_alarm, | 279 | .read_alarm = vr41xx_rtc_read_alarm, |
312 | .set_alarm = vr41xx_rtc_set_alarm, | 280 | .set_alarm = vr41xx_rtc_set_alarm, |
313 | .irq_set_freq = vr41xx_rtc_irq_set_freq, | ||
314 | .irq_set_state = vr41xx_rtc_irq_set_state, | ||
315 | }; | 281 | }; |
316 | 282 | ||
317 | static int __devinit rtc_probe(struct platform_device *pdev) | 283 | static int __devinit rtc_probe(struct platform_device *pdev) |
diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c new file mode 100644 index 000000000000..efd6066b5cd2 --- /dev/null +++ b/drivers/rtc/rtc-vt8500.c | |||
@@ -0,0 +1,327 @@ | |||
1 | /* | ||
2 | * drivers/rtc/rtc-vt8500.c | ||
3 | * | ||
4 | * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> | ||
5 | * | ||
6 | * Based on rtc-pxa.c | ||
7 | * | ||
8 | * This software is licensed under the terms of the GNU General Public | ||
9 | * License version 2, as published by the Free Software Foundation, and | ||
10 | * may be copied, distributed, and modified under those terms. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/module.h> | ||
19 | #include <linux/rtc.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/io.h> | ||
23 | #include <linux/bcd.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/slab.h> | ||
26 | |||
27 | /* | ||
28 | * Register definitions | ||
29 | */ | ||
30 | #define VT8500_RTC_TS 0x00 /* Time set */ | ||
31 | #define VT8500_RTC_DS 0x04 /* Date set */ | ||
32 | #define VT8500_RTC_AS 0x08 /* Alarm set */ | ||
33 | #define VT8500_RTC_CR 0x0c /* Control */ | ||
34 | #define VT8500_RTC_TR 0x10 /* Time read */ | ||
35 | #define VT8500_RTC_DR 0x14 /* Date read */ | ||
36 | #define VT8500_RTC_WS 0x18 /* Write status */ | ||
37 | #define VT8500_RTC_CL 0x20 /* Calibration */ | ||
38 | #define VT8500_RTC_IS 0x24 /* Interrupt status */ | ||
39 | #define VT8500_RTC_ST 0x28 /* Status */ | ||
40 | |||
41 | #define INVALID_TIME_BIT (1 << 31) | ||
42 | |||
43 | #define DATE_CENTURY_S 19 | ||
44 | #define DATE_YEAR_S 11 | ||
45 | #define DATE_YEAR_MASK (0xff << DATE_YEAR_S) | ||
46 | #define DATE_MONTH_S 6 | ||
47 | #define DATE_MONTH_MASK (0x1f << DATE_MONTH_S) | ||
48 | #define DATE_DAY_MASK 0x3f | ||
49 | |||
50 | #define TIME_DOW_S 20 | ||
51 | #define TIME_DOW_MASK (0x07 << TIME_DOW_S) | ||
52 | #define TIME_HOUR_S 14 | ||
53 | #define TIME_HOUR_MASK (0x3f << TIME_HOUR_S) | ||
54 | #define TIME_MIN_S 7 | ||
55 | #define TIME_MIN_MASK (0x7f << TIME_MIN_S) | ||
56 | #define TIME_SEC_MASK 0x7f | ||
57 | |||
58 | #define ALARM_DAY_S 20 | ||
59 | #define ALARM_DAY_MASK (0x3f << ALARM_DAY_S) | ||
60 | |||
61 | #define ALARM_DAY_BIT (1 << 29) | ||
62 | #define ALARM_HOUR_BIT (1 << 28) | ||
63 | #define ALARM_MIN_BIT (1 << 27) | ||
64 | #define ALARM_SEC_BIT (1 << 26) | ||
65 | |||
66 | #define ALARM_ENABLE_MASK (ALARM_DAY_BIT \ | ||
67 | | ALARM_HOUR_BIT \ | ||
68 | | ALARM_MIN_BIT \ | ||
69 | | ALARM_SEC_BIT) | ||
70 | |||
71 | #define VT8500_RTC_CR_ENABLE (1 << 0) /* Enable RTC */ | ||
72 | #define VT8500_RTC_CR_24H (1 << 1) /* 24h time format */ | ||
73 | #define VT8500_RTC_CR_SM_ENABLE (1 << 2) /* Enable periodic irqs */ | ||
74 | #define VT8500_RTC_CR_SM_SEC (1 << 3) /* 0: 1Hz/60, 1: 1Hz */ | ||
75 | #define VT8500_RTC_CR_CALIB (1 << 4) /* Enable calibration */ | ||
76 | |||
77 | struct vt8500_rtc { | ||
78 | void __iomem *regbase; | ||
79 | struct resource *res; | ||
80 | int irq_alarm; | ||
81 | struct rtc_device *rtc; | ||
82 | spinlock_t lock; /* Protects this structure */ | ||
83 | }; | ||
84 | |||
85 | static irqreturn_t vt8500_rtc_irq(int irq, void *dev_id) | ||
86 | { | ||
87 | struct vt8500_rtc *vt8500_rtc = dev_id; | ||
88 | u32 isr; | ||
89 | unsigned long events = 0; | ||
90 | |||
91 | spin_lock(&vt8500_rtc->lock); | ||
92 | |||
93 | /* clear interrupt sources */ | ||
94 | isr = readl(vt8500_rtc->regbase + VT8500_RTC_IS); | ||
95 | writel(isr, vt8500_rtc->regbase + VT8500_RTC_IS); | ||
96 | |||
97 | spin_unlock(&vt8500_rtc->lock); | ||
98 | |||
99 | if (isr & 1) | ||
100 | events |= RTC_AF | RTC_IRQF; | ||
101 | |||
102 | rtc_update_irq(vt8500_rtc->rtc, 1, events); | ||
103 | |||
104 | return IRQ_HANDLED; | ||
105 | } | ||
106 | |||
107 | static int vt8500_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
108 | { | ||
109 | struct vt8500_rtc *vt8500_rtc = dev_get_drvdata(dev); | ||
110 | u32 date, time; | ||
111 | |||
112 | date = readl(vt8500_rtc->regbase + VT8500_RTC_DR); | ||
113 | time = readl(vt8500_rtc->regbase + VT8500_RTC_TR); | ||
114 | |||
115 | tm->tm_sec = bcd2bin(time & TIME_SEC_MASK); | ||
116 | tm->tm_min = bcd2bin((time & TIME_MIN_MASK) >> TIME_MIN_S); | ||
117 | tm->tm_hour = bcd2bin((time & TIME_HOUR_MASK) >> TIME_HOUR_S); | ||
118 | tm->tm_mday = bcd2bin(date & DATE_DAY_MASK); | ||
119 | tm->tm_mon = bcd2bin((date & DATE_MONTH_MASK) >> DATE_MONTH_S); | ||
120 | tm->tm_year = bcd2bin((date & DATE_YEAR_MASK) >> DATE_YEAR_S) | ||
121 | + ((date >> DATE_CENTURY_S) & 1 ? 200 : 100); | ||
122 | tm->tm_wday = (time & TIME_DOW_MASK) >> TIME_DOW_S; | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static int vt8500_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
128 | { | ||
129 | struct vt8500_rtc *vt8500_rtc = dev_get_drvdata(dev); | ||
130 | |||
131 | if (tm->tm_year < 100) { | ||
132 | dev_warn(dev, "Only years 2000-2199 are supported by the " | ||
133 | "hardware!\n"); | ||
134 | return -EINVAL; | ||
135 | } | ||
136 | |||
137 | writel((bin2bcd(tm->tm_year - 100) << DATE_YEAR_S) | ||
138 | | (bin2bcd(tm->tm_mon) << DATE_MONTH_S) | ||
139 | | (bin2bcd(tm->tm_mday)), | ||
140 | vt8500_rtc->regbase + VT8500_RTC_DS); | ||
141 | writel((bin2bcd(tm->tm_wday) << TIME_DOW_S) | ||
142 | | (bin2bcd(tm->tm_hour) << TIME_HOUR_S) | ||
143 | | (bin2bcd(tm->tm_min) << TIME_MIN_S) | ||
144 | | (bin2bcd(tm->tm_sec)), | ||
145 | vt8500_rtc->regbase + VT8500_RTC_TS); | ||
146 | |||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | static int vt8500_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
151 | { | ||
152 | struct vt8500_rtc *vt8500_rtc = dev_get_drvdata(dev); | ||
153 | u32 isr, alarm; | ||
154 | |||
155 | alarm = readl(vt8500_rtc->regbase + VT8500_RTC_AS); | ||
156 | isr = readl(vt8500_rtc->regbase + VT8500_RTC_IS); | ||
157 | |||
158 | alrm->time.tm_mday = bcd2bin((alarm & ALARM_DAY_MASK) >> ALARM_DAY_S); | ||
159 | alrm->time.tm_hour = bcd2bin((alarm & TIME_HOUR_MASK) >> TIME_HOUR_S); | ||
160 | alrm->time.tm_min = bcd2bin((alarm & TIME_MIN_MASK) >> TIME_MIN_S); | ||
161 | alrm->time.tm_sec = bcd2bin((alarm & TIME_SEC_MASK)); | ||
162 | |||
163 | alrm->enabled = (alarm & ALARM_ENABLE_MASK) ? 1 : 0; | ||
164 | |||
165 | alrm->pending = (isr & 1) ? 1 : 0; | ||
166 | return rtc_valid_tm(&alrm->time); | ||
167 | } | ||
168 | |||
169 | static int vt8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
170 | { | ||
171 | struct vt8500_rtc *vt8500_rtc = dev_get_drvdata(dev); | ||
172 | |||
173 | writel((alrm->enabled ? ALARM_ENABLE_MASK : 0) | ||
174 | | (bin2bcd(alrm->time.tm_mday) << ALARM_DAY_S) | ||
175 | | (bin2bcd(alrm->time.tm_hour) << TIME_HOUR_S) | ||
176 | | (bin2bcd(alrm->time.tm_min) << TIME_MIN_S) | ||
177 | | (bin2bcd(alrm->time.tm_sec)), | ||
178 | vt8500_rtc->regbase + VT8500_RTC_AS); | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | static int vt8500_alarm_irq_enable(struct device *dev, unsigned int enabled) | ||
184 | { | ||
185 | struct vt8500_rtc *vt8500_rtc = dev_get_drvdata(dev); | ||
186 | unsigned long tmp = readl(vt8500_rtc->regbase + VT8500_RTC_AS); | ||
187 | |||
188 | if (enabled) | ||
189 | tmp |= ALARM_ENABLE_MASK; | ||
190 | else | ||
191 | tmp &= ~ALARM_ENABLE_MASK; | ||
192 | |||
193 | writel(tmp, vt8500_rtc->regbase + VT8500_RTC_AS); | ||
194 | return 0; | ||
195 | } | ||
196 | |||
197 | static const struct rtc_class_ops vt8500_rtc_ops = { | ||
198 | .read_time = vt8500_rtc_read_time, | ||
199 | .set_time = vt8500_rtc_set_time, | ||
200 | .read_alarm = vt8500_rtc_read_alarm, | ||
201 | .set_alarm = vt8500_rtc_set_alarm, | ||
202 | .alarm_irq_enable = vt8500_alarm_irq_enable, | ||
203 | }; | ||
204 | |||
205 | static int __devinit vt8500_rtc_probe(struct platform_device *pdev) | ||
206 | { | ||
207 | struct vt8500_rtc *vt8500_rtc; | ||
208 | int ret; | ||
209 | |||
210 | vt8500_rtc = kzalloc(sizeof(struct vt8500_rtc), GFP_KERNEL); | ||
211 | if (!vt8500_rtc) | ||
212 | return -ENOMEM; | ||
213 | |||
214 | spin_lock_init(&vt8500_rtc->lock); | ||
215 | platform_set_drvdata(pdev, vt8500_rtc); | ||
216 | |||
217 | vt8500_rtc->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
218 | if (!vt8500_rtc->res) { | ||
219 | dev_err(&pdev->dev, "No I/O memory resource defined\n"); | ||
220 | ret = -ENXIO; | ||
221 | goto err_free; | ||
222 | } | ||
223 | |||
224 | vt8500_rtc->irq_alarm = platform_get_irq(pdev, 0); | ||
225 | if (vt8500_rtc->irq_alarm < 0) { | ||
226 | dev_err(&pdev->dev, "No alarm IRQ resource defined\n"); | ||
227 | ret = -ENXIO; | ||
228 | goto err_free; | ||
229 | } | ||
230 | |||
231 | vt8500_rtc->res = request_mem_region(vt8500_rtc->res->start, | ||
232 | resource_size(vt8500_rtc->res), | ||
233 | "vt8500-rtc"); | ||
234 | if (vt8500_rtc->res == NULL) { | ||
235 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | ||
236 | ret = -EBUSY; | ||
237 | goto err_free; | ||
238 | } | ||
239 | |||
240 | vt8500_rtc->regbase = ioremap(vt8500_rtc->res->start, | ||
241 | resource_size(vt8500_rtc->res)); | ||
242 | if (!vt8500_rtc->regbase) { | ||
243 | dev_err(&pdev->dev, "Unable to map RTC I/O memory\n"); | ||
244 | ret = -EBUSY; | ||
245 | goto err_release; | ||
246 | } | ||
247 | |||
248 | /* Enable RTC and set it to 24-hour mode */ | ||
249 | writel(VT8500_RTC_CR_ENABLE | VT8500_RTC_CR_24H, | ||
250 | vt8500_rtc->regbase + VT8500_RTC_CR); | ||
251 | |||
252 | vt8500_rtc->rtc = rtc_device_register("vt8500-rtc", &pdev->dev, | ||
253 | &vt8500_rtc_ops, THIS_MODULE); | ||
254 | if (IS_ERR(vt8500_rtc->rtc)) { | ||
255 | ret = PTR_ERR(vt8500_rtc->rtc); | ||
256 | dev_err(&pdev->dev, | ||
257 | "Failed to register RTC device -> %d\n", ret); | ||
258 | goto err_unmap; | ||
259 | } | ||
260 | |||
261 | ret = request_irq(vt8500_rtc->irq_alarm, vt8500_rtc_irq, 0, | ||
262 | "rtc alarm", vt8500_rtc); | ||
263 | if (ret < 0) { | ||
264 | dev_err(&pdev->dev, "can't get irq %i, err %d\n", | ||
265 | vt8500_rtc->irq_alarm, ret); | ||
266 | goto err_unreg; | ||
267 | } | ||
268 | |||
269 | return 0; | ||
270 | |||
271 | err_unreg: | ||
272 | rtc_device_unregister(vt8500_rtc->rtc); | ||
273 | err_unmap: | ||
274 | iounmap(vt8500_rtc->regbase); | ||
275 | err_release: | ||
276 | release_mem_region(vt8500_rtc->res->start, | ||
277 | resource_size(vt8500_rtc->res)); | ||
278 | err_free: | ||
279 | kfree(vt8500_rtc); | ||
280 | return ret; | ||
281 | } | ||
282 | |||
283 | static int __devexit vt8500_rtc_remove(struct platform_device *pdev) | ||
284 | { | ||
285 | struct vt8500_rtc *vt8500_rtc = platform_get_drvdata(pdev); | ||
286 | |||
287 | free_irq(vt8500_rtc->irq_alarm, vt8500_rtc); | ||
288 | |||
289 | rtc_device_unregister(vt8500_rtc->rtc); | ||
290 | |||
291 | /* Disable alarm matching */ | ||
292 | writel(0, vt8500_rtc->regbase + VT8500_RTC_IS); | ||
293 | iounmap(vt8500_rtc->regbase); | ||
294 | release_mem_region(vt8500_rtc->res->start, | ||
295 | resource_size(vt8500_rtc->res)); | ||
296 | |||
297 | kfree(vt8500_rtc); | ||
298 | platform_set_drvdata(pdev, NULL); | ||
299 | |||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | static struct platform_driver vt8500_rtc_driver = { | ||
304 | .probe = vt8500_rtc_probe, | ||
305 | .remove = __devexit_p(vt8500_rtc_remove), | ||
306 | .driver = { | ||
307 | .name = "vt8500-rtc", | ||
308 | .owner = THIS_MODULE, | ||
309 | }, | ||
310 | }; | ||
311 | |||
312 | static int __init vt8500_rtc_init(void) | ||
313 | { | ||
314 | return platform_driver_register(&vt8500_rtc_driver); | ||
315 | } | ||
316 | module_init(vt8500_rtc_init); | ||
317 | |||
318 | static void __exit vt8500_rtc_exit(void) | ||
319 | { | ||
320 | platform_driver_unregister(&vt8500_rtc_driver); | ||
321 | } | ||
322 | module_exit(vt8500_rtc_exit); | ||
323 | |||
324 | MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>"); | ||
325 | MODULE_DESCRIPTION("VIA VT8500 SoC Realtime Clock Driver (RTC)"); | ||
326 | MODULE_LICENSE("GPL"); | ||
327 | MODULE_ALIAS("platform:vt8500-rtc"); | ||
diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c index 82931dc65c0b..bdc909bd56da 100644 --- a/drivers/rtc/rtc-wm831x.c +++ b/drivers/rtc/rtc-wm831x.c | |||
@@ -315,21 +315,6 @@ static int wm831x_rtc_alarm_irq_enable(struct device *dev, | |||
315 | return wm831x_rtc_stop_alarm(wm831x_rtc); | 315 | return wm831x_rtc_stop_alarm(wm831x_rtc); |
316 | } | 316 | } |
317 | 317 | ||
318 | static int wm831x_rtc_update_irq_enable(struct device *dev, | ||
319 | unsigned int enabled) | ||
320 | { | ||
321 | struct wm831x_rtc *wm831x_rtc = dev_get_drvdata(dev); | ||
322 | int val; | ||
323 | |||
324 | if (enabled) | ||
325 | val = 1 << WM831X_RTC_PINT_FREQ_SHIFT; | ||
326 | else | ||
327 | val = 0; | ||
328 | |||
329 | return wm831x_set_bits(wm831x_rtc->wm831x, WM831X_RTC_CONTROL, | ||
330 | WM831X_RTC_PINT_FREQ_MASK, val); | ||
331 | } | ||
332 | |||
333 | static irqreturn_t wm831x_alm_irq(int irq, void *data) | 318 | static irqreturn_t wm831x_alm_irq(int irq, void *data) |
334 | { | 319 | { |
335 | struct wm831x_rtc *wm831x_rtc = data; | 320 | struct wm831x_rtc *wm831x_rtc = data; |
@@ -354,7 +339,6 @@ static const struct rtc_class_ops wm831x_rtc_ops = { | |||
354 | .read_alarm = wm831x_rtc_readalarm, | 339 | .read_alarm = wm831x_rtc_readalarm, |
355 | .set_alarm = wm831x_rtc_setalarm, | 340 | .set_alarm = wm831x_rtc_setalarm, |
356 | .alarm_irq_enable = wm831x_rtc_alarm_irq_enable, | 341 | .alarm_irq_enable = wm831x_rtc_alarm_irq_enable, |
357 | .update_irq_enable = wm831x_rtc_update_irq_enable, | ||
358 | }; | 342 | }; |
359 | 343 | ||
360 | #ifdef CONFIG_PM | 344 | #ifdef CONFIG_PM |
diff --git a/drivers/rtc/rtc-wm8350.c b/drivers/rtc/rtc-wm8350.c index 3d0dc76b38af..66421426e404 100644 --- a/drivers/rtc/rtc-wm8350.c +++ b/drivers/rtc/rtc-wm8350.c | |||
@@ -302,26 +302,6 @@ static int wm8350_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
302 | return ret; | 302 | return ret; |
303 | } | 303 | } |
304 | 304 | ||
305 | static int wm8350_rtc_update_irq_enable(struct device *dev, | ||
306 | unsigned int enabled) | ||
307 | { | ||
308 | struct wm8350 *wm8350 = dev_get_drvdata(dev); | ||
309 | |||
310 | /* Suppress duplicate changes since genirq nests enable and | ||
311 | * disable calls. */ | ||
312 | if (enabled == wm8350->rtc.update_enabled) | ||
313 | return 0; | ||
314 | |||
315 | if (enabled) | ||
316 | wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_SEC); | ||
317 | else | ||
318 | wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); | ||
319 | |||
320 | wm8350->rtc.update_enabled = enabled; | ||
321 | |||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | static irqreturn_t wm8350_rtc_alarm_handler(int irq, void *data) | 305 | static irqreturn_t wm8350_rtc_alarm_handler(int irq, void *data) |
326 | { | 306 | { |
327 | struct wm8350 *wm8350 = data; | 307 | struct wm8350 *wm8350 = data; |
@@ -357,7 +337,6 @@ static const struct rtc_class_ops wm8350_rtc_ops = { | |||
357 | .read_alarm = wm8350_rtc_readalarm, | 337 | .read_alarm = wm8350_rtc_readalarm, |
358 | .set_alarm = wm8350_rtc_setalarm, | 338 | .set_alarm = wm8350_rtc_setalarm, |
359 | .alarm_irq_enable = wm8350_rtc_alarm_irq_enable, | 339 | .alarm_irq_enable = wm8350_rtc_alarm_irq_enable, |
360 | .update_irq_enable = wm8350_rtc_update_irq_enable, | ||
361 | }; | 340 | }; |
362 | 341 | ||
363 | #ifdef CONFIG_PM | 342 | #ifdef CONFIG_PM |
diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index 9aae49139a0a..b00aad2620d4 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c | |||
@@ -573,7 +573,7 @@ static int x1205_probe(struct i2c_client *client, | |||
573 | 573 | ||
574 | i2c_set_clientdata(client, rtc); | 574 | i2c_set_clientdata(client, rtc); |
575 | 575 | ||
576 | /* Check for power failures and eventualy enable the osc */ | 576 | /* Check for power failures and eventually enable the osc */ |
577 | if ((err = x1205_get_status(client, &sr)) == 0) { | 577 | if ((err = x1205_get_status(client, &sr)) == 0) { |
578 | if (sr & X1205_SR_RTCF) { | 578 | if (sr & X1205_SR_RTCF) { |
579 | dev_err(&client->dev, | 579 | dev_err(&client->dev, |