diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/rtc | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/rtc')
105 files changed, 2401 insertions, 5710 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 923a9da9c82..45f4c804084 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -8,7 +8,7 @@ config RTC_LIB | |||
8 | menuconfig RTC_CLASS | 8 | menuconfig RTC_CLASS |
9 | bool "Real Time Clock" | 9 | bool "Real Time Clock" |
10 | default n | 10 | default n |
11 | depends on !S390 && !UML | 11 | depends on !S390 |
12 | select RTC_LIB | 12 | select RTC_LIB |
13 | help | 13 | help |
14 | Generic RTC class support. If you say yes here, you will | 14 | Generic RTC class support. If you say yes here, you will |
@@ -19,6 +19,7 @@ if RTC_CLASS | |||
19 | 19 | ||
20 | config RTC_HCTOSYS | 20 | config RTC_HCTOSYS |
21 | bool "Set system time from RTC on startup and resume" | 21 | bool "Set system time from RTC on startup and resume" |
22 | depends on RTC_CLASS = y | ||
22 | default y | 23 | default y |
23 | help | 24 | help |
24 | If you say yes here, the system time (wall clock) will be set using | 25 | If you say yes here, the system time (wall clock) will be set using |
@@ -50,6 +51,7 @@ config RTC_HCTOSYS_DEVICE | |||
50 | 51 | ||
51 | config RTC_DEBUG | 52 | config RTC_DEBUG |
52 | bool "RTC debug support" | 53 | bool "RTC debug support" |
54 | depends on RTC_CLASS = y | ||
53 | help | 55 | help |
54 | Say yes here to enable debugging support in the RTC framework | 56 | Say yes here to enable debugging support in the RTC framework |
55 | and individual RTC drivers. | 57 | and individual RTC drivers. |
@@ -67,15 +69,13 @@ config RTC_INTF_SYSFS | |||
67 | If unsure, say Y. | 69 | If unsure, say Y. |
68 | 70 | ||
69 | config RTC_INTF_PROC | 71 | config RTC_INTF_PROC |
70 | boolean "/proc/driver/rtc (procfs for rtcN)" | 72 | boolean "/proc/driver/rtc (procfs for rtc0)" |
71 | depends on PROC_FS | 73 | depends on PROC_FS |
72 | default RTC_CLASS | 74 | default RTC_CLASS |
73 | help | 75 | help |
74 | Say yes here if you want to use your system clock RTC through | 76 | Say yes here if you want to use your first RTC through the proc |
75 | the proc interface, /proc/driver/rtc. | 77 | interface, /proc/driver/rtc. Other RTCs will not be available |
76 | Other RTCs will not be available through that API. | 78 | through that API. |
77 | If there is no RTC for the system clock, then the first RTC(rtc0) | ||
78 | is used by default. | ||
79 | 79 | ||
80 | If unsure, say Y. | 80 | If unsure, say Y. |
81 | 81 | ||
@@ -106,6 +106,24 @@ config RTC_INTF_DEV_UIE_EMUL | |||
106 | clock several times per second, please enable this option | 106 | clock several times per second, please enable this option |
107 | only if you know that you really need it. | 107 | only if you know that you really need it. |
108 | 108 | ||
109 | config RTC_INTF_ALARM | ||
110 | bool "Android alarm driver" | ||
111 | depends on RTC_CLASS | ||
112 | default y | ||
113 | help | ||
114 | Provides non-wakeup and rtc backed wakeup alarms based on rtc or | ||
115 | elapsed realtime, and a non-wakeup alarm on the monotonic clock. | ||
116 | Also provides an interface to set the wall time which must be used | ||
117 | for elapsed realtime to work. | ||
118 | |||
119 | config RTC_INTF_ALARM_DEV | ||
120 | bool "Android alarm device" | ||
121 | depends on RTC_INTF_ALARM | ||
122 | default y | ||
123 | help | ||
124 | Exports the alarm interface to user-space. | ||
125 | |||
126 | |||
109 | config RTC_DRV_TEST | 127 | config RTC_DRV_TEST |
110 | tristate "Test driver/device" | 128 | tristate "Test driver/device" |
111 | help | 129 | help |
@@ -127,7 +145,7 @@ if I2C | |||
127 | 145 | ||
128 | config RTC_DRV_88PM860X | 146 | config RTC_DRV_88PM860X |
129 | tristate "Marvell 88PM860x" | 147 | tristate "Marvell 88PM860x" |
130 | depends on I2C && MFD_88PM860X | 148 | depends on RTC_CLASS && I2C && MFD_88PM860X |
131 | help | 149 | help |
132 | If you say yes here you get support for RTC function in Marvell | 150 | If you say yes here you get support for RTC function in Marvell |
133 | 88PM860x chips. | 151 | 88PM860x chips. |
@@ -135,16 +153,6 @@ config RTC_DRV_88PM860X | |||
135 | This driver can also be built as a module. If so, the module | 153 | This driver can also be built as a module. If so, the module |
136 | will be called rtc-88pm860x. | 154 | will be called rtc-88pm860x. |
137 | 155 | ||
138 | config RTC_DRV_88PM80X | ||
139 | tristate "Marvell 88PM80x" | ||
140 | depends on I2C && MFD_88PM800 | ||
141 | help | ||
142 | If you say yes here you get support for RTC function in Marvell | ||
143 | 88PM80x chips. | ||
144 | |||
145 | This driver can also be built as a module. If so, the module | ||
146 | will be called rtc-88pm80x. | ||
147 | |||
148 | config RTC_DRV_DS1307 | 156 | config RTC_DRV_DS1307 |
149 | tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025" | 157 | tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025" |
150 | help | 158 | help |
@@ -165,7 +173,7 @@ config RTC_DRV_DS1307 | |||
165 | 173 | ||
166 | config RTC_DRV_DS1374 | 174 | config RTC_DRV_DS1374 |
167 | tristate "Dallas/Maxim DS1374" | 175 | tristate "Dallas/Maxim DS1374" |
168 | depends on I2C | 176 | depends on RTC_CLASS && I2C |
169 | help | 177 | help |
170 | If you say yes here you get support for Dallas Semiconductor | 178 | If you say yes here you get support for Dallas Semiconductor |
171 | DS1374 real-time clock chips. If an interrupt is associated | 179 | DS1374 real-time clock chips. If an interrupt is associated |
@@ -185,7 +193,7 @@ config RTC_DRV_DS1672 | |||
185 | 193 | ||
186 | config RTC_DRV_DS3232 | 194 | config RTC_DRV_DS3232 |
187 | tristate "Dallas/Maxim DS3232" | 195 | tristate "Dallas/Maxim DS3232" |
188 | depends on I2C | 196 | depends on RTC_CLASS && I2C |
189 | help | 197 | help |
190 | If you say yes here you get support for Dallas Semiconductor | 198 | If you say yes here you get support for Dallas Semiconductor |
191 | DS3232 real-time clock chips. If an interrupt is associated | 199 | DS3232 real-time clock chips. If an interrupt is associated |
@@ -203,16 +211,6 @@ config RTC_DRV_MAX6900 | |||
203 | This driver can also be built as a module. If so, the module | 211 | This driver can also be built as a module. If so, the module |
204 | will be called rtc-max6900. | 212 | will be called rtc-max6900. |
205 | 213 | ||
206 | config RTC_DRV_MAX8907 | ||
207 | tristate "Maxim MAX8907" | ||
208 | depends on MFD_MAX8907 | ||
209 | help | ||
210 | If you say yes here you will get support for the | ||
211 | RTC of Maxim MAX8907 PMIC. | ||
212 | |||
213 | This driver can also be built as a module. If so, the module | ||
214 | will be called rtc-max8907. | ||
215 | |||
216 | config RTC_DRV_MAX8925 | 214 | config RTC_DRV_MAX8925 |
217 | tristate "Maxim MAX8925" | 215 | tristate "Maxim MAX8925" |
218 | depends on MFD_MAX8925 | 216 | depends on MFD_MAX8925 |
@@ -233,6 +231,26 @@ config RTC_DRV_MAX8998 | |||
233 | This driver can also be built as a module. If so, the module | 231 | This driver can also be built as a module. If so, the module |
234 | will be called rtc-max8998. | 232 | will be called rtc-max8998. |
235 | 233 | ||
234 | config RTC_DRV_MAX8907C | ||
235 | tristate "Maxim MAX8907C" | ||
236 | depends on MFD_MAX8907C | ||
237 | help | ||
238 | If you say yes here you will get support for the | ||
239 | RTC of Maxim MAX8907C PMIC. | ||
240 | |||
241 | This driver can also be built as a module. If so, the module | ||
242 | will be called rtc-max8907c. | ||
243 | |||
244 | config RTC_DRV_MAX77663 | ||
245 | tristate "Maxim MAX77663" | ||
246 | depends on MFD_MAX77663 | ||
247 | help | ||
248 | If you say yes here you will get support for the | ||
249 | RTC of Maxim MAX77663 PMIC. | ||
250 | |||
251 | This driver can also be built as a module. If so, the module | ||
252 | will be called rtc-max77663. | ||
253 | |||
236 | config RTC_DRV_RS5C372 | 254 | config RTC_DRV_RS5C372 |
237 | tristate "Ricoh R2025S/D, RS5C372A/B, RV5C386, RV5C387A" | 255 | tristate "Ricoh R2025S/D, RS5C372A/B, RV5C386, RV5C387A" |
238 | help | 256 | help |
@@ -269,15 +287,6 @@ config RTC_DRV_X1205 | |||
269 | This driver can also be built as a module. If so, the module | 287 | This driver can also be built as a module. If so, the module |
270 | will be called rtc-x1205. | 288 | will be called rtc-x1205. |
271 | 289 | ||
272 | config RTC_DRV_PCF8523 | ||
273 | tristate "NXP PCF8523" | ||
274 | help | ||
275 | If you say yes here you get support for the NXP PCF8523 RTC | ||
276 | chips. | ||
277 | |||
278 | This driver can also be built as a module. If so, the module | ||
279 | will be called rtc-pcf8523. | ||
280 | |||
281 | config RTC_DRV_PCF8563 | 290 | config RTC_DRV_PCF8563 |
282 | tristate "Philips PCF8563/Epson RTC8564" | 291 | tristate "Philips PCF8563/Epson RTC8564" |
283 | help | 292 | help |
@@ -333,6 +342,12 @@ config RTC_DRV_DM355EVM | |||
333 | help | 342 | help |
334 | Supports the RTC firmware in the MSP430 on the DM355 EVM. | 343 | Supports the RTC firmware in the MSP430 on the DM355 EVM. |
335 | 344 | ||
345 | config RTC_DRV_TPS6586X | ||
346 | tristate "TI TPS6586X RTC" | ||
347 | depends on MFD_TPS6586X | ||
348 | help | ||
349 | This driver supports TPS6586X RTC | ||
350 | |||
336 | config RTC_DRV_TWL92330 | 351 | config RTC_DRV_TWL92330 |
337 | boolean "TI TWL92330/Menelaus" | 352 | boolean "TI TWL92330/Menelaus" |
338 | depends on MENELAUS | 353 | depends on MENELAUS |
@@ -344,7 +359,7 @@ config RTC_DRV_TWL92330 | |||
344 | 359 | ||
345 | config RTC_DRV_TWL4030 | 360 | config RTC_DRV_TWL4030 |
346 | tristate "TI TWL4030/TWL5030/TWL6030/TPS659x0" | 361 | tristate "TI TWL4030/TWL5030/TWL6030/TPS659x0" |
347 | depends on TWL4030_CORE | 362 | depends on RTC_CLASS && TWL4030_CORE |
348 | help | 363 | help |
349 | If you say yes here you get support for the RTC on the | 364 | If you say yes here you get support for the RTC on the |
350 | TWL4030/TWL5030/TWL6030 family chips, used mostly with OMAP3 platforms. | 365 | TWL4030/TWL5030/TWL6030 family chips, used mostly with OMAP3 platforms. |
@@ -352,34 +367,6 @@ config RTC_DRV_TWL4030 | |||
352 | This driver can also be built as a module. If so, the module | 367 | This driver can also be built as a module. If so, the module |
353 | will be called rtc-twl. | 368 | will be called rtc-twl. |
354 | 369 | ||
355 | config RTC_DRV_TPS6586X | ||
356 | tristate "TI TPS6586X RTC driver" | ||
357 | depends on MFD_TPS6586X | ||
358 | help | ||
359 | TI Power Managment IC TPS6586X supports RTC functionality | ||
360 | along with alarm. This driver supports the RTC driver for | ||
361 | the TPS6586X RTC module. | ||
362 | |||
363 | config RTC_DRV_TPS65910 | ||
364 | tristate "TI TPS65910 RTC driver" | ||
365 | depends on RTC_CLASS && MFD_TPS65910 | ||
366 | help | ||
367 | If you say yes here you get support for the RTC on the | ||
368 | TPS65910 chips. | ||
369 | |||
370 | This driver can also be built as a module. If so, the module | ||
371 | will be called rtc-tps65910. | ||
372 | |||
373 | config RTC_DRV_RC5T583 | ||
374 | tristate "RICOH 5T583 RTC driver" | ||
375 | depends on MFD_RC5T583 | ||
376 | help | ||
377 | If you say yes here you get support for the RTC on the | ||
378 | RICOH 5T583 chips. | ||
379 | |||
380 | This driver can also be built as a module. If so, the module | ||
381 | will be called rtc-rc5t583. | ||
382 | |||
383 | config RTC_DRV_S35390A | 370 | config RTC_DRV_S35390A |
384 | tristate "Seiko Instruments S-35390A" | 371 | tristate "Seiko Instruments S-35390A" |
385 | select BITREVERSE | 372 | select BITREVERSE |
@@ -555,9 +542,9 @@ config RTC_DRV_CMOS | |||
555 | will be called rtc-cmos. | 542 | will be called rtc-cmos. |
556 | 543 | ||
557 | config RTC_DRV_VRTC | 544 | config RTC_DRV_VRTC |
558 | tristate "Virtual RTC for Intel MID platforms" | 545 | tristate "Virtual RTC for Moorestown platforms" |
559 | depends on X86_INTEL_MID | 546 | depends on X86_MRST |
560 | default y if X86_INTEL_MID | 547 | default y if X86_MRST |
561 | 548 | ||
562 | help | 549 | help |
563 | Say "yes" here to get direct support for the real time clock | 550 | Say "yes" here to get direct support for the real time clock |
@@ -585,6 +572,7 @@ config RTC_DRV_DS1302 | |||
585 | 572 | ||
586 | config RTC_DRV_DS1511 | 573 | config RTC_DRV_DS1511 |
587 | tristate "Dallas DS1511" | 574 | tristate "Dallas DS1511" |
575 | depends on RTC_CLASS | ||
588 | help | 576 | help |
589 | If you say yes here you get support for the | 577 | If you say yes here you get support for the |
590 | Dallas DS1511 timekeeping/watchdog chip. | 578 | Dallas DS1511 timekeeping/watchdog chip. |
@@ -610,23 +598,6 @@ config RTC_DRV_DS1742 | |||
610 | This driver can also be built as a module. If so, the module | 598 | This driver can also be built as a module. If so, the module |
611 | will be called rtc-ds1742. | 599 | will be called rtc-ds1742. |
612 | 600 | ||
613 | config RTC_DRV_DA9052 | ||
614 | tristate "Dialog DA9052/DA9053 RTC" | ||
615 | depends on PMIC_DA9052 | ||
616 | help | ||
617 | Say y here to support the RTC driver for Dialog Semiconductor | ||
618 | DA9052-BC and DA9053-AA/Bx PMICs. | ||
619 | |||
620 | config RTC_DRV_DA9055 | ||
621 | tristate "Dialog Semiconductor DA9055 RTC" | ||
622 | depends on MFD_DA9055 | ||
623 | help | ||
624 | If you say yes here you will get support for the | ||
625 | RTC of the Dialog DA9055 PMIC. | ||
626 | |||
627 | This driver can also be built as a module. If so, the module | ||
628 | will be called rtc-da9055 | ||
629 | |||
630 | config RTC_DRV_EFI | 601 | config RTC_DRV_EFI |
631 | tristate "EFI RTC" | 602 | tristate "EFI RTC" |
632 | depends on IA64 | 603 | depends on IA64 |
@@ -639,6 +610,7 @@ config RTC_DRV_EFI | |||
639 | 610 | ||
640 | config RTC_DRV_STK17TA8 | 611 | config RTC_DRV_STK17TA8 |
641 | tristate "Simtek STK17TA8" | 612 | tristate "Simtek STK17TA8" |
613 | depends on RTC_CLASS | ||
642 | help | 614 | help |
643 | If you say yes here you get support for the | 615 | If you say yes here you get support for the |
644 | Simtek STK17TA8 timekeeping chip. | 616 | Simtek STK17TA8 timekeeping chip. |
@@ -685,6 +657,27 @@ config RTC_DRV_MSM6242 | |||
685 | This driver can also be built as a module. If so, the module | 657 | This driver can also be built as a module. If so, the module |
686 | will be called rtc-msm6242. | 658 | will be called rtc-msm6242. |
687 | 659 | ||
660 | config RTC_DRV_IMXDI | ||
661 | tristate "Freescale IMX DryIce Real Time Clock" | ||
662 | depends on ARCH_MX25 | ||
663 | depends on RTC_CLASS | ||
664 | help | ||
665 | Support for Freescale IMX DryIce RTC | ||
666 | |||
667 | This driver can also be built as a module, if so, the module | ||
668 | will be called "rtc-imxdi". | ||
669 | |||
670 | config RTC_MXC | ||
671 | tristate "Freescale MXC Real Time Clock" | ||
672 | depends on ARCH_MXC | ||
673 | depends on RTC_CLASS | ||
674 | help | ||
675 | If you say yes here you get support for the Freescale MXC | ||
676 | RTC module. | ||
677 | |||
678 | This driver can also be built as a module, if so, the module | ||
679 | will be called "rtc-mxc". | ||
680 | |||
688 | config RTC_DRV_BQ4802 | 681 | config RTC_DRV_BQ4802 |
689 | tristate "TI BQ4802" | 682 | tristate "TI BQ4802" |
690 | help | 683 | help |
@@ -713,15 +706,6 @@ config RTC_DRV_V3020 | |||
713 | This driver can also be built as a module. If so, the module | 706 | This driver can also be built as a module. If so, the module |
714 | will be called rtc-v3020. | 707 | will be called rtc-v3020. |
715 | 708 | ||
716 | config RTC_DRV_DS2404 | ||
717 | tristate "Dallas DS2404" | ||
718 | help | ||
719 | If you say yes here you get support for the | ||
720 | Dallas DS2404 RTC chip. | ||
721 | |||
722 | This driver can also be built as a module. If so, the module | ||
723 | will be called rtc-ds2404. | ||
724 | |||
725 | config RTC_DRV_WM831X | 709 | config RTC_DRV_WM831X |
726 | tristate "Wolfson Microelectronics WM831x RTC" | 710 | tristate "Wolfson Microelectronics WM831x RTC" |
727 | depends on MFD_WM831X | 711 | depends on MFD_WM831X |
@@ -768,15 +752,13 @@ config RTC_DRV_AB3100 | |||
768 | config RTC_DRV_AB8500 | 752 | config RTC_DRV_AB8500 |
769 | tristate "ST-Ericsson AB8500 RTC" | 753 | tristate "ST-Ericsson AB8500 RTC" |
770 | depends on AB8500_CORE | 754 | depends on AB8500_CORE |
771 | select RTC_INTF_DEV | ||
772 | select RTC_INTF_DEV_UIE_EMUL | ||
773 | help | 755 | help |
774 | Select this to enable the ST-Ericsson AB8500 power management IC RTC | 756 | Select this to enable the ST-Ericsson AB8500 power management IC RTC |
775 | support. This chip contains a battery- and capacitor-backed RTC. | 757 | support. This chip contains a battery- and capacitor-backed RTC. |
776 | 758 | ||
777 | config RTC_DRV_NUC900 | 759 | config RTC_DRV_NUC900 |
778 | tristate "NUC910/NUC920 RTC driver" | 760 | tristate "NUC910/NUC920 RTC driver" |
779 | depends on ARCH_W90X900 | 761 | depends on RTC_CLASS && ARCH_W90X900 |
780 | help | 762 | help |
781 | If you say yes here you get support for the RTC subsystem of the | 763 | If you say yes here you get support for the RTC subsystem of the |
782 | NUC910/NUC920 used in embedded systems. | 764 | NUC910/NUC920 used in embedded systems. |
@@ -793,24 +775,13 @@ config RTC_DRV_DAVINCI | |||
793 | This driver can also be built as a module. If so, the module | 775 | This driver can also be built as a module. If so, the module |
794 | will be called rtc-davinci. | 776 | will be called rtc-davinci. |
795 | 777 | ||
796 | config RTC_DRV_IMXDI | ||
797 | tristate "Freescale IMX DryIce Real Time Clock" | ||
798 | depends on ARCH_MXC | ||
799 | help | ||
800 | Support for Freescale IMX DryIce RTC | ||
801 | |||
802 | This driver can also be built as a module, if so, the module | ||
803 | will be called "rtc-imxdi". | ||
804 | |||
805 | config RTC_DRV_OMAP | 778 | config RTC_DRV_OMAP |
806 | tristate "TI OMAP1" | 779 | tristate "TI OMAP1" |
807 | depends on ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_DAVINCI_DA8XX || SOC_AM33XX | 780 | depends on ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_DAVINCI_DA8XX |
808 | help | 781 | help |
809 | Say "yes" here to support the on chip real time clock | 782 | Say "yes" here to support the real time clock on TI OMAP1 and |
810 | present on TI OMAP1, AM33xx and DA8xx/OMAP-L13x. | 783 | DA8xx/OMAP-L13x chips. This driver can also be built as a |
811 | 784 | module called rtc-omap. | |
812 | This driver can also be built as a module, if so, module | ||
813 | will be called rtc-omap. | ||
814 | 785 | ||
815 | config HAVE_S3C_RTC | 786 | config HAVE_S3C_RTC |
816 | bool | 787 | bool |
@@ -821,7 +792,7 @@ config HAVE_S3C_RTC | |||
821 | 792 | ||
822 | config RTC_DRV_S3C | 793 | config RTC_DRV_S3C |
823 | tristate "Samsung S3C series SoC RTC" | 794 | tristate "Samsung S3C series SoC RTC" |
824 | depends on ARCH_S3C64XX || HAVE_S3C_RTC | 795 | depends on ARCH_S3C2410 || ARCH_S3C64XX || HAVE_S3C_RTC |
825 | help | 796 | help |
826 | RTC (Realtime Clock) driver for the clock inbuilt into the | 797 | RTC (Realtime Clock) driver for the clock inbuilt into the |
827 | Samsung S3C24XX series of SoCs. This can provide periodic | 798 | Samsung S3C24XX series of SoCs. This can provide periodic |
@@ -846,8 +817,8 @@ config RTC_DRV_EP93XX | |||
846 | will be called rtc-ep93xx. | 817 | will be called rtc-ep93xx. |
847 | 818 | ||
848 | config RTC_DRV_SA1100 | 819 | config RTC_DRV_SA1100 |
849 | tristate "SA11x0/PXA2xx/PXA910" | 820 | tristate "SA11x0/PXA2xx" |
850 | depends on ARCH_SA1100 || ARCH_PXA || ARCH_MMP | 821 | depends on ARCH_SA1100 || ARCH_PXA |
851 | help | 822 | help |
852 | If you say Y here you will get access to the real time clock | 823 | If you say Y here you will get access to the real time clock |
853 | built into your SA11x0 or PXA2xx CPU. | 824 | built into your SA11x0 or PXA2xx CPU. |
@@ -857,7 +828,7 @@ config RTC_DRV_SA1100 | |||
857 | 828 | ||
858 | config RTC_DRV_SH | 829 | config RTC_DRV_SH |
859 | tristate "SuperH On-Chip RTC" | 830 | tristate "SuperH On-Chip RTC" |
860 | depends on SUPERH && HAVE_CLK | 831 | depends on RTC_CLASS && SUPERH && HAVE_CLK |
861 | help | 832 | help |
862 | Say Y here to enable support for the on-chip RTC found in | 833 | Say Y here to enable support for the on-chip RTC found in |
863 | most SuperH processors. | 834 | most SuperH processors. |
@@ -904,7 +875,7 @@ config RTC_DRV_AT32AP700X | |||
904 | 875 | ||
905 | config RTC_DRV_AT91RM9200 | 876 | config RTC_DRV_AT91RM9200 |
906 | tristate "AT91RM9200 or some AT91SAM9 RTC" | 877 | tristate "AT91RM9200 or some AT91SAM9 RTC" |
907 | depends on ARCH_AT91 | 878 | depends on ARCH_AT91RM9200 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 |
908 | help | 879 | help |
909 | Driver for the internal RTC (Realtime Clock) module found on | 880 | Driver for the internal RTC (Realtime Clock) module found on |
910 | Atmel AT91RM9200's and some AT91SAM9 chips. On AT91SAM9 chips | 881 | Atmel AT91RM9200's and some AT91SAM9 chips. On AT91SAM9 chips |
@@ -1089,6 +1060,7 @@ config RTC_DRV_MPC5121 | |||
1089 | 1060 | ||
1090 | config RTC_DRV_JZ4740 | 1061 | config RTC_DRV_JZ4740 |
1091 | tristate "Ingenic JZ4740 SoC" | 1062 | tristate "Ingenic JZ4740 SoC" |
1063 | depends on RTC_CLASS | ||
1092 | depends on MACH_JZ4740 | 1064 | depends on MACH_JZ4740 |
1093 | help | 1065 | help |
1094 | If you say yes here you get support for the Ingenic JZ4740 SoC RTC | 1066 | If you say yes here you get support for the Ingenic JZ4740 SoC RTC |
@@ -1118,10 +1090,9 @@ config RTC_DRV_PM8XXX | |||
1118 | 1090 | ||
1119 | config RTC_DRV_TEGRA | 1091 | config RTC_DRV_TEGRA |
1120 | tristate "NVIDIA Tegra Internal RTC driver" | 1092 | tristate "NVIDIA Tegra Internal RTC driver" |
1121 | depends on ARCH_TEGRA | 1093 | depends on RTC_CLASS && ARCH_TEGRA |
1122 | help | 1094 | help |
1123 | If you say yes here you get support for the | 1095 | If you say yes here you get support for the Tegra internal RTC module. |
1124 | Tegra 200 series internal RTC module. | ||
1125 | 1096 | ||
1126 | This drive can also be built as a module. If so, the module | 1097 | This drive can also be built as a module. If so, the module |
1127 | will be called rtc-tegra. | 1098 | will be called rtc-tegra. |
@@ -1133,44 +1104,43 @@ config RTC_DRV_TILE | |||
1133 | Enable support for the Linux driver side of the Tilera | 1104 | Enable support for the Linux driver side of the Tilera |
1134 | hypervisor's real-time clock interface. | 1105 | hypervisor's real-time clock interface. |
1135 | 1106 | ||
1136 | config RTC_DRV_PUV3 | 1107 | config RTC_DRV_TPS6591x |
1137 | tristate "PKUnity v3 RTC support" | 1108 | tristate "TPS6591x RTC driver" |
1138 | depends on ARCH_PUV3 | 1109 | depends on MFD_TPS6591X |
1110 | default n | ||
1139 | help | 1111 | help |
1140 | This enables support for the RTC in the PKUnity-v3 SoCs. | 1112 | If you say yes here you get support for the TPS6591x RTC module. |
1141 | 1113 | ||
1142 | This drive can also be built as a module. If so, the module | 1114 | This driver can also be built as a module. If so, the module |
1143 | will be called rtc-puv3. | 1115 | will be called rtc-tps6591x. |
1144 | 1116 | ||
1145 | config RTC_DRV_LOONGSON1 | 1117 | config RTC_DRV_TPS80031 |
1146 | tristate "loongson1 RTC support" | 1118 | tristate "TPS80031 RTC driver" |
1147 | depends on MACH_LOONGSON1 | 1119 | depends on MFD_TPS80031 |
1120 | default n | ||
1148 | help | 1121 | help |
1149 | This is a driver for the loongson1 on-chip Counter0 (Time-Of-Year | 1122 | If you say yes here you get support for the TPS80031 RTC module. |
1150 | counter) to be used as a RTC. | ||
1151 | 1123 | ||
1152 | This driver can also be built as a module. If so, the module | 1124 | This driver can also be built as a module. If so, the module |
1153 | will be called rtc-ls1x. | 1125 | will be called rtc-tps6591x. |
1154 | 1126 | ||
1155 | config RTC_DRV_MXC | 1127 | config RTC_DRV_PUV3 |
1156 | tristate "Freescale MXC Real Time Clock" | 1128 | tristate "PKUnity v3 RTC support" |
1157 | depends on ARCH_MXC | 1129 | depends on ARCH_PUV3 |
1158 | help | 1130 | help |
1159 | If you say yes here you get support for the Freescale MXC | 1131 | This enables support for the RTC in the PKUnity-v3 SoCs. |
1160 | RTC module. | ||
1161 | 1132 | ||
1162 | This driver can also be built as a module, if so, the module | 1133 | This drive can also be built as a module. If so, the module |
1163 | will be called "rtc-mxc". | 1134 | will be called rtc-puv3. |
1164 | 1135 | ||
1165 | config RTC_DRV_SNVS | 1136 | config RTC_DRV_RC5T583 |
1166 | tristate "Freescale SNVS RTC support" | 1137 | tristate "RICOH RC5T583 PMU RTC driver" |
1167 | depends on HAS_IOMEM | 1138 | depends on MFD_RICOH583 |
1168 | depends on OF | 1139 | default n |
1169 | help | 1140 | help |
1170 | If you say yes here you get support for the Freescale SNVS | 1141 | If you say yes here you get support for the RICOH RC5T583 RTC module. |
1171 | Low Power (LP) RTC module. | ||
1172 | 1142 | ||
1173 | This driver can also be built as a module, if so, the module | 1143 | This driver can also be built as a module. If so, the module |
1174 | will be called "rtc-snvs". | 1144 | will be called rtc-rc5t583. |
1175 | 1145 | ||
1176 | endif # RTC_CLASS | 1146 | endif # RTC_CLASS |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 4418ef3f9ec..be5b16284db 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -9,6 +9,8 @@ obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o | |||
9 | obj-$(CONFIG_RTC_CLASS) += rtc-core.o | 9 | obj-$(CONFIG_RTC_CLASS) += rtc-core.o |
10 | rtc-core-y := class.o interface.o | 10 | rtc-core-y := class.o interface.o |
11 | 11 | ||
12 | obj-$(CONFIG_RTC_INTF_ALARM) += alarm.o | ||
13 | obj-$(CONFIG_RTC_INTF_ALARM_DEV) += alarm-dev.o | ||
12 | rtc-core-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o | 14 | rtc-core-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o |
13 | rtc-core-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o | 15 | rtc-core-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o |
14 | rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o | 16 | rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o |
@@ -16,7 +18,6 @@ rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o | |||
16 | # Keep the list ordered. | 18 | # Keep the list ordered. |
17 | 19 | ||
18 | obj-$(CONFIG_RTC_DRV_88PM860X) += rtc-88pm860x.o | 20 | obj-$(CONFIG_RTC_DRV_88PM860X) += rtc-88pm860x.o |
19 | obj-$(CONFIG_RTC_DRV_88PM80X) += rtc-88pm80x.o | ||
20 | obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o | 21 | obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o |
21 | obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o | 22 | obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o |
22 | obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o | 23 | obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o |
@@ -28,8 +29,6 @@ obj-$(CONFIG_RTC_DRV_BQ32K) += rtc-bq32k.o | |||
28 | obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o | 29 | obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o |
29 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o | 30 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o |
30 | obj-$(CONFIG_RTC_DRV_COH901331) += rtc-coh901331.o | 31 | obj-$(CONFIG_RTC_DRV_COH901331) += rtc-coh901331.o |
31 | obj-$(CONFIG_RTC_DRV_DA9052) += rtc-da9052.o | ||
32 | obj-$(CONFIG_RTC_DRV_DA9055) += rtc-da9055.o | ||
33 | obj-$(CONFIG_RTC_DRV_DAVINCI) += rtc-davinci.o | 32 | obj-$(CONFIG_RTC_DRV_DAVINCI) += rtc-davinci.o |
34 | obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o | 33 | obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o |
35 | obj-$(CONFIG_RTC_DRV_VRTC) += rtc-mrst.o | 34 | obj-$(CONFIG_RTC_DRV_VRTC) += rtc-mrst.o |
@@ -44,7 +43,6 @@ obj-$(CONFIG_RTC_DRV_DS1511) += rtc-ds1511.o | |||
44 | obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o | 43 | obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o |
45 | obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o | 44 | obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o |
46 | obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o | 45 | obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o |
47 | obj-$(CONFIG_RTC_DRV_DS2404) += rtc-ds2404.o | ||
48 | obj-$(CONFIG_RTC_DRV_DS3232) += rtc-ds3232.o | 46 | obj-$(CONFIG_RTC_DRV_DS3232) += rtc-ds3232.o |
49 | obj-$(CONFIG_RTC_DRV_DS3234) += rtc-ds3234.o | 47 | obj-$(CONFIG_RTC_DRV_DS3234) += rtc-ds3234.o |
50 | obj-$(CONFIG_RTC_DRV_EFI) += rtc-efi.o | 48 | obj-$(CONFIG_RTC_DRV_EFI) += rtc-efi.o |
@@ -57,27 +55,26 @@ obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o | |||
57 | obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o | 55 | obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o |
58 | obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o | 56 | obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o |
59 | obj-$(CONFIG_RTC_DRV_LPC32XX) += rtc-lpc32xx.o | 57 | obj-$(CONFIG_RTC_DRV_LPC32XX) += rtc-lpc32xx.o |
60 | obj-$(CONFIG_RTC_DRV_LOONGSON1) += rtc-ls1x.o | ||
61 | obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o | 58 | obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o |
62 | obj-$(CONFIG_RTC_DRV_M41T93) += rtc-m41t93.o | 59 | obj-$(CONFIG_RTC_DRV_M41T93) += rtc-m41t93.o |
63 | obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o | 60 | obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o |
64 | obj-$(CONFIG_RTC_DRV_M48T35) += rtc-m48t35.o | 61 | obj-$(CONFIG_RTC_DRV_M48T35) += rtc-m48t35.o |
65 | obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o | 62 | obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o |
66 | obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o | 63 | obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o |
67 | obj-$(CONFIG_RTC_DRV_MXC) += rtc-mxc.o | 64 | obj-$(CONFIG_RTC_MXC) += rtc-mxc.o |
68 | obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o | 65 | obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o |
69 | obj-$(CONFIG_RTC_DRV_MAX8907) += rtc-max8907.o | ||
70 | obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o | 66 | obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o |
71 | obj-$(CONFIG_RTC_DRV_MAX8998) += rtc-max8998.o | 67 | obj-$(CONFIG_RTC_DRV_MAX8998) += rtc-max8998.o |
68 | obj-$(CONFIG_RTC_DRV_MAX8907C) += rtc-max8907c.o | ||
72 | obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o | 69 | obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o |
73 | obj-$(CONFIG_RTC_DRV_MC13XXX) += rtc-mc13xxx.o | 70 | obj-$(CONFIG_RTC_DRV_MC13XXX) += rtc-mc13xxx.o |
71 | obj-$(CONFIG_RTC_DRV_MAX77663) += rtc-max77663.o | ||
74 | obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o | 72 | obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o |
75 | obj-$(CONFIG_RTC_DRV_MPC5121) += rtc-mpc5121.o | 73 | obj-$(CONFIG_RTC_DRV_MPC5121) += rtc-mpc5121.o |
76 | obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o | 74 | obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o |
77 | obj-$(CONFIG_RTC_DRV_NUC900) += rtc-nuc900.o | 75 | obj-$(CONFIG_RTC_DRV_NUC900) += rtc-nuc900.o |
78 | obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o | 76 | obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o |
79 | obj-$(CONFIG_RTC_DRV_PCAP) += rtc-pcap.o | 77 | obj-$(CONFIG_RTC_DRV_PCAP) += rtc-pcap.o |
80 | obj-$(CONFIG_RTC_DRV_PCF8523) += rtc-pcf8523.o | ||
81 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o | 78 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o |
82 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o | 79 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o |
83 | obj-$(CONFIG_RTC_DRV_PCF2123) += rtc-pcf2123.o | 80 | obj-$(CONFIG_RTC_DRV_PCF2123) += rtc-pcf2123.o |
@@ -89,7 +86,6 @@ obj-$(CONFIG_RTC_DRV_PS3) += rtc-ps3.o | |||
89 | obj-$(CONFIG_RTC_DRV_PUV3) += rtc-puv3.o | 86 | obj-$(CONFIG_RTC_DRV_PUV3) += rtc-puv3.o |
90 | obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o | 87 | obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o |
91 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o | 88 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o |
92 | obj-$(CONFIG_RTC_DRV_RC5T583) += rtc-rc5t583.o | ||
93 | obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c01.o | 89 | obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c01.o |
94 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o | 90 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o |
95 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o | 91 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o |
@@ -101,7 +97,6 @@ obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o | |||
101 | obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o | 97 | obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o |
102 | obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o | 98 | obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o |
103 | obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o | 99 | obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o |
104 | obj-$(CONFIG_RTC_DRV_SNVS) += rtc-snvs.o | ||
105 | obj-$(CONFIG_RTC_DRV_SPEAR) += rtc-spear.o | 100 | obj-$(CONFIG_RTC_DRV_SPEAR) += rtc-spear.o |
106 | obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o | 101 | obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o |
107 | obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o | 102 | obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o |
@@ -110,9 +105,11 @@ obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o | |||
110 | obj-$(CONFIG_RTC_DRV_TEGRA) += rtc-tegra.o | 105 | obj-$(CONFIG_RTC_DRV_TEGRA) += rtc-tegra.o |
111 | obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o | 106 | obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o |
112 | obj-$(CONFIG_RTC_DRV_TILE) += rtc-tile.o | 107 | obj-$(CONFIG_RTC_DRV_TILE) += rtc-tile.o |
113 | obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o | ||
114 | obj-$(CONFIG_RTC_DRV_TPS6586X) += rtc-tps6586x.o | 108 | obj-$(CONFIG_RTC_DRV_TPS6586X) += rtc-tps6586x.o |
115 | obj-$(CONFIG_RTC_DRV_TPS65910) += rtc-tps65910.o | 109 | obj-$(CONFIG_RTC_DRV_TPS6591x) += rtc-tps6591x.o |
110 | obj-$(CONFIG_RTC_DRV_TPS80031) += rtc-tps80031.o | ||
111 | obj-$(CONFIG_RTC_DRV_RC5T583) += rtc-ricoh583.o | ||
112 | obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o | ||
116 | obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o | 113 | obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o |
117 | obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o | 114 | obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o |
118 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o | 115 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o |
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 5143629dedb..b82a1554cdc 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c | |||
@@ -21,22 +21,21 @@ | |||
21 | #include "rtc-core.h" | 21 | #include "rtc-core.h" |
22 | 22 | ||
23 | 23 | ||
24 | static DEFINE_IDA(rtc_ida); | 24 | static DEFINE_IDR(rtc_idr); |
25 | static DEFINE_MUTEX(idr_lock); | ||
25 | struct class *rtc_class; | 26 | struct class *rtc_class; |
26 | 27 | ||
27 | static void rtc_device_release(struct device *dev) | 28 | static void rtc_device_release(struct device *dev) |
28 | { | 29 | { |
29 | struct rtc_device *rtc = to_rtc_device(dev); | 30 | struct rtc_device *rtc = to_rtc_device(dev); |
30 | ida_simple_remove(&rtc_ida, rtc->id); | 31 | mutex_lock(&idr_lock); |
32 | idr_remove(&rtc_idr, rtc->id); | ||
33 | mutex_unlock(&idr_lock); | ||
31 | kfree(rtc); | 34 | kfree(rtc); |
32 | } | 35 | } |
33 | 36 | ||
34 | #ifdef CONFIG_RTC_HCTOSYS_DEVICE | ||
35 | /* Result of the last RTC to system clock attempt. */ | ||
36 | int rtc_hctosys_ret = -ENODEV; | ||
37 | #endif | ||
38 | |||
39 | #if defined(CONFIG_PM) && defined(CONFIG_RTC_HCTOSYS_DEVICE) | 37 | #if defined(CONFIG_PM) && defined(CONFIG_RTC_HCTOSYS_DEVICE) |
38 | |||
40 | /* | 39 | /* |
41 | * On suspend(), measure the delta between one RTC and the | 40 | * On suspend(), measure the delta between one RTC and the |
42 | * system's wall clock; restore it on resume(). | 41 | * system's wall clock; restore it on resume(). |
@@ -88,7 +87,6 @@ static int rtc_resume(struct device *dev) | |||
88 | struct timespec new_system, new_rtc; | 87 | struct timespec new_system, new_rtc; |
89 | struct timespec sleep_time; | 88 | struct timespec sleep_time; |
90 | 89 | ||
91 | rtc_hctosys_ret = -ENODEV; | ||
92 | if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) | 90 | if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) |
93 | return 0; | 91 | return 0; |
94 | 92 | ||
@@ -122,7 +120,6 @@ static int rtc_resume(struct device *dev) | |||
122 | 120 | ||
123 | if (sleep_time.tv_sec >= 0) | 121 | if (sleep_time.tv_sec >= 0) |
124 | timekeeping_inject_sleeptime(&sleep_time); | 122 | timekeeping_inject_sleeptime(&sleep_time); |
125 | rtc_hctosys_ret = 0; | ||
126 | return 0; | 123 | return 0; |
127 | } | 124 | } |
128 | 125 | ||
@@ -149,16 +146,25 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, | |||
149 | struct rtc_wkalrm alrm; | 146 | struct rtc_wkalrm alrm; |
150 | int id, err; | 147 | int id, err; |
151 | 148 | ||
152 | id = ida_simple_get(&rtc_ida, 0, 0, GFP_KERNEL); | 149 | if (idr_pre_get(&rtc_idr, GFP_KERNEL) == 0) { |
153 | if (id < 0) { | 150 | err = -ENOMEM; |
154 | err = id; | ||
155 | goto exit; | 151 | goto exit; |
156 | } | 152 | } |
157 | 153 | ||
154 | |||
155 | mutex_lock(&idr_lock); | ||
156 | err = idr_get_new(&rtc_idr, NULL, &id); | ||
157 | mutex_unlock(&idr_lock); | ||
158 | |||
159 | if (err < 0) | ||
160 | goto exit; | ||
161 | |||
162 | id = id & MAX_ID_MASK; | ||
163 | |||
158 | rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL); | 164 | rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL); |
159 | if (rtc == NULL) { | 165 | if (rtc == NULL) { |
160 | err = -ENOMEM; | 166 | err = -ENOMEM; |
161 | goto exit_ida; | 167 | goto exit_idr; |
162 | } | 168 | } |
163 | 169 | ||
164 | rtc->id = id; | 170 | rtc->id = id; |
@@ -216,8 +222,10 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, | |||
216 | exit_kfree: | 222 | exit_kfree: |
217 | kfree(rtc); | 223 | kfree(rtc); |
218 | 224 | ||
219 | exit_ida: | 225 | exit_idr: |
220 | ida_simple_remove(&rtc_ida, id); | 226 | mutex_lock(&idr_lock); |
227 | idr_remove(&rtc_idr, id); | ||
228 | mutex_unlock(&idr_lock); | ||
221 | 229 | ||
222 | exit: | 230 | exit: |
223 | dev_err(dev, "rtc core: unable to register %s, err = %d\n", | 231 | dev_err(dev, "rtc core: unable to register %s, err = %d\n", |
@@ -268,7 +276,7 @@ static void __exit rtc_exit(void) | |||
268 | { | 276 | { |
269 | rtc_dev_exit(); | 277 | rtc_dev_exit(); |
270 | class_destroy(rtc_class); | 278 | class_destroy(rtc_class); |
271 | ida_destroy(&rtc_ida); | 279 | idr_destroy(&rtc_idr); |
272 | } | 280 | } |
273 | 281 | ||
274 | subsys_initcall(rtc_init); | 282 | subsys_initcall(rtc_init); |
diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c index 4aa60d74004..bc90b091f19 100644 --- a/drivers/rtc/hctosys.c +++ b/drivers/rtc/hctosys.c | |||
@@ -22,6 +22,8 @@ | |||
22 | * the best guess is to add 0.5s. | 22 | * the best guess is to add 0.5s. |
23 | */ | 23 | */ |
24 | 24 | ||
25 | int rtc_hctosys_ret = -ENODEV; | ||
26 | |||
25 | static int __init rtc_hctosys(void) | 27 | static int __init rtc_hctosys(void) |
26 | { | 28 | { |
27 | int err = -ENODEV; | 29 | int err = -ENODEV; |
@@ -54,7 +56,7 @@ static int __init rtc_hctosys(void) | |||
54 | 56 | ||
55 | rtc_tm_to_time(&tm, &tv.tv_sec); | 57 | rtc_tm_to_time(&tm, &tv.tv_sec); |
56 | 58 | ||
57 | err = do_settimeofday(&tv); | 59 | do_settimeofday(&tv); |
58 | 60 | ||
59 | dev_info(rtc->dev.parent, | 61 | dev_info(rtc->dev.parent, |
60 | "setting system clock to " | 62 | "setting system clock to " |
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 9592b936b71..a86f3013747 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
@@ -13,7 +13,6 @@ | |||
13 | 13 | ||
14 | #include <linux/rtc.h> | 14 | #include <linux/rtc.h> |
15 | #include <linux/sched.h> | 15 | #include <linux/sched.h> |
16 | #include <linux/module.h> | ||
17 | #include <linux/log2.h> | 16 | #include <linux/log2.h> |
18 | #include <linux/workqueue.h> | 17 | #include <linux/workqueue.h> |
19 | 18 | ||
@@ -73,8 +72,6 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) | |||
73 | err = -EINVAL; | 72 | err = -EINVAL; |
74 | 73 | ||
75 | mutex_unlock(&rtc->ops_lock); | 74 | mutex_unlock(&rtc->ops_lock); |
76 | /* A timer might have just expired */ | ||
77 | schedule_work(&rtc->irqwork); | ||
78 | return err; | 75 | return err; |
79 | } | 76 | } |
80 | EXPORT_SYMBOL_GPL(rtc_set_time); | 77 | EXPORT_SYMBOL_GPL(rtc_set_time); |
@@ -114,8 +111,6 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs) | |||
114 | err = -EINVAL; | 111 | err = -EINVAL; |
115 | 112 | ||
116 | mutex_unlock(&rtc->ops_lock); | 113 | mutex_unlock(&rtc->ops_lock); |
117 | /* A timer might have just expired */ | ||
118 | schedule_work(&rtc->irqwork); | ||
119 | 114 | ||
120 | return err; | 115 | return err; |
121 | } | 116 | } |
@@ -384,27 +379,18 @@ EXPORT_SYMBOL_GPL(rtc_set_alarm); | |||
384 | int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | 379 | int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) |
385 | { | 380 | { |
386 | int err; | 381 | int err; |
387 | struct rtc_time now; | ||
388 | 382 | ||
389 | err = rtc_valid_tm(&alarm->time); | 383 | err = rtc_valid_tm(&alarm->time); |
390 | if (err != 0) | 384 | if (err != 0) |
391 | return err; | 385 | return err; |
392 | 386 | ||
393 | err = rtc_read_time(rtc, &now); | ||
394 | if (err) | ||
395 | return err; | ||
396 | |||
397 | err = mutex_lock_interruptible(&rtc->ops_lock); | 387 | err = mutex_lock_interruptible(&rtc->ops_lock); |
398 | if (err) | 388 | if (err) |
399 | return err; | 389 | return err; |
400 | 390 | ||
401 | rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time); | 391 | rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time); |
402 | rtc->aie_timer.period = ktime_set(0, 0); | 392 | rtc->aie_timer.period = ktime_set(0, 0); |
403 | 393 | if (alarm->enabled) { | |
404 | /* Alarm has to be enabled & in the futrure for us to enqueue it */ | ||
405 | if (alarm->enabled && (rtc_tm_to_ktime(now).tv64 < | ||
406 | rtc->aie_timer.node.expires.tv64)) { | ||
407 | |||
408 | rtc->aie_timer.enabled = 1; | 394 | rtc->aie_timer.enabled = 1; |
409 | timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node); | 395 | timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node); |
410 | } | 396 | } |
@@ -458,11 +444,6 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) | |||
458 | if (rtc->uie_rtctimer.enabled == enabled) | 444 | if (rtc->uie_rtctimer.enabled == enabled) |
459 | goto out; | 445 | goto out; |
460 | 446 | ||
461 | if (rtc->uie_unsupported) { | ||
462 | err = -EINVAL; | ||
463 | goto out; | ||
464 | } | ||
465 | |||
466 | if (enabled) { | 447 | if (enabled) { |
467 | struct rtc_time tm; | 448 | struct rtc_time tm; |
468 | ktime_t now, onesec; | 449 | ktime_t now, onesec; |
@@ -582,7 +563,6 @@ enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer) | |||
582 | void rtc_update_irq(struct rtc_device *rtc, | 563 | void rtc_update_irq(struct rtc_device *rtc, |
583 | unsigned long num, unsigned long events) | 564 | unsigned long num, unsigned long events) |
584 | { | 565 | { |
585 | pm_stay_awake(rtc->dev.parent); | ||
586 | schedule_work(&rtc->irqwork); | 566 | schedule_work(&rtc->irqwork); |
587 | } | 567 | } |
588 | EXPORT_SYMBOL_GPL(rtc_update_irq); | 568 | EXPORT_SYMBOL_GPL(rtc_update_irq); |
@@ -782,14 +762,6 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) | |||
782 | return 0; | 762 | return 0; |
783 | } | 763 | } |
784 | 764 | ||
785 | static void rtc_alarm_disable(struct rtc_device *rtc) | ||
786 | { | ||
787 | if (!rtc->ops || !rtc->ops->alarm_irq_enable) | ||
788 | return; | ||
789 | |||
790 | rtc->ops->alarm_irq_enable(rtc->dev.parent, false); | ||
791 | } | ||
792 | |||
793 | /** | 765 | /** |
794 | * rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue | 766 | * rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue |
795 | * @rtc rtc device | 767 | * @rtc rtc device |
@@ -811,10 +783,8 @@ static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer) | |||
811 | struct rtc_wkalrm alarm; | 783 | struct rtc_wkalrm alarm; |
812 | int err; | 784 | int err; |
813 | next = timerqueue_getnext(&rtc->timerqueue); | 785 | next = timerqueue_getnext(&rtc->timerqueue); |
814 | if (!next) { | 786 | if (!next) |
815 | rtc_alarm_disable(rtc); | ||
816 | return; | 787 | return; |
817 | } | ||
818 | alarm.time = rtc_ktime_to_tm(next->expires); | 788 | alarm.time = rtc_ktime_to_tm(next->expires); |
819 | alarm.enabled = 1; | 789 | alarm.enabled = 1; |
820 | err = __rtc_set_alarm(rtc, &alarm); | 790 | err = __rtc_set_alarm(rtc, &alarm); |
@@ -845,7 +815,6 @@ void rtc_timer_do_work(struct work_struct *work) | |||
845 | 815 | ||
846 | mutex_lock(&rtc->ops_lock); | 816 | mutex_lock(&rtc->ops_lock); |
847 | again: | 817 | again: |
848 | pm_relax(rtc->dev.parent); | ||
849 | __rtc_read_time(rtc, &tm); | 818 | __rtc_read_time(rtc, &tm); |
850 | now = rtc_tm_to_ktime(tm); | 819 | now = rtc_tm_to_ktime(tm); |
851 | while ((next = timerqueue_getnext(&rtc->timerqueue))) { | 820 | while ((next = timerqueue_getnext(&rtc->timerqueue))) { |
@@ -877,8 +846,7 @@ again: | |||
877 | err = __rtc_set_alarm(rtc, &alarm); | 846 | err = __rtc_set_alarm(rtc, &alarm); |
878 | if (err == -ETIME) | 847 | if (err == -ETIME) |
879 | goto again; | 848 | goto again; |
880 | } else | 849 | } |
881 | rtc_alarm_disable(rtc); | ||
882 | 850 | ||
883 | mutex_unlock(&rtc->ops_lock); | 851 | mutex_unlock(&rtc->ops_lock); |
884 | } | 852 | } |
diff --git a/drivers/rtc/rtc-88pm80x.c b/drivers/rtc/rtc-88pm80x.c deleted file mode 100644 index 63b17ebe90e..00000000000 --- a/drivers/rtc/rtc-88pm80x.c +++ /dev/null | |||
@@ -1,369 +0,0 @@ | |||
1 | /* | ||
2 | * Real Time Clock driver for Marvell 88PM80x PMIC | ||
3 | * | ||
4 | * Copyright (c) 2012 Marvell International Ltd. | ||
5 | * Wenzeng Chen<wzch@marvell.com> | ||
6 | * Qiao Zhou <zhouqiao@marvell.com> | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General | ||
9 | * Public License. See the file "COPYING" in the main directory of this | ||
10 | * archive for more details. | ||
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 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/regmap.h> | ||
26 | #include <linux/mfd/core.h> | ||
27 | #include <linux/mfd/88pm80x.h> | ||
28 | #include <linux/rtc.h> | ||
29 | |||
30 | #define PM800_RTC_COUNTER1 (0xD1) | ||
31 | #define PM800_RTC_COUNTER2 (0xD2) | ||
32 | #define PM800_RTC_COUNTER3 (0xD3) | ||
33 | #define PM800_RTC_COUNTER4 (0xD4) | ||
34 | #define PM800_RTC_EXPIRE1_1 (0xD5) | ||
35 | #define PM800_RTC_EXPIRE1_2 (0xD6) | ||
36 | #define PM800_RTC_EXPIRE1_3 (0xD7) | ||
37 | #define PM800_RTC_EXPIRE1_4 (0xD8) | ||
38 | #define PM800_RTC_TRIM1 (0xD9) | ||
39 | #define PM800_RTC_TRIM2 (0xDA) | ||
40 | #define PM800_RTC_TRIM3 (0xDB) | ||
41 | #define PM800_RTC_TRIM4 (0xDC) | ||
42 | #define PM800_RTC_EXPIRE2_1 (0xDD) | ||
43 | #define PM800_RTC_EXPIRE2_2 (0xDE) | ||
44 | #define PM800_RTC_EXPIRE2_3 (0xDF) | ||
45 | #define PM800_RTC_EXPIRE2_4 (0xE0) | ||
46 | |||
47 | #define PM800_POWER_DOWN_LOG1 (0xE5) | ||
48 | #define PM800_POWER_DOWN_LOG2 (0xE6) | ||
49 | |||
50 | struct pm80x_rtc_info { | ||
51 | struct pm80x_chip *chip; | ||
52 | struct regmap *map; | ||
53 | struct rtc_device *rtc_dev; | ||
54 | struct device *dev; | ||
55 | struct delayed_work calib_work; | ||
56 | |||
57 | int irq; | ||
58 | int vrtc; | ||
59 | }; | ||
60 | |||
61 | static irqreturn_t rtc_update_handler(int irq, void *data) | ||
62 | { | ||
63 | struct pm80x_rtc_info *info = (struct pm80x_rtc_info *)data; | ||
64 | int mask; | ||
65 | |||
66 | mask = PM800_ALARM | PM800_ALARM_WAKEUP; | ||
67 | regmap_update_bits(info->map, PM800_RTC_CONTROL, mask | PM800_ALARM1_EN, | ||
68 | mask); | ||
69 | rtc_update_irq(info->rtc_dev, 1, RTC_AF); | ||
70 | return IRQ_HANDLED; | ||
71 | } | ||
72 | |||
73 | static int pm80x_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | ||
74 | { | ||
75 | struct pm80x_rtc_info *info = dev_get_drvdata(dev); | ||
76 | |||
77 | if (enabled) | ||
78 | regmap_update_bits(info->map, PM800_RTC_CONTROL, | ||
79 | PM800_ALARM1_EN, PM800_ALARM1_EN); | ||
80 | else | ||
81 | regmap_update_bits(info->map, PM800_RTC_CONTROL, | ||
82 | PM800_ALARM1_EN, 0); | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | /* | ||
87 | * Calculate the next alarm time given the requested alarm time mask | ||
88 | * and the current time. | ||
89 | */ | ||
90 | static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, | ||
91 | struct rtc_time *alrm) | ||
92 | { | ||
93 | unsigned long next_time; | ||
94 | unsigned long now_time; | ||
95 | |||
96 | next->tm_year = now->tm_year; | ||
97 | next->tm_mon = now->tm_mon; | ||
98 | next->tm_mday = now->tm_mday; | ||
99 | next->tm_hour = alrm->tm_hour; | ||
100 | next->tm_min = alrm->tm_min; | ||
101 | next->tm_sec = alrm->tm_sec; | ||
102 | |||
103 | rtc_tm_to_time(now, &now_time); | ||
104 | rtc_tm_to_time(next, &next_time); | ||
105 | |||
106 | if (next_time < now_time) { | ||
107 | /* Advance one day */ | ||
108 | next_time += 60 * 60 * 24; | ||
109 | rtc_time_to_tm(next_time, next); | ||
110 | } | ||
111 | } | ||
112 | |||
113 | static int pm80x_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
114 | { | ||
115 | struct pm80x_rtc_info *info = dev_get_drvdata(dev); | ||
116 | unsigned char buf[4]; | ||
117 | unsigned long ticks, base, data; | ||
118 | regmap_raw_read(info->map, PM800_RTC_EXPIRE2_1, buf, 4); | ||
119 | base = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; | ||
120 | dev_dbg(info->dev, "%x-%x-%x-%x\n", buf[0], buf[1], buf[2], buf[3]); | ||
121 | |||
122 | /* load 32-bit read-only counter */ | ||
123 | regmap_raw_read(info->map, PM800_RTC_COUNTER1, buf, 4); | ||
124 | data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; | ||
125 | ticks = base + data; | ||
126 | dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", | ||
127 | base, data, ticks); | ||
128 | rtc_time_to_tm(ticks, tm); | ||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | static int pm80x_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
133 | { | ||
134 | struct pm80x_rtc_info *info = dev_get_drvdata(dev); | ||
135 | unsigned char buf[4]; | ||
136 | unsigned long ticks, base, data; | ||
137 | if ((tm->tm_year < 70) || (tm->tm_year > 138)) { | ||
138 | dev_dbg(info->dev, | ||
139 | "Set time %d out of range. 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 | regmap_raw_read(info->map, PM800_RTC_COUNTER1, buf, 4); | ||
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 | buf[0] = base & 0xFF; | ||
152 | buf[1] = (base >> 8) & 0xFF; | ||
153 | buf[2] = (base >> 16) & 0xFF; | ||
154 | buf[3] = (base >> 24) & 0xFF; | ||
155 | regmap_raw_write(info->map, PM800_RTC_EXPIRE2_1, buf, 4); | ||
156 | |||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | static int pm80x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
161 | { | ||
162 | struct pm80x_rtc_info *info = dev_get_drvdata(dev); | ||
163 | unsigned char buf[4]; | ||
164 | unsigned long ticks, base, data; | ||
165 | int ret; | ||
166 | |||
167 | regmap_raw_read(info->map, PM800_RTC_EXPIRE2_1, buf, 4); | ||
168 | base = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; | ||
169 | dev_dbg(info->dev, "%x-%x-%x-%x\n", buf[0], buf[1], buf[2], buf[3]); | ||
170 | |||
171 | regmap_raw_read(info->map, PM800_RTC_EXPIRE1_1, buf, 4); | ||
172 | data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; | ||
173 | ticks = base + data; | ||
174 | dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", | ||
175 | base, data, ticks); | ||
176 | |||
177 | rtc_time_to_tm(ticks, &alrm->time); | ||
178 | regmap_read(info->map, PM800_RTC_CONTROL, &ret); | ||
179 | alrm->enabled = (ret & PM800_ALARM1_EN) ? 1 : 0; | ||
180 | alrm->pending = (ret & (PM800_ALARM | PM800_ALARM_WAKEUP)) ? 1 : 0; | ||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | static int pm80x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
185 | { | ||
186 | struct pm80x_rtc_info *info = dev_get_drvdata(dev); | ||
187 | struct rtc_time now_tm, alarm_tm; | ||
188 | unsigned long ticks, base, data; | ||
189 | unsigned char buf[4]; | ||
190 | int mask; | ||
191 | |||
192 | regmap_update_bits(info->map, PM800_RTC_CONTROL, PM800_ALARM1_EN, 0); | ||
193 | |||
194 | regmap_raw_read(info->map, PM800_RTC_EXPIRE2_1, buf, 4); | ||
195 | base = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; | ||
196 | dev_dbg(info->dev, "%x-%x-%x-%x\n", buf[0], buf[1], buf[2], buf[3]); | ||
197 | |||
198 | /* load 32-bit read-only counter */ | ||
199 | regmap_raw_read(info->map, PM800_RTC_COUNTER1, buf, 4); | ||
200 | data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; | ||
201 | ticks = base + data; | ||
202 | dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", | ||
203 | base, data, ticks); | ||
204 | |||
205 | rtc_time_to_tm(ticks, &now_tm); | ||
206 | dev_dbg(info->dev, "%s, now time : %lu\n", __func__, ticks); | ||
207 | rtc_next_alarm_time(&alarm_tm, &now_tm, &alrm->time); | ||
208 | /* get new ticks for alarm in 24 hours */ | ||
209 | rtc_tm_to_time(&alarm_tm, &ticks); | ||
210 | dev_dbg(info->dev, "%s, alarm time: %lu\n", __func__, ticks); | ||
211 | data = ticks - base; | ||
212 | |||
213 | buf[0] = data & 0xff; | ||
214 | buf[1] = (data >> 8) & 0xff; | ||
215 | buf[2] = (data >> 16) & 0xff; | ||
216 | buf[3] = (data >> 24) & 0xff; | ||
217 | regmap_raw_write(info->map, PM800_RTC_EXPIRE1_1, buf, 4); | ||
218 | if (alrm->enabled) { | ||
219 | mask = PM800_ALARM | PM800_ALARM_WAKEUP | PM800_ALARM1_EN; | ||
220 | regmap_update_bits(info->map, PM800_RTC_CONTROL, mask, mask); | ||
221 | } else { | ||
222 | mask = PM800_ALARM | PM800_ALARM_WAKEUP | PM800_ALARM1_EN; | ||
223 | regmap_update_bits(info->map, PM800_RTC_CONTROL, mask, | ||
224 | PM800_ALARM | PM800_ALARM_WAKEUP); | ||
225 | } | ||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | static const struct rtc_class_ops pm80x_rtc_ops = { | ||
230 | .read_time = pm80x_rtc_read_time, | ||
231 | .set_time = pm80x_rtc_set_time, | ||
232 | .read_alarm = pm80x_rtc_read_alarm, | ||
233 | .set_alarm = pm80x_rtc_set_alarm, | ||
234 | .alarm_irq_enable = pm80x_rtc_alarm_irq_enable, | ||
235 | }; | ||
236 | |||
237 | #ifdef CONFIG_PM | ||
238 | static int pm80x_rtc_suspend(struct device *dev) | ||
239 | { | ||
240 | return pm80x_dev_suspend(dev); | ||
241 | } | ||
242 | |||
243 | static int pm80x_rtc_resume(struct device *dev) | ||
244 | { | ||
245 | return pm80x_dev_resume(dev); | ||
246 | } | ||
247 | #endif | ||
248 | |||
249 | static SIMPLE_DEV_PM_OPS(pm80x_rtc_pm_ops, pm80x_rtc_suspend, pm80x_rtc_resume); | ||
250 | |||
251 | static int pm80x_rtc_probe(struct platform_device *pdev) | ||
252 | { | ||
253 | struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent); | ||
254 | struct pm80x_platform_data *pm80x_pdata; | ||
255 | struct pm80x_rtc_pdata *pdata = NULL; | ||
256 | struct pm80x_rtc_info *info; | ||
257 | struct rtc_time tm; | ||
258 | unsigned long ticks = 0; | ||
259 | int ret; | ||
260 | |||
261 | pdata = pdev->dev.platform_data; | ||
262 | if (pdata == NULL) | ||
263 | dev_warn(&pdev->dev, "No platform data!\n"); | ||
264 | |||
265 | info = | ||
266 | devm_kzalloc(&pdev->dev, sizeof(struct pm80x_rtc_info), GFP_KERNEL); | ||
267 | if (!info) | ||
268 | return -ENOMEM; | ||
269 | info->irq = platform_get_irq(pdev, 0); | ||
270 | if (info->irq < 0) { | ||
271 | dev_err(&pdev->dev, "No IRQ resource!\n"); | ||
272 | ret = -EINVAL; | ||
273 | goto out; | ||
274 | } | ||
275 | |||
276 | info->chip = chip; | ||
277 | info->map = chip->regmap; | ||
278 | if (!info->map) { | ||
279 | dev_err(&pdev->dev, "no regmap!\n"); | ||
280 | ret = -EINVAL; | ||
281 | goto out; | ||
282 | } | ||
283 | |||
284 | info->dev = &pdev->dev; | ||
285 | dev_set_drvdata(&pdev->dev, info); | ||
286 | |||
287 | ret = pm80x_request_irq(chip, info->irq, rtc_update_handler, | ||
288 | IRQF_ONESHOT, "rtc", info); | ||
289 | if (ret < 0) { | ||
290 | dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", | ||
291 | info->irq, ret); | ||
292 | goto out; | ||
293 | } | ||
294 | |||
295 | ret = pm80x_rtc_read_time(&pdev->dev, &tm); | ||
296 | if (ret < 0) { | ||
297 | dev_err(&pdev->dev, "Failed to read initial time.\n"); | ||
298 | goto out_rtc; | ||
299 | } | ||
300 | if ((tm.tm_year < 70) || (tm.tm_year > 138)) { | ||
301 | tm.tm_year = 70; | ||
302 | tm.tm_mon = 0; | ||
303 | tm.tm_mday = 1; | ||
304 | tm.tm_hour = 0; | ||
305 | tm.tm_min = 0; | ||
306 | tm.tm_sec = 0; | ||
307 | ret = pm80x_rtc_set_time(&pdev->dev, &tm); | ||
308 | if (ret < 0) { | ||
309 | dev_err(&pdev->dev, "Failed to set initial time.\n"); | ||
310 | goto out_rtc; | ||
311 | } | ||
312 | } | ||
313 | rtc_tm_to_time(&tm, &ticks); | ||
314 | |||
315 | info->rtc_dev = rtc_device_register("88pm80x-rtc", &pdev->dev, | ||
316 | &pm80x_rtc_ops, THIS_MODULE); | ||
317 | if (IS_ERR(info->rtc_dev)) { | ||
318 | ret = PTR_ERR(info->rtc_dev); | ||
319 | dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); | ||
320 | goto out_rtc; | ||
321 | } | ||
322 | /* | ||
323 | * enable internal XO instead of internal 3.25MHz clock since it can | ||
324 | * free running in PMIC power-down state. | ||
325 | */ | ||
326 | regmap_update_bits(info->map, PM800_RTC_CONTROL, PM800_RTC1_USE_XO, | ||
327 | PM800_RTC1_USE_XO); | ||
328 | |||
329 | if (pdev->dev.parent->platform_data) { | ||
330 | pm80x_pdata = pdev->dev.parent->platform_data; | ||
331 | pdata = pm80x_pdata->rtc; | ||
332 | if (pdata) | ||
333 | info->rtc_dev->dev.platform_data = &pdata->rtc_wakeup; | ||
334 | } | ||
335 | |||
336 | device_init_wakeup(&pdev->dev, 1); | ||
337 | |||
338 | return 0; | ||
339 | out_rtc: | ||
340 | pm80x_free_irq(chip, info->irq, info); | ||
341 | out: | ||
342 | return ret; | ||
343 | } | ||
344 | |||
345 | static int pm80x_rtc_remove(struct platform_device *pdev) | ||
346 | { | ||
347 | struct pm80x_rtc_info *info = platform_get_drvdata(pdev); | ||
348 | platform_set_drvdata(pdev, NULL); | ||
349 | rtc_device_unregister(info->rtc_dev); | ||
350 | pm80x_free_irq(info->chip, info->irq, info); | ||
351 | return 0; | ||
352 | } | ||
353 | |||
354 | static struct platform_driver pm80x_rtc_driver = { | ||
355 | .driver = { | ||
356 | .name = "88pm80x-rtc", | ||
357 | .owner = THIS_MODULE, | ||
358 | .pm = &pm80x_rtc_pm_ops, | ||
359 | }, | ||
360 | .probe = pm80x_rtc_probe, | ||
361 | .remove = pm80x_rtc_remove, | ||
362 | }; | ||
363 | |||
364 | module_platform_driver(pm80x_rtc_driver); | ||
365 | |||
366 | MODULE_LICENSE("GPL"); | ||
367 | MODULE_DESCRIPTION("Marvell 88PM80x RTC driver"); | ||
368 | MODULE_AUTHOR("Qiao Zhou <zhouqiao@marvell.com>"); | ||
369 | MODULE_ALIAS("platform:88pm80x-rtc"); | ||
diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c index f663746f460..64b847b7f97 100644 --- a/drivers/rtc/rtc-88pm860x.c +++ b/drivers/rtc/rtc-88pm860x.c | |||
@@ -11,7 +11,6 @@ | |||
11 | 11 | ||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/of.h> | ||
15 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
16 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
17 | #include <linux/mutex.h> | 16 | #include <linux/mutex.h> |
@@ -73,9 +72,9 @@ static int pm860x_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | |||
73 | struct pm860x_rtc_info *info = dev_get_drvdata(dev); | 72 | struct pm860x_rtc_info *info = dev_get_drvdata(dev); |
74 | 73 | ||
75 | if (enabled) | 74 | if (enabled) |
76 | pm860x_set_bits(info->i2c, PM8607_RTC1, ALARM_EN, ALARM_EN); | 75 | pm860x_set_bits(info->i2c, PM8607_RTC1, ALARM, ALARM); |
77 | else | 76 | else |
78 | pm860x_set_bits(info->i2c, PM8607_RTC1, ALARM_EN, 0); | 77 | pm860x_set_bits(info->i2c, PM8607_RTC1, ALARM, 0); |
79 | return 0; | 78 | return 0; |
80 | } | 79 | } |
81 | 80 | ||
@@ -285,29 +284,7 @@ out: | |||
285 | } | 284 | } |
286 | #endif | 285 | #endif |
287 | 286 | ||
288 | #ifdef CONFIG_OF | 287 | static int __devinit pm860x_rtc_probe(struct platform_device *pdev) |
289 | static int pm860x_rtc_dt_init(struct platform_device *pdev, | ||
290 | struct pm860x_rtc_info *info) | ||
291 | { | ||
292 | struct device_node *np = pdev->dev.parent->of_node; | ||
293 | int ret; | ||
294 | if (!np) | ||
295 | return -ENODEV; | ||
296 | np = of_find_node_by_name(np, "rtc"); | ||
297 | if (!np) { | ||
298 | dev_err(&pdev->dev, "failed to find rtc node\n"); | ||
299 | return -ENODEV; | ||
300 | } | ||
301 | ret = of_property_read_u32(np, "marvell,88pm860x-vrtc", &info->vrtc); | ||
302 | if (ret) | ||
303 | info->vrtc = 0; | ||
304 | return 0; | ||
305 | } | ||
306 | #else | ||
307 | #define pm860x_rtc_dt_init(x, y) (-1) | ||
308 | #endif | ||
309 | |||
310 | static int pm860x_rtc_probe(struct platform_device *pdev) | ||
311 | { | 288 | { |
312 | struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); | 289 | struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); |
313 | struct pm860x_rtc_pdata *pdata = NULL; | 290 | struct pm860x_rtc_pdata *pdata = NULL; |
@@ -317,6 +294,8 @@ static int pm860x_rtc_probe(struct platform_device *pdev) | |||
317 | int ret; | 294 | int ret; |
318 | 295 | ||
319 | pdata = pdev->dev.platform_data; | 296 | pdata = pdev->dev.platform_data; |
297 | if (pdata == NULL) | ||
298 | dev_warn(&pdev->dev, "No platform data!\n"); | ||
320 | 299 | ||
321 | info = kzalloc(sizeof(struct pm860x_rtc_info), GFP_KERNEL); | 300 | info = kzalloc(sizeof(struct pm860x_rtc_info), GFP_KERNEL); |
322 | if (!info) | 301 | if (!info) |
@@ -366,11 +345,9 @@ static int pm860x_rtc_probe(struct platform_device *pdev) | |||
366 | } | 345 | } |
367 | } | 346 | } |
368 | rtc_tm_to_time(&tm, &ticks); | 347 | rtc_tm_to_time(&tm, &ticks); |
369 | if (pm860x_rtc_dt_init(pdev, info)) { | 348 | if (pdata && pdata->sync) { |
370 | if (pdata && pdata->sync) { | 349 | pdata->sync(ticks); |
371 | pdata->sync(ticks); | 350 | info->sync = pdata->sync; |
372 | info->sync = pdata->sync; | ||
373 | } | ||
374 | } | 351 | } |
375 | 352 | ||
376 | info->rtc_dev = rtc_device_register("88pm860x-rtc", &pdev->dev, | 353 | info->rtc_dev = rtc_device_register("88pm860x-rtc", &pdev->dev, |
@@ -389,21 +366,16 @@ static int pm860x_rtc_probe(struct platform_device *pdev) | |||
389 | 366 | ||
390 | #ifdef VRTC_CALIBRATION | 367 | #ifdef VRTC_CALIBRATION |
391 | /* <00> -- 2.7V, <01> -- 2.9V, <10> -- 3.1V, <11> -- 3.3V */ | 368 | /* <00> -- 2.7V, <01> -- 2.9V, <10> -- 3.1V, <11> -- 3.3V */ |
392 | if (pm860x_rtc_dt_init(pdev, info)) { | 369 | if (pdata && pdata->vrtc) |
393 | if (pdata && pdata->vrtc) | 370 | info->vrtc = pdata->vrtc & 0x3; |
394 | info->vrtc = pdata->vrtc & 0x3; | 371 | else |
395 | else | 372 | info->vrtc = 1; |
396 | info->vrtc = 1; | ||
397 | } | ||
398 | pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, MEAS2_VRTC); | 373 | pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, MEAS2_VRTC); |
399 | 374 | ||
400 | /* calibrate VRTC */ | 375 | /* calibrate VRTC */ |
401 | INIT_DELAYED_WORK(&info->calib_work, calibrate_vrtc_work); | 376 | INIT_DELAYED_WORK(&info->calib_work, calibrate_vrtc_work); |
402 | schedule_delayed_work(&info->calib_work, VRTC_CALIB_INTERVAL); | 377 | schedule_delayed_work(&info->calib_work, VRTC_CALIB_INTERVAL); |
403 | #endif /* VRTC_CALIBRATION */ | 378 | #endif /* VRTC_CALIBRATION */ |
404 | |||
405 | device_init_wakeup(&pdev->dev, 1); | ||
406 | |||
407 | return 0; | 379 | return 0; |
408 | out_rtc: | 380 | out_rtc: |
409 | free_irq(info->irq, info); | 381 | free_irq(info->irq, info); |
@@ -412,7 +384,7 @@ out: | |||
412 | return ret; | 384 | return ret; |
413 | } | 385 | } |
414 | 386 | ||
415 | static int pm860x_rtc_remove(struct platform_device *pdev) | 387 | static int __devexit pm860x_rtc_remove(struct platform_device *pdev) |
416 | { | 388 | { |
417 | struct pm860x_rtc_info *info = platform_get_drvdata(pdev); | 389 | struct pm860x_rtc_info *info = platform_get_drvdata(pdev); |
418 | 390 | ||
@@ -429,40 +401,26 @@ static int pm860x_rtc_remove(struct platform_device *pdev) | |||
429 | return 0; | 401 | return 0; |
430 | } | 402 | } |
431 | 403 | ||
432 | #ifdef CONFIG_PM_SLEEP | ||
433 | static int pm860x_rtc_suspend(struct device *dev) | ||
434 | { | ||
435 | struct platform_device *pdev = to_platform_device(dev); | ||
436 | struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); | ||
437 | |||
438 | if (device_may_wakeup(dev)) | ||
439 | chip->wakeup_flag |= 1 << PM8607_IRQ_RTC; | ||
440 | return 0; | ||
441 | } | ||
442 | static int pm860x_rtc_resume(struct device *dev) | ||
443 | { | ||
444 | struct platform_device *pdev = to_platform_device(dev); | ||
445 | struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); | ||
446 | |||
447 | if (device_may_wakeup(dev)) | ||
448 | chip->wakeup_flag &= ~(1 << PM8607_IRQ_RTC); | ||
449 | return 0; | ||
450 | } | ||
451 | #endif | ||
452 | |||
453 | static SIMPLE_DEV_PM_OPS(pm860x_rtc_pm_ops, pm860x_rtc_suspend, pm860x_rtc_resume); | ||
454 | |||
455 | static struct platform_driver pm860x_rtc_driver = { | 404 | static struct platform_driver pm860x_rtc_driver = { |
456 | .driver = { | 405 | .driver = { |
457 | .name = "88pm860x-rtc", | 406 | .name = "88pm860x-rtc", |
458 | .owner = THIS_MODULE, | 407 | .owner = THIS_MODULE, |
459 | .pm = &pm860x_rtc_pm_ops, | ||
460 | }, | 408 | }, |
461 | .probe = pm860x_rtc_probe, | 409 | .probe = pm860x_rtc_probe, |
462 | .remove = pm860x_rtc_remove, | 410 | .remove = __devexit_p(pm860x_rtc_remove), |
463 | }; | 411 | }; |
464 | 412 | ||
465 | module_platform_driver(pm860x_rtc_driver); | 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); | ||
466 | 424 | ||
467 | MODULE_DESCRIPTION("Marvell 88PM860x RTC driver"); | 425 | MODULE_DESCRIPTION("Marvell 88PM860x RTC driver"); |
468 | MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); | 426 | MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); |
diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c index 57cde2b061e..e346705aae9 100644 --- a/drivers/rtc/rtc-ab8500.c +++ b/drivers/rtc/rtc-ab8500.c | |||
@@ -15,9 +15,8 @@ | |||
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/abx500.h> |
18 | #include <linux/mfd/abx500/ab8500.h> | 18 | #include <linux/mfd/ab8500.h> |
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/of.h> | ||
21 | 20 | ||
22 | #define AB8500_RTC_SOFF_STAT_REG 0x00 | 21 | #define AB8500_RTC_SOFF_STAT_REG 0x00 |
23 | #define AB8500_RTC_CC_CONF_REG 0x01 | 22 | #define AB8500_RTC_CC_CONF_REG 0x01 |
@@ -89,17 +88,22 @@ static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
89 | if (retval < 0) | 88 | if (retval < 0) |
90 | return retval; | 89 | return retval; |
91 | 90 | ||
92 | /* Wait for some cycles after enabling the rtc read in ab8500 */ | 91 | /* Early AB8500 chips will not clear the rtc read request bit */ |
93 | while (time_before(jiffies, timeout)) { | 92 | if (abx500_get_chip_id(dev) == 0) { |
94 | retval = abx500_get_register_interruptible(dev, | 93 | msleep(1); |
95 | AB8500_RTC, AB8500_RTC_READ_REQ_REG, &value); | 94 | } else { |
96 | if (retval < 0) | 95 | /* Wait for some cycles after enabling the rtc read in ab8500 */ |
97 | return retval; | 96 | while (time_before(jiffies, timeout)) { |
98 | 97 | retval = abx500_get_register_interruptible(dev, | |
99 | if (!(value & RTC_READ_REQUEST)) | 98 | AB8500_RTC, AB8500_RTC_READ_REQ_REG, &value); |
100 | break; | 99 | if (retval < 0) |
101 | 100 | return retval; | |
102 | usleep_range(1000, 5000); | 101 | |
102 | if (!(value & RTC_READ_REQUEST)) | ||
103 | break; | ||
104 | |||
105 | msleep(1); | ||
106 | } | ||
103 | } | 107 | } |
104 | 108 | ||
105 | /* Read the Watchtime registers */ | 109 | /* Read the Watchtime registers */ |
@@ -220,8 +224,7 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
220 | { | 224 | { |
221 | int retval, i; | 225 | int retval, i; |
222 | unsigned char buf[ARRAY_SIZE(ab8500_rtc_alarm_regs)]; | 226 | unsigned char buf[ARRAY_SIZE(ab8500_rtc_alarm_regs)]; |
223 | unsigned long mins, secs = 0, cursec = 0; | 227 | unsigned long mins, secs = 0; |
224 | struct rtc_time curtm; | ||
225 | 228 | ||
226 | if (alarm->time.tm_year < (AB8500_RTC_EPOCH - 1900)) { | 229 | if (alarm->time.tm_year < (AB8500_RTC_EPOCH - 1900)) { |
227 | dev_dbg(dev, "year should be equal to or greater than %d\n", | 230 | dev_dbg(dev, "year should be equal to or greater than %d\n", |
@@ -233,18 +236,6 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
233 | rtc_tm_to_time(&alarm->time, &secs); | 236 | rtc_tm_to_time(&alarm->time, &secs); |
234 | 237 | ||
235 | /* | 238 | /* |
236 | * Check whether alarm is set less than 1min. | ||
237 | * Since our RTC doesn't support alarm resolution less than 1min, | ||
238 | * return -EINVAL, so UIE EMUL can take it up, incase of UIE_ON | ||
239 | */ | ||
240 | ab8500_rtc_read_time(dev, &curtm); /* Read current time */ | ||
241 | rtc_tm_to_time(&curtm, &cursec); | ||
242 | if ((secs - cursec) < 59) { | ||
243 | dev_dbg(dev, "Alarm less than 1 minute not supported\r\n"); | ||
244 | return -EINVAL; | ||
245 | } | ||
246 | |||
247 | /* | ||
248 | * Convert it to the number of seconds since 01-01-2000 00:00:00, since | 239 | * Convert it to the number of seconds since 01-01-2000 00:00:00, since |
249 | * we only have a small counter in the RTC. | 240 | * we only have a small counter in the RTC. |
250 | */ | 241 | */ |
@@ -267,109 +258,6 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
267 | return ab8500_rtc_irq_enable(dev, alarm->enabled); | 258 | return ab8500_rtc_irq_enable(dev, alarm->enabled); |
268 | } | 259 | } |
269 | 260 | ||
270 | |||
271 | static int ab8500_rtc_set_calibration(struct device *dev, int calibration) | ||
272 | { | ||
273 | int retval; | ||
274 | u8 rtccal = 0; | ||
275 | |||
276 | /* | ||
277 | * Check that the calibration value (which is in units of 0.5 | ||
278 | * parts-per-million) is in the AB8500's range for RtcCalibration | ||
279 | * register. -128 (0x80) is not permitted because the AB8500 uses | ||
280 | * a sign-bit rather than two's complement, so 0x80 is just another | ||
281 | * representation of zero. | ||
282 | */ | ||
283 | if ((calibration < -127) || (calibration > 127)) { | ||
284 | dev_err(dev, "RtcCalibration value outside permitted range\n"); | ||
285 | return -EINVAL; | ||
286 | } | ||
287 | |||
288 | /* | ||
289 | * The AB8500 uses sign (in bit7) and magnitude (in bits0-7) | ||
290 | * so need to convert to this sort of representation before writing | ||
291 | * into RtcCalibration register... | ||
292 | */ | ||
293 | if (calibration >= 0) | ||
294 | rtccal = 0x7F & calibration; | ||
295 | else | ||
296 | rtccal = ~(calibration - 1) | 0x80; | ||
297 | |||
298 | retval = abx500_set_register_interruptible(dev, AB8500_RTC, | ||
299 | AB8500_RTC_CALIB_REG, rtccal); | ||
300 | |||
301 | return retval; | ||
302 | } | ||
303 | |||
304 | static int ab8500_rtc_get_calibration(struct device *dev, int *calibration) | ||
305 | { | ||
306 | int retval; | ||
307 | u8 rtccal = 0; | ||
308 | |||
309 | retval = abx500_get_register_interruptible(dev, AB8500_RTC, | ||
310 | AB8500_RTC_CALIB_REG, &rtccal); | ||
311 | if (retval >= 0) { | ||
312 | /* | ||
313 | * The AB8500 uses sign (in bit7) and magnitude (in bits0-7) | ||
314 | * so need to convert value from RtcCalibration register into | ||
315 | * a two's complement signed value... | ||
316 | */ | ||
317 | if (rtccal & 0x80) | ||
318 | *calibration = 0 - (rtccal & 0x7F); | ||
319 | else | ||
320 | *calibration = 0x7F & rtccal; | ||
321 | } | ||
322 | |||
323 | return retval; | ||
324 | } | ||
325 | |||
326 | static ssize_t ab8500_sysfs_store_rtc_calibration(struct device *dev, | ||
327 | struct device_attribute *attr, | ||
328 | const char *buf, size_t count) | ||
329 | { | ||
330 | int retval; | ||
331 | int calibration = 0; | ||
332 | |||
333 | if (sscanf(buf, " %i ", &calibration) != 1) { | ||
334 | dev_err(dev, "Failed to store RTC calibration attribute\n"); | ||
335 | return -EINVAL; | ||
336 | } | ||
337 | |||
338 | retval = ab8500_rtc_set_calibration(dev, calibration); | ||
339 | |||
340 | return retval ? retval : count; | ||
341 | } | ||
342 | |||
343 | static ssize_t ab8500_sysfs_show_rtc_calibration(struct device *dev, | ||
344 | struct device_attribute *attr, char *buf) | ||
345 | { | ||
346 | int retval = 0; | ||
347 | int calibration = 0; | ||
348 | |||
349 | retval = ab8500_rtc_get_calibration(dev, &calibration); | ||
350 | if (retval < 0) { | ||
351 | dev_err(dev, "Failed to read RTC calibration attribute\n"); | ||
352 | sprintf(buf, "0\n"); | ||
353 | return retval; | ||
354 | } | ||
355 | |||
356 | return sprintf(buf, "%d\n", calibration); | ||
357 | } | ||
358 | |||
359 | static DEVICE_ATTR(rtc_calibration, S_IRUGO | S_IWUSR, | ||
360 | ab8500_sysfs_show_rtc_calibration, | ||
361 | ab8500_sysfs_store_rtc_calibration); | ||
362 | |||
363 | static int ab8500_sysfs_rtc_register(struct device *dev) | ||
364 | { | ||
365 | return device_create_file(dev, &dev_attr_rtc_calibration); | ||
366 | } | ||
367 | |||
368 | static void ab8500_sysfs_rtc_unregister(struct device *dev) | ||
369 | { | ||
370 | device_remove_file(dev, &dev_attr_rtc_calibration); | ||
371 | } | ||
372 | |||
373 | static irqreturn_t rtc_alarm_handler(int irq, void *data) | 261 | static irqreturn_t rtc_alarm_handler(int irq, void *data) |
374 | { | 262 | { |
375 | struct rtc_device *rtc = data; | 263 | struct rtc_device *rtc = data; |
@@ -389,7 +277,7 @@ static const struct rtc_class_ops ab8500_rtc_ops = { | |||
389 | .alarm_irq_enable = ab8500_rtc_irq_enable, | 277 | .alarm_irq_enable = ab8500_rtc_irq_enable, |
390 | }; | 278 | }; |
391 | 279 | ||
392 | static int ab8500_rtc_probe(struct platform_device *pdev) | 280 | static int __devinit ab8500_rtc_probe(struct platform_device *pdev) |
393 | { | 281 | { |
394 | int err; | 282 | int err; |
395 | struct rtc_device *rtc; | 283 | struct rtc_device *rtc; |
@@ -407,7 +295,7 @@ static int ab8500_rtc_probe(struct platform_device *pdev) | |||
407 | return err; | 295 | return err; |
408 | 296 | ||
409 | /* Wait for reset by the PorRtc */ | 297 | /* Wait for reset by the PorRtc */ |
410 | usleep_range(1000, 5000); | 298 | msleep(1); |
411 | 299 | ||
412 | err = abx500_get_register_interruptible(&pdev->dev, AB8500_RTC, | 300 | err = abx500_get_register_interruptible(&pdev->dev, AB8500_RTC, |
413 | AB8500_RTC_STAT_REG, &rtc_ctrl); | 301 | AB8500_RTC_STAT_REG, &rtc_ctrl); |
@@ -420,8 +308,6 @@ static int ab8500_rtc_probe(struct platform_device *pdev) | |||
420 | return -ENODEV; | 308 | return -ENODEV; |
421 | } | 309 | } |
422 | 310 | ||
423 | device_init_wakeup(&pdev->dev, true); | ||
424 | |||
425 | rtc = rtc_device_register("ab8500-rtc", &pdev->dev, &ab8500_rtc_ops, | 311 | rtc = rtc_device_register("ab8500-rtc", &pdev->dev, &ab8500_rtc_ops, |
426 | THIS_MODULE); | 312 | THIS_MODULE); |
427 | if (IS_ERR(rtc)) { | 313 | if (IS_ERR(rtc)) { |
@@ -430,8 +316,8 @@ static int ab8500_rtc_probe(struct platform_device *pdev) | |||
430 | return err; | 316 | return err; |
431 | } | 317 | } |
432 | 318 | ||
433 | err = request_threaded_irq(irq, NULL, rtc_alarm_handler, | 319 | err = request_threaded_irq(irq, NULL, rtc_alarm_handler, 0, |
434 | IRQF_NO_SUSPEND | IRQF_ONESHOT, "ab8500-rtc", rtc); | 320 | "ab8500-rtc", rtc); |
435 | if (err < 0) { | 321 | if (err < 0) { |
436 | rtc_device_unregister(rtc); | 322 | rtc_device_unregister(rtc); |
437 | return err; | 323 | return err; |
@@ -439,22 +325,14 @@ static int ab8500_rtc_probe(struct platform_device *pdev) | |||
439 | 325 | ||
440 | platform_set_drvdata(pdev, rtc); | 326 | platform_set_drvdata(pdev, rtc); |
441 | 327 | ||
442 | err = ab8500_sysfs_rtc_register(&pdev->dev); | ||
443 | if (err) { | ||
444 | dev_err(&pdev->dev, "sysfs RTC failed to register\n"); | ||
445 | return err; | ||
446 | } | ||
447 | |||
448 | return 0; | 328 | return 0; |
449 | } | 329 | } |
450 | 330 | ||
451 | static int ab8500_rtc_remove(struct platform_device *pdev) | 331 | static int __devexit ab8500_rtc_remove(struct platform_device *pdev) |
452 | { | 332 | { |
453 | struct rtc_device *rtc = platform_get_drvdata(pdev); | 333 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
454 | int irq = platform_get_irq_byname(pdev, "ALARM"); | 334 | int irq = platform_get_irq_byname(pdev, "ALARM"); |
455 | 335 | ||
456 | ab8500_sysfs_rtc_unregister(&pdev->dev); | ||
457 | |||
458 | free_irq(irq, rtc); | 336 | free_irq(irq, rtc); |
459 | rtc_device_unregister(rtc); | 337 | rtc_device_unregister(rtc); |
460 | platform_set_drvdata(pdev, NULL); | 338 | platform_set_drvdata(pdev, NULL); |
@@ -468,11 +346,21 @@ static struct platform_driver ab8500_rtc_driver = { | |||
468 | .owner = THIS_MODULE, | 346 | .owner = THIS_MODULE, |
469 | }, | 347 | }, |
470 | .probe = ab8500_rtc_probe, | 348 | .probe = ab8500_rtc_probe, |
471 | .remove = ab8500_rtc_remove, | 349 | .remove = __devexit_p(ab8500_rtc_remove), |
472 | }; | 350 | }; |
473 | 351 | ||
474 | module_platform_driver(ab8500_rtc_driver); | 352 | static int __init ab8500_rtc_init(void) |
353 | { | ||
354 | return platform_driver_register(&ab8500_rtc_driver); | ||
355 | } | ||
356 | |||
357 | static void __exit ab8500_rtc_exit(void) | ||
358 | { | ||
359 | platform_driver_unregister(&ab8500_rtc_driver); | ||
360 | } | ||
475 | 361 | ||
362 | module_init(ab8500_rtc_init); | ||
363 | module_exit(ab8500_rtc_exit); | ||
476 | MODULE_AUTHOR("Virupax Sadashivpetimath <virupax.sadashivpetimath@stericsson.com>"); | 364 | MODULE_AUTHOR("Virupax Sadashivpetimath <virupax.sadashivpetimath@stericsson.com>"); |
477 | MODULE_DESCRIPTION("AB8500 RTC Driver"); | 365 | MODULE_DESCRIPTION("AB8500 RTC Driver"); |
478 | MODULE_LICENSE("GPL v2"); | 366 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index b6469e2cae8..e39b77a4609 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c | |||
@@ -27,23 +27,16 @@ | |||
27 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
28 | #include <linux/ioctl.h> | 28 | #include <linux/ioctl.h> |
29 | #include <linux/completion.h> | 29 | #include <linux/completion.h> |
30 | #include <linux/io.h> | ||
31 | 30 | ||
32 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
33 | 32 | ||
34 | #include "rtc-at91rm9200.h" | 33 | #include <mach/at91_rtc.h> |
35 | 34 | ||
36 | #define at91_rtc_read(field) \ | ||
37 | __raw_readl(at91_rtc_regs + field) | ||
38 | #define at91_rtc_write(field, val) \ | ||
39 | __raw_writel((val), at91_rtc_regs + field) | ||
40 | 35 | ||
41 | #define AT91_RTC_EPOCH 1900UL /* just like arch/arm/common/rtctime.c */ | 36 | #define AT91_RTC_EPOCH 1900UL /* just like arch/arm/common/rtctime.c */ |
42 | 37 | ||
43 | static DECLARE_COMPLETION(at91_rtc_updated); | 38 | static DECLARE_COMPLETION(at91_rtc_updated); |
44 | static unsigned int at91_alarm_year = AT91_RTC_EPOCH; | 39 | static unsigned int at91_alarm_year = AT91_RTC_EPOCH; |
45 | static void __iomem *at91_rtc_regs; | ||
46 | static int irq; | ||
47 | 40 | ||
48 | /* | 41 | /* |
49 | * Decode time/date into rtc_time structure | 42 | * Decode time/date into rtc_time structure |
@@ -55,10 +48,10 @@ static void at91_rtc_decodetime(unsigned int timereg, unsigned int calreg, | |||
55 | 48 | ||
56 | /* must read twice in case it changes */ | 49 | /* must read twice in case it changes */ |
57 | do { | 50 | do { |
58 | time = at91_rtc_read(timereg); | 51 | time = at91_sys_read(timereg); |
59 | date = at91_rtc_read(calreg); | 52 | date = at91_sys_read(calreg); |
60 | } while ((time != at91_rtc_read(timereg)) || | 53 | } while ((time != at91_sys_read(timereg)) || |
61 | (date != at91_rtc_read(calreg))); | 54 | (date != at91_sys_read(calreg))); |
62 | 55 | ||
63 | tm->tm_sec = bcd2bin((time & AT91_RTC_SEC) >> 0); | 56 | tm->tm_sec = bcd2bin((time & AT91_RTC_SEC) >> 0); |
64 | tm->tm_min = bcd2bin((time & AT91_RTC_MIN) >> 8); | 57 | tm->tm_min = bcd2bin((time & AT91_RTC_MIN) >> 8); |
@@ -105,19 +98,19 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) | |||
105 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 98 | tm->tm_hour, tm->tm_min, tm->tm_sec); |
106 | 99 | ||
107 | /* Stop Time/Calendar from counting */ | 100 | /* Stop Time/Calendar from counting */ |
108 | cr = at91_rtc_read(AT91_RTC_CR); | 101 | cr = at91_sys_read(AT91_RTC_CR); |
109 | at91_rtc_write(AT91_RTC_CR, cr | AT91_RTC_UPDCAL | AT91_RTC_UPDTIM); | 102 | at91_sys_write(AT91_RTC_CR, cr | AT91_RTC_UPDCAL | AT91_RTC_UPDTIM); |
110 | 103 | ||
111 | at91_rtc_write(AT91_RTC_IER, AT91_RTC_ACKUPD); | 104 | at91_sys_write(AT91_RTC_IER, AT91_RTC_ACKUPD); |
112 | wait_for_completion(&at91_rtc_updated); /* wait for ACKUPD interrupt */ | 105 | wait_for_completion(&at91_rtc_updated); /* wait for ACKUPD interrupt */ |
113 | at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD); | 106 | at91_sys_write(AT91_RTC_IDR, AT91_RTC_ACKUPD); |
114 | 107 | ||
115 | at91_rtc_write(AT91_RTC_TIMR, | 108 | at91_sys_write(AT91_RTC_TIMR, |
116 | bin2bcd(tm->tm_sec) << 0 | 109 | bin2bcd(tm->tm_sec) << 0 |
117 | | bin2bcd(tm->tm_min) << 8 | 110 | | bin2bcd(tm->tm_min) << 8 |
118 | | bin2bcd(tm->tm_hour) << 16); | 111 | | bin2bcd(tm->tm_hour) << 16); |
119 | 112 | ||
120 | at91_rtc_write(AT91_RTC_CALR, | 113 | at91_sys_write(AT91_RTC_CALR, |
121 | bin2bcd((tm->tm_year + 1900) / 100) /* century */ | 114 | bin2bcd((tm->tm_year + 1900) / 100) /* century */ |
122 | | bin2bcd(tm->tm_year % 100) << 8 /* year */ | 115 | | bin2bcd(tm->tm_year % 100) << 8 /* year */ |
123 | | bin2bcd(tm->tm_mon + 1) << 16 /* tm_mon starts at zero */ | 116 | | bin2bcd(tm->tm_mon + 1) << 16 /* tm_mon starts at zero */ |
@@ -125,8 +118,8 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) | |||
125 | | bin2bcd(tm->tm_mday) << 24); | 118 | | bin2bcd(tm->tm_mday) << 24); |
126 | 119 | ||
127 | /* Restart Time/Calendar */ | 120 | /* Restart Time/Calendar */ |
128 | cr = at91_rtc_read(AT91_RTC_CR); | 121 | cr = at91_sys_read(AT91_RTC_CR); |
129 | at91_rtc_write(AT91_RTC_CR, cr & ~(AT91_RTC_UPDCAL | AT91_RTC_UPDTIM)); | 122 | at91_sys_write(AT91_RTC_CR, cr & ~(AT91_RTC_UPDCAL | AT91_RTC_UPDTIM)); |
130 | 123 | ||
131 | return 0; | 124 | return 0; |
132 | } | 125 | } |
@@ -142,7 +135,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
142 | tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); | 135 | tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); |
143 | tm->tm_year = at91_alarm_year - 1900; | 136 | tm->tm_year = at91_alarm_year - 1900; |
144 | 137 | ||
145 | alrm->enabled = (at91_rtc_read(AT91_RTC_IMR) & AT91_RTC_ALARM) | 138 | alrm->enabled = (at91_sys_read(AT91_RTC_IMR) & AT91_RTC_ALARM) |
146 | ? 1 : 0; | 139 | ? 1 : 0; |
147 | 140 | ||
148 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, | 141 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, |
@@ -167,20 +160,20 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
167 | tm.tm_min = alrm->time.tm_min; | 160 | tm.tm_min = alrm->time.tm_min; |
168 | tm.tm_sec = alrm->time.tm_sec; | 161 | tm.tm_sec = alrm->time.tm_sec; |
169 | 162 | ||
170 | at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ALARM); | 163 | at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM); |
171 | at91_rtc_write(AT91_RTC_TIMALR, | 164 | at91_sys_write(AT91_RTC_TIMALR, |
172 | bin2bcd(tm.tm_sec) << 0 | 165 | bin2bcd(tm.tm_sec) << 0 |
173 | | bin2bcd(tm.tm_min) << 8 | 166 | | bin2bcd(tm.tm_min) << 8 |
174 | | bin2bcd(tm.tm_hour) << 16 | 167 | | bin2bcd(tm.tm_hour) << 16 |
175 | | AT91_RTC_HOUREN | AT91_RTC_MINEN | AT91_RTC_SECEN); | 168 | | AT91_RTC_HOUREN | AT91_RTC_MINEN | AT91_RTC_SECEN); |
176 | at91_rtc_write(AT91_RTC_CALALR, | 169 | at91_sys_write(AT91_RTC_CALALR, |
177 | bin2bcd(tm.tm_mon + 1) << 16 /* tm_mon starts at zero */ | 170 | bin2bcd(tm.tm_mon + 1) << 16 /* tm_mon starts at zero */ |
178 | | bin2bcd(tm.tm_mday) << 24 | 171 | | bin2bcd(tm.tm_mday) << 24 |
179 | | AT91_RTC_DATEEN | AT91_RTC_MTHEN); | 172 | | AT91_RTC_DATEEN | AT91_RTC_MTHEN); |
180 | 173 | ||
181 | if (alrm->enabled) { | 174 | if (alrm->enabled) { |
182 | at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM); | 175 | at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM); |
183 | at91_rtc_write(AT91_RTC_IER, AT91_RTC_ALARM); | 176 | at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); |
184 | } | 177 | } |
185 | 178 | ||
186 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, | 179 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, |
@@ -195,10 +188,10 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | |||
195 | pr_debug("%s(): cmd=%08x\n", __func__, enabled); | 188 | pr_debug("%s(): cmd=%08x\n", __func__, enabled); |
196 | 189 | ||
197 | if (enabled) { | 190 | if (enabled) { |
198 | at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM); | 191 | at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM); |
199 | at91_rtc_write(AT91_RTC_IER, AT91_RTC_ALARM); | 192 | at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); |
200 | } else | 193 | } else |
201 | at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ALARM); | 194 | at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM); |
202 | 195 | ||
203 | return 0; | 196 | return 0; |
204 | } | 197 | } |
@@ -207,7 +200,7 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | |||
207 | */ | 200 | */ |
208 | static int at91_rtc_proc(struct device *dev, struct seq_file *seq) | 201 | static int at91_rtc_proc(struct device *dev, struct seq_file *seq) |
209 | { | 202 | { |
210 | unsigned long imr = at91_rtc_read(AT91_RTC_IMR); | 203 | unsigned long imr = at91_sys_read(AT91_RTC_IMR); |
211 | 204 | ||
212 | seq_printf(seq, "update_IRQ\t: %s\n", | 205 | seq_printf(seq, "update_IRQ\t: %s\n", |
213 | (imr & AT91_RTC_ACKUPD) ? "yes" : "no"); | 206 | (imr & AT91_RTC_ACKUPD) ? "yes" : "no"); |
@@ -227,7 +220,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) | |||
227 | unsigned int rtsr; | 220 | unsigned int rtsr; |
228 | unsigned long events = 0; | 221 | unsigned long events = 0; |
229 | 222 | ||
230 | rtsr = at91_rtc_read(AT91_RTC_SR) & at91_rtc_read(AT91_RTC_IMR); | 223 | rtsr = at91_sys_read(AT91_RTC_SR) & at91_sys_read(AT91_RTC_IMR); |
231 | if (rtsr) { /* this interrupt is shared! Is it ours? */ | 224 | if (rtsr) { /* this interrupt is shared! Is it ours? */ |
232 | if (rtsr & AT91_RTC_ALARM) | 225 | if (rtsr & AT91_RTC_ALARM) |
233 | events |= (RTC_AF | RTC_IRQF); | 226 | events |= (RTC_AF | RTC_IRQF); |
@@ -236,7 +229,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) | |||
236 | if (rtsr & AT91_RTC_ACKUPD) | 229 | if (rtsr & AT91_RTC_ACKUPD) |
237 | complete(&at91_rtc_updated); | 230 | complete(&at91_rtc_updated); |
238 | 231 | ||
239 | at91_rtc_write(AT91_RTC_SCCR, rtsr); /* clear status reg */ | 232 | at91_sys_write(AT91_RTC_SCCR, rtsr); /* clear status reg */ |
240 | 233 | ||
241 | rtc_update_irq(rtc, 1, events); | 234 | rtc_update_irq(rtc, 1, events); |
242 | 235 | ||
@@ -263,41 +256,22 @@ static const struct rtc_class_ops at91_rtc_ops = { | |||
263 | static int __init at91_rtc_probe(struct platform_device *pdev) | 256 | static int __init at91_rtc_probe(struct platform_device *pdev) |
264 | { | 257 | { |
265 | struct rtc_device *rtc; | 258 | struct rtc_device *rtc; |
266 | struct resource *regs; | 259 | int ret; |
267 | int ret = 0; | ||
268 | 260 | ||
269 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 261 | at91_sys_write(AT91_RTC_CR, 0); |
270 | if (!regs) { | 262 | at91_sys_write(AT91_RTC_MR, 0); /* 24 hour mode */ |
271 | dev_err(&pdev->dev, "no mmio resource defined\n"); | ||
272 | return -ENXIO; | ||
273 | } | ||
274 | |||
275 | irq = platform_get_irq(pdev, 0); | ||
276 | if (irq < 0) { | ||
277 | dev_err(&pdev->dev, "no irq resource defined\n"); | ||
278 | return -ENXIO; | ||
279 | } | ||
280 | |||
281 | at91_rtc_regs = ioremap(regs->start, resource_size(regs)); | ||
282 | if (!at91_rtc_regs) { | ||
283 | dev_err(&pdev->dev, "failed to map registers, aborting.\n"); | ||
284 | return -ENOMEM; | ||
285 | } | ||
286 | |||
287 | at91_rtc_write(AT91_RTC_CR, 0); | ||
288 | at91_rtc_write(AT91_RTC_MR, 0); /* 24 hour mode */ | ||
289 | 263 | ||
290 | /* Disable all interrupts */ | 264 | /* Disable all interrupts */ |
291 | at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM | | 265 | at91_sys_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM | |
292 | AT91_RTC_SECEV | AT91_RTC_TIMEV | | 266 | AT91_RTC_SECEV | AT91_RTC_TIMEV | |
293 | AT91_RTC_CALEV); | 267 | AT91_RTC_CALEV); |
294 | 268 | ||
295 | ret = request_irq(irq, at91_rtc_interrupt, | 269 | ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt, |
296 | IRQF_SHARED, | 270 | IRQF_SHARED, |
297 | "at91_rtc", pdev); | 271 | "at91_rtc", pdev); |
298 | if (ret) { | 272 | if (ret) { |
299 | printk(KERN_ERR "at91_rtc: IRQ %d already in use.\n", | 273 | printk(KERN_ERR "at91_rtc: IRQ %d already in use.\n", |
300 | irq); | 274 | AT91_ID_SYS); |
301 | return ret; | 275 | return ret; |
302 | } | 276 | } |
303 | 277 | ||
@@ -310,7 +284,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev) | |||
310 | rtc = rtc_device_register(pdev->name, &pdev->dev, | 284 | rtc = rtc_device_register(pdev->name, &pdev->dev, |
311 | &at91_rtc_ops, THIS_MODULE); | 285 | &at91_rtc_ops, THIS_MODULE); |
312 | if (IS_ERR(rtc)) { | 286 | if (IS_ERR(rtc)) { |
313 | free_irq(irq, pdev); | 287 | free_irq(AT91_ID_SYS, pdev); |
314 | return PTR_ERR(rtc); | 288 | return PTR_ERR(rtc); |
315 | } | 289 | } |
316 | platform_set_drvdata(pdev, rtc); | 290 | platform_set_drvdata(pdev, rtc); |
@@ -327,10 +301,10 @@ static int __exit at91_rtc_remove(struct platform_device *pdev) | |||
327 | struct rtc_device *rtc = platform_get_drvdata(pdev); | 301 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
328 | 302 | ||
329 | /* Disable all interrupts */ | 303 | /* Disable all interrupts */ |
330 | at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM | | 304 | at91_sys_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM | |
331 | AT91_RTC_SECEV | AT91_RTC_TIMEV | | 305 | AT91_RTC_SECEV | AT91_RTC_TIMEV | |
332 | AT91_RTC_CALEV); | 306 | AT91_RTC_CALEV); |
333 | free_irq(irq, pdev); | 307 | free_irq(AT91_ID_SYS, pdev); |
334 | 308 | ||
335 | rtc_device_unregister(rtc); | 309 | rtc_device_unregister(rtc); |
336 | platform_set_drvdata(pdev, NULL); | 310 | platform_set_drvdata(pdev, NULL); |
@@ -349,13 +323,13 @@ static int at91_rtc_suspend(struct device *dev) | |||
349 | /* this IRQ is shared with DBGU and other hardware which isn't | 323 | /* this IRQ is shared with DBGU and other hardware which isn't |
350 | * necessarily doing PM like we are... | 324 | * necessarily doing PM like we are... |
351 | */ | 325 | */ |
352 | at91_rtc_imr = at91_rtc_read(AT91_RTC_IMR) | 326 | at91_rtc_imr = at91_sys_read(AT91_RTC_IMR) |
353 | & (AT91_RTC_ALARM|AT91_RTC_SECEV); | 327 | & (AT91_RTC_ALARM|AT91_RTC_SECEV); |
354 | if (at91_rtc_imr) { | 328 | if (at91_rtc_imr) { |
355 | if (device_may_wakeup(dev)) | 329 | if (device_may_wakeup(dev)) |
356 | enable_irq_wake(irq); | 330 | enable_irq_wake(AT91_ID_SYS); |
357 | else | 331 | else |
358 | at91_rtc_write(AT91_RTC_IDR, at91_rtc_imr); | 332 | at91_sys_write(AT91_RTC_IDR, at91_rtc_imr); |
359 | } | 333 | } |
360 | return 0; | 334 | return 0; |
361 | } | 335 | } |
@@ -364,9 +338,9 @@ static int at91_rtc_resume(struct device *dev) | |||
364 | { | 338 | { |
365 | if (at91_rtc_imr) { | 339 | if (at91_rtc_imr) { |
366 | if (device_may_wakeup(dev)) | 340 | if (device_may_wakeup(dev)) |
367 | disable_irq_wake(irq); | 341 | disable_irq_wake(AT91_ID_SYS); |
368 | else | 342 | else |
369 | at91_rtc_write(AT91_RTC_IER, at91_rtc_imr); | 343 | at91_sys_write(AT91_RTC_IER, at91_rtc_imr); |
370 | } | 344 | } |
371 | return 0; | 345 | return 0; |
372 | } | 346 | } |
diff --git a/drivers/rtc/rtc-at91rm9200.h b/drivers/rtc/rtc-at91rm9200.h deleted file mode 100644 index da1945e5f71..00000000000 --- a/drivers/rtc/rtc-at91rm9200.h +++ /dev/null | |||
@@ -1,75 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-at91/include/mach/at91_rtc.h | ||
3 | * | ||
4 | * Copyright (C) 2005 Ivan Kokshaysky | ||
5 | * Copyright (C) SAN People | ||
6 | * | ||
7 | * Real Time Clock (RTC) - System peripheral registers. | ||
8 | * Based on AT91RM9200 datasheet revision E. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | */ | ||
15 | |||
16 | #ifndef AT91_RTC_H | ||
17 | #define AT91_RTC_H | ||
18 | |||
19 | #define AT91_RTC_CR 0x00 /* Control Register */ | ||
20 | #define AT91_RTC_UPDTIM (1 << 0) /* Update Request Time Register */ | ||
21 | #define AT91_RTC_UPDCAL (1 << 1) /* Update Request Calendar Register */ | ||
22 | #define AT91_RTC_TIMEVSEL (3 << 8) /* Time Event Selection */ | ||
23 | #define AT91_RTC_TIMEVSEL_MINUTE (0 << 8) | ||
24 | #define AT91_RTC_TIMEVSEL_HOUR (1 << 8) | ||
25 | #define AT91_RTC_TIMEVSEL_DAY24 (2 << 8) | ||
26 | #define AT91_RTC_TIMEVSEL_DAY12 (3 << 8) | ||
27 | #define AT91_RTC_CALEVSEL (3 << 16) /* Calendar Event Selection */ | ||
28 | #define AT91_RTC_CALEVSEL_WEEK (0 << 16) | ||
29 | #define AT91_RTC_CALEVSEL_MONTH (1 << 16) | ||
30 | #define AT91_RTC_CALEVSEL_YEAR (2 << 16) | ||
31 | |||
32 | #define AT91_RTC_MR 0x04 /* Mode Register */ | ||
33 | #define AT91_RTC_HRMOD (1 << 0) /* 12/24 Hour Mode */ | ||
34 | |||
35 | #define AT91_RTC_TIMR 0x08 /* Time Register */ | ||
36 | #define AT91_RTC_SEC (0x7f << 0) /* Current Second */ | ||
37 | #define AT91_RTC_MIN (0x7f << 8) /* Current Minute */ | ||
38 | #define AT91_RTC_HOUR (0x3f << 16) /* Current Hour */ | ||
39 | #define AT91_RTC_AMPM (1 << 22) /* Ante Meridiem Post Meridiem Indicator */ | ||
40 | |||
41 | #define AT91_RTC_CALR 0x0c /* Calendar Register */ | ||
42 | #define AT91_RTC_CENT (0x7f << 0) /* Current Century */ | ||
43 | #define AT91_RTC_YEAR (0xff << 8) /* Current Year */ | ||
44 | #define AT91_RTC_MONTH (0x1f << 16) /* Current Month */ | ||
45 | #define AT91_RTC_DAY (7 << 21) /* Current Day */ | ||
46 | #define AT91_RTC_DATE (0x3f << 24) /* Current Date */ | ||
47 | |||
48 | #define AT91_RTC_TIMALR 0x10 /* Time Alarm Register */ | ||
49 | #define AT91_RTC_SECEN (1 << 7) /* Second Alarm Enable */ | ||
50 | #define AT91_RTC_MINEN (1 << 15) /* Minute Alarm Enable */ | ||
51 | #define AT91_RTC_HOUREN (1 << 23) /* Hour Alarm Enable */ | ||
52 | |||
53 | #define AT91_RTC_CALALR 0x14 /* Calendar Alarm Register */ | ||
54 | #define AT91_RTC_MTHEN (1 << 23) /* Month Alarm Enable */ | ||
55 | #define AT91_RTC_DATEEN (1 << 31) /* Date Alarm Enable */ | ||
56 | |||
57 | #define AT91_RTC_SR 0x18 /* Status Register */ | ||
58 | #define AT91_RTC_ACKUPD (1 << 0) /* Acknowledge for Update */ | ||
59 | #define AT91_RTC_ALARM (1 << 1) /* Alarm Flag */ | ||
60 | #define AT91_RTC_SECEV (1 << 2) /* Second Event */ | ||
61 | #define AT91_RTC_TIMEV (1 << 3) /* Time Event */ | ||
62 | #define AT91_RTC_CALEV (1 << 4) /* Calendar Event */ | ||
63 | |||
64 | #define AT91_RTC_SCCR 0x1c /* Status Clear Command Register */ | ||
65 | #define AT91_RTC_IER 0x20 /* Interrupt Enable Register */ | ||
66 | #define AT91_RTC_IDR 0x24 /* Interrupt Disable Register */ | ||
67 | #define AT91_RTC_IMR 0x28 /* Interrupt Mask Register */ | ||
68 | |||
69 | #define AT91_RTC_VER 0x2c /* Valid Entry Register */ | ||
70 | #define AT91_RTC_NVTIM (1 << 0) /* Non valid Time */ | ||
71 | #define AT91_RTC_NVCAL (1 << 1) /* Non valid Calendar */ | ||
72 | #define AT91_RTC_NVTIMALR (1 << 2) /* Non valid Time Alarm */ | ||
73 | #define AT91_RTC_NVCALALR (1 << 3) /* Non valid Calendar Alarm */ | ||
74 | |||
75 | #endif | ||
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 39cfd2ee004..a3ad957507d 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c | |||
@@ -19,8 +19,8 @@ | |||
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/ioctl.h> | 20 | #include <linux/ioctl.h> |
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/platform_data/atmel.h> | ||
23 | 22 | ||
23 | #include <mach/board.h> | ||
24 | #include <mach/at91_rtt.h> | 24 | #include <mach/at91_rtt.h> |
25 | #include <mach/cpu.h> | 25 | #include <mach/cpu.h> |
26 | 26 | ||
@@ -57,8 +57,6 @@ struct sam9_rtc { | |||
57 | void __iomem *rtt; | 57 | void __iomem *rtt; |
58 | struct rtc_device *rtcdev; | 58 | struct rtc_device *rtcdev; |
59 | u32 imr; | 59 | u32 imr; |
60 | void __iomem *gpbr; | ||
61 | int irq; | ||
62 | }; | 60 | }; |
63 | 61 | ||
64 | #define rtt_readl(rtc, field) \ | 62 | #define rtt_readl(rtc, field) \ |
@@ -67,9 +65,9 @@ struct sam9_rtc { | |||
67 | __raw_writel((val), (rtc)->rtt + AT91_RTT_ ## field) | 65 | __raw_writel((val), (rtc)->rtt + AT91_RTT_ ## field) |
68 | 66 | ||
69 | #define gpbr_readl(rtc) \ | 67 | #define gpbr_readl(rtc) \ |
70 | __raw_readl((rtc)->gpbr) | 68 | at91_sys_read(AT91_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR) |
71 | #define gpbr_writel(rtc, val) \ | 69 | #define gpbr_writel(rtc, val) \ |
72 | __raw_writel((val), (rtc)->gpbr) | 70 | at91_sys_write(AT91_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR, (val)) |
73 | 71 | ||
74 | /* | 72 | /* |
75 | * Read current time and date in RTC | 73 | * Read current time and date in RTC |
@@ -289,50 +287,28 @@ static const struct rtc_class_ops at91_rtc_ops = { | |||
289 | /* | 287 | /* |
290 | * Initialize and install RTC driver | 288 | * Initialize and install RTC driver |
291 | */ | 289 | */ |
292 | static int at91_rtc_probe(struct platform_device *pdev) | 290 | static int __init at91_rtc_probe(struct platform_device *pdev) |
293 | { | 291 | { |
294 | struct resource *r, *r_gpbr; | 292 | struct resource *r; |
295 | struct sam9_rtc *rtc; | 293 | struct sam9_rtc *rtc; |
296 | int ret, irq; | 294 | int ret; |
297 | u32 mr; | 295 | u32 mr; |
298 | 296 | ||
299 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 297 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
300 | r_gpbr = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 298 | if (!r) |
301 | if (!r || !r_gpbr) { | ||
302 | dev_err(&pdev->dev, "need 2 ressources\n"); | ||
303 | return -ENODEV; | 299 | return -ENODEV; |
304 | } | ||
305 | |||
306 | irq = platform_get_irq(pdev, 0); | ||
307 | if (irq < 0) { | ||
308 | dev_err(&pdev->dev, "failed to get interrupt resource\n"); | ||
309 | return irq; | ||
310 | } | ||
311 | 300 | ||
312 | rtc = kzalloc(sizeof *rtc, GFP_KERNEL); | 301 | rtc = kzalloc(sizeof *rtc, GFP_KERNEL); |
313 | if (!rtc) | 302 | if (!rtc) |
314 | return -ENOMEM; | 303 | return -ENOMEM; |
315 | 304 | ||
316 | rtc->irq = irq; | ||
317 | |||
318 | /* platform setup code should have handled this; sigh */ | 305 | /* platform setup code should have handled this; sigh */ |
319 | if (!device_can_wakeup(&pdev->dev)) | 306 | if (!device_can_wakeup(&pdev->dev)) |
320 | device_init_wakeup(&pdev->dev, 1); | 307 | device_init_wakeup(&pdev->dev, 1); |
321 | 308 | ||
322 | platform_set_drvdata(pdev, rtc); | 309 | platform_set_drvdata(pdev, rtc); |
323 | rtc->rtt = ioremap(r->start, resource_size(r)); | 310 | rtc->rtt = (void __force __iomem *) (AT91_VA_BASE_SYS - AT91_BASE_SYS); |
324 | if (!rtc->rtt) { | 311 | rtc->rtt += r->start; |
325 | dev_err(&pdev->dev, "failed to map registers, aborting.\n"); | ||
326 | ret = -ENOMEM; | ||
327 | goto fail; | ||
328 | } | ||
329 | |||
330 | rtc->gpbr = ioremap(r_gpbr->start, resource_size(r_gpbr)); | ||
331 | if (!rtc->gpbr) { | ||
332 | dev_err(&pdev->dev, "failed to map gpbr registers, aborting.\n"); | ||
333 | ret = -ENOMEM; | ||
334 | goto fail_gpbr; | ||
335 | } | ||
336 | 312 | ||
337 | mr = rtt_readl(rtc, MR); | 313 | mr = rtt_readl(rtc, MR); |
338 | 314 | ||
@@ -350,16 +326,17 @@ static int at91_rtc_probe(struct platform_device *pdev) | |||
350 | &at91_rtc_ops, THIS_MODULE); | 326 | &at91_rtc_ops, THIS_MODULE); |
351 | if (IS_ERR(rtc->rtcdev)) { | 327 | if (IS_ERR(rtc->rtcdev)) { |
352 | ret = PTR_ERR(rtc->rtcdev); | 328 | ret = PTR_ERR(rtc->rtcdev); |
353 | goto fail_register; | 329 | goto fail; |
354 | } | 330 | } |
355 | 331 | ||
356 | /* register irq handler after we know what name we'll use */ | 332 | /* register irq handler after we know what name we'll use */ |
357 | ret = request_irq(rtc->irq, at91_rtc_interrupt, IRQF_SHARED, | 333 | ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt, |
334 | IRQF_DISABLED | IRQF_SHARED, | ||
358 | dev_name(&rtc->rtcdev->dev), rtc); | 335 | dev_name(&rtc->rtcdev->dev), rtc); |
359 | if (ret) { | 336 | if (ret) { |
360 | dev_dbg(&pdev->dev, "can't share IRQ %d?\n", rtc->irq); | 337 | dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS); |
361 | rtc_device_unregister(rtc->rtcdev); | 338 | rtc_device_unregister(rtc->rtcdev); |
362 | goto fail_register; | 339 | goto fail; |
363 | } | 340 | } |
364 | 341 | ||
365 | /* NOTE: sam9260 rev A silicon has a ROM bug which resets the | 342 | /* NOTE: sam9260 rev A silicon has a ROM bug which resets the |
@@ -374,10 +351,6 @@ static int at91_rtc_probe(struct platform_device *pdev) | |||
374 | 351 | ||
375 | return 0; | 352 | return 0; |
376 | 353 | ||
377 | fail_register: | ||
378 | iounmap(rtc->gpbr); | ||
379 | fail_gpbr: | ||
380 | iounmap(rtc->rtt); | ||
381 | fail: | 354 | fail: |
382 | platform_set_drvdata(pdev, NULL); | 355 | platform_set_drvdata(pdev, NULL); |
383 | kfree(rtc); | 356 | kfree(rtc); |
@@ -387,19 +360,17 @@ fail: | |||
387 | /* | 360 | /* |
388 | * Disable and remove the RTC driver | 361 | * Disable and remove the RTC driver |
389 | */ | 362 | */ |
390 | static int at91_rtc_remove(struct platform_device *pdev) | 363 | static int __exit at91_rtc_remove(struct platform_device *pdev) |
391 | { | 364 | { |
392 | struct sam9_rtc *rtc = platform_get_drvdata(pdev); | 365 | struct sam9_rtc *rtc = platform_get_drvdata(pdev); |
393 | u32 mr = rtt_readl(rtc, MR); | 366 | u32 mr = rtt_readl(rtc, MR); |
394 | 367 | ||
395 | /* disable all interrupts */ | 368 | /* disable all interrupts */ |
396 | rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)); | 369 | rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)); |
397 | free_irq(rtc->irq, rtc); | 370 | free_irq(AT91_ID_SYS, rtc); |
398 | 371 | ||
399 | rtc_device_unregister(rtc->rtcdev); | 372 | rtc_device_unregister(rtc->rtcdev); |
400 | 373 | ||
401 | iounmap(rtc->gpbr); | ||
402 | iounmap(rtc->rtt); | ||
403 | platform_set_drvdata(pdev, NULL); | 374 | platform_set_drvdata(pdev, NULL); |
404 | kfree(rtc); | 375 | kfree(rtc); |
405 | return 0; | 376 | return 0; |
@@ -431,7 +402,7 @@ static int at91_rtc_suspend(struct platform_device *pdev, | |||
431 | rtc->imr = mr & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); | 402 | rtc->imr = mr & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); |
432 | if (rtc->imr) { | 403 | if (rtc->imr) { |
433 | if (device_may_wakeup(&pdev->dev) && (mr & AT91_RTT_ALMIEN)) { | 404 | if (device_may_wakeup(&pdev->dev) && (mr & AT91_RTT_ALMIEN)) { |
434 | enable_irq_wake(rtc->irq); | 405 | enable_irq_wake(AT91_ID_SYS); |
435 | /* don't let RTTINC cause wakeups */ | 406 | /* don't let RTTINC cause wakeups */ |
436 | if (mr & AT91_RTT_RTTINCIEN) | 407 | if (mr & AT91_RTT_RTTINCIEN) |
437 | rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN); | 408 | rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN); |
@@ -449,7 +420,7 @@ static int at91_rtc_resume(struct platform_device *pdev) | |||
449 | 420 | ||
450 | if (rtc->imr) { | 421 | if (rtc->imr) { |
451 | if (device_may_wakeup(&pdev->dev)) | 422 | if (device_may_wakeup(&pdev->dev)) |
452 | disable_irq_wake(rtc->irq); | 423 | disable_irq_wake(AT91_ID_SYS); |
453 | mr = rtt_readl(rtc, MR); | 424 | mr = rtt_readl(rtc, MR); |
454 | rtt_writel(rtc, MR, mr | rtc->imr); | 425 | rtt_writel(rtc, MR, mr | rtc->imr); |
455 | } | 426 | } |
@@ -462,18 +433,72 @@ static int at91_rtc_resume(struct platform_device *pdev) | |||
462 | #endif | 433 | #endif |
463 | 434 | ||
464 | static struct platform_driver at91_rtc_driver = { | 435 | static struct platform_driver at91_rtc_driver = { |
465 | .probe = at91_rtc_probe, | 436 | .driver.name = "rtc-at91sam9", |
466 | .remove = at91_rtc_remove, | 437 | .driver.owner = THIS_MODULE, |
438 | .remove = __exit_p(at91_rtc_remove), | ||
467 | .shutdown = at91_rtc_shutdown, | 439 | .shutdown = at91_rtc_shutdown, |
468 | .suspend = at91_rtc_suspend, | 440 | .suspend = at91_rtc_suspend, |
469 | .resume = at91_rtc_resume, | 441 | .resume = at91_rtc_resume, |
470 | .driver = { | ||
471 | .name = "rtc-at91sam9", | ||
472 | .owner = THIS_MODULE, | ||
473 | }, | ||
474 | }; | 442 | }; |
475 | 443 | ||
476 | module_platform_driver(at91_rtc_driver); | 444 | /* Chips can have more than one RTT module, and they can be used for more |
445 | * than just RTCs. So we can't just register as "the" RTT driver. | ||
446 | * | ||
447 | * A normal approach in such cases is to create a library to allocate and | ||
448 | * free the modules. Here we just use bus_find_device() as like such a | ||
449 | * library, binding directly ... no runtime "library" footprint is needed. | ||
450 | */ | ||
451 | static int __init at91_rtc_match(struct device *dev, void *v) | ||
452 | { | ||
453 | struct platform_device *pdev = to_platform_device(dev); | ||
454 | int ret; | ||
455 | |||
456 | /* continue searching if this isn't the RTT we need */ | ||
457 | if (strcmp("at91_rtt", pdev->name) != 0 | ||
458 | || pdev->id != CONFIG_RTC_DRV_AT91SAM9_RTT) | ||
459 | goto fail; | ||
460 | |||
461 | /* else we found it ... but fail unless we can bind to the RTC driver */ | ||
462 | if (dev->driver) { | ||
463 | dev_dbg(dev, "busy, can't use as RTC!\n"); | ||
464 | goto fail; | ||
465 | } | ||
466 | dev->driver = &at91_rtc_driver.driver; | ||
467 | if (device_attach(dev) == 0) { | ||
468 | dev_dbg(dev, "can't attach RTC!\n"); | ||
469 | goto fail; | ||
470 | } | ||
471 | ret = at91_rtc_probe(pdev); | ||
472 | if (ret == 0) | ||
473 | return true; | ||
474 | |||
475 | dev_dbg(dev, "RTC probe err %d!\n", ret); | ||
476 | fail: | ||
477 | return false; | ||
478 | } | ||
479 | |||
480 | static int __init at91_rtc_init(void) | ||
481 | { | ||
482 | int status; | ||
483 | struct device *rtc; | ||
484 | |||
485 | status = platform_driver_register(&at91_rtc_driver); | ||
486 | if (status) | ||
487 | return status; | ||
488 | rtc = bus_find_device(&platform_bus_type, NULL, | ||
489 | NULL, at91_rtc_match); | ||
490 | if (!rtc) | ||
491 | platform_driver_unregister(&at91_rtc_driver); | ||
492 | return rtc ? 0 : -ENODEV; | ||
493 | } | ||
494 | module_init(at91_rtc_init); | ||
495 | |||
496 | static void __exit at91_rtc_exit(void) | ||
497 | { | ||
498 | platform_driver_unregister(&at91_rtc_driver); | ||
499 | } | ||
500 | module_exit(at91_rtc_exit); | ||
501 | |||
477 | 502 | ||
478 | MODULE_AUTHOR("Michel Benoit"); | 503 | MODULE_AUTHOR("Michel Benoit"); |
479 | MODULE_DESCRIPTION("RTC driver for Atmel AT91SAM9x"); | 504 | MODULE_DESCRIPTION("RTC driver for Atmel AT91SAM9x"); |
diff --git a/drivers/rtc/rtc-au1xxx.c b/drivers/rtc/rtc-au1xxx.c index b309da4ec74..979ed0406ce 100644 --- a/drivers/rtc/rtc-au1xxx.c +++ b/drivers/rtc/rtc-au1xxx.c | |||
@@ -62,7 +62,7 @@ static struct rtc_class_ops au1xtoy_rtc_ops = { | |||
62 | .set_time = au1xtoy_rtc_set_time, | 62 | .set_time = au1xtoy_rtc_set_time, |
63 | }; | 63 | }; |
64 | 64 | ||
65 | static int au1xtoy_rtc_probe(struct platform_device *pdev) | 65 | static int __devinit au1xtoy_rtc_probe(struct platform_device *pdev) |
66 | { | 66 | { |
67 | struct rtc_device *rtcdev; | 67 | struct rtc_device *rtcdev; |
68 | unsigned long t; | 68 | unsigned long t; |
@@ -116,7 +116,7 @@ out_err: | |||
116 | return ret; | 116 | return ret; |
117 | } | 117 | } |
118 | 118 | ||
119 | static int au1xtoy_rtc_remove(struct platform_device *pdev) | 119 | static int __devexit au1xtoy_rtc_remove(struct platform_device *pdev) |
120 | { | 120 | { |
121 | struct rtc_device *rtcdev = platform_get_drvdata(pdev); | 121 | struct rtc_device *rtcdev = platform_get_drvdata(pdev); |
122 | 122 | ||
@@ -131,7 +131,7 @@ static struct platform_driver au1xrtc_driver = { | |||
131 | .name = "rtc-au1xxx", | 131 | .name = "rtc-au1xxx", |
132 | .owner = THIS_MODULE, | 132 | .owner = THIS_MODULE, |
133 | }, | 133 | }, |
134 | .remove = au1xtoy_rtc_remove, | 134 | .remove = __devexit_p(au1xtoy_rtc_remove), |
135 | }; | 135 | }; |
136 | 136 | ||
137 | static int __init au1xtoy_rtc_init(void) | 137 | static int __init au1xtoy_rtc_init(void) |
diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index 4ec614b0954..90d866272c8 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c | |||
@@ -342,7 +342,7 @@ static struct rtc_class_ops bfin_rtc_ops = { | |||
342 | .alarm_irq_enable = bfin_rtc_alarm_irq_enable, | 342 | .alarm_irq_enable = bfin_rtc_alarm_irq_enable, |
343 | }; | 343 | }; |
344 | 344 | ||
345 | static int bfin_rtc_probe(struct platform_device *pdev) | 345 | static int __devinit bfin_rtc_probe(struct platform_device *pdev) |
346 | { | 346 | { |
347 | struct bfin_rtc *rtc; | 347 | struct bfin_rtc *rtc; |
348 | struct device *dev = &pdev->dev; | 348 | struct device *dev = &pdev->dev; |
@@ -388,7 +388,7 @@ err: | |||
388 | return ret; | 388 | return ret; |
389 | } | 389 | } |
390 | 390 | ||
391 | static int bfin_rtc_remove(struct platform_device *pdev) | 391 | static int __devexit bfin_rtc_remove(struct platform_device *pdev) |
392 | { | 392 | { |
393 | struct bfin_rtc *rtc = platform_get_drvdata(pdev); | 393 | struct bfin_rtc *rtc = platform_get_drvdata(pdev); |
394 | struct device *dev = &pdev->dev; | 394 | struct device *dev = &pdev->dev; |
@@ -451,12 +451,23 @@ static struct platform_driver bfin_rtc_driver = { | |||
451 | .owner = THIS_MODULE, | 451 | .owner = THIS_MODULE, |
452 | }, | 452 | }, |
453 | .probe = bfin_rtc_probe, | 453 | .probe = bfin_rtc_probe, |
454 | .remove = bfin_rtc_remove, | 454 | .remove = __devexit_p(bfin_rtc_remove), |
455 | .suspend = bfin_rtc_suspend, | 455 | .suspend = bfin_rtc_suspend, |
456 | .resume = bfin_rtc_resume, | 456 | .resume = bfin_rtc_resume, |
457 | }; | 457 | }; |
458 | 458 | ||
459 | module_platform_driver(bfin_rtc_driver); | 459 | static int __init bfin_rtc_init(void) |
460 | { | ||
461 | return platform_driver_register(&bfin_rtc_driver); | ||
462 | } | ||
463 | |||
464 | static void __exit bfin_rtc_exit(void) | ||
465 | { | ||
466 | platform_driver_unregister(&bfin_rtc_driver); | ||
467 | } | ||
468 | |||
469 | module_init(bfin_rtc_init); | ||
470 | module_exit(bfin_rtc_exit); | ||
460 | 471 | ||
461 | MODULE_DESCRIPTION("Blackfin On-Chip Real Time Clock Driver"); | 472 | MODULE_DESCRIPTION("Blackfin On-Chip Real Time Clock Driver"); |
462 | MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>"); | 473 | MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>"); |
diff --git a/drivers/rtc/rtc-bq32k.c b/drivers/rtc/rtc-bq32k.c index 036cb89f818..408cc8f735b 100644 --- a/drivers/rtc/rtc-bq32k.c +++ b/drivers/rtc/rtc-bq32k.c | |||
@@ -163,7 +163,7 @@ static int bq32k_probe(struct i2c_client *client, | |||
163 | return 0; | 163 | return 0; |
164 | } | 164 | } |
165 | 165 | ||
166 | static int bq32k_remove(struct i2c_client *client) | 166 | static int __devexit bq32k_remove(struct i2c_client *client) |
167 | { | 167 | { |
168 | struct rtc_device *rtc = i2c_get_clientdata(client); | 168 | struct rtc_device *rtc = i2c_get_clientdata(client); |
169 | 169 | ||
@@ -183,11 +183,21 @@ static struct i2c_driver bq32k_driver = { | |||
183 | .owner = THIS_MODULE, | 183 | .owner = THIS_MODULE, |
184 | }, | 184 | }, |
185 | .probe = bq32k_probe, | 185 | .probe = bq32k_probe, |
186 | .remove = bq32k_remove, | 186 | .remove = __devexit_p(bq32k_remove), |
187 | .id_table = bq32k_id, | 187 | .id_table = bq32k_id, |
188 | }; | 188 | }; |
189 | 189 | ||
190 | module_i2c_driver(bq32k_driver); | 190 | static __init int bq32k_init(void) |
191 | { | ||
192 | return i2c_add_driver(&bq32k_driver); | ||
193 | } | ||
194 | module_init(bq32k_init); | ||
195 | |||
196 | static __exit void bq32k_exit(void) | ||
197 | { | ||
198 | i2c_del_driver(&bq32k_driver); | ||
199 | } | ||
200 | module_exit(bq32k_exit); | ||
191 | 201 | ||
192 | MODULE_AUTHOR("Semihalf, Piotr Ziecik <kosmo@semihalf.com>"); | 202 | MODULE_AUTHOR("Semihalf, Piotr Ziecik <kosmo@semihalf.com>"); |
193 | MODULE_DESCRIPTION("TI BQ32000 I2C RTC driver"); | 203 | MODULE_DESCRIPTION("TI BQ32000 I2C RTC driver"); |
diff --git a/drivers/rtc/rtc-bq4802.c b/drivers/rtc/rtc-bq4802.c index 693be71b5b1..128270ce355 100644 --- a/drivers/rtc/rtc-bq4802.c +++ b/drivers/rtc/rtc-bq4802.c | |||
@@ -140,7 +140,7 @@ static const struct rtc_class_ops bq4802_ops = { | |||
140 | .set_time = bq4802_set_time, | 140 | .set_time = bq4802_set_time, |
141 | }; | 141 | }; |
142 | 142 | ||
143 | static int bq4802_probe(struct platform_device *pdev) | 143 | static int __devinit bq4802_probe(struct platform_device *pdev) |
144 | { | 144 | { |
145 | struct bq4802 *p = kzalloc(sizeof(*p), GFP_KERNEL); | 145 | struct bq4802 *p = kzalloc(sizeof(*p), GFP_KERNEL); |
146 | int err = -ENOMEM; | 146 | int err = -ENOMEM; |
@@ -191,7 +191,7 @@ out_free: | |||
191 | goto out; | 191 | goto out; |
192 | } | 192 | } |
193 | 193 | ||
194 | static int bq4802_remove(struct platform_device *pdev) | 194 | static int __devexit bq4802_remove(struct platform_device *pdev) |
195 | { | 195 | { |
196 | struct bq4802 *p = platform_get_drvdata(pdev); | 196 | struct bq4802 *p = platform_get_drvdata(pdev); |
197 | 197 | ||
@@ -215,7 +215,18 @@ static struct platform_driver bq4802_driver = { | |||
215 | .owner = THIS_MODULE, | 215 | .owner = THIS_MODULE, |
216 | }, | 216 | }, |
217 | .probe = bq4802_probe, | 217 | .probe = bq4802_probe, |
218 | .remove = bq4802_remove, | 218 | .remove = __devexit_p(bq4802_remove), |
219 | }; | 219 | }; |
220 | 220 | ||
221 | module_platform_driver(bq4802_driver); | 221 | static int __init bq4802_init(void) |
222 | { | ||
223 | return platform_driver_register(&bq4802_driver); | ||
224 | } | ||
225 | |||
226 | static void __exit bq4802_exit(void) | ||
227 | { | ||
228 | platform_driver_unregister(&bq4802_driver); | ||
229 | } | ||
230 | |||
231 | module_init(bq4802_init); | ||
232 | module_exit(bq4802_exit); | ||
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 16630aa87f4..05beb6c1ca7 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -164,7 +164,7 @@ static inline unsigned char cmos_read_bank2(unsigned char addr) | |||
164 | static inline void cmos_write_bank2(unsigned char val, unsigned char addr) | 164 | static inline void cmos_write_bank2(unsigned char val, unsigned char addr) |
165 | { | 165 | { |
166 | outb(addr, RTC_PORT(2)); | 166 | outb(addr, RTC_PORT(2)); |
167 | outb(val, RTC_PORT(3)); | 167 | outb(val, RTC_PORT(2)); |
168 | } | 168 | } |
169 | 169 | ||
170 | #else | 170 | #else |
@@ -714,7 +714,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
714 | rtc_cmos_int_handler = cmos_interrupt; | 714 | rtc_cmos_int_handler = cmos_interrupt; |
715 | 715 | ||
716 | retval = request_irq(rtc_irq, rtc_cmos_int_handler, | 716 | retval = request_irq(rtc_irq, rtc_cmos_int_handler, |
717 | 0, dev_name(&cmos_rtc.rtc->dev), | 717 | IRQF_DISABLED, dev_name(&cmos_rtc.rtc->dev), |
718 | cmos_rtc.rtc); | 718 | cmos_rtc.rtc); |
719 | if (retval < 0) { | 719 | if (retval < 0) { |
720 | dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq); | 720 | dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq); |
@@ -910,17 +910,14 @@ static inline int cmos_poweroff(struct device *dev) | |||
910 | 910 | ||
911 | static u32 rtc_handler(void *context) | 911 | static u32 rtc_handler(void *context) |
912 | { | 912 | { |
913 | struct device *dev = context; | ||
914 | |||
915 | pm_wakeup_event(dev, 0); | ||
916 | acpi_clear_event(ACPI_EVENT_RTC); | 913 | acpi_clear_event(ACPI_EVENT_RTC); |
917 | acpi_disable_event(ACPI_EVENT_RTC, 0); | 914 | acpi_disable_event(ACPI_EVENT_RTC, 0); |
918 | return ACPI_INTERRUPT_HANDLED; | 915 | return ACPI_INTERRUPT_HANDLED; |
919 | } | 916 | } |
920 | 917 | ||
921 | static inline void rtc_wake_setup(struct device *dev) | 918 | static inline void rtc_wake_setup(void) |
922 | { | 919 | { |
923 | acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, dev); | 920 | acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); |
924 | /* | 921 | /* |
925 | * After the RTC handler is installed, the Fixed_RTC event should | 922 | * After the RTC handler is installed, the Fixed_RTC event should |
926 | * be disabled. Only when the RTC alarm is set will it be enabled. | 923 | * be disabled. Only when the RTC alarm is set will it be enabled. |
@@ -947,12 +944,13 @@ static void rtc_wake_off(struct device *dev) | |||
947 | */ | 944 | */ |
948 | static struct cmos_rtc_board_info acpi_rtc_info; | 945 | static struct cmos_rtc_board_info acpi_rtc_info; |
949 | 946 | ||
950 | static void cmos_wake_setup(struct device *dev) | 947 | static void __devinit |
948 | cmos_wake_setup(struct device *dev) | ||
951 | { | 949 | { |
952 | if (acpi_disabled) | 950 | if (acpi_disabled) |
953 | return; | 951 | return; |
954 | 952 | ||
955 | rtc_wake_setup(dev); | 953 | rtc_wake_setup(); |
956 | acpi_rtc_info.wake_on = rtc_wake_on; | 954 | acpi_rtc_info.wake_on = rtc_wake_on; |
957 | acpi_rtc_info.wake_off = rtc_wake_off; | 955 | acpi_rtc_info.wake_off = rtc_wake_off; |
958 | 956 | ||
@@ -979,7 +977,8 @@ static void cmos_wake_setup(struct device *dev) | |||
979 | 977 | ||
980 | #else | 978 | #else |
981 | 979 | ||
982 | static void cmos_wake_setup(struct device *dev) | 980 | static void __devinit |
981 | cmos_wake_setup(struct device *dev) | ||
983 | { | 982 | { |
984 | } | 983 | } |
985 | 984 | ||
@@ -989,7 +988,8 @@ static void cmos_wake_setup(struct device *dev) | |||
989 | 988 | ||
990 | #include <linux/pnp.h> | 989 | #include <linux/pnp.h> |
991 | 990 | ||
992 | static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) | 991 | static int __devinit |
992 | cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) | ||
993 | { | 993 | { |
994 | cmos_wake_setup(&pnp->dev); | 994 | cmos_wake_setup(&pnp->dev); |
995 | 995 | ||
diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c index c8115b83e5a..80f9c88214c 100644 --- a/drivers/rtc/rtc-coh901331.c +++ b/drivers/rtc/rtc-coh901331.c | |||
@@ -155,10 +155,13 @@ static int __exit coh901331_remove(struct platform_device *pdev) | |||
155 | struct coh901331_port *rtap = dev_get_drvdata(&pdev->dev); | 155 | struct coh901331_port *rtap = dev_get_drvdata(&pdev->dev); |
156 | 156 | ||
157 | if (rtap) { | 157 | if (rtap) { |
158 | free_irq(rtap->irq, rtap); | ||
158 | rtc_device_unregister(rtap->rtc); | 159 | rtc_device_unregister(rtap->rtc); |
159 | clk_unprepare(rtap->clk); | ||
160 | clk_put(rtap->clk); | 160 | clk_put(rtap->clk); |
161 | iounmap(rtap->virtbase); | ||
162 | release_mem_region(rtap->phybase, rtap->physize); | ||
161 | platform_set_drvdata(pdev, NULL); | 163 | platform_set_drvdata(pdev, NULL); |
164 | kfree(rtap); | ||
162 | } | 165 | } |
163 | 166 | ||
164 | return 0; | 167 | return 0; |
@@ -171,43 +174,49 @@ static int __init coh901331_probe(struct platform_device *pdev) | |||
171 | struct coh901331_port *rtap; | 174 | struct coh901331_port *rtap; |
172 | struct resource *res; | 175 | struct resource *res; |
173 | 176 | ||
174 | rtap = devm_kzalloc(&pdev->dev, | 177 | rtap = kzalloc(sizeof(struct coh901331_port), GFP_KERNEL); |
175 | sizeof(struct coh901331_port), GFP_KERNEL); | ||
176 | if (!rtap) | 178 | if (!rtap) |
177 | return -ENOMEM; | 179 | return -ENOMEM; |
178 | 180 | ||
179 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 181 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
180 | if (!res) | 182 | if (!res) { |
181 | return -ENOENT; | 183 | ret = -ENOENT; |
182 | 184 | goto out_no_resource; | |
185 | } | ||
183 | rtap->phybase = res->start; | 186 | rtap->phybase = res->start; |
184 | rtap->physize = resource_size(res); | 187 | rtap->physize = resource_size(res); |
185 | 188 | ||
186 | if (devm_request_mem_region(&pdev->dev, rtap->phybase, rtap->physize, | 189 | if (request_mem_region(rtap->phybase, rtap->physize, |
187 | "rtc-coh901331") == NULL) | 190 | "rtc-coh901331") == NULL) { |
188 | return -EBUSY; | 191 | ret = -EBUSY; |
192 | goto out_no_memregion; | ||
193 | } | ||
189 | 194 | ||
190 | rtap->virtbase = devm_ioremap(&pdev->dev, rtap->phybase, rtap->physize); | 195 | rtap->virtbase = ioremap(rtap->phybase, rtap->physize); |
191 | if (!rtap->virtbase) | 196 | if (!rtap->virtbase) { |
192 | return -ENOMEM; | 197 | ret = -ENOMEM; |
198 | goto out_no_remap; | ||
199 | } | ||
193 | 200 | ||
194 | rtap->irq = platform_get_irq(pdev, 0); | 201 | rtap->irq = platform_get_irq(pdev, 0); |
195 | if (devm_request_irq(&pdev->dev, rtap->irq, coh901331_interrupt, 0, | 202 | if (request_irq(rtap->irq, coh901331_interrupt, IRQF_DISABLED, |
196 | "RTC COH 901 331 Alarm", rtap)) | 203 | "RTC COH 901 331 Alarm", rtap)) { |
197 | return -EIO; | 204 | ret = -EIO; |
205 | goto out_no_irq; | ||
206 | } | ||
198 | 207 | ||
199 | rtap->clk = clk_get(&pdev->dev, NULL); | 208 | rtap->clk = clk_get(&pdev->dev, NULL); |
200 | if (IS_ERR(rtap->clk)) { | 209 | if (IS_ERR(rtap->clk)) { |
201 | ret = PTR_ERR(rtap->clk); | 210 | ret = PTR_ERR(rtap->clk); |
202 | dev_err(&pdev->dev, "could not get clock\n"); | 211 | dev_err(&pdev->dev, "could not get clock\n"); |
203 | return ret; | 212 | goto out_no_clk; |
204 | } | 213 | } |
205 | 214 | ||
206 | /* We enable/disable the clock only to assure it works */ | 215 | /* We enable/disable the clock only to assure it works */ |
207 | ret = clk_prepare_enable(rtap->clk); | 216 | ret = clk_enable(rtap->clk); |
208 | if (ret) { | 217 | if (ret) { |
209 | dev_err(&pdev->dev, "could not enable clock\n"); | 218 | dev_err(&pdev->dev, "could not enable clock\n"); |
210 | goto out_no_clk_prepenable; | 219 | goto out_no_clk_enable; |
211 | } | 220 | } |
212 | clk_disable(rtap->clk); | 221 | clk_disable(rtap->clk); |
213 | 222 | ||
@@ -223,9 +232,18 @@ static int __init coh901331_probe(struct platform_device *pdev) | |||
223 | 232 | ||
224 | out_no_rtc: | 233 | out_no_rtc: |
225 | platform_set_drvdata(pdev, NULL); | 234 | platform_set_drvdata(pdev, NULL); |
226 | clk_unprepare(rtap->clk); | 235 | out_no_clk_enable: |
227 | out_no_clk_prepenable: | ||
228 | clk_put(rtap->clk); | 236 | clk_put(rtap->clk); |
237 | out_no_clk: | ||
238 | free_irq(rtap->irq, rtap); | ||
239 | out_no_irq: | ||
240 | iounmap(rtap->virtbase); | ||
241 | out_no_remap: | ||
242 | platform_set_drvdata(pdev, NULL); | ||
243 | out_no_memregion: | ||
244 | release_mem_region(rtap->phybase, SZ_4K); | ||
245 | out_no_resource: | ||
246 | kfree(rtap); | ||
229 | return ret; | 247 | return ret; |
230 | } | 248 | } |
231 | 249 | ||
@@ -247,7 +265,6 @@ static int coh901331_suspend(struct platform_device *pdev, pm_message_t state) | |||
247 | writel(0, rtap->virtbase + COH901331_IRQ_MASK); | 265 | writel(0, rtap->virtbase + COH901331_IRQ_MASK); |
248 | clk_disable(rtap->clk); | 266 | clk_disable(rtap->clk); |
249 | } | 267 | } |
250 | clk_unprepare(rtap->clk); | ||
251 | return 0; | 268 | return 0; |
252 | } | 269 | } |
253 | 270 | ||
@@ -255,7 +272,6 @@ static int coh901331_resume(struct platform_device *pdev) | |||
255 | { | 272 | { |
256 | struct coh901331_port *rtap = dev_get_drvdata(&pdev->dev); | 273 | struct coh901331_port *rtap = dev_get_drvdata(&pdev->dev); |
257 | 274 | ||
258 | clk_prepare(rtap->clk); | ||
259 | if (device_may_wakeup(&pdev->dev)) { | 275 | if (device_may_wakeup(&pdev->dev)) { |
260 | disable_irq_wake(rtap->irq); | 276 | disable_irq_wake(rtap->irq); |
261 | } else { | 277 | } else { |
@@ -276,7 +292,7 @@ static void coh901331_shutdown(struct platform_device *pdev) | |||
276 | 292 | ||
277 | clk_enable(rtap->clk); | 293 | clk_enable(rtap->clk); |
278 | writel(0, rtap->virtbase + COH901331_IRQ_MASK); | 294 | writel(0, rtap->virtbase + COH901331_IRQ_MASK); |
279 | clk_disable_unprepare(rtap->clk); | 295 | clk_disable(rtap->clk); |
280 | } | 296 | } |
281 | 297 | ||
282 | static struct platform_driver coh901331_driver = { | 298 | static struct platform_driver coh901331_driver = { |
diff --git a/drivers/rtc/rtc-da9052.c b/drivers/rtc/rtc-da9052.c deleted file mode 100644 index 60b826e520e..00000000000 --- a/drivers/rtc/rtc-da9052.c +++ /dev/null | |||
@@ -1,290 +0,0 @@ | |||
1 | /* | ||
2 | * Real time clock driver for DA9052 | ||
3 | * | ||
4 | * Copyright(c) 2012 Dialog Semiconductor Ltd. | ||
5 | * | ||
6 | * Author: Dajun Dajun Chen <dajun.chen@diasemi.com> | ||
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 as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/rtc.h> | ||
18 | |||
19 | #include <linux/mfd/da9052/da9052.h> | ||
20 | #include <linux/mfd/da9052/reg.h> | ||
21 | |||
22 | #define rtc_err(da9052, fmt, ...) \ | ||
23 | dev_err(da9052->dev, "%s: " fmt, __func__, ##__VA_ARGS__) | ||
24 | |||
25 | struct da9052_rtc { | ||
26 | struct rtc_device *rtc; | ||
27 | struct da9052 *da9052; | ||
28 | int irq; | ||
29 | }; | ||
30 | |||
31 | static int da9052_rtc_enable_alarm(struct da9052 *da9052, bool enable) | ||
32 | { | ||
33 | int ret; | ||
34 | if (enable) { | ||
35 | ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG, | ||
36 | DA9052_ALARM_Y_ALARM_ON, | ||
37 | DA9052_ALARM_Y_ALARM_ON); | ||
38 | if (ret != 0) | ||
39 | rtc_err(da9052, "Failed to enable ALM: %d\n", ret); | ||
40 | } else { | ||
41 | ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG, | ||
42 | DA9052_ALARM_Y_ALARM_ON, 0); | ||
43 | if (ret != 0) | ||
44 | rtc_err(da9052, "Write error: %d\n", ret); | ||
45 | } | ||
46 | return ret; | ||
47 | } | ||
48 | |||
49 | static irqreturn_t da9052_rtc_irq(int irq, void *data) | ||
50 | { | ||
51 | struct da9052_rtc *rtc = data; | ||
52 | int ret; | ||
53 | |||
54 | ret = da9052_reg_read(rtc->da9052, DA9052_ALARM_MI_REG); | ||
55 | if (ret < 0) { | ||
56 | rtc_err(rtc->da9052, "Read error: %d\n", ret); | ||
57 | return IRQ_NONE; | ||
58 | } | ||
59 | |||
60 | if (ret & DA9052_ALARMMI_ALARMTYPE) { | ||
61 | da9052_rtc_enable_alarm(rtc->da9052, 0); | ||
62 | rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); | ||
63 | } else | ||
64 | rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_PF); | ||
65 | |||
66 | return IRQ_HANDLED; | ||
67 | } | ||
68 | |||
69 | static int da9052_read_alarm(struct da9052 *da9052, struct rtc_time *rtc_tm) | ||
70 | { | ||
71 | int ret; | ||
72 | uint8_t v[5]; | ||
73 | |||
74 | ret = da9052_group_read(da9052, DA9052_ALARM_MI_REG, 5, v); | ||
75 | if (ret != 0) { | ||
76 | rtc_err(da9052, "Failed to group read ALM: %d\n", ret); | ||
77 | return ret; | ||
78 | } | ||
79 | |||
80 | rtc_tm->tm_year = (v[4] & DA9052_RTC_YEAR) + 100; | ||
81 | rtc_tm->tm_mon = (v[3] & DA9052_RTC_MONTH) - 1; | ||
82 | rtc_tm->tm_mday = v[2] & DA9052_RTC_DAY; | ||
83 | rtc_tm->tm_hour = v[1] & DA9052_RTC_HOUR; | ||
84 | rtc_tm->tm_min = v[0] & DA9052_RTC_MIN; | ||
85 | |||
86 | ret = rtc_valid_tm(rtc_tm); | ||
87 | if (ret != 0) | ||
88 | return ret; | ||
89 | return ret; | ||
90 | } | ||
91 | |||
92 | static int da9052_set_alarm(struct da9052 *da9052, struct rtc_time *rtc_tm) | ||
93 | { | ||
94 | int ret; | ||
95 | uint8_t v[3]; | ||
96 | |||
97 | rtc_tm->tm_year -= 100; | ||
98 | rtc_tm->tm_mon += 1; | ||
99 | |||
100 | ret = da9052_reg_update(da9052, DA9052_ALARM_MI_REG, | ||
101 | DA9052_RTC_MIN, rtc_tm->tm_min); | ||
102 | if (ret != 0) { | ||
103 | rtc_err(da9052, "Failed to write ALRM MIN: %d\n", ret); | ||
104 | return ret; | ||
105 | } | ||
106 | |||
107 | v[0] = rtc_tm->tm_hour; | ||
108 | v[1] = rtc_tm->tm_mday; | ||
109 | v[2] = rtc_tm->tm_mon; | ||
110 | |||
111 | ret = da9052_group_write(da9052, DA9052_ALARM_H_REG, 3, v); | ||
112 | if (ret < 0) | ||
113 | return ret; | ||
114 | |||
115 | ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG, | ||
116 | DA9052_RTC_YEAR, rtc_tm->tm_year); | ||
117 | if (ret != 0) | ||
118 | rtc_err(da9052, "Failed to write ALRM YEAR: %d\n", ret); | ||
119 | |||
120 | return ret; | ||
121 | } | ||
122 | |||
123 | static int da9052_rtc_get_alarm_status(struct da9052 *da9052) | ||
124 | { | ||
125 | int ret; | ||
126 | |||
127 | ret = da9052_reg_read(da9052, DA9052_ALARM_Y_REG); | ||
128 | if (ret < 0) { | ||
129 | rtc_err(da9052, "Failed to read ALM: %d\n", ret); | ||
130 | return ret; | ||
131 | } | ||
132 | ret &= DA9052_ALARM_Y_ALARM_ON; | ||
133 | return (ret > 0) ? 1 : 0; | ||
134 | } | ||
135 | |||
136 | static int da9052_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm) | ||
137 | { | ||
138 | struct da9052_rtc *rtc = dev_get_drvdata(dev); | ||
139 | uint8_t v[6]; | ||
140 | int ret; | ||
141 | |||
142 | ret = da9052_group_read(rtc->da9052, DA9052_COUNT_S_REG, 6, v); | ||
143 | if (ret < 0) { | ||
144 | rtc_err(rtc->da9052, "Failed to read RTC time : %d\n", ret); | ||
145 | return ret; | ||
146 | } | ||
147 | |||
148 | rtc_tm->tm_year = (v[5] & DA9052_RTC_YEAR) + 100; | ||
149 | rtc_tm->tm_mon = (v[4] & DA9052_RTC_MONTH) - 1; | ||
150 | rtc_tm->tm_mday = v[3] & DA9052_RTC_DAY; | ||
151 | rtc_tm->tm_hour = v[2] & DA9052_RTC_HOUR; | ||
152 | rtc_tm->tm_min = v[1] & DA9052_RTC_MIN; | ||
153 | rtc_tm->tm_sec = v[0] & DA9052_RTC_SEC; | ||
154 | |||
155 | ret = rtc_valid_tm(rtc_tm); | ||
156 | if (ret != 0) { | ||
157 | rtc_err(rtc->da9052, "rtc_valid_tm failed: %d\n", ret); | ||
158 | return ret; | ||
159 | } | ||
160 | |||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static int da9052_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
165 | { | ||
166 | struct da9052_rtc *rtc; | ||
167 | uint8_t v[6]; | ||
168 | |||
169 | rtc = dev_get_drvdata(dev); | ||
170 | |||
171 | v[0] = tm->tm_sec; | ||
172 | v[1] = tm->tm_min; | ||
173 | v[2] = tm->tm_hour; | ||
174 | v[3] = tm->tm_mday; | ||
175 | v[4] = tm->tm_mon + 1; | ||
176 | v[5] = tm->tm_year - 100; | ||
177 | |||
178 | return da9052_group_write(rtc->da9052, DA9052_COUNT_S_REG, 6, v); | ||
179 | } | ||
180 | |||
181 | static int da9052_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
182 | { | ||
183 | int ret; | ||
184 | struct rtc_time *tm = &alrm->time; | ||
185 | struct da9052_rtc *rtc = dev_get_drvdata(dev); | ||
186 | |||
187 | ret = da9052_read_alarm(rtc->da9052, tm); | ||
188 | |||
189 | if (ret) | ||
190 | return ret; | ||
191 | |||
192 | alrm->enabled = da9052_rtc_get_alarm_status(rtc->da9052); | ||
193 | |||
194 | return 0; | ||
195 | } | ||
196 | |||
197 | static int da9052_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
198 | { | ||
199 | int ret; | ||
200 | struct rtc_time *tm = &alrm->time; | ||
201 | struct da9052_rtc *rtc = dev_get_drvdata(dev); | ||
202 | |||
203 | ret = da9052_rtc_enable_alarm(rtc->da9052, 0); | ||
204 | if (ret < 0) | ||
205 | return ret; | ||
206 | |||
207 | ret = da9052_set_alarm(rtc->da9052, tm); | ||
208 | if (ret) | ||
209 | return ret; | ||
210 | |||
211 | ret = da9052_rtc_enable_alarm(rtc->da9052, 1); | ||
212 | |||
213 | return ret; | ||
214 | } | ||
215 | |||
216 | static int da9052_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | ||
217 | { | ||
218 | struct da9052_rtc *rtc = dev_get_drvdata(dev); | ||
219 | |||
220 | return da9052_rtc_enable_alarm(rtc->da9052, enabled); | ||
221 | } | ||
222 | |||
223 | static const struct rtc_class_ops da9052_rtc_ops = { | ||
224 | .read_time = da9052_rtc_read_time, | ||
225 | .set_time = da9052_rtc_set_time, | ||
226 | .read_alarm = da9052_rtc_read_alarm, | ||
227 | .set_alarm = da9052_rtc_set_alarm, | ||
228 | .alarm_irq_enable = da9052_rtc_alarm_irq_enable, | ||
229 | }; | ||
230 | |||
231 | static int da9052_rtc_probe(struct platform_device *pdev) | ||
232 | { | ||
233 | struct da9052_rtc *rtc; | ||
234 | int ret; | ||
235 | |||
236 | rtc = devm_kzalloc(&pdev->dev, sizeof(struct da9052_rtc), GFP_KERNEL); | ||
237 | if (!rtc) | ||
238 | return -ENOMEM; | ||
239 | |||
240 | rtc->da9052 = dev_get_drvdata(pdev->dev.parent); | ||
241 | platform_set_drvdata(pdev, rtc); | ||
242 | rtc->irq = platform_get_irq_byname(pdev, "ALM"); | ||
243 | ret = request_threaded_irq(rtc->irq, NULL, da9052_rtc_irq, | ||
244 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | ||
245 | "ALM", rtc); | ||
246 | if (ret != 0) { | ||
247 | rtc_err(rtc->da9052, "irq registration failed: %d\n", ret); | ||
248 | return ret; | ||
249 | } | ||
250 | |||
251 | rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, | ||
252 | &da9052_rtc_ops, THIS_MODULE); | ||
253 | if (IS_ERR(rtc->rtc)) { | ||
254 | ret = PTR_ERR(rtc->rtc); | ||
255 | goto err_free_irq; | ||
256 | } | ||
257 | |||
258 | return 0; | ||
259 | |||
260 | err_free_irq: | ||
261 | free_irq(rtc->irq, rtc); | ||
262 | return ret; | ||
263 | } | ||
264 | |||
265 | static int da9052_rtc_remove(struct platform_device *pdev) | ||
266 | { | ||
267 | struct da9052_rtc *rtc = pdev->dev.platform_data; | ||
268 | |||
269 | rtc_device_unregister(rtc->rtc); | ||
270 | free_irq(rtc->irq, rtc); | ||
271 | platform_set_drvdata(pdev, NULL); | ||
272 | |||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static struct platform_driver da9052_rtc_driver = { | ||
277 | .probe = da9052_rtc_probe, | ||
278 | .remove = da9052_rtc_remove, | ||
279 | .driver = { | ||
280 | .name = "da9052-rtc", | ||
281 | .owner = THIS_MODULE, | ||
282 | }, | ||
283 | }; | ||
284 | |||
285 | module_platform_driver(da9052_rtc_driver); | ||
286 | |||
287 | MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>"); | ||
288 | MODULE_DESCRIPTION("RTC driver for Dialog DA9052 PMIC"); | ||
289 | MODULE_LICENSE("GPL"); | ||
290 | MODULE_ALIAS("platform:da9052-rtc"); | ||
diff --git a/drivers/rtc/rtc-da9055.c b/drivers/rtc/rtc-da9055.c deleted file mode 100644 index 8f0dcfedb83..00000000000 --- a/drivers/rtc/rtc-da9055.c +++ /dev/null | |||
@@ -1,413 +0,0 @@ | |||
1 | /* | ||
2 | * Real time clock driver for DA9055 | ||
3 | * | ||
4 | * Copyright(c) 2012 Dialog Semiconductor Ltd. | ||
5 | * | ||
6 | * Author: Dajun Dajun Chen <dajun.chen@diasemi.com> | ||
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 as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/rtc.h> | ||
18 | |||
19 | #include <linux/mfd/da9055/core.h> | ||
20 | #include <linux/mfd/da9055/reg.h> | ||
21 | #include <linux/mfd/da9055/pdata.h> | ||
22 | |||
23 | struct da9055_rtc { | ||
24 | struct rtc_device *rtc; | ||
25 | struct da9055 *da9055; | ||
26 | int alarm_enable; | ||
27 | }; | ||
28 | |||
29 | static int da9055_rtc_enable_alarm(struct da9055_rtc *rtc, bool enable) | ||
30 | { | ||
31 | int ret; | ||
32 | if (enable) { | ||
33 | ret = da9055_reg_update(rtc->da9055, DA9055_REG_ALARM_Y, | ||
34 | DA9055_RTC_ALM_EN, | ||
35 | DA9055_RTC_ALM_EN); | ||
36 | if (ret != 0) | ||
37 | dev_err(rtc->da9055->dev, "Failed to enable ALM: %d\n", | ||
38 | ret); | ||
39 | rtc->alarm_enable = 1; | ||
40 | } else { | ||
41 | ret = da9055_reg_update(rtc->da9055, DA9055_REG_ALARM_Y, | ||
42 | DA9055_RTC_ALM_EN, 0); | ||
43 | if (ret != 0) | ||
44 | dev_err(rtc->da9055->dev, | ||
45 | "Failed to disable ALM: %d\n", ret); | ||
46 | rtc->alarm_enable = 0; | ||
47 | } | ||
48 | return ret; | ||
49 | } | ||
50 | |||
51 | static irqreturn_t da9055_rtc_alm_irq(int irq, void *data) | ||
52 | { | ||
53 | struct da9055_rtc *rtc = data; | ||
54 | |||
55 | da9055_rtc_enable_alarm(rtc, 0); | ||
56 | rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); | ||
57 | |||
58 | return IRQ_HANDLED; | ||
59 | } | ||
60 | |||
61 | static int da9055_read_alarm(struct da9055 *da9055, struct rtc_time *rtc_tm) | ||
62 | { | ||
63 | int ret; | ||
64 | uint8_t v[5]; | ||
65 | |||
66 | ret = da9055_group_read(da9055, DA9055_REG_ALARM_MI, 5, v); | ||
67 | if (ret != 0) { | ||
68 | dev_err(da9055->dev, "Failed to group read ALM: %d\n", ret); | ||
69 | return ret; | ||
70 | } | ||
71 | |||
72 | rtc_tm->tm_year = (v[4] & DA9055_RTC_ALM_YEAR) + 100; | ||
73 | rtc_tm->tm_mon = (v[3] & DA9055_RTC_ALM_MONTH) - 1; | ||
74 | rtc_tm->tm_mday = v[2] & DA9055_RTC_ALM_DAY; | ||
75 | rtc_tm->tm_hour = v[1] & DA9055_RTC_ALM_HOUR; | ||
76 | rtc_tm->tm_min = v[0] & DA9055_RTC_ALM_MIN; | ||
77 | |||
78 | return rtc_valid_tm(rtc_tm); | ||
79 | } | ||
80 | |||
81 | static int da9055_set_alarm(struct da9055 *da9055, struct rtc_time *rtc_tm) | ||
82 | { | ||
83 | int ret; | ||
84 | uint8_t v[2]; | ||
85 | |||
86 | rtc_tm->tm_year -= 100; | ||
87 | rtc_tm->tm_mon += 1; | ||
88 | |||
89 | ret = da9055_reg_update(da9055, DA9055_REG_ALARM_MI, | ||
90 | DA9055_RTC_ALM_MIN, rtc_tm->tm_min); | ||
91 | if (ret != 0) { | ||
92 | dev_err(da9055->dev, "Failed to write ALRM MIN: %d\n", ret); | ||
93 | return ret; | ||
94 | } | ||
95 | |||
96 | v[0] = rtc_tm->tm_hour; | ||
97 | v[1] = rtc_tm->tm_mday; | ||
98 | |||
99 | ret = da9055_group_write(da9055, DA9055_REG_ALARM_H, 2, v); | ||
100 | if (ret < 0) | ||
101 | return ret; | ||
102 | |||
103 | ret = da9055_reg_update(da9055, DA9055_REG_ALARM_MO, | ||
104 | DA9055_RTC_ALM_MONTH, rtc_tm->tm_mon); | ||
105 | if (ret < 0) | ||
106 | dev_err(da9055->dev, "Failed to write ALM Month:%d\n", ret); | ||
107 | |||
108 | ret = da9055_reg_update(da9055, DA9055_REG_ALARM_Y, | ||
109 | DA9055_RTC_ALM_YEAR, rtc_tm->tm_year); | ||
110 | if (ret < 0) | ||
111 | dev_err(da9055->dev, "Failed to write ALM Year:%d\n", ret); | ||
112 | |||
113 | return ret; | ||
114 | } | ||
115 | |||
116 | static int da9055_rtc_get_alarm_status(struct da9055 *da9055) | ||
117 | { | ||
118 | int ret; | ||
119 | |||
120 | ret = da9055_reg_read(da9055, DA9055_REG_ALARM_Y); | ||
121 | if (ret < 0) { | ||
122 | dev_err(da9055->dev, "Failed to read ALM: %d\n", ret); | ||
123 | return ret; | ||
124 | } | ||
125 | ret &= DA9055_RTC_ALM_EN; | ||
126 | return (ret > 0) ? 1 : 0; | ||
127 | } | ||
128 | |||
129 | static int da9055_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm) | ||
130 | { | ||
131 | struct da9055_rtc *rtc = dev_get_drvdata(dev); | ||
132 | uint8_t v[6]; | ||
133 | int ret; | ||
134 | |||
135 | ret = da9055_reg_read(rtc->da9055, DA9055_REG_COUNT_S); | ||
136 | if (ret < 0) | ||
137 | return ret; | ||
138 | |||
139 | /* | ||
140 | * Registers are only valid when RTC_READ | ||
141 | * status bit is asserted | ||
142 | */ | ||
143 | if (!(ret & DA9055_RTC_READ)) | ||
144 | return -EBUSY; | ||
145 | |||
146 | ret = da9055_group_read(rtc->da9055, DA9055_REG_COUNT_S, 6, v); | ||
147 | if (ret < 0) { | ||
148 | dev_err(rtc->da9055->dev, "Failed to read RTC time : %d\n", | ||
149 | ret); | ||
150 | return ret; | ||
151 | } | ||
152 | |||
153 | rtc_tm->tm_year = (v[5] & DA9055_RTC_YEAR) + 100; | ||
154 | rtc_tm->tm_mon = (v[4] & DA9055_RTC_MONTH) - 1; | ||
155 | rtc_tm->tm_mday = v[3] & DA9055_RTC_DAY; | ||
156 | rtc_tm->tm_hour = v[2] & DA9055_RTC_HOUR; | ||
157 | rtc_tm->tm_min = v[1] & DA9055_RTC_MIN; | ||
158 | rtc_tm->tm_sec = v[0] & DA9055_RTC_SEC; | ||
159 | |||
160 | return rtc_valid_tm(rtc_tm); | ||
161 | } | ||
162 | |||
163 | static int da9055_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
164 | { | ||
165 | struct da9055_rtc *rtc; | ||
166 | uint8_t v[6]; | ||
167 | |||
168 | rtc = dev_get_drvdata(dev); | ||
169 | |||
170 | v[0] = tm->tm_sec; | ||
171 | v[1] = tm->tm_min; | ||
172 | v[2] = tm->tm_hour; | ||
173 | v[3] = tm->tm_mday; | ||
174 | v[4] = tm->tm_mon + 1; | ||
175 | v[5] = tm->tm_year - 100; | ||
176 | |||
177 | return da9055_group_write(rtc->da9055, DA9055_REG_COUNT_S, 6, v); | ||
178 | } | ||
179 | |||
180 | static int da9055_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
181 | { | ||
182 | int ret; | ||
183 | struct rtc_time *tm = &alrm->time; | ||
184 | struct da9055_rtc *rtc = dev_get_drvdata(dev); | ||
185 | |||
186 | ret = da9055_read_alarm(rtc->da9055, tm); | ||
187 | |||
188 | if (ret) | ||
189 | return ret; | ||
190 | |||
191 | alrm->enabled = da9055_rtc_get_alarm_status(rtc->da9055); | ||
192 | |||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | static int da9055_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
197 | { | ||
198 | int ret; | ||
199 | struct rtc_time *tm = &alrm->time; | ||
200 | struct da9055_rtc *rtc = dev_get_drvdata(dev); | ||
201 | |||
202 | ret = da9055_rtc_enable_alarm(rtc, 0); | ||
203 | if (ret < 0) | ||
204 | return ret; | ||
205 | |||
206 | ret = da9055_set_alarm(rtc->da9055, tm); | ||
207 | if (ret) | ||
208 | return ret; | ||
209 | |||
210 | ret = da9055_rtc_enable_alarm(rtc, 1); | ||
211 | |||
212 | return ret; | ||
213 | } | ||
214 | |||
215 | static int da9055_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | ||
216 | { | ||
217 | struct da9055_rtc *rtc = dev_get_drvdata(dev); | ||
218 | |||
219 | return da9055_rtc_enable_alarm(rtc, enabled); | ||
220 | } | ||
221 | |||
222 | static const struct rtc_class_ops da9055_rtc_ops = { | ||
223 | .read_time = da9055_rtc_read_time, | ||
224 | .set_time = da9055_rtc_set_time, | ||
225 | .read_alarm = da9055_rtc_read_alarm, | ||
226 | .set_alarm = da9055_rtc_set_alarm, | ||
227 | .alarm_irq_enable = da9055_rtc_alarm_irq_enable, | ||
228 | }; | ||
229 | |||
230 | static int da9055_rtc_device_init(struct da9055 *da9055, | ||
231 | struct da9055_pdata *pdata) | ||
232 | { | ||
233 | int ret; | ||
234 | |||
235 | /* Enable RTC and the internal Crystal */ | ||
236 | ret = da9055_reg_update(da9055, DA9055_REG_CONTROL_B, | ||
237 | DA9055_RTC_EN, DA9055_RTC_EN); | ||
238 | if (ret < 0) | ||
239 | return ret; | ||
240 | ret = da9055_reg_update(da9055, DA9055_REG_EN_32K, | ||
241 | DA9055_CRYSTAL_EN, DA9055_CRYSTAL_EN); | ||
242 | if (ret < 0) | ||
243 | return ret; | ||
244 | |||
245 | /* Enable RTC in Power Down mode */ | ||
246 | ret = da9055_reg_update(da9055, DA9055_REG_CONTROL_B, | ||
247 | DA9055_RTC_MODE_PD, DA9055_RTC_MODE_PD); | ||
248 | if (ret < 0) | ||
249 | return ret; | ||
250 | |||
251 | /* Enable RTC in Reset mode */ | ||
252 | if (pdata && pdata->reset_enable) { | ||
253 | ret = da9055_reg_update(da9055, DA9055_REG_CONTROL_B, | ||
254 | DA9055_RTC_MODE_SD, | ||
255 | DA9055_RTC_MODE_SD << | ||
256 | DA9055_RTC_MODE_SD_SHIFT); | ||
257 | if (ret < 0) | ||
258 | return ret; | ||
259 | } | ||
260 | |||
261 | /* Disable the RTC TICK ALM */ | ||
262 | ret = da9055_reg_update(da9055, DA9055_REG_ALARM_MO, | ||
263 | DA9055_RTC_TICK_WAKE_MASK, 0); | ||
264 | if (ret < 0) | ||
265 | return ret; | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | static int da9055_rtc_probe(struct platform_device *pdev) | ||
271 | { | ||
272 | struct da9055_rtc *rtc; | ||
273 | struct da9055_pdata *pdata = NULL; | ||
274 | int ret, alm_irq; | ||
275 | |||
276 | rtc = devm_kzalloc(&pdev->dev, sizeof(struct da9055_rtc), GFP_KERNEL); | ||
277 | if (!rtc) | ||
278 | return -ENOMEM; | ||
279 | |||
280 | rtc->da9055 = dev_get_drvdata(pdev->dev.parent); | ||
281 | pdata = rtc->da9055->dev->platform_data; | ||
282 | platform_set_drvdata(pdev, rtc); | ||
283 | |||
284 | ret = da9055_rtc_device_init(rtc->da9055, pdata); | ||
285 | if (ret < 0) | ||
286 | goto err_rtc; | ||
287 | |||
288 | ret = da9055_reg_read(rtc->da9055, DA9055_REG_ALARM_Y); | ||
289 | if (ret < 0) | ||
290 | goto err_rtc; | ||
291 | |||
292 | if (ret & DA9055_RTC_ALM_EN) | ||
293 | rtc->alarm_enable = 1; | ||
294 | |||
295 | device_init_wakeup(&pdev->dev, 1); | ||
296 | |||
297 | rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, | ||
298 | &da9055_rtc_ops, THIS_MODULE); | ||
299 | if (IS_ERR(rtc->rtc)) { | ||
300 | ret = PTR_ERR(rtc->rtc); | ||
301 | goto err_rtc; | ||
302 | } | ||
303 | |||
304 | alm_irq = platform_get_irq_byname(pdev, "ALM"); | ||
305 | alm_irq = regmap_irq_get_virq(rtc->da9055->irq_data, alm_irq); | ||
306 | ret = devm_request_threaded_irq(&pdev->dev, alm_irq, NULL, | ||
307 | da9055_rtc_alm_irq, | ||
308 | IRQF_TRIGGER_HIGH | IRQF_ONESHOT, | ||
309 | "ALM", rtc); | ||
310 | if (ret != 0) | ||
311 | dev_err(rtc->da9055->dev, "irq registration failed: %d\n", ret); | ||
312 | |||
313 | err_rtc: | ||
314 | return ret; | ||
315 | |||
316 | } | ||
317 | |||
318 | static int da9055_rtc_remove(struct platform_device *pdev) | ||
319 | { | ||
320 | struct da9055_rtc *rtc = pdev->dev.platform_data; | ||
321 | |||
322 | rtc_device_unregister(rtc->rtc); | ||
323 | platform_set_drvdata(pdev, NULL); | ||
324 | |||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | #ifdef CONFIG_PM | ||
329 | /* Turn off the alarm if it should not be a wake source. */ | ||
330 | static int da9055_rtc_suspend(struct device *dev) | ||
331 | { | ||
332 | struct platform_device *pdev = to_platform_device(dev); | ||
333 | struct da9055_rtc *rtc = dev_get_drvdata(&pdev->dev); | ||
334 | int ret; | ||
335 | |||
336 | if (!device_may_wakeup(&pdev->dev)) { | ||
337 | /* Disable the ALM IRQ */ | ||
338 | ret = da9055_rtc_enable_alarm(rtc, 0); | ||
339 | if (ret < 0) | ||
340 | dev_err(&pdev->dev, "Failed to disable RTC ALM\n"); | ||
341 | } | ||
342 | |||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | /* Enable the alarm if it should be enabled (in case it was disabled to | ||
347 | * prevent use as a wake source). | ||
348 | */ | ||
349 | static int da9055_rtc_resume(struct device *dev) | ||
350 | { | ||
351 | struct platform_device *pdev = to_platform_device(dev); | ||
352 | struct da9055_rtc *rtc = dev_get_drvdata(&pdev->dev); | ||
353 | int ret; | ||
354 | |||
355 | if (!device_may_wakeup(&pdev->dev)) { | ||
356 | if (rtc->alarm_enable) { | ||
357 | ret = da9055_rtc_enable_alarm(rtc, 1); | ||
358 | if (ret < 0) | ||
359 | dev_err(&pdev->dev, | ||
360 | "Failed to restart RTC ALM\n"); | ||
361 | } | ||
362 | } | ||
363 | |||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | /* Unconditionally disable the alarm */ | ||
368 | static int da9055_rtc_freeze(struct device *dev) | ||
369 | { | ||
370 | struct platform_device *pdev = to_platform_device(dev); | ||
371 | struct da9055_rtc *rtc = dev_get_drvdata(&pdev->dev); | ||
372 | int ret; | ||
373 | |||
374 | ret = da9055_rtc_enable_alarm(rtc, 0); | ||
375 | if (ret < 0) | ||
376 | dev_err(&pdev->dev, "Failed to freeze RTC ALMs\n"); | ||
377 | |||
378 | return 0; | ||
379 | |||
380 | } | ||
381 | #else | ||
382 | #define da9055_rtc_suspend NULL | ||
383 | #define da9055_rtc_resume NULL | ||
384 | #define da9055_rtc_freeze NULL | ||
385 | #endif | ||
386 | |||
387 | static const struct dev_pm_ops da9055_rtc_pm_ops = { | ||
388 | .suspend = da9055_rtc_suspend, | ||
389 | .resume = da9055_rtc_resume, | ||
390 | |||
391 | .freeze = da9055_rtc_freeze, | ||
392 | .thaw = da9055_rtc_resume, | ||
393 | .restore = da9055_rtc_resume, | ||
394 | |||
395 | .poweroff = da9055_rtc_suspend, | ||
396 | }; | ||
397 | |||
398 | static struct platform_driver da9055_rtc_driver = { | ||
399 | .probe = da9055_rtc_probe, | ||
400 | .remove = da9055_rtc_remove, | ||
401 | .driver = { | ||
402 | .name = "da9055-rtc", | ||
403 | .owner = THIS_MODULE, | ||
404 | .pm = &da9055_rtc_pm_ops, | ||
405 | }, | ||
406 | }; | ||
407 | |||
408 | module_platform_driver(da9055_rtc_driver); | ||
409 | |||
410 | MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>"); | ||
411 | MODULE_DESCRIPTION("RTC driver for Dialog DA9055 PMIC"); | ||
412 | MODULE_LICENSE("GPL"); | ||
413 | MODULE_ALIAS("platform:da9055-rtc"); | ||
diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c index 5f7982f7c1b..755e1fe914a 100644 --- a/drivers/rtc/rtc-davinci.c +++ b/drivers/rtc/rtc-davinci.c | |||
@@ -485,7 +485,7 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) | |||
485 | struct resource *res, *mem; | 485 | struct resource *res, *mem; |
486 | int ret = 0; | 486 | int ret = 0; |
487 | 487 | ||
488 | davinci_rtc = devm_kzalloc(&pdev->dev, sizeof(struct davinci_rtc), GFP_KERNEL); | 488 | davinci_rtc = kzalloc(sizeof(struct davinci_rtc), GFP_KERNEL); |
489 | if (!davinci_rtc) { | 489 | if (!davinci_rtc) { |
490 | dev_dbg(dev, "could not allocate memory for private data\n"); | 490 | dev_dbg(dev, "could not allocate memory for private data\n"); |
491 | return -ENOMEM; | 491 | return -ENOMEM; |
@@ -494,13 +494,15 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) | |||
494 | davinci_rtc->irq = platform_get_irq(pdev, 0); | 494 | davinci_rtc->irq = platform_get_irq(pdev, 0); |
495 | if (davinci_rtc->irq < 0) { | 495 | if (davinci_rtc->irq < 0) { |
496 | dev_err(dev, "no RTC irq\n"); | 496 | dev_err(dev, "no RTC irq\n"); |
497 | return davinci_rtc->irq; | 497 | ret = davinci_rtc->irq; |
498 | goto fail1; | ||
498 | } | 499 | } |
499 | 500 | ||
500 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 501 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
501 | if (!res) { | 502 | if (!res) { |
502 | dev_err(dev, "no mem resource\n"); | 503 | dev_err(dev, "no mem resource\n"); |
503 | return -EINVAL; | 504 | ret = -EINVAL; |
505 | goto fail1; | ||
504 | } | 506 | } |
505 | 507 | ||
506 | davinci_rtc->pbase = res->start; | 508 | davinci_rtc->pbase = res->start; |
@@ -511,7 +513,8 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) | |||
511 | if (!mem) { | 513 | if (!mem) { |
512 | dev_err(dev, "RTC registers at %08x are not free\n", | 514 | dev_err(dev, "RTC registers at %08x are not free\n", |
513 | davinci_rtc->pbase); | 515 | davinci_rtc->pbase); |
514 | return -EBUSY; | 516 | ret = -EBUSY; |
517 | goto fail1; | ||
515 | } | 518 | } |
516 | 519 | ||
517 | davinci_rtc->base = ioremap(davinci_rtc->pbase, davinci_rtc->base_size); | 520 | davinci_rtc->base = ioremap(davinci_rtc->pbase, davinci_rtc->base_size); |
@@ -526,9 +529,8 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) | |||
526 | davinci_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, | 529 | davinci_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, |
527 | &davinci_rtc_ops, THIS_MODULE); | 530 | &davinci_rtc_ops, THIS_MODULE); |
528 | if (IS_ERR(davinci_rtc->rtc)) { | 531 | if (IS_ERR(davinci_rtc->rtc)) { |
529 | ret = PTR_ERR(davinci_rtc->rtc); | 532 | dev_err(dev, "unable to register RTC device, err %ld\n", |
530 | dev_err(dev, "unable to register RTC device, err %d\n", | 533 | PTR_ERR(davinci_rtc->rtc)); |
531 | ret); | ||
532 | goto fail3; | 534 | goto fail3; |
533 | } | 535 | } |
534 | 536 | ||
@@ -540,7 +542,7 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) | |||
540 | rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CCTRL); | 542 | rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CCTRL); |
541 | 543 | ||
542 | ret = request_irq(davinci_rtc->irq, davinci_rtc_interrupt, | 544 | ret = request_irq(davinci_rtc->irq, davinci_rtc_interrupt, |
543 | 0, "davinci_rtc", davinci_rtc); | 545 | IRQF_DISABLED, "davinci_rtc", davinci_rtc); |
544 | if (ret < 0) { | 546 | if (ret < 0) { |
545 | dev_err(dev, "unable to register davinci RTC interrupt\n"); | 547 | dev_err(dev, "unable to register davinci RTC interrupt\n"); |
546 | goto fail4; | 548 | goto fail4; |
@@ -564,10 +566,13 @@ fail3: | |||
564 | iounmap(davinci_rtc->base); | 566 | iounmap(davinci_rtc->base); |
565 | fail2: | 567 | fail2: |
566 | release_mem_region(davinci_rtc->pbase, davinci_rtc->base_size); | 568 | release_mem_region(davinci_rtc->pbase, davinci_rtc->base_size); |
569 | fail1: | ||
570 | kfree(davinci_rtc); | ||
571 | |||
567 | return ret; | 572 | return ret; |
568 | } | 573 | } |
569 | 574 | ||
570 | static int davinci_rtc_remove(struct platform_device *pdev) | 575 | static int __devexit davinci_rtc_remove(struct platform_device *pdev) |
571 | { | 576 | { |
572 | struct davinci_rtc *davinci_rtc = platform_get_drvdata(pdev); | 577 | struct davinci_rtc *davinci_rtc = platform_get_drvdata(pdev); |
573 | 578 | ||
@@ -584,12 +589,14 @@ static int davinci_rtc_remove(struct platform_device *pdev) | |||
584 | 589 | ||
585 | platform_set_drvdata(pdev, NULL); | 590 | platform_set_drvdata(pdev, NULL); |
586 | 591 | ||
592 | kfree(davinci_rtc); | ||
593 | |||
587 | return 0; | 594 | return 0; |
588 | } | 595 | } |
589 | 596 | ||
590 | static struct platform_driver davinci_rtc_driver = { | 597 | static struct platform_driver davinci_rtc_driver = { |
591 | .probe = davinci_rtc_probe, | 598 | .probe = davinci_rtc_probe, |
592 | .remove = davinci_rtc_remove, | 599 | .remove = __devexit_p(davinci_rtc_remove), |
593 | .driver = { | 600 | .driver = { |
594 | .name = "rtc_davinci", | 601 | .name = "rtc_davinci", |
595 | .owner = THIS_MODULE, | 602 | .owner = THIS_MODULE, |
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 9a86b4bd869..cace6d3aed9 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c | |||
@@ -379,6 +379,25 @@ static long rtc_dev_ioctl(struct file *file, | |||
379 | err = put_user(rtc->irq_freq, (unsigned long __user *)uarg); | 379 | err = put_user(rtc->irq_freq, (unsigned long __user *)uarg); |
380 | break; | 380 | break; |
381 | 381 | ||
382 | #if 0 | ||
383 | case RTC_EPOCH_SET: | ||
384 | #ifndef rtc_epoch | ||
385 | /* | ||
386 | * There were no RTC clocks before 1900. | ||
387 | */ | ||
388 | if (arg < 1900) { | ||
389 | err = -EINVAL; | ||
390 | break; | ||
391 | } | ||
392 | rtc_epoch = arg; | ||
393 | err = 0; | ||
394 | #endif | ||
395 | break; | ||
396 | |||
397 | case RTC_EPOCH_READ: | ||
398 | err = put_user(rtc_epoch, (unsigned long __user *)uarg); | ||
399 | break; | ||
400 | #endif | ||
382 | case RTC_WKALM_SET: | 401 | case RTC_WKALM_SET: |
383 | mutex_unlock(&rtc->ops_lock); | 402 | mutex_unlock(&rtc->ops_lock); |
384 | if (copy_from_user(&alarm, uarg, sizeof(alarm))) | 403 | if (copy_from_user(&alarm, uarg, sizeof(alarm))) |
diff --git a/drivers/rtc/rtc-dm355evm.c b/drivers/rtc/rtc-dm355evm.c index b2ed2c94b08..58d4e18530d 100644 --- a/drivers/rtc/rtc-dm355evm.c +++ b/drivers/rtc/rtc-dm355evm.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | 15 | ||
16 | #include <linux/i2c/dm355evm_msp.h> | 16 | #include <linux/i2c/dm355evm_msp.h> |
17 | #include <linux/module.h> | ||
18 | 17 | ||
19 | 18 | ||
20 | /* | 19 | /* |
@@ -123,7 +122,7 @@ static struct rtc_class_ops dm355evm_rtc_ops = { | |||
123 | 122 | ||
124 | /*----------------------------------------------------------------------*/ | 123 | /*----------------------------------------------------------------------*/ |
125 | 124 | ||
126 | static int dm355evm_rtc_probe(struct platform_device *pdev) | 125 | static int __devinit dm355evm_rtc_probe(struct platform_device *pdev) |
127 | { | 126 | { |
128 | struct rtc_device *rtc; | 127 | struct rtc_device *rtc; |
129 | 128 | ||
@@ -139,7 +138,7 @@ static int dm355evm_rtc_probe(struct platform_device *pdev) | |||
139 | return 0; | 138 | return 0; |
140 | } | 139 | } |
141 | 140 | ||
142 | static int dm355evm_rtc_remove(struct platform_device *pdev) | 141 | static int __devexit dm355evm_rtc_remove(struct platform_device *pdev) |
143 | { | 142 | { |
144 | struct rtc_device *rtc = platform_get_drvdata(pdev); | 143 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
145 | 144 | ||
@@ -154,13 +153,23 @@ static int dm355evm_rtc_remove(struct platform_device *pdev) | |||
154 | */ | 153 | */ |
155 | static struct platform_driver rtc_dm355evm_driver = { | 154 | static struct platform_driver rtc_dm355evm_driver = { |
156 | .probe = dm355evm_rtc_probe, | 155 | .probe = dm355evm_rtc_probe, |
157 | .remove = dm355evm_rtc_remove, | 156 | .remove = __devexit_p(dm355evm_rtc_remove), |
158 | .driver = { | 157 | .driver = { |
159 | .owner = THIS_MODULE, | 158 | .owner = THIS_MODULE, |
160 | .name = "rtc-dm355evm", | 159 | .name = "rtc-dm355evm", |
161 | }, | 160 | }, |
162 | }; | 161 | }; |
163 | 162 | ||
164 | module_platform_driver(rtc_dm355evm_driver); | 163 | static int __init dm355evm_rtc_init(void) |
164 | { | ||
165 | return platform_driver_register(&rtc_dm355evm_driver); | ||
166 | } | ||
167 | module_init(dm355evm_rtc_init); | ||
168 | |||
169 | static void __exit dm355evm_rtc_exit(void) | ||
170 | { | ||
171 | platform_driver_unregister(&rtc_dm355evm_driver); | ||
172 | } | ||
173 | module_exit(dm355evm_rtc_exit); | ||
165 | 174 | ||
166 | MODULE_LICENSE("GPL"); | 175 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/rtc/rtc-ds1286.c b/drivers/rtc/rtc-ds1286.c index d989412a348..68e6caf2549 100644 --- a/drivers/rtc/rtc-ds1286.c +++ b/drivers/rtc/rtc-ds1286.c | |||
@@ -329,7 +329,7 @@ static const struct rtc_class_ops ds1286_ops = { | |||
329 | .alarm_irq_enable = ds1286_alarm_irq_enable, | 329 | .alarm_irq_enable = ds1286_alarm_irq_enable, |
330 | }; | 330 | }; |
331 | 331 | ||
332 | static int ds1286_probe(struct platform_device *pdev) | 332 | static int __devinit ds1286_probe(struct platform_device *pdev) |
333 | { | 333 | { |
334 | struct rtc_device *rtc; | 334 | struct rtc_device *rtc; |
335 | struct resource *res; | 335 | struct resource *res; |
@@ -376,7 +376,7 @@ out: | |||
376 | return ret; | 376 | return ret; |
377 | } | 377 | } |
378 | 378 | ||
379 | static int ds1286_remove(struct platform_device *pdev) | 379 | static int __devexit ds1286_remove(struct platform_device *pdev) |
380 | { | 380 | { |
381 | struct ds1286_priv *priv = platform_get_drvdata(pdev); | 381 | struct ds1286_priv *priv = platform_get_drvdata(pdev); |
382 | 382 | ||
@@ -393,13 +393,24 @@ static struct platform_driver ds1286_platform_driver = { | |||
393 | .owner = THIS_MODULE, | 393 | .owner = THIS_MODULE, |
394 | }, | 394 | }, |
395 | .probe = ds1286_probe, | 395 | .probe = ds1286_probe, |
396 | .remove = ds1286_remove, | 396 | .remove = __devexit_p(ds1286_remove), |
397 | }; | 397 | }; |
398 | 398 | ||
399 | module_platform_driver(ds1286_platform_driver); | 399 | static int __init ds1286_init(void) |
400 | { | ||
401 | return platform_driver_register(&ds1286_platform_driver); | ||
402 | } | ||
403 | |||
404 | static void __exit ds1286_exit(void) | ||
405 | { | ||
406 | platform_driver_unregister(&ds1286_platform_driver); | ||
407 | } | ||
400 | 408 | ||
401 | MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>"); | 409 | MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>"); |
402 | MODULE_DESCRIPTION("DS1286 RTC driver"); | 410 | MODULE_DESCRIPTION("DS1286 RTC driver"); |
403 | MODULE_LICENSE("GPL"); | 411 | MODULE_LICENSE("GPL"); |
404 | MODULE_VERSION(DRV_VERSION); | 412 | MODULE_VERSION(DRV_VERSION); |
405 | MODULE_ALIAS("platform:rtc-ds1286"); | 413 | MODULE_ALIAS("platform:rtc-ds1286"); |
414 | |||
415 | module_init(ds1286_init); | ||
416 | module_exit(ds1286_exit); | ||
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c index fdbcdb289d6..f0d63892264 100644 --- a/drivers/rtc/rtc-ds1302.c +++ b/drivers/rtc/rtc-ds1302.c | |||
@@ -234,7 +234,7 @@ static int __init ds1302_rtc_probe(struct platform_device *pdev) | |||
234 | return 0; | 234 | return 0; |
235 | } | 235 | } |
236 | 236 | ||
237 | static int ds1302_rtc_remove(struct platform_device *pdev) | 237 | static int __devexit ds1302_rtc_remove(struct platform_device *pdev) |
238 | { | 238 | { |
239 | struct rtc_device *rtc = platform_get_drvdata(pdev); | 239 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
240 | 240 | ||
@@ -249,7 +249,7 @@ static struct platform_driver ds1302_platform_driver = { | |||
249 | .name = DRV_NAME, | 249 | .name = DRV_NAME, |
250 | .owner = THIS_MODULE, | 250 | .owner = THIS_MODULE, |
251 | }, | 251 | }, |
252 | .remove = ds1302_rtc_remove, | 252 | .remove = __devexit_p(ds1302_rtc_remove), |
253 | }; | 253 | }; |
254 | 254 | ||
255 | static int __init ds1302_rtc_init(void) | 255 | static int __init ds1302_rtc_init(void) |
diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index d578773f5ce..57fbcc149ba 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c | |||
@@ -17,7 +17,6 @@ | |||
17 | 17 | ||
18 | #include <linux/spi/spi.h> | 18 | #include <linux/spi/spi.h> |
19 | #include <linux/spi/ds1305.h> | 19 | #include <linux/spi/ds1305.h> |
20 | #include <linux/module.h> | ||
21 | 20 | ||
22 | 21 | ||
23 | /* | 22 | /* |
@@ -601,7 +600,7 @@ static struct bin_attribute nvram = { | |||
601 | * Interface to SPI stack | 600 | * Interface to SPI stack |
602 | */ | 601 | */ |
603 | 602 | ||
604 | static int ds1305_probe(struct spi_device *spi) | 603 | static int __devinit ds1305_probe(struct spi_device *spi) |
605 | { | 604 | { |
606 | struct ds1305 *ds1305; | 605 | struct ds1305 *ds1305; |
607 | int status; | 606 | int status; |
@@ -787,7 +786,7 @@ fail0: | |||
787 | return status; | 786 | return status; |
788 | } | 787 | } |
789 | 788 | ||
790 | static int ds1305_remove(struct spi_device *spi) | 789 | static int __devexit ds1305_remove(struct spi_device *spi) |
791 | { | 790 | { |
792 | struct ds1305 *ds1305 = spi_get_drvdata(spi); | 791 | struct ds1305 *ds1305 = spi_get_drvdata(spi); |
793 | 792 | ||
@@ -810,11 +809,21 @@ static struct spi_driver ds1305_driver = { | |||
810 | .driver.name = "rtc-ds1305", | 809 | .driver.name = "rtc-ds1305", |
811 | .driver.owner = THIS_MODULE, | 810 | .driver.owner = THIS_MODULE, |
812 | .probe = ds1305_probe, | 811 | .probe = ds1305_probe, |
813 | .remove = ds1305_remove, | 812 | .remove = __devexit_p(ds1305_remove), |
814 | /* REVISIT add suspend/resume */ | 813 | /* REVISIT add suspend/resume */ |
815 | }; | 814 | }; |
816 | 815 | ||
817 | module_spi_driver(ds1305_driver); | 816 | static int __init ds1305_init(void) |
817 | { | ||
818 | return spi_register_driver(&ds1305_driver); | ||
819 | } | ||
820 | module_init(ds1305_init); | ||
821 | |||
822 | static void __exit ds1305_exit(void) | ||
823 | { | ||
824 | spi_unregister_driver(&ds1305_driver); | ||
825 | } | ||
826 | module_exit(ds1305_exit); | ||
818 | 827 | ||
819 | MODULE_DESCRIPTION("RTC driver for DS1305 and DS1306 chips"); | 828 | MODULE_DESCRIPTION("RTC driver for DS1305 and DS1306 chips"); |
820 | MODULE_LICENSE("GPL"); | 829 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index e0d0ba4de03..b2005b44e4f 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c | |||
@@ -17,10 +17,10 @@ | |||
17 | #include <linux/string.h> | 17 | #include <linux/string.h> |
18 | #include <linux/rtc.h> | 18 | #include <linux/rtc.h> |
19 | #include <linux/bcd.h> | 19 | #include <linux/bcd.h> |
20 | #include <linux/rtc/ds1307.h> | ||
21 | 20 | ||
22 | /* | 21 | |
23 | * We can't determine type by probing, but if we expect pre-Linux code | 22 | |
23 | /* We can't determine type by probing, but if we expect pre-Linux code | ||
24 | * to have set the chip up as a clock (turning on the oscillator and | 24 | * to have set the chip up as a clock (turning on the oscillator and |
25 | * setting the date and time), Linux can ignore the non-clock features. | 25 | * setting the date and time), Linux can ignore the non-clock features. |
26 | * That's a natural job for a factory or repair bench. | 26 | * That's a natural job for a factory or repair bench. |
@@ -34,10 +34,8 @@ enum ds_type { | |||
34 | ds_1388, | 34 | ds_1388, |
35 | ds_3231, | 35 | ds_3231, |
36 | m41t00, | 36 | m41t00, |
37 | mcp7941x, | ||
38 | rx_8025, | 37 | rx_8025, |
39 | last_ds_type /* always last */ | 38 | // rs5c372 too? different address... |
40 | /* rs5c372 too? different address... */ | ||
41 | }; | 39 | }; |
42 | 40 | ||
43 | 41 | ||
@@ -45,7 +43,6 @@ enum ds_type { | |||
45 | #define DS1307_REG_SECS 0x00 /* 00-59 */ | 43 | #define DS1307_REG_SECS 0x00 /* 00-59 */ |
46 | # define DS1307_BIT_CH 0x80 | 44 | # define DS1307_BIT_CH 0x80 |
47 | # define DS1340_BIT_nEOSC 0x80 | 45 | # define DS1340_BIT_nEOSC 0x80 |
48 | # define MCP7941X_BIT_ST 0x80 | ||
49 | #define DS1307_REG_MIN 0x01 /* 00-59 */ | 46 | #define DS1307_REG_MIN 0x01 /* 00-59 */ |
50 | #define DS1307_REG_HOUR 0x02 /* 00-23, or 1-12{am,pm} */ | 47 | #define DS1307_REG_HOUR 0x02 /* 00-23, or 1-12{am,pm} */ |
51 | # define DS1307_BIT_12HR 0x40 /* in REG_HOUR */ | 48 | # define DS1307_BIT_12HR 0x40 /* in REG_HOUR */ |
@@ -53,14 +50,12 @@ enum ds_type { | |||
53 | # define DS1340_BIT_CENTURY_EN 0x80 /* in REG_HOUR */ | 50 | # define DS1340_BIT_CENTURY_EN 0x80 /* in REG_HOUR */ |
54 | # define DS1340_BIT_CENTURY 0x40 /* in REG_HOUR */ | 51 | # define DS1340_BIT_CENTURY 0x40 /* in REG_HOUR */ |
55 | #define DS1307_REG_WDAY 0x03 /* 01-07 */ | 52 | #define DS1307_REG_WDAY 0x03 /* 01-07 */ |
56 | # define MCP7941X_BIT_VBATEN 0x08 | ||
57 | #define DS1307_REG_MDAY 0x04 /* 01-31 */ | 53 | #define DS1307_REG_MDAY 0x04 /* 01-31 */ |
58 | #define DS1307_REG_MONTH 0x05 /* 01-12 */ | 54 | #define DS1307_REG_MONTH 0x05 /* 01-12 */ |
59 | # define DS1337_BIT_CENTURY 0x80 /* in REG_MONTH */ | 55 | # define DS1337_BIT_CENTURY 0x80 /* in REG_MONTH */ |
60 | #define DS1307_REG_YEAR 0x06 /* 00-99 */ | 56 | #define DS1307_REG_YEAR 0x06 /* 00-99 */ |
61 | 57 | ||
62 | /* | 58 | /* Other registers (control, status, alarms, trickle charge, NVRAM, etc) |
63 | * Other registers (control, status, alarms, trickle charge, NVRAM, etc) | ||
64 | * start at 7, and they differ a LOT. Only control and status matter for | 59 | * start at 7, and they differ a LOT. Only control and status matter for |
65 | * basic RTC date and time functionality; be careful using them. | 60 | * basic RTC date and time functionality; be careful using them. |
66 | */ | 61 | */ |
@@ -91,8 +86,7 @@ enum ds_type { | |||
91 | # define DS1337_BIT_A2I 0x02 | 86 | # define DS1337_BIT_A2I 0x02 |
92 | # define DS1337_BIT_A1I 0x01 | 87 | # define DS1337_BIT_A1I 0x01 |
93 | #define DS1339_REG_ALARM1_SECS 0x07 | 88 | #define DS1339_REG_ALARM1_SECS 0x07 |
94 | 89 | #define DS1339_REG_TRICKLE 0x10 | |
95 | #define DS13XX_TRICKLE_CHARGER_MAGIC 0xa0 | ||
96 | 90 | ||
97 | #define RX8025_REG_CTRL1 0x0e | 91 | #define RX8025_REG_CTRL1 0x0e |
98 | # define RX8025_BIT_2412 0x20 | 92 | # define RX8025_BIT_2412 0x20 |
@@ -105,8 +99,6 @@ enum ds_type { | |||
105 | struct ds1307 { | 99 | struct ds1307 { |
106 | u8 offset; /* register's offset */ | 100 | u8 offset; /* register's offset */ |
107 | u8 regs[11]; | 101 | u8 regs[11]; |
108 | u16 nvram_offset; | ||
109 | struct bin_attribute *nvram; | ||
110 | enum ds_type type; | 102 | enum ds_type type; |
111 | unsigned long flags; | 103 | unsigned long flags; |
112 | #define HAS_NVRAM 0 /* bit 0 == sysfs file active */ | 104 | #define HAS_NVRAM 0 /* bit 0 == sysfs file active */ |
@@ -121,43 +113,32 @@ struct ds1307 { | |||
121 | }; | 113 | }; |
122 | 114 | ||
123 | struct chip_desc { | 115 | struct chip_desc { |
116 | unsigned nvram56:1; | ||
124 | unsigned alarm:1; | 117 | unsigned alarm:1; |
125 | u16 nvram_offset; | ||
126 | u16 nvram_size; | ||
127 | u16 trickle_charger_reg; | ||
128 | }; | 118 | }; |
129 | 119 | ||
130 | static const struct chip_desc chips[last_ds_type] = { | 120 | static const struct chip_desc chips[] = { |
131 | [ds_1307] = { | 121 | [ds_1307] = { |
132 | .nvram_offset = 8, | 122 | .nvram56 = 1, |
133 | .nvram_size = 56, | 123 | }, |
134 | }, | 124 | [ds_1337] = { |
135 | [ds_1337] = { | 125 | .alarm = 1, |
136 | .alarm = 1, | 126 | }, |
137 | }, | 127 | [ds_1338] = { |
138 | [ds_1338] = { | 128 | .nvram56 = 1, |
139 | .nvram_offset = 8, | 129 | }, |
140 | .nvram_size = 56, | 130 | [ds_1339] = { |
141 | }, | 131 | .alarm = 1, |
142 | [ds_1339] = { | 132 | }, |
143 | .alarm = 1, | 133 | [ds_1340] = { |
144 | .trickle_charger_reg = 0x10, | 134 | }, |
145 | }, | 135 | [ds_3231] = { |
146 | [ds_1340] = { | 136 | .alarm = 1, |
147 | .trickle_charger_reg = 0x08, | 137 | }, |
148 | }, | 138 | [m41t00] = { |
149 | [ds_1388] = { | 139 | }, |
150 | .trickle_charger_reg = 0x0a, | 140 | [rx_8025] = { |
151 | }, | 141 | }, }; |
152 | [ds_3231] = { | ||
153 | .alarm = 1, | ||
154 | }, | ||
155 | [mcp7941x] = { | ||
156 | /* this is battery backed SRAM */ | ||
157 | .nvram_offset = 0x20, | ||
158 | .nvram_size = 0x40, | ||
159 | }, | ||
160 | }; | ||
161 | 142 | ||
162 | static const struct i2c_device_id ds1307_id[] = { | 143 | static const struct i2c_device_id ds1307_id[] = { |
163 | { "ds1307", ds_1307 }, | 144 | { "ds1307", ds_1307 }, |
@@ -168,7 +149,6 @@ static const struct i2c_device_id ds1307_id[] = { | |||
168 | { "ds1340", ds_1340 }, | 149 | { "ds1340", ds_1340 }, |
169 | { "ds3231", ds_3231 }, | 150 | { "ds3231", ds_3231 }, |
170 | { "m41t00", m41t00 }, | 151 | { "m41t00", m41t00 }, |
171 | { "mcp7941x", mcp7941x }, | ||
172 | { "pt7c4338", ds_1307 }, | 152 | { "pt7c4338", ds_1307 }, |
173 | { "rx8025", rx_8025 }, | 153 | { "rx8025", rx_8025 }, |
174 | { } | 154 | { } |
@@ -385,15 +365,6 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) | |||
385 | buf[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY_EN | 365 | buf[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY_EN |
386 | | DS1340_BIT_CENTURY; | 366 | | DS1340_BIT_CENTURY; |
387 | break; | 367 | break; |
388 | case mcp7941x: | ||
389 | /* | ||
390 | * these bits were cleared when preparing the date/time | ||
391 | * values and need to be set again before writing the | ||
392 | * buffer out to the device. | ||
393 | */ | ||
394 | buf[DS1307_REG_SECS] |= MCP7941X_BIT_ST; | ||
395 | buf[DS1307_REG_WDAY] |= MCP7941X_BIT_VBATEN; | ||
396 | break; | ||
397 | default: | 368 | default: |
398 | break; | 369 | break; |
399 | } | 370 | } |
@@ -436,8 +407,7 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
436 | ds1307->regs[6], ds1307->regs[7], | 407 | ds1307->regs[6], ds1307->regs[7], |
437 | ds1307->regs[8]); | 408 | ds1307->regs[8]); |
438 | 409 | ||
439 | /* | 410 | /* report alarm time (ALARM1); assume 24 hour and day-of-month modes, |
440 | * report alarm time (ALARM1); assume 24 hour and day-of-month modes, | ||
441 | * and that all four fields are checked matches | 411 | * and that all four fields are checked matches |
442 | */ | 412 | */ |
443 | t->time.tm_sec = bcd2bin(ds1307->regs[0] & 0x7f); | 413 | t->time.tm_sec = bcd2bin(ds1307->regs[0] & 0x7f); |
@@ -465,7 +435,7 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
465 | 435 | ||
466 | static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t) | 436 | static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t) |
467 | { | 437 | { |
468 | struct i2c_client *client = to_i2c_client(dev); | 438 | struct i2c_client *client = to_i2c_client(dev); |
469 | struct ds1307 *ds1307 = i2c_get_clientdata(client); | 439 | struct ds1307 *ds1307 = i2c_get_clientdata(client); |
470 | unsigned char *buf = ds1307->regs; | 440 | unsigned char *buf = ds1307->regs; |
471 | u8 control, status; | 441 | u8 control, status; |
@@ -561,6 +531,8 @@ static const struct rtc_class_ops ds13xx_rtc_ops = { | |||
561 | 531 | ||
562 | /*----------------------------------------------------------------------*/ | 532 | /*----------------------------------------------------------------------*/ |
563 | 533 | ||
534 | #define NVRAM_SIZE 56 | ||
535 | |||
564 | static ssize_t | 536 | static ssize_t |
565 | ds1307_nvram_read(struct file *filp, struct kobject *kobj, | 537 | ds1307_nvram_read(struct file *filp, struct kobject *kobj, |
566 | struct bin_attribute *attr, | 538 | struct bin_attribute *attr, |
@@ -573,15 +545,14 @@ ds1307_nvram_read(struct file *filp, struct kobject *kobj, | |||
573 | client = kobj_to_i2c_client(kobj); | 545 | client = kobj_to_i2c_client(kobj); |
574 | ds1307 = i2c_get_clientdata(client); | 546 | ds1307 = i2c_get_clientdata(client); |
575 | 547 | ||
576 | if (unlikely(off >= ds1307->nvram->size)) | 548 | if (unlikely(off >= NVRAM_SIZE)) |
577 | return 0; | 549 | return 0; |
578 | if ((off + count) > ds1307->nvram->size) | 550 | if ((off + count) > NVRAM_SIZE) |
579 | count = ds1307->nvram->size - off; | 551 | count = NVRAM_SIZE - off; |
580 | if (unlikely(!count)) | 552 | if (unlikely(!count)) |
581 | return count; | 553 | return count; |
582 | 554 | ||
583 | result = ds1307->read_block_data(client, ds1307->nvram_offset + off, | 555 | result = ds1307->read_block_data(client, 8 + off, count, buf); |
584 | count, buf); | ||
585 | if (result < 0) | 556 | if (result < 0) |
586 | dev_err(&client->dev, "%s error %d\n", "nvram read", result); | 557 | dev_err(&client->dev, "%s error %d\n", "nvram read", result); |
587 | return result; | 558 | return result; |
@@ -599,15 +570,14 @@ ds1307_nvram_write(struct file *filp, struct kobject *kobj, | |||
599 | client = kobj_to_i2c_client(kobj); | 570 | client = kobj_to_i2c_client(kobj); |
600 | ds1307 = i2c_get_clientdata(client); | 571 | ds1307 = i2c_get_clientdata(client); |
601 | 572 | ||
602 | if (unlikely(off >= ds1307->nvram->size)) | 573 | if (unlikely(off >= NVRAM_SIZE)) |
603 | return -EFBIG; | 574 | return -EFBIG; |
604 | if ((off + count) > ds1307->nvram->size) | 575 | if ((off + count) > NVRAM_SIZE) |
605 | count = ds1307->nvram->size - off; | 576 | count = NVRAM_SIZE - off; |
606 | if (unlikely(!count)) | 577 | if (unlikely(!count)) |
607 | return count; | 578 | return count; |
608 | 579 | ||
609 | result = ds1307->write_block_data(client, ds1307->nvram_offset + off, | 580 | result = ds1307->write_block_data(client, 8 + off, count, buf); |
610 | count, buf); | ||
611 | if (result < 0) { | 581 | if (result < 0) { |
612 | dev_err(&client->dev, "%s error %d\n", "nvram write", result); | 582 | dev_err(&client->dev, "%s error %d\n", "nvram write", result); |
613 | return result; | 583 | return result; |
@@ -615,10 +585,23 @@ ds1307_nvram_write(struct file *filp, struct kobject *kobj, | |||
615 | return count; | 585 | return count; |
616 | } | 586 | } |
617 | 587 | ||
588 | static struct bin_attribute nvram = { | ||
589 | .attr = { | ||
590 | .name = "nvram", | ||
591 | .mode = S_IRUGO | S_IWUSR, | ||
592 | }, | ||
593 | |||
594 | .read = ds1307_nvram_read, | ||
595 | .write = ds1307_nvram_write, | ||
596 | .size = NVRAM_SIZE, | ||
597 | }; | ||
598 | |||
618 | /*----------------------------------------------------------------------*/ | 599 | /*----------------------------------------------------------------------*/ |
619 | 600 | ||
620 | static int ds1307_probe(struct i2c_client *client, | 601 | static struct i2c_driver ds1307_driver; |
621 | const struct i2c_device_id *id) | 602 | |
603 | static int __devinit ds1307_probe(struct i2c_client *client, | ||
604 | const struct i2c_device_id *id) | ||
622 | { | 605 | { |
623 | struct ds1307 *ds1307; | 606 | struct ds1307 *ds1307; |
624 | int err = -ENODEV; | 607 | int err = -ENODEV; |
@@ -627,7 +610,6 @@ static int ds1307_probe(struct i2c_client *client, | |||
627 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 610 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
628 | int want_irq = false; | 611 | int want_irq = false; |
629 | unsigned char *buf; | 612 | unsigned char *buf; |
630 | struct ds1307_platform_data *pdata = client->dev.platform_data; | ||
631 | static const int bbsqi_bitpos[] = { | 613 | static const int bbsqi_bitpos[] = { |
632 | [ds_1337] = 0, | 614 | [ds_1337] = 0, |
633 | [ds_1339] = DS1339_BIT_BBSQI, | 615 | [ds_1339] = DS1339_BIT_BBSQI, |
@@ -638,18 +620,14 @@ static int ds1307_probe(struct i2c_client *client, | |||
638 | && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) | 620 | && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) |
639 | return -EIO; | 621 | return -EIO; |
640 | 622 | ||
641 | ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL); | 623 | if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL))) |
642 | if (!ds1307) | ||
643 | return -ENOMEM; | 624 | return -ENOMEM; |
644 | 625 | ||
645 | i2c_set_clientdata(client, ds1307); | 626 | i2c_set_clientdata(client, ds1307); |
646 | 627 | ||
647 | ds1307->client = client; | 628 | ds1307->client = client; |
648 | ds1307->type = id->driver_data; | 629 | ds1307->type = id->driver_data; |
649 | 630 | ds1307->offset = 0; | |
650 | if (pdata && pdata->trickle_charger_setup && chip->trickle_charger_reg) | ||
651 | i2c_smbus_write_byte_data(client, chip->trickle_charger_reg, | ||
652 | DS13XX_TRICKLE_CHARGER_MAGIC | pdata->trickle_charger_setup); | ||
653 | 631 | ||
654 | buf = ds1307->regs; | 632 | buf = ds1307->regs; |
655 | if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { | 633 | if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { |
@@ -664,6 +642,11 @@ static int ds1307_probe(struct i2c_client *client, | |||
664 | case ds_1337: | 642 | case ds_1337: |
665 | case ds_1339: | 643 | case ds_1339: |
666 | case ds_3231: | 644 | case ds_3231: |
645 | /* has IRQ? */ | ||
646 | if (ds1307->client->irq > 0 && chip->alarm) { | ||
647 | INIT_WORK(&ds1307->work, ds1307_work); | ||
648 | want_irq = true; | ||
649 | } | ||
667 | /* get registers that the "rtc" read below won't read... */ | 650 | /* get registers that the "rtc" read below won't read... */ |
668 | tmp = ds1307->read_block_data(ds1307->client, | 651 | tmp = ds1307->read_block_data(ds1307->client, |
669 | DS1337_REG_CONTROL, 2, buf); | 652 | DS1337_REG_CONTROL, 2, buf); |
@@ -677,19 +660,14 @@ static int ds1307_probe(struct i2c_client *client, | |||
677 | if (ds1307->regs[0] & DS1337_BIT_nEOSC) | 660 | if (ds1307->regs[0] & DS1337_BIT_nEOSC) |
678 | ds1307->regs[0] &= ~DS1337_BIT_nEOSC; | 661 | ds1307->regs[0] &= ~DS1337_BIT_nEOSC; |
679 | 662 | ||
680 | /* | 663 | /* Using IRQ? Disable the square wave and both alarms. |
681 | * Using IRQ? Disable the square wave and both alarms. | ||
682 | * For some variants, be sure alarms can trigger when we're | 664 | * For some variants, be sure alarms can trigger when we're |
683 | * running on Vbackup (BBSQI/BBSQW) | 665 | * running on Vbackup (BBSQI/BBSQW) |
684 | */ | 666 | */ |
685 | if (ds1307->client->irq > 0 && chip->alarm) { | 667 | if (want_irq) { |
686 | INIT_WORK(&ds1307->work, ds1307_work); | ||
687 | |||
688 | ds1307->regs[0] |= DS1337_BIT_INTCN | 668 | ds1307->regs[0] |= DS1337_BIT_INTCN |
689 | | bbsqi_bitpos[ds1307->type]; | 669 | | bbsqi_bitpos[ds1307->type]; |
690 | ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE); | 670 | ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE); |
691 | |||
692 | want_irq = true; | ||
693 | } | 671 | } |
694 | 672 | ||
695 | i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, | 673 | i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, |
@@ -784,8 +762,7 @@ read_rtc: | |||
784 | goto exit_free; | 762 | goto exit_free; |
785 | } | 763 | } |
786 | 764 | ||
787 | /* | 765 | /* minimal sanity checking; some chips (like DS1340) don't |
788 | * minimal sanity checking; some chips (like DS1340) don't | ||
789 | * specify the extra bits as must-be-zero, but there are | 766 | * specify the extra bits as must-be-zero, but there are |
790 | * still a few values that are clearly out-of-range. | 767 | * still a few values that are clearly out-of-range. |
791 | */ | 768 | */ |
@@ -832,24 +809,11 @@ read_rtc: | |||
832 | dev_warn(&client->dev, "SET TIME!\n"); | 809 | dev_warn(&client->dev, "SET TIME!\n"); |
833 | } | 810 | } |
834 | break; | 811 | break; |
835 | case mcp7941x: | 812 | case rx_8025: |
836 | /* make sure that the backup battery is enabled */ | 813 | case ds_1337: |
837 | if (!(ds1307->regs[DS1307_REG_WDAY] & MCP7941X_BIT_VBATEN)) { | 814 | case ds_1339: |
838 | i2c_smbus_write_byte_data(client, DS1307_REG_WDAY, | 815 | case ds_1388: |
839 | ds1307->regs[DS1307_REG_WDAY] | 816 | case ds_3231: |
840 | | MCP7941X_BIT_VBATEN); | ||
841 | } | ||
842 | |||
843 | /* clock halted? turn it on, so clock can tick. */ | ||
844 | if (!(tmp & MCP7941X_BIT_ST)) { | ||
845 | i2c_smbus_write_byte_data(client, DS1307_REG_SECS, | ||
846 | MCP7941X_BIT_ST); | ||
847 | dev_warn(&client->dev, "SET TIME!\n"); | ||
848 | goto read_rtc; | ||
849 | } | ||
850 | |||
851 | break; | ||
852 | default: | ||
853 | break; | 817 | break; |
854 | } | 818 | } |
855 | 819 | ||
@@ -857,8 +821,7 @@ read_rtc: | |||
857 | switch (ds1307->type) { | 821 | switch (ds1307->type) { |
858 | case ds_1340: | 822 | case ds_1340: |
859 | case m41t00: | 823 | case m41t00: |
860 | /* | 824 | /* NOTE: ignores century bits; fix before deploying |
861 | * NOTE: ignores century bits; fix before deploying | ||
862 | * systems that will run through year 2100. | 825 | * systems that will run through year 2100. |
863 | */ | 826 | */ |
864 | break; | 827 | break; |
@@ -868,8 +831,7 @@ read_rtc: | |||
868 | if (!(tmp & DS1307_BIT_12HR)) | 831 | if (!(tmp & DS1307_BIT_12HR)) |
869 | break; | 832 | break; |
870 | 833 | ||
871 | /* | 834 | /* Be sure we're in 24 hour mode. Multi-master systems |
872 | * Be sure we're in 24 hour mode. Multi-master systems | ||
873 | * take note... | 835 | * take note... |
874 | */ | 836 | */ |
875 | tmp = bcd2bin(tmp & 0x1f); | 837 | tmp = bcd2bin(tmp & 0x1f); |
@@ -905,32 +867,16 @@ read_rtc: | |||
905 | dev_dbg(&client->dev, "got IRQ %d\n", client->irq); | 867 | dev_dbg(&client->dev, "got IRQ %d\n", client->irq); |
906 | } | 868 | } |
907 | 869 | ||
908 | if (chip->nvram_size) { | 870 | if (chip->nvram56) { |
909 | ds1307->nvram = kzalloc(sizeof(struct bin_attribute), | 871 | err = sysfs_create_bin_file(&client->dev.kobj, &nvram); |
910 | GFP_KERNEL); | 872 | if (err == 0) { |
911 | if (!ds1307->nvram) { | 873 | set_bit(HAS_NVRAM, &ds1307->flags); |
912 | err = -ENOMEM; | 874 | dev_info(&client->dev, "56 bytes nvram\n"); |
913 | goto exit_nvram; | ||
914 | } | ||
915 | ds1307->nvram->attr.name = "nvram"; | ||
916 | ds1307->nvram->attr.mode = S_IRUGO | S_IWUSR; | ||
917 | sysfs_bin_attr_init(ds1307->nvram); | ||
918 | ds1307->nvram->read = ds1307_nvram_read, | ||
919 | ds1307->nvram->write = ds1307_nvram_write, | ||
920 | ds1307->nvram->size = chip->nvram_size; | ||
921 | ds1307->nvram_offset = chip->nvram_offset; | ||
922 | err = sysfs_create_bin_file(&client->dev.kobj, ds1307->nvram); | ||
923 | if (err) { | ||
924 | kfree(ds1307->nvram); | ||
925 | goto exit_nvram; | ||
926 | } | 875 | } |
927 | set_bit(HAS_NVRAM, &ds1307->flags); | ||
928 | dev_info(&client->dev, "%zu bytes nvram\n", ds1307->nvram->size); | ||
929 | } | 876 | } |
930 | 877 | ||
931 | return 0; | 878 | return 0; |
932 | 879 | ||
933 | exit_nvram: | ||
934 | exit_irq: | 880 | exit_irq: |
935 | rtc_device_unregister(ds1307->rtc); | 881 | rtc_device_unregister(ds1307->rtc); |
936 | exit_free: | 882 | exit_free: |
@@ -938,19 +884,17 @@ exit_free: | |||
938 | return err; | 884 | return err; |
939 | } | 885 | } |
940 | 886 | ||
941 | static int ds1307_remove(struct i2c_client *client) | 887 | static int __devexit ds1307_remove(struct i2c_client *client) |
942 | { | 888 | { |
943 | struct ds1307 *ds1307 = i2c_get_clientdata(client); | 889 | struct ds1307 *ds1307 = i2c_get_clientdata(client); |
944 | 890 | ||
945 | if (test_and_clear_bit(HAS_ALARM, &ds1307->flags)) { | 891 | if (test_and_clear_bit(HAS_ALARM, &ds1307->flags)) { |
946 | free_irq(client->irq, client); | 892 | free_irq(client->irq, client); |
947 | cancel_work_sync(&ds1307->work); | 893 | cancel_work_sync(&ds1307->work); |
948 | } | 894 | } |
949 | 895 | ||
950 | if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags)) { | 896 | if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags)) |
951 | sysfs_remove_bin_file(&client->dev.kobj, ds1307->nvram); | 897 | sysfs_remove_bin_file(&client->dev.kobj, &nvram); |
952 | kfree(ds1307->nvram); | ||
953 | } | ||
954 | 898 | ||
955 | rtc_device_unregister(ds1307->rtc); | 899 | rtc_device_unregister(ds1307->rtc); |
956 | kfree(ds1307); | 900 | kfree(ds1307); |
@@ -963,11 +907,21 @@ static struct i2c_driver ds1307_driver = { | |||
963 | .owner = THIS_MODULE, | 907 | .owner = THIS_MODULE, |
964 | }, | 908 | }, |
965 | .probe = ds1307_probe, | 909 | .probe = ds1307_probe, |
966 | .remove = ds1307_remove, | 910 | .remove = __devexit_p(ds1307_remove), |
967 | .id_table = ds1307_id, | 911 | .id_table = ds1307_id, |
968 | }; | 912 | }; |
969 | 913 | ||
970 | module_i2c_driver(ds1307_driver); | 914 | static int __init ds1307_init(void) |
915 | { | ||
916 | return i2c_add_driver(&ds1307_driver); | ||
917 | } | ||
918 | module_init(ds1307_init); | ||
919 | |||
920 | static void __exit ds1307_exit(void) | ||
921 | { | ||
922 | i2c_del_driver(&ds1307_driver); | ||
923 | } | ||
924 | module_exit(ds1307_exit); | ||
971 | 925 | ||
972 | MODULE_DESCRIPTION("RTC driver for DS1307 and similar chips"); | 926 | MODULE_DESCRIPTION("RTC driver for DS1307 and similar chips"); |
973 | MODULE_LICENSE("GPL"); | 927 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index fef76868aae..e6e71deb188 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c | |||
@@ -391,7 +391,7 @@ out_free: | |||
391 | return ret; | 391 | return ret; |
392 | } | 392 | } |
393 | 393 | ||
394 | static int ds1374_remove(struct i2c_client *client) | 394 | static int __devexit ds1374_remove(struct i2c_client *client) |
395 | { | 395 | { |
396 | struct ds1374 *ds1374 = i2c_get_clientdata(client); | 396 | struct ds1374 *ds1374 = i2c_get_clientdata(client); |
397 | 397 | ||
@@ -442,11 +442,22 @@ static struct i2c_driver ds1374_driver = { | |||
442 | .pm = DS1374_PM, | 442 | .pm = DS1374_PM, |
443 | }, | 443 | }, |
444 | .probe = ds1374_probe, | 444 | .probe = ds1374_probe, |
445 | .remove = ds1374_remove, | 445 | .remove = __devexit_p(ds1374_remove), |
446 | .id_table = ds1374_id, | 446 | .id_table = ds1374_id, |
447 | }; | 447 | }; |
448 | 448 | ||
449 | module_i2c_driver(ds1374_driver); | 449 | static int __init ds1374_init(void) |
450 | { | ||
451 | return i2c_add_driver(&ds1374_driver); | ||
452 | } | ||
453 | |||
454 | static void __exit ds1374_exit(void) | ||
455 | { | ||
456 | i2c_del_driver(&ds1374_driver); | ||
457 | } | ||
458 | |||
459 | module_init(ds1374_init); | ||
460 | module_exit(ds1374_exit); | ||
450 | 461 | ||
451 | MODULE_AUTHOR("Scott Wood <scottwood@freescale.com>"); | 462 | MODULE_AUTHOR("Scott Wood <scottwood@freescale.com>"); |
452 | MODULE_DESCRIPTION("Maxim/Dallas DS1374 RTC Driver"); | 463 | MODULE_DESCRIPTION("Maxim/Dallas DS1374 RTC Driver"); |
diff --git a/drivers/rtc/rtc-ds1390.c b/drivers/rtc/rtc-ds1390.c index f994257981a..b038d2cfef2 100644 --- a/drivers/rtc/rtc-ds1390.c +++ b/drivers/rtc/rtc-ds1390.c | |||
@@ -121,7 +121,7 @@ static const struct rtc_class_ops ds1390_rtc_ops = { | |||
121 | .set_time = ds1390_set_time, | 121 | .set_time = ds1390_set_time, |
122 | }; | 122 | }; |
123 | 123 | ||
124 | static int ds1390_probe(struct spi_device *spi) | 124 | static int __devinit ds1390_probe(struct spi_device *spi) |
125 | { | 125 | { |
126 | unsigned char tmp; | 126 | unsigned char tmp; |
127 | struct ds1390 *chip; | 127 | struct ds1390 *chip; |
@@ -156,7 +156,7 @@ static int ds1390_probe(struct spi_device *spi) | |||
156 | return res; | 156 | return res; |
157 | } | 157 | } |
158 | 158 | ||
159 | static int ds1390_remove(struct spi_device *spi) | 159 | static int __devexit ds1390_remove(struct spi_device *spi) |
160 | { | 160 | { |
161 | struct ds1390 *chip = spi_get_drvdata(spi); | 161 | struct ds1390 *chip = spi_get_drvdata(spi); |
162 | 162 | ||
@@ -172,10 +172,20 @@ static struct spi_driver ds1390_driver = { | |||
172 | .owner = THIS_MODULE, | 172 | .owner = THIS_MODULE, |
173 | }, | 173 | }, |
174 | .probe = ds1390_probe, | 174 | .probe = ds1390_probe, |
175 | .remove = ds1390_remove, | 175 | .remove = __devexit_p(ds1390_remove), |
176 | }; | 176 | }; |
177 | 177 | ||
178 | module_spi_driver(ds1390_driver); | 178 | static __init int ds1390_init(void) |
179 | { | ||
180 | return spi_register_driver(&ds1390_driver); | ||
181 | } | ||
182 | module_init(ds1390_init); | ||
183 | |||
184 | static __exit void ds1390_exit(void) | ||
185 | { | ||
186 | spi_unregister_driver(&ds1390_driver); | ||
187 | } | ||
188 | module_exit(ds1390_exit); | ||
179 | 189 | ||
180 | MODULE_DESCRIPTION("Dallas/Maxim DS1390/93/94 SPI RTC driver"); | 190 | MODULE_DESCRIPTION("Dallas/Maxim DS1390/93/94 SPI RTC driver"); |
181 | MODULE_AUTHOR("Mark Jackson <mpfj@mimc.co.uk>"); | 191 | MODULE_AUTHOR("Mark Jackson <mpfj@mimc.co.uk>"); |
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index 6a3fcfe3b0e..568ad30617e 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/rtc.h> | 23 | #include <linux/rtc.h> |
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
26 | #include <linux/module.h> | ||
27 | 26 | ||
28 | #define DRV_VERSION "0.6" | 27 | #define DRV_VERSION "0.6" |
29 | 28 | ||
@@ -476,7 +475,8 @@ static struct bin_attribute ds1511_nvram_attr = { | |||
476 | .write = ds1511_nvram_write, | 475 | .write = ds1511_nvram_write, |
477 | }; | 476 | }; |
478 | 477 | ||
479 | static int ds1511_rtc_probe(struct platform_device *pdev) | 478 | static int __devinit |
479 | ds1511_rtc_probe(struct platform_device *pdev) | ||
480 | { | 480 | { |
481 | struct rtc_device *rtc; | 481 | struct rtc_device *rtc; |
482 | struct resource *res; | 482 | struct resource *res; |
@@ -531,7 +531,7 @@ static int ds1511_rtc_probe(struct platform_device *pdev) | |||
531 | if (pdata->irq > 0) { | 531 | if (pdata->irq > 0) { |
532 | rtc_read(RTC_CMD1); | 532 | rtc_read(RTC_CMD1); |
533 | if (devm_request_irq(&pdev->dev, pdata->irq, ds1511_interrupt, | 533 | if (devm_request_irq(&pdev->dev, pdata->irq, ds1511_interrupt, |
534 | IRQF_SHARED, pdev->name, pdev) < 0) { | 534 | IRQF_DISABLED | IRQF_SHARED, pdev->name, pdev) < 0) { |
535 | 535 | ||
536 | dev_warn(&pdev->dev, "interrupt not available.\n"); | 536 | dev_warn(&pdev->dev, "interrupt not available.\n"); |
537 | pdata->irq = 0; | 537 | pdata->irq = 0; |
@@ -550,7 +550,8 @@ static int ds1511_rtc_probe(struct platform_device *pdev) | |||
550 | return ret; | 550 | return ret; |
551 | } | 551 | } |
552 | 552 | ||
553 | static int ds1511_rtc_remove(struct platform_device *pdev) | 553 | static int __devexit |
554 | ds1511_rtc_remove(struct platform_device *pdev) | ||
554 | { | 555 | { |
555 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 556 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
556 | 557 | ||
@@ -571,14 +572,27 @@ MODULE_ALIAS("platform:ds1511"); | |||
571 | 572 | ||
572 | static struct platform_driver ds1511_rtc_driver = { | 573 | static struct platform_driver ds1511_rtc_driver = { |
573 | .probe = ds1511_rtc_probe, | 574 | .probe = ds1511_rtc_probe, |
574 | .remove = ds1511_rtc_remove, | 575 | .remove = __devexit_p(ds1511_rtc_remove), |
575 | .driver = { | 576 | .driver = { |
576 | .name = "ds1511", | 577 | .name = "ds1511", |
577 | .owner = THIS_MODULE, | 578 | .owner = THIS_MODULE, |
578 | }, | 579 | }, |
579 | }; | 580 | }; |
580 | 581 | ||
581 | module_platform_driver(ds1511_rtc_driver); | 582 | static int __init |
583 | ds1511_rtc_init(void) | ||
584 | { | ||
585 | return platform_driver_register(&ds1511_rtc_driver); | ||
586 | } | ||
587 | |||
588 | static void __exit | ||
589 | ds1511_rtc_exit(void) | ||
590 | { | ||
591 | platform_driver_unregister(&ds1511_rtc_driver); | ||
592 | } | ||
593 | |||
594 | module_init(ds1511_rtc_init); | ||
595 | module_exit(ds1511_rtc_exit); | ||
582 | 596 | ||
583 | MODULE_AUTHOR("Andrew Sharp <andy.sharp@lsi.com>"); | 597 | MODULE_AUTHOR("Andrew Sharp <andy.sharp@lsi.com>"); |
584 | MODULE_DESCRIPTION("Dallas DS1511 RTC driver"); | 598 | MODULE_DESCRIPTION("Dallas DS1511 RTC driver"); |
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index 25ce0621ade..fee41b97c9e 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/rtc.h> | 18 | #include <linux/rtc.h> |
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/module.h> | ||
22 | 21 | ||
23 | #define DRV_VERSION "0.3" | 22 | #define DRV_VERSION "0.3" |
24 | 23 | ||
@@ -276,7 +275,7 @@ static struct bin_attribute ds1553_nvram_attr = { | |||
276 | .write = ds1553_nvram_write, | 275 | .write = ds1553_nvram_write, |
277 | }; | 276 | }; |
278 | 277 | ||
279 | static int ds1553_rtc_probe(struct platform_device *pdev) | 278 | static int __devinit ds1553_rtc_probe(struct platform_device *pdev) |
280 | { | 279 | { |
281 | struct rtc_device *rtc; | 280 | struct rtc_device *rtc; |
282 | struct resource *res; | 281 | struct resource *res; |
@@ -320,7 +319,7 @@ static int ds1553_rtc_probe(struct platform_device *pdev) | |||
320 | writeb(0, ioaddr + RTC_INTERRUPTS); | 319 | writeb(0, ioaddr + RTC_INTERRUPTS); |
321 | if (devm_request_irq(&pdev->dev, pdata->irq, | 320 | if (devm_request_irq(&pdev->dev, pdata->irq, |
322 | ds1553_rtc_interrupt, | 321 | ds1553_rtc_interrupt, |
323 | 0, pdev->name, pdev) < 0) { | 322 | IRQF_DISABLED, pdev->name, pdev) < 0) { |
324 | dev_warn(&pdev->dev, "interrupt not available.\n"); | 323 | dev_warn(&pdev->dev, "interrupt not available.\n"); |
325 | pdata->irq = 0; | 324 | pdata->irq = 0; |
326 | } | 325 | } |
@@ -338,7 +337,7 @@ static int ds1553_rtc_probe(struct platform_device *pdev) | |||
338 | return ret; | 337 | return ret; |
339 | } | 338 | } |
340 | 339 | ||
341 | static int ds1553_rtc_remove(struct platform_device *pdev) | 340 | static int __devexit ds1553_rtc_remove(struct platform_device *pdev) |
342 | { | 341 | { |
343 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 342 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
344 | 343 | ||
@@ -354,14 +353,25 @@ MODULE_ALIAS("platform:rtc-ds1553"); | |||
354 | 353 | ||
355 | static struct platform_driver ds1553_rtc_driver = { | 354 | static struct platform_driver ds1553_rtc_driver = { |
356 | .probe = ds1553_rtc_probe, | 355 | .probe = ds1553_rtc_probe, |
357 | .remove = ds1553_rtc_remove, | 356 | .remove = __devexit_p(ds1553_rtc_remove), |
358 | .driver = { | 357 | .driver = { |
359 | .name = "rtc-ds1553", | 358 | .name = "rtc-ds1553", |
360 | .owner = THIS_MODULE, | 359 | .owner = THIS_MODULE, |
361 | }, | 360 | }, |
362 | }; | 361 | }; |
363 | 362 | ||
364 | module_platform_driver(ds1553_rtc_driver); | 363 | static __init int ds1553_init(void) |
364 | { | ||
365 | return platform_driver_register(&ds1553_rtc_driver); | ||
366 | } | ||
367 | |||
368 | static __exit void ds1553_exit(void) | ||
369 | { | ||
370 | platform_driver_unregister(&ds1553_rtc_driver); | ||
371 | } | ||
372 | |||
373 | module_init(ds1553_init); | ||
374 | module_exit(ds1553_exit); | ||
365 | 375 | ||
366 | MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); | 376 | MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); |
367 | MODULE_DESCRIPTION("Dallas DS1553 RTC driver"); | 377 | MODULE_DESCRIPTION("Dallas DS1553 RTC driver"); |
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c index 45d65c0b3a8..06dfb54f99b 100644 --- a/drivers/rtc/rtc-ds1672.c +++ b/drivers/rtc/rtc-ds1672.c | |||
@@ -11,7 +11,6 @@ | |||
11 | 11 | ||
12 | #include <linux/i2c.h> | 12 | #include <linux/i2c.h> |
13 | #include <linux/rtc.h> | 13 | #include <linux/rtc.h> |
14 | #include <linux/module.h> | ||
15 | 14 | ||
16 | #define DRV_VERSION "0.4" | 15 | #define DRV_VERSION "0.4" |
17 | 16 | ||
@@ -37,17 +36,8 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
37 | unsigned char buf[4]; | 36 | unsigned char buf[4]; |
38 | 37 | ||
39 | struct i2c_msg msgs[] = { | 38 | struct i2c_msg msgs[] = { |
40 | {/* setup read ptr */ | 39 | {client->addr, 0, 1, &addr}, /* setup read ptr */ |
41 | .addr = client->addr, | 40 | {client->addr, I2C_M_RD, 4, buf}, /* read date */ |
42 | .len = 1, | ||
43 | .buf = &addr | ||
44 | }, | ||
45 | {/* read date */ | ||
46 | .addr = client->addr, | ||
47 | .flags = I2C_M_RD, | ||
48 | .len = 4, | ||
49 | .buf = buf | ||
50 | }, | ||
51 | }; | 41 | }; |
52 | 42 | ||
53 | /* read date registers */ | 43 | /* read date registers */ |
@@ -108,17 +98,8 @@ static int ds1672_get_control(struct i2c_client *client, u8 *status) | |||
108 | unsigned char addr = DS1672_REG_CONTROL; | 98 | unsigned char addr = DS1672_REG_CONTROL; |
109 | 99 | ||
110 | struct i2c_msg msgs[] = { | 100 | struct i2c_msg msgs[] = { |
111 | {/* setup read ptr */ | 101 | {client->addr, 0, 1, &addr}, /* setup read ptr */ |
112 | .addr = client->addr, | 102 | {client->addr, I2C_M_RD, 1, status}, /* read control */ |
113 | .len = 1, | ||
114 | .buf = &addr | ||
115 | }, | ||
116 | {/* read control */ | ||
117 | .addr = client->addr, | ||
118 | .flags = I2C_M_RD, | ||
119 | .len = 1, | ||
120 | .buf = status | ||
121 | }, | ||
122 | }; | 103 | }; |
123 | 104 | ||
124 | /* read control register */ | 105 | /* read control register */ |
@@ -220,9 +201,20 @@ static struct i2c_driver ds1672_driver = { | |||
220 | .id_table = ds1672_id, | 201 | .id_table = ds1672_id, |
221 | }; | 202 | }; |
222 | 203 | ||
223 | module_i2c_driver(ds1672_driver); | 204 | static int __init ds1672_init(void) |
205 | { | ||
206 | return i2c_add_driver(&ds1672_driver); | ||
207 | } | ||
208 | |||
209 | static void __exit ds1672_exit(void) | ||
210 | { | ||
211 | i2c_del_driver(&ds1672_driver); | ||
212 | } | ||
224 | 213 | ||
225 | MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); | 214 | MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); |
226 | MODULE_DESCRIPTION("Dallas/Maxim DS1672 timekeeper driver"); | 215 | MODULE_DESCRIPTION("Dallas/Maxim DS1672 timekeeper driver"); |
227 | MODULE_LICENSE("GPL"); | 216 | MODULE_LICENSE("GPL"); |
228 | MODULE_VERSION(DRV_VERSION); | 217 | MODULE_VERSION(DRV_VERSION); |
218 | |||
219 | module_init(ds1672_init); | ||
220 | module_exit(ds1672_exit); | ||
diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c index 609c870e2cc..d84a448dd75 100644 --- a/drivers/rtc/rtc-ds1742.c +++ b/drivers/rtc/rtc-ds1742.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/rtc.h> | 21 | #include <linux/rtc.h> |
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
24 | #include <linux/module.h> | ||
25 | 24 | ||
26 | #define DRV_VERSION "0.4" | 25 | #define DRV_VERSION "0.4" |
27 | 26 | ||
@@ -159,7 +158,7 @@ static ssize_t ds1742_nvram_write(struct file *filp, struct kobject *kobj, | |||
159 | return count; | 158 | return count; |
160 | } | 159 | } |
161 | 160 | ||
162 | static int ds1742_rtc_probe(struct platform_device *pdev) | 161 | static int __devinit ds1742_rtc_probe(struct platform_device *pdev) |
163 | { | 162 | { |
164 | struct rtc_device *rtc; | 163 | struct rtc_device *rtc; |
165 | struct resource *res; | 164 | struct resource *res; |
@@ -222,7 +221,7 @@ static int ds1742_rtc_probe(struct platform_device *pdev) | |||
222 | return ret; | 221 | return ret; |
223 | } | 222 | } |
224 | 223 | ||
225 | static int ds1742_rtc_remove(struct platform_device *pdev) | 224 | static int __devexit ds1742_rtc_remove(struct platform_device *pdev) |
226 | { | 225 | { |
227 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 226 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
228 | 227 | ||
@@ -233,14 +232,25 @@ static int ds1742_rtc_remove(struct platform_device *pdev) | |||
233 | 232 | ||
234 | static struct platform_driver ds1742_rtc_driver = { | 233 | static struct platform_driver ds1742_rtc_driver = { |
235 | .probe = ds1742_rtc_probe, | 234 | .probe = ds1742_rtc_probe, |
236 | .remove = ds1742_rtc_remove, | 235 | .remove = __devexit_p(ds1742_rtc_remove), |
237 | .driver = { | 236 | .driver = { |
238 | .name = "rtc-ds1742", | 237 | .name = "rtc-ds1742", |
239 | .owner = THIS_MODULE, | 238 | .owner = THIS_MODULE, |
240 | }, | 239 | }, |
241 | }; | 240 | }; |
242 | 241 | ||
243 | module_platform_driver(ds1742_rtc_driver); | 242 | static __init int ds1742_init(void) |
243 | { | ||
244 | return platform_driver_register(&ds1742_rtc_driver); | ||
245 | } | ||
246 | |||
247 | static __exit void ds1742_exit(void) | ||
248 | { | ||
249 | platform_driver_unregister(&ds1742_rtc_driver); | ||
250 | } | ||
251 | |||
252 | module_init(ds1742_init); | ||
253 | module_exit(ds1742_exit); | ||
244 | 254 | ||
245 | MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); | 255 | MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); |
246 | MODULE_DESCRIPTION("Dallas DS1742 RTC driver"); | 256 | MODULE_DESCRIPTION("Dallas DS1742 RTC driver"); |
diff --git a/drivers/rtc/rtc-ds2404.c b/drivers/rtc/rtc-ds2404.c deleted file mode 100644 index 5ea9df7c8c3..00000000000 --- a/drivers/rtc/rtc-ds2404.c +++ /dev/null | |||
@@ -1,303 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Sven Schnelle <svens@stackframe.org> | ||
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 version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #include <linux/platform_device.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/rtc.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/bcd.h> | ||
16 | #include <linux/rtc-ds2404.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/gpio.h> | ||
19 | #include <linux/slab.h> | ||
20 | |||
21 | #include <linux/io.h> | ||
22 | |||
23 | #define DS2404_STATUS_REG 0x200 | ||
24 | #define DS2404_CONTROL_REG 0x201 | ||
25 | #define DS2404_RTC_REG 0x202 | ||
26 | |||
27 | #define DS2404_WRITE_SCRATCHPAD_CMD 0x0f | ||
28 | #define DS2404_READ_SCRATCHPAD_CMD 0xaa | ||
29 | #define DS2404_COPY_SCRATCHPAD_CMD 0x55 | ||
30 | #define DS2404_READ_MEMORY_CMD 0xf0 | ||
31 | |||
32 | struct ds2404; | ||
33 | |||
34 | struct ds2404_chip_ops { | ||
35 | int (*map_io)(struct ds2404 *chip, struct platform_device *pdev, | ||
36 | struct ds2404_platform_data *pdata); | ||
37 | void (*unmap_io)(struct ds2404 *chip); | ||
38 | }; | ||
39 | |||
40 | #define DS2404_RST 0 | ||
41 | #define DS2404_CLK 1 | ||
42 | #define DS2404_DQ 2 | ||
43 | |||
44 | struct ds2404_gpio { | ||
45 | const char *name; | ||
46 | unsigned int gpio; | ||
47 | }; | ||
48 | |||
49 | struct ds2404 { | ||
50 | struct ds2404_gpio *gpio; | ||
51 | struct ds2404_chip_ops *ops; | ||
52 | struct rtc_device *rtc; | ||
53 | }; | ||
54 | |||
55 | static struct ds2404_gpio ds2404_gpio[] = { | ||
56 | { "RTC RST", 0 }, | ||
57 | { "RTC CLK", 0 }, | ||
58 | { "RTC DQ", 0 }, | ||
59 | }; | ||
60 | |||
61 | static int ds2404_gpio_map(struct ds2404 *chip, struct platform_device *pdev, | ||
62 | struct ds2404_platform_data *pdata) | ||
63 | { | ||
64 | int i, err; | ||
65 | |||
66 | ds2404_gpio[DS2404_RST].gpio = pdata->gpio_rst; | ||
67 | ds2404_gpio[DS2404_CLK].gpio = pdata->gpio_clk; | ||
68 | ds2404_gpio[DS2404_DQ].gpio = pdata->gpio_dq; | ||
69 | |||
70 | for (i = 0; i < ARRAY_SIZE(ds2404_gpio); i++) { | ||
71 | err = gpio_request(ds2404_gpio[i].gpio, ds2404_gpio[i].name); | ||
72 | if (err) { | ||
73 | printk(KERN_ERR "error mapping gpio %s: %d\n", | ||
74 | ds2404_gpio[i].name, err); | ||
75 | goto err_request; | ||
76 | } | ||
77 | if (i != DS2404_DQ) | ||
78 | gpio_direction_output(ds2404_gpio[i].gpio, 1); | ||
79 | } | ||
80 | |||
81 | chip->gpio = ds2404_gpio; | ||
82 | return 0; | ||
83 | |||
84 | err_request: | ||
85 | while (--i >= 0) | ||
86 | gpio_free(ds2404_gpio[i].gpio); | ||
87 | return err; | ||
88 | } | ||
89 | |||
90 | static void ds2404_gpio_unmap(struct ds2404 *chip) | ||
91 | { | ||
92 | int i; | ||
93 | |||
94 | for (i = 0; i < ARRAY_SIZE(ds2404_gpio); i++) | ||
95 | gpio_free(ds2404_gpio[i].gpio); | ||
96 | } | ||
97 | |||
98 | static struct ds2404_chip_ops ds2404_gpio_ops = { | ||
99 | .map_io = ds2404_gpio_map, | ||
100 | .unmap_io = ds2404_gpio_unmap, | ||
101 | }; | ||
102 | |||
103 | static void ds2404_reset(struct device *dev) | ||
104 | { | ||
105 | gpio_set_value(ds2404_gpio[DS2404_RST].gpio, 0); | ||
106 | udelay(1000); | ||
107 | gpio_set_value(ds2404_gpio[DS2404_RST].gpio, 1); | ||
108 | gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 0); | ||
109 | gpio_direction_output(ds2404_gpio[DS2404_DQ].gpio, 0); | ||
110 | udelay(10); | ||
111 | } | ||
112 | |||
113 | static void ds2404_write_byte(struct device *dev, u8 byte) | ||
114 | { | ||
115 | int i; | ||
116 | |||
117 | gpio_direction_output(ds2404_gpio[DS2404_DQ].gpio, 1); | ||
118 | for (i = 0; i < 8; i++) { | ||
119 | gpio_set_value(ds2404_gpio[DS2404_DQ].gpio, byte & (1 << i)); | ||
120 | udelay(10); | ||
121 | gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 1); | ||
122 | udelay(10); | ||
123 | gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 0); | ||
124 | udelay(10); | ||
125 | } | ||
126 | } | ||
127 | |||
128 | static u8 ds2404_read_byte(struct device *dev) | ||
129 | { | ||
130 | int i; | ||
131 | u8 ret = 0; | ||
132 | |||
133 | gpio_direction_input(ds2404_gpio[DS2404_DQ].gpio); | ||
134 | |||
135 | for (i = 0; i < 8; i++) { | ||
136 | gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 0); | ||
137 | udelay(10); | ||
138 | if (gpio_get_value(ds2404_gpio[DS2404_DQ].gpio)) | ||
139 | ret |= 1 << i; | ||
140 | gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 1); | ||
141 | udelay(10); | ||
142 | } | ||
143 | return ret; | ||
144 | } | ||
145 | |||
146 | static void ds2404_read_memory(struct device *dev, u16 offset, | ||
147 | int length, u8 *out) | ||
148 | { | ||
149 | ds2404_reset(dev); | ||
150 | ds2404_write_byte(dev, DS2404_READ_MEMORY_CMD); | ||
151 | ds2404_write_byte(dev, offset & 0xff); | ||
152 | ds2404_write_byte(dev, (offset >> 8) & 0xff); | ||
153 | while (length--) | ||
154 | *out++ = ds2404_read_byte(dev); | ||
155 | } | ||
156 | |||
157 | static void ds2404_write_memory(struct device *dev, u16 offset, | ||
158 | int length, u8 *out) | ||
159 | { | ||
160 | int i; | ||
161 | u8 ta01, ta02, es; | ||
162 | |||
163 | ds2404_reset(dev); | ||
164 | ds2404_write_byte(dev, DS2404_WRITE_SCRATCHPAD_CMD); | ||
165 | ds2404_write_byte(dev, offset & 0xff); | ||
166 | ds2404_write_byte(dev, (offset >> 8) & 0xff); | ||
167 | |||
168 | for (i = 0; i < length; i++) | ||
169 | ds2404_write_byte(dev, out[i]); | ||
170 | |||
171 | ds2404_reset(dev); | ||
172 | ds2404_write_byte(dev, DS2404_READ_SCRATCHPAD_CMD); | ||
173 | |||
174 | ta01 = ds2404_read_byte(dev); | ||
175 | ta02 = ds2404_read_byte(dev); | ||
176 | es = ds2404_read_byte(dev); | ||
177 | |||
178 | for (i = 0; i < length; i++) { | ||
179 | if (out[i] != ds2404_read_byte(dev)) { | ||
180 | printk(KERN_ERR "read invalid data\n"); | ||
181 | return; | ||
182 | } | ||
183 | } | ||
184 | |||
185 | ds2404_reset(dev); | ||
186 | ds2404_write_byte(dev, DS2404_COPY_SCRATCHPAD_CMD); | ||
187 | ds2404_write_byte(dev, ta01); | ||
188 | ds2404_write_byte(dev, ta02); | ||
189 | ds2404_write_byte(dev, es); | ||
190 | |||
191 | gpio_direction_input(ds2404_gpio[DS2404_DQ].gpio); | ||
192 | while (gpio_get_value(ds2404_gpio[DS2404_DQ].gpio)) | ||
193 | ; | ||
194 | } | ||
195 | |||
196 | static void ds2404_enable_osc(struct device *dev) | ||
197 | { | ||
198 | u8 in[1] = { 0x10 }; /* enable oscillator */ | ||
199 | ds2404_write_memory(dev, 0x201, 1, in); | ||
200 | } | ||
201 | |||
202 | static int ds2404_read_time(struct device *dev, struct rtc_time *dt) | ||
203 | { | ||
204 | unsigned long time = 0; | ||
205 | |||
206 | ds2404_read_memory(dev, 0x203, 4, (u8 *)&time); | ||
207 | time = le32_to_cpu(time); | ||
208 | |||
209 | rtc_time_to_tm(time, dt); | ||
210 | return rtc_valid_tm(dt); | ||
211 | } | ||
212 | |||
213 | static int ds2404_set_mmss(struct device *dev, unsigned long secs) | ||
214 | { | ||
215 | u32 time = cpu_to_le32(secs); | ||
216 | ds2404_write_memory(dev, 0x203, 4, (u8 *)&time); | ||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | static const struct rtc_class_ops ds2404_rtc_ops = { | ||
221 | .read_time = ds2404_read_time, | ||
222 | .set_mmss = ds2404_set_mmss, | ||
223 | }; | ||
224 | |||
225 | static int rtc_probe(struct platform_device *pdev) | ||
226 | { | ||
227 | struct ds2404_platform_data *pdata = pdev->dev.platform_data; | ||
228 | struct ds2404 *chip; | ||
229 | int retval = -EBUSY; | ||
230 | |||
231 | chip = kzalloc(sizeof(struct ds2404), GFP_KERNEL); | ||
232 | if (!chip) | ||
233 | return -ENOMEM; | ||
234 | |||
235 | chip->ops = &ds2404_gpio_ops; | ||
236 | |||
237 | retval = chip->ops->map_io(chip, pdev, pdata); | ||
238 | if (retval) | ||
239 | goto err_chip; | ||
240 | |||
241 | dev_info(&pdev->dev, "using GPIOs RST:%d, CLK:%d, DQ:%d\n", | ||
242 | chip->gpio[DS2404_RST].gpio, chip->gpio[DS2404_CLK].gpio, | ||
243 | chip->gpio[DS2404_DQ].gpio); | ||
244 | |||
245 | platform_set_drvdata(pdev, chip); | ||
246 | |||
247 | chip->rtc = rtc_device_register("ds2404", | ||
248 | &pdev->dev, &ds2404_rtc_ops, THIS_MODULE); | ||
249 | if (IS_ERR(chip->rtc)) { | ||
250 | retval = PTR_ERR(chip->rtc); | ||
251 | goto err_io; | ||
252 | } | ||
253 | |||
254 | ds2404_enable_osc(&pdev->dev); | ||
255 | return 0; | ||
256 | |||
257 | err_io: | ||
258 | chip->ops->unmap_io(chip); | ||
259 | err_chip: | ||
260 | kfree(chip); | ||
261 | return retval; | ||
262 | } | ||
263 | |||
264 | static int rtc_remove(struct platform_device *dev) | ||
265 | { | ||
266 | struct ds2404 *chip = platform_get_drvdata(dev); | ||
267 | struct rtc_device *rtc = chip->rtc; | ||
268 | |||
269 | if (rtc) | ||
270 | rtc_device_unregister(rtc); | ||
271 | |||
272 | chip->ops->unmap_io(chip); | ||
273 | kfree(chip); | ||
274 | |||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | static struct platform_driver rtc_device_driver = { | ||
279 | .probe = rtc_probe, | ||
280 | .remove = rtc_remove, | ||
281 | .driver = { | ||
282 | .name = "ds2404", | ||
283 | .owner = THIS_MODULE, | ||
284 | }, | ||
285 | }; | ||
286 | |||
287 | static __init int ds2404_init(void) | ||
288 | { | ||
289 | return platform_driver_register(&rtc_device_driver); | ||
290 | } | ||
291 | |||
292 | static __exit void ds2404_exit(void) | ||
293 | { | ||
294 | platform_driver_unregister(&rtc_device_driver); | ||
295 | } | ||
296 | |||
297 | module_init(ds2404_init); | ||
298 | module_exit(ds2404_exit); | ||
299 | |||
300 | MODULE_DESCRIPTION("DS2404 RTC"); | ||
301 | MODULE_AUTHOR("Sven Schnelle"); | ||
302 | MODULE_LICENSE("GPL"); | ||
303 | MODULE_ALIAS("platform:ds2404"); | ||
diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index db0ca08db31..27b7bf672ac 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c | |||
@@ -391,8 +391,8 @@ static const struct rtc_class_ops ds3232_rtc_ops = { | |||
391 | .alarm_irq_enable = ds3232_alarm_irq_enable, | 391 | .alarm_irq_enable = ds3232_alarm_irq_enable, |
392 | }; | 392 | }; |
393 | 393 | ||
394 | static int ds3232_probe(struct i2c_client *client, | 394 | static int __devinit ds3232_probe(struct i2c_client *client, |
395 | const struct i2c_device_id *id) | 395 | const struct i2c_device_id *id) |
396 | { | 396 | { |
397 | struct ds3232 *ds3232; | 397 | struct ds3232 *ds3232; |
398 | int ret; | 398 | int ret; |
@@ -439,7 +439,7 @@ out_free: | |||
439 | return ret; | 439 | return ret; |
440 | } | 440 | } |
441 | 441 | ||
442 | static int ds3232_remove(struct i2c_client *client) | 442 | static int __devexit ds3232_remove(struct i2c_client *client) |
443 | { | 443 | { |
444 | struct ds3232 *ds3232 = i2c_get_clientdata(client); | 444 | struct ds3232 *ds3232 = i2c_get_clientdata(client); |
445 | 445 | ||
@@ -469,11 +469,22 @@ static struct i2c_driver ds3232_driver = { | |||
469 | .owner = THIS_MODULE, | 469 | .owner = THIS_MODULE, |
470 | }, | 470 | }, |
471 | .probe = ds3232_probe, | 471 | .probe = ds3232_probe, |
472 | .remove = ds3232_remove, | 472 | .remove = __devexit_p(ds3232_remove), |
473 | .id_table = ds3232_id, | 473 | .id_table = ds3232_id, |
474 | }; | 474 | }; |
475 | 475 | ||
476 | module_i2c_driver(ds3232_driver); | 476 | static int __init ds3232_init(void) |
477 | { | ||
478 | return i2c_add_driver(&ds3232_driver); | ||
479 | } | ||
480 | |||
481 | static void __exit ds3232_exit(void) | ||
482 | { | ||
483 | i2c_del_driver(&ds3232_driver); | ||
484 | } | ||
485 | |||
486 | module_init(ds3232_init); | ||
487 | module_exit(ds3232_exit); | ||
477 | 488 | ||
478 | MODULE_AUTHOR("Srikanth Srinivasan <srikanth.srinivasan@freescale.com>"); | 489 | MODULE_AUTHOR("Srikanth Srinivasan <srikanth.srinivasan@freescale.com>"); |
479 | MODULE_DESCRIPTION("Maxim/Dallas DS3232 RTC Driver"); | 490 | MODULE_DESCRIPTION("Maxim/Dallas DS3232 RTC Driver"); |
diff --git a/drivers/rtc/rtc-ds3234.c b/drivers/rtc/rtc-ds3234.c index 7a4495ef1c3..bbd26228f53 100644 --- a/drivers/rtc/rtc-ds3234.c +++ b/drivers/rtc/rtc-ds3234.c | |||
@@ -105,7 +105,7 @@ static const struct rtc_class_ops ds3234_rtc_ops = { | |||
105 | .set_time = ds3234_set_time, | 105 | .set_time = ds3234_set_time, |
106 | }; | 106 | }; |
107 | 107 | ||
108 | static int ds3234_probe(struct spi_device *spi) | 108 | static int __devinit ds3234_probe(struct spi_device *spi) |
109 | { | 109 | { |
110 | struct rtc_device *rtc; | 110 | struct rtc_device *rtc; |
111 | unsigned char tmp; | 111 | unsigned char tmp; |
@@ -156,7 +156,7 @@ static int ds3234_probe(struct spi_device *spi) | |||
156 | return 0; | 156 | return 0; |
157 | } | 157 | } |
158 | 158 | ||
159 | static int ds3234_remove(struct spi_device *spi) | 159 | static int __devexit ds3234_remove(struct spi_device *spi) |
160 | { | 160 | { |
161 | struct rtc_device *rtc = spi_get_drvdata(spi); | 161 | struct rtc_device *rtc = spi_get_drvdata(spi); |
162 | 162 | ||
@@ -170,10 +170,20 @@ static struct spi_driver ds3234_driver = { | |||
170 | .owner = THIS_MODULE, | 170 | .owner = THIS_MODULE, |
171 | }, | 171 | }, |
172 | .probe = ds3234_probe, | 172 | .probe = ds3234_probe, |
173 | .remove = ds3234_remove, | 173 | .remove = __devexit_p(ds3234_remove), |
174 | }; | 174 | }; |
175 | 175 | ||
176 | module_spi_driver(ds3234_driver); | 176 | static __init int ds3234_init(void) |
177 | { | ||
178 | return spi_register_driver(&ds3234_driver); | ||
179 | } | ||
180 | module_init(ds3234_init); | ||
181 | |||
182 | static __exit void ds3234_exit(void) | ||
183 | { | ||
184 | spi_unregister_driver(&ds3234_driver); | ||
185 | } | ||
186 | module_exit(ds3234_exit); | ||
177 | 187 | ||
178 | MODULE_DESCRIPTION("DS3234 SPI RTC driver"); | 188 | MODULE_DESCRIPTION("DS3234 SPI RTC driver"); |
179 | MODULE_AUTHOR("Dennis Aberilla <denzzzhome@yahoo.com>"); | 189 | MODULE_AUTHOR("Dennis Aberilla <denzzzhome@yahoo.com>"); |
diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c index c9f890b088d..550292304b0 100644 --- a/drivers/rtc/rtc-efi.c +++ b/drivers/rtc/rtc-efi.c | |||
@@ -213,6 +213,7 @@ static struct platform_driver efi_rtc_driver = { | |||
213 | .name = "rtc-efi", | 213 | .name = "rtc-efi", |
214 | .owner = THIS_MODULE, | 214 | .owner = THIS_MODULE, |
215 | }, | 215 | }, |
216 | .probe = efi_rtc_probe, | ||
216 | .remove = __exit_p(efi_rtc_remove), | 217 | .remove = __exit_p(efi_rtc_remove), |
217 | }; | 218 | }; |
218 | 219 | ||
diff --git a/drivers/rtc/rtc-em3027.c b/drivers/rtc/rtc-em3027.c index f6c24ce35d3..d8e1c257855 100644 --- a/drivers/rtc/rtc-em3027.c +++ b/drivers/rtc/rtc-em3027.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/i2c.h> | 14 | #include <linux/i2c.h> |
15 | #include <linux/rtc.h> | 15 | #include <linux/rtc.h> |
16 | #include <linux/bcd.h> | 16 | #include <linux/bcd.h> |
17 | #include <linux/module.h> | ||
18 | 17 | ||
19 | /* Registers */ | 18 | /* Registers */ |
20 | #define EM3027_REG_ON_OFF_CTRL 0x00 | 19 | #define EM3027_REG_ON_OFF_CTRL 0x00 |
@@ -49,17 +48,8 @@ static int em3027_get_time(struct device *dev, struct rtc_time *tm) | |||
49 | unsigned char buf[7]; | 48 | unsigned char buf[7]; |
50 | 49 | ||
51 | struct i2c_msg msgs[] = { | 50 | struct i2c_msg msgs[] = { |
52 | {/* setup read addr */ | 51 | {client->addr, 0, 1, &addr}, /* setup read addr */ |
53 | .addr = client->addr, | 52 | {client->addr, I2C_M_RD, 7, buf}, /* read time/date */ |
54 | .len = 1, | ||
55 | .buf = &addr | ||
56 | }, | ||
57 | {/* read time/date */ | ||
58 | .addr = client->addr, | ||
59 | .flags = I2C_M_RD, | ||
60 | .len = 7, | ||
61 | .buf = buf | ||
62 | }, | ||
63 | }; | 53 | }; |
64 | 54 | ||
65 | /* read time/date registers */ | 55 | /* read time/date registers */ |
@@ -85,9 +75,7 @@ static int em3027_set_time(struct device *dev, struct rtc_time *tm) | |||
85 | unsigned char buf[8]; | 75 | unsigned char buf[8]; |
86 | 76 | ||
87 | struct i2c_msg msg = { | 77 | struct i2c_msg msg = { |
88 | .addr = client->addr, | 78 | client->addr, 0, 8, buf, /* write time/date */ |
89 | .len = 8, | ||
90 | .buf = buf, /* write time/date */ | ||
91 | }; | 79 | }; |
92 | 80 | ||
93 | buf[0] = EM3027_REG_WATCH_SEC; | 81 | buf[0] = EM3027_REG_WATCH_SEC; |
@@ -155,8 +143,19 @@ static struct i2c_driver em3027_driver = { | |||
155 | .id_table = em3027_id, | 143 | .id_table = em3027_id, |
156 | }; | 144 | }; |
157 | 145 | ||
158 | module_i2c_driver(em3027_driver); | 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 | } | ||
159 | 155 | ||
160 | MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>"); | 156 | MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>"); |
161 | MODULE_DESCRIPTION("EM Microelectronic EM3027 RTC driver"); | 157 | MODULE_DESCRIPTION("EM Microelectronic EM3027 RTC driver"); |
162 | MODULE_LICENSE("GPL"); | 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 1a4e5e4a70c..14a42a1edc6 100644 --- a/drivers/rtc/rtc-ep93xx.c +++ b/drivers/rtc/rtc-ep93xx.c | |||
@@ -127,7 +127,7 @@ static const struct attribute_group ep93xx_rtc_sysfs_files = { | |||
127 | .attrs = ep93xx_rtc_attrs, | 127 | .attrs = ep93xx_rtc_attrs, |
128 | }; | 128 | }; |
129 | 129 | ||
130 | static int ep93xx_rtc_probe(struct platform_device *pdev) | 130 | static int __init ep93xx_rtc_probe(struct platform_device *pdev) |
131 | { | 131 | { |
132 | struct ep93xx_rtc *ep93xx_rtc; | 132 | struct ep93xx_rtc *ep93xx_rtc; |
133 | struct resource *res; | 133 | struct resource *res; |
@@ -174,7 +174,7 @@ exit: | |||
174 | return err; | 174 | return err; |
175 | } | 175 | } |
176 | 176 | ||
177 | static int ep93xx_rtc_remove(struct platform_device *pdev) | 177 | static int __exit ep93xx_rtc_remove(struct platform_device *pdev) |
178 | { | 178 | { |
179 | struct ep93xx_rtc *ep93xx_rtc = platform_get_drvdata(pdev); | 179 | struct ep93xx_rtc *ep93xx_rtc = platform_get_drvdata(pdev); |
180 | 180 | ||
@@ -186,19 +186,31 @@ static int ep93xx_rtc_remove(struct platform_device *pdev) | |||
186 | return 0; | 186 | return 0; |
187 | } | 187 | } |
188 | 188 | ||
189 | /* work with hotplug and coldplug */ | ||
190 | MODULE_ALIAS("platform:ep93xx-rtc"); | ||
191 | |||
189 | static struct platform_driver ep93xx_rtc_driver = { | 192 | static struct platform_driver ep93xx_rtc_driver = { |
190 | .driver = { | 193 | .driver = { |
191 | .name = "ep93xx-rtc", | 194 | .name = "ep93xx-rtc", |
192 | .owner = THIS_MODULE, | 195 | .owner = THIS_MODULE, |
193 | }, | 196 | }, |
194 | .probe = ep93xx_rtc_probe, | 197 | .remove = __exit_p(ep93xx_rtc_remove), |
195 | .remove = ep93xx_rtc_remove, | ||
196 | }; | 198 | }; |
197 | 199 | ||
198 | module_platform_driver(ep93xx_rtc_driver); | 200 | static int __init ep93xx_rtc_init(void) |
201 | { | ||
202 | return platform_driver_probe(&ep93xx_rtc_driver, ep93xx_rtc_probe); | ||
203 | } | ||
204 | |||
205 | static void __exit ep93xx_rtc_exit(void) | ||
206 | { | ||
207 | platform_driver_unregister(&ep93xx_rtc_driver); | ||
208 | } | ||
199 | 209 | ||
200 | MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); | 210 | MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); |
201 | MODULE_DESCRIPTION("EP93XX RTC driver"); | 211 | MODULE_DESCRIPTION("EP93XX RTC driver"); |
202 | MODULE_LICENSE("GPL"); | 212 | MODULE_LICENSE("GPL"); |
203 | MODULE_VERSION(DRV_VERSION); | 213 | MODULE_VERSION(DRV_VERSION); |
204 | MODULE_ALIAS("platform:ep93xx-rtc"); | 214 | |
215 | module_init(ep93xx_rtc_init); | ||
216 | module_exit(ep93xx_rtc_exit); | ||
diff --git a/drivers/rtc/rtc-fm3130.c b/drivers/rtc/rtc-fm3130.c index 04e93c6597f..4cf2e70c507 100644 --- a/drivers/rtc/rtc-fm3130.c +++ b/drivers/rtc/rtc-fm3130.c | |||
@@ -361,8 +361,8 @@ static const struct rtc_class_ops fm3130_rtc_ops = { | |||
361 | 361 | ||
362 | static struct i2c_driver fm3130_driver; | 362 | static struct i2c_driver fm3130_driver; |
363 | 363 | ||
364 | static int fm3130_probe(struct i2c_client *client, | 364 | static int __devinit fm3130_probe(struct i2c_client *client, |
365 | const struct i2c_device_id *id) | 365 | const struct i2c_device_id *id) |
366 | { | 366 | { |
367 | struct fm3130 *fm3130; | 367 | struct fm3130 *fm3130; |
368 | int err = -ENODEV; | 368 | int err = -ENODEV; |
@@ -546,7 +546,7 @@ exit_free: | |||
546 | return err; | 546 | return err; |
547 | } | 547 | } |
548 | 548 | ||
549 | static int fm3130_remove(struct i2c_client *client) | 549 | static int __devexit fm3130_remove(struct i2c_client *client) |
550 | { | 550 | { |
551 | struct fm3130 *fm3130 = i2c_get_clientdata(client); | 551 | struct fm3130 *fm3130 = i2c_get_clientdata(client); |
552 | 552 | ||
@@ -561,11 +561,21 @@ static struct i2c_driver fm3130_driver = { | |||
561 | .owner = THIS_MODULE, | 561 | .owner = THIS_MODULE, |
562 | }, | 562 | }, |
563 | .probe = fm3130_probe, | 563 | .probe = fm3130_probe, |
564 | .remove = fm3130_remove, | 564 | .remove = __devexit_p(fm3130_remove), |
565 | .id_table = fm3130_id, | 565 | .id_table = fm3130_id, |
566 | }; | 566 | }; |
567 | 567 | ||
568 | module_i2c_driver(fm3130_driver); | 568 | static int __init fm3130_init(void) |
569 | { | ||
570 | return i2c_add_driver(&fm3130_driver); | ||
571 | } | ||
572 | module_init(fm3130_init); | ||
573 | |||
574 | static void __exit fm3130_exit(void) | ||
575 | { | ||
576 | i2c_del_driver(&fm3130_driver); | ||
577 | } | ||
578 | module_exit(fm3130_exit); | ||
569 | 579 | ||
570 | MODULE_DESCRIPTION("RTC driver for FM3130"); | 580 | MODULE_DESCRIPTION("RTC driver for FM3130"); |
571 | MODULE_AUTHOR("Sergey Lapin <slapin@ossfans.org>"); | 581 | MODULE_AUTHOR("Sergey Lapin <slapin@ossfans.org>"); |
diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c index 75d307ab37f..d93a9608b1f 100644 --- a/drivers/rtc/rtc-imxdi.c +++ b/drivers/rtc/rtc-imxdi.c | |||
@@ -36,9 +36,7 @@ | |||
36 | #include <linux/platform_device.h> | 36 | #include <linux/platform_device.h> |
37 | #include <linux/rtc.h> | 37 | #include <linux/rtc.h> |
38 | #include <linux/sched.h> | 38 | #include <linux/sched.h> |
39 | #include <linux/spinlock.h> | ||
40 | #include <linux/workqueue.h> | 39 | #include <linux/workqueue.h> |
41 | #include <linux/of.h> | ||
42 | 40 | ||
43 | /* DryIce Register Definitions */ | 41 | /* DryIce Register Definitions */ |
44 | 42 | ||
@@ -394,8 +392,6 @@ static int dryice_rtc_probe(struct platform_device *pdev) | |||
394 | if (imxdi->ioaddr == NULL) | 392 | if (imxdi->ioaddr == NULL) |
395 | return -ENOMEM; | 393 | return -ENOMEM; |
396 | 394 | ||
397 | spin_lock_init(&imxdi->irq_lock); | ||
398 | |||
399 | imxdi->irq = platform_get_irq(pdev, 0); | 395 | imxdi->irq = platform_get_irq(pdev, 0); |
400 | if (imxdi->irq < 0) | 396 | if (imxdi->irq < 0) |
401 | return imxdi->irq; | 397 | return imxdi->irq; |
@@ -409,7 +405,7 @@ static int dryice_rtc_probe(struct platform_device *pdev) | |||
409 | imxdi->clk = clk_get(&pdev->dev, NULL); | 405 | imxdi->clk = clk_get(&pdev->dev, NULL); |
410 | if (IS_ERR(imxdi->clk)) | 406 | if (IS_ERR(imxdi->clk)) |
411 | return PTR_ERR(imxdi->clk); | 407 | return PTR_ERR(imxdi->clk); |
412 | clk_prepare_enable(imxdi->clk); | 408 | clk_enable(imxdi->clk); |
413 | 409 | ||
414 | /* | 410 | /* |
415 | * Initialize dryice hardware | 411 | * Initialize dryice hardware |
@@ -474,13 +470,13 @@ static int dryice_rtc_probe(struct platform_device *pdev) | |||
474 | return 0; | 470 | return 0; |
475 | 471 | ||
476 | err: | 472 | err: |
477 | clk_disable_unprepare(imxdi->clk); | 473 | clk_disable(imxdi->clk); |
478 | clk_put(imxdi->clk); | 474 | clk_put(imxdi->clk); |
479 | 475 | ||
480 | return rc; | 476 | return rc; |
481 | } | 477 | } |
482 | 478 | ||
483 | static int dryice_rtc_remove(struct platform_device *pdev) | 479 | static int __devexit dryice_rtc_remove(struct platform_device *pdev) |
484 | { | 480 | { |
485 | struct imxdi_dev *imxdi = platform_get_drvdata(pdev); | 481 | struct imxdi_dev *imxdi = platform_get_drvdata(pdev); |
486 | 482 | ||
@@ -491,28 +487,18 @@ static int dryice_rtc_remove(struct platform_device *pdev) | |||
491 | 487 | ||
492 | rtc_device_unregister(imxdi->rtc); | 488 | rtc_device_unregister(imxdi->rtc); |
493 | 489 | ||
494 | clk_disable_unprepare(imxdi->clk); | 490 | clk_disable(imxdi->clk); |
495 | clk_put(imxdi->clk); | 491 | clk_put(imxdi->clk); |
496 | 492 | ||
497 | return 0; | 493 | return 0; |
498 | } | 494 | } |
499 | 495 | ||
500 | #ifdef CONFIG_OF | ||
501 | static const struct of_device_id dryice_dt_ids[] = { | ||
502 | { .compatible = "fsl,imx25-rtc" }, | ||
503 | { /* sentinel */ } | ||
504 | }; | ||
505 | |||
506 | MODULE_DEVICE_TABLE(of, dryice_dt_ids); | ||
507 | #endif | ||
508 | |||
509 | static struct platform_driver dryice_rtc_driver = { | 496 | static struct platform_driver dryice_rtc_driver = { |
510 | .driver = { | 497 | .driver = { |
511 | .name = "imxdi_rtc", | 498 | .name = "imxdi_rtc", |
512 | .owner = THIS_MODULE, | 499 | .owner = THIS_MODULE, |
513 | .of_match_table = of_match_ptr(dryice_dt_ids), | ||
514 | }, | 500 | }, |
515 | .remove = dryice_rtc_remove, | 501 | .remove = __devexit_p(dryice_rtc_remove), |
516 | }; | 502 | }; |
517 | 503 | ||
518 | static int __init dryice_rtc_init(void) | 504 | static int __init dryice_rtc_init(void) |
diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c index 1850104705c..ddbc797ea6c 100644 --- a/drivers/rtc/rtc-isl12022.c +++ b/drivers/rtc/rtc-isl12022.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/bcd.h> | 15 | #include <linux/bcd.h> |
16 | #include <linux/rtc.h> | 16 | #include <linux/rtc.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/module.h> | ||
19 | 18 | ||
20 | #define DRV_VERSION "0.1" | 19 | #define DRV_VERSION "0.1" |
21 | 20 | ||
@@ -309,7 +308,18 @@ static struct i2c_driver isl12022_driver = { | |||
309 | .id_table = isl12022_id, | 308 | .id_table = isl12022_id, |
310 | }; | 309 | }; |
311 | 310 | ||
312 | module_i2c_driver(isl12022_driver); | 311 | static int __init isl12022_init(void) |
312 | { | ||
313 | return i2c_add_driver(&isl12022_driver); | ||
314 | } | ||
315 | |||
316 | static void __exit isl12022_exit(void) | ||
317 | { | ||
318 | i2c_del_driver(&isl12022_driver); | ||
319 | } | ||
320 | |||
321 | module_init(isl12022_init); | ||
322 | module_exit(isl12022_exit); | ||
313 | 323 | ||
314 | MODULE_AUTHOR("roman.fietze@telemotive.de"); | 324 | MODULE_AUTHOR("roman.fietze@telemotive.de"); |
315 | MODULE_DESCRIPTION("ISL 12022 RTC driver"); | 325 | MODULE_DESCRIPTION("ISL 12022 RTC driver"); |
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index afb7cfa85cc..da8beb8cae5 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c | |||
@@ -68,17 +68,9 @@ isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[], | |||
68 | { | 68 | { |
69 | u8 reg_addr[1] = { reg }; | 69 | u8 reg_addr[1] = { reg }; |
70 | struct i2c_msg msgs[2] = { | 70 | struct i2c_msg msgs[2] = { |
71 | { | 71 | {client->addr, 0, sizeof(reg_addr), reg_addr} |
72 | .addr = client->addr, | 72 | , |
73 | .len = sizeof(reg_addr), | 73 | {client->addr, I2C_M_RD, len, buf} |
74 | .buf = reg_addr | ||
75 | }, | ||
76 | { | ||
77 | .addr = client->addr, | ||
78 | .flags = I2C_M_RD, | ||
79 | .len = len, | ||
80 | .buf = buf | ||
81 | } | ||
82 | }; | 74 | }; |
83 | int ret; | 75 | int ret; |
84 | 76 | ||
@@ -98,11 +90,7 @@ isl1208_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[], | |||
98 | { | 90 | { |
99 | u8 i2c_buf[ISL1208_REG_USR2 + 2]; | 91 | u8 i2c_buf[ISL1208_REG_USR2 + 2]; |
100 | struct i2c_msg msgs[1] = { | 92 | struct i2c_msg msgs[1] = { |
101 | { | 93 | {client->addr, 0, len + 1, i2c_buf} |
102 | .addr = client->addr, | ||
103 | .len = len + 1, | ||
104 | .buf = i2c_buf | ||
105 | } | ||
106 | }; | 94 | }; |
107 | int ret; | 95 | int ret; |
108 | 96 | ||
@@ -118,7 +106,7 @@ isl1208_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[], | |||
118 | return ret; | 106 | return ret; |
119 | } | 107 | } |
120 | 108 | ||
121 | /* simple check to see whether we have a isl1208 */ | 109 | /* simple check to see wether we have a isl1208 */ |
122 | static int | 110 | static int |
123 | isl1208_i2c_validate_client(struct i2c_client *client) | 111 | isl1208_i2c_validate_client(struct i2c_client *client) |
124 | { | 112 | { |
@@ -709,7 +697,6 @@ isl1208_remove(struct i2c_client *client) | |||
709 | 697 | ||
710 | static const struct i2c_device_id isl1208_id[] = { | 698 | static const struct i2c_device_id isl1208_id[] = { |
711 | { "isl1208", 0 }, | 699 | { "isl1208", 0 }, |
712 | { "isl1218", 0 }, | ||
713 | { } | 700 | { } |
714 | }; | 701 | }; |
715 | MODULE_DEVICE_TABLE(i2c, isl1208_id); | 702 | MODULE_DEVICE_TABLE(i2c, isl1208_id); |
@@ -723,9 +710,22 @@ static struct i2c_driver isl1208_driver = { | |||
723 | .id_table = isl1208_id, | 710 | .id_table = isl1208_id, |
724 | }; | 711 | }; |
725 | 712 | ||
726 | module_i2c_driver(isl1208_driver); | 713 | static int __init |
714 | isl1208_init(void) | ||
715 | { | ||
716 | return i2c_add_driver(&isl1208_driver); | ||
717 | } | ||
718 | |||
719 | static void __exit | ||
720 | isl1208_exit(void) | ||
721 | { | ||
722 | i2c_del_driver(&isl1208_driver); | ||
723 | } | ||
727 | 724 | ||
728 | MODULE_AUTHOR("Herbert Valerio Riedel <hvr@gnu.org>"); | 725 | MODULE_AUTHOR("Herbert Valerio Riedel <hvr@gnu.org>"); |
729 | MODULE_DESCRIPTION("Intersil ISL1208 RTC driver"); | 726 | MODULE_DESCRIPTION("Intersil ISL1208 RTC driver"); |
730 | MODULE_LICENSE("GPL"); | 727 | MODULE_LICENSE("GPL"); |
731 | MODULE_VERSION(DRV_VERSION); | 728 | MODULE_VERSION(DRV_VERSION); |
729 | |||
730 | module_init(isl1208_init); | ||
731 | module_exit(isl1208_exit); | ||
diff --git a/drivers/rtc/rtc-jz4740.c b/drivers/rtc/rtc-jz4740.c index 1e48686ca6d..b6473631d18 100644 --- a/drivers/rtc/rtc-jz4740.c +++ b/drivers/rtc/rtc-jz4740.c | |||
@@ -42,7 +42,7 @@ struct jz4740_rtc { | |||
42 | 42 | ||
43 | struct rtc_device *rtc; | 43 | struct rtc_device *rtc; |
44 | 44 | ||
45 | int irq; | 45 | unsigned int irq; |
46 | 46 | ||
47 | spinlock_t lock; | 47 | spinlock_t lock; |
48 | }; | 48 | }; |
@@ -210,7 +210,7 @@ void jz4740_rtc_poweroff(struct device *dev) | |||
210 | } | 210 | } |
211 | EXPORT_SYMBOL_GPL(jz4740_rtc_poweroff); | 211 | EXPORT_SYMBOL_GPL(jz4740_rtc_poweroff); |
212 | 212 | ||
213 | static int jz4740_rtc_probe(struct platform_device *pdev) | 213 | static int __devinit jz4740_rtc_probe(struct platform_device *pdev) |
214 | { | 214 | { |
215 | int ret; | 215 | int ret; |
216 | struct jz4740_rtc *rtc; | 216 | struct jz4740_rtc *rtc; |
@@ -297,7 +297,7 @@ err_free: | |||
297 | return ret; | 297 | return ret; |
298 | } | 298 | } |
299 | 299 | ||
300 | static int jz4740_rtc_remove(struct platform_device *pdev) | 300 | static int __devexit jz4740_rtc_remove(struct platform_device *pdev) |
301 | { | 301 | { |
302 | struct jz4740_rtc *rtc = platform_get_drvdata(pdev); | 302 | struct jz4740_rtc *rtc = platform_get_drvdata(pdev); |
303 | 303 | ||
@@ -345,9 +345,9 @@ static const struct dev_pm_ops jz4740_pm_ops = { | |||
345 | #define JZ4740_RTC_PM_OPS NULL | 345 | #define JZ4740_RTC_PM_OPS NULL |
346 | #endif /* CONFIG_PM */ | 346 | #endif /* CONFIG_PM */ |
347 | 347 | ||
348 | static struct platform_driver jz4740_rtc_driver = { | 348 | struct platform_driver jz4740_rtc_driver = { |
349 | .probe = jz4740_rtc_probe, | 349 | .probe = jz4740_rtc_probe, |
350 | .remove = jz4740_rtc_remove, | 350 | .remove = __devexit_p(jz4740_rtc_remove), |
351 | .driver = { | 351 | .driver = { |
352 | .name = "jz4740-rtc", | 352 | .name = "jz4740-rtc", |
353 | .owner = THIS_MODULE, | 353 | .owner = THIS_MODULE, |
@@ -355,7 +355,17 @@ static struct platform_driver jz4740_rtc_driver = { | |||
355 | }, | 355 | }, |
356 | }; | 356 | }; |
357 | 357 | ||
358 | module_platform_driver(jz4740_rtc_driver); | 358 | static int __init jz4740_rtc_init(void) |
359 | { | ||
360 | return platform_driver_register(&jz4740_rtc_driver); | ||
361 | } | ||
362 | module_init(jz4740_rtc_init); | ||
363 | |||
364 | static void __exit jz4740_rtc_exit(void) | ||
365 | { | ||
366 | platform_driver_unregister(&jz4740_rtc_driver); | ||
367 | } | ||
368 | module_exit(jz4740_rtc_exit); | ||
359 | 369 | ||
360 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | 370 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); |
361 | MODULE_LICENSE("GPL"); | 371 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/rtc/rtc-lpc32xx.c b/drivers/rtc/rtc-lpc32xx.c index 40a598332ba..ae16250c762 100644 --- a/drivers/rtc/rtc-lpc32xx.c +++ b/drivers/rtc/rtc-lpc32xx.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/rtc.h> | 19 | #include <linux/rtc.h> |
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | #include <linux/of.h> | ||
23 | 22 | ||
24 | /* | 23 | /* |
25 | * Clock and Power control register offsets | 24 | * Clock and Power control register offsets |
@@ -197,7 +196,7 @@ static const struct rtc_class_ops lpc32xx_rtc_ops = { | |||
197 | .alarm_irq_enable = lpc32xx_rtc_alarm_irq_enable, | 196 | .alarm_irq_enable = lpc32xx_rtc_alarm_irq_enable, |
198 | }; | 197 | }; |
199 | 198 | ||
200 | static int lpc32xx_rtc_probe(struct platform_device *pdev) | 199 | static int __devinit lpc32xx_rtc_probe(struct platform_device *pdev) |
201 | { | 200 | { |
202 | struct resource *res; | 201 | struct resource *res; |
203 | struct lpc32xx_rtc *rtc; | 202 | struct lpc32xx_rtc *rtc; |
@@ -288,7 +287,7 @@ static int lpc32xx_rtc_probe(struct platform_device *pdev) | |||
288 | if (rtc->irq >= 0) { | 287 | if (rtc->irq >= 0) { |
289 | if (devm_request_irq(&pdev->dev, rtc->irq, | 288 | if (devm_request_irq(&pdev->dev, rtc->irq, |
290 | lpc32xx_rtc_alarm_interrupt, | 289 | lpc32xx_rtc_alarm_interrupt, |
291 | 0, pdev->name, rtc) < 0) { | 290 | IRQF_DISABLED, pdev->name, rtc) < 0) { |
292 | dev_warn(&pdev->dev, "Can't request interrupt.\n"); | 291 | dev_warn(&pdev->dev, "Can't request interrupt.\n"); |
293 | rtc->irq = -1; | 292 | rtc->irq = -1; |
294 | } else { | 293 | } else { |
@@ -299,7 +298,7 @@ static int lpc32xx_rtc_probe(struct platform_device *pdev) | |||
299 | return 0; | 298 | return 0; |
300 | } | 299 | } |
301 | 300 | ||
302 | static int lpc32xx_rtc_remove(struct platform_device *pdev) | 301 | static int __devexit lpc32xx_rtc_remove(struct platform_device *pdev) |
303 | { | 302 | { |
304 | struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev); | 303 | struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev); |
305 | 304 | ||
@@ -387,26 +386,27 @@ static const struct dev_pm_ops lpc32xx_rtc_pm_ops = { | |||
387 | #define LPC32XX_RTC_PM_OPS NULL | 386 | #define LPC32XX_RTC_PM_OPS NULL |
388 | #endif | 387 | #endif |
389 | 388 | ||
390 | #ifdef CONFIG_OF | ||
391 | static const struct of_device_id lpc32xx_rtc_match[] = { | ||
392 | { .compatible = "nxp,lpc3220-rtc" }, | ||
393 | { } | ||
394 | }; | ||
395 | MODULE_DEVICE_TABLE(of, lpc32xx_rtc_match); | ||
396 | #endif | ||
397 | |||
398 | static struct platform_driver lpc32xx_rtc_driver = { | 389 | static struct platform_driver lpc32xx_rtc_driver = { |
399 | .probe = lpc32xx_rtc_probe, | 390 | .probe = lpc32xx_rtc_probe, |
400 | .remove = lpc32xx_rtc_remove, | 391 | .remove = __devexit_p(lpc32xx_rtc_remove), |
401 | .driver = { | 392 | .driver = { |
402 | .name = RTC_NAME, | 393 | .name = RTC_NAME, |
403 | .owner = THIS_MODULE, | 394 | .owner = THIS_MODULE, |
404 | .pm = LPC32XX_RTC_PM_OPS, | 395 | .pm = LPC32XX_RTC_PM_OPS |
405 | .of_match_table = of_match_ptr(lpc32xx_rtc_match), | ||
406 | }, | 396 | }, |
407 | }; | 397 | }; |
408 | 398 | ||
409 | module_platform_driver(lpc32xx_rtc_driver); | 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 | 410 | ||
411 | MODULE_AUTHOR("Kevin Wells <wellsk40@gmail.com"); | 411 | MODULE_AUTHOR("Kevin Wells <wellsk40@gmail.com"); |
412 | MODULE_DESCRIPTION("RTC driver for the LPC32xx SoC"); | 412 | MODULE_DESCRIPTION("RTC driver for the LPC32xx SoC"); |
diff --git a/drivers/rtc/rtc-ls1x.c b/drivers/rtc/rtc-ls1x.c deleted file mode 100644 index f59b6349551..00000000000 --- a/drivers/rtc/rtc-ls1x.c +++ /dev/null | |||
@@ -1,210 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Zhao Zhang <zhzhl555@gmail.com> | ||
3 | * | ||
4 | * Derived from driver/rtc/rtc-au1xxx.c | ||
5 | * | ||
6 | * 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 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/rtc.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/types.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <asm/mach-loongson1/loongson1.h> | ||
21 | |||
22 | #define LS1X_RTC_REG_OFFSET (LS1X_RTC_BASE + 0x20) | ||
23 | #define LS1X_RTC_REGS(x) \ | ||
24 | ((void __iomem *)KSEG1ADDR(LS1X_RTC_REG_OFFSET + (x))) | ||
25 | |||
26 | /*RTC programmable counters 0 and 1*/ | ||
27 | #define SYS_COUNTER_CNTRL (LS1X_RTC_REGS(0x20)) | ||
28 | #define SYS_CNTRL_ERS (1 << 23) | ||
29 | #define SYS_CNTRL_RTS (1 << 20) | ||
30 | #define SYS_CNTRL_RM2 (1 << 19) | ||
31 | #define SYS_CNTRL_RM1 (1 << 18) | ||
32 | #define SYS_CNTRL_RM0 (1 << 17) | ||
33 | #define SYS_CNTRL_RS (1 << 16) | ||
34 | #define SYS_CNTRL_BP (1 << 14) | ||
35 | #define SYS_CNTRL_REN (1 << 13) | ||
36 | #define SYS_CNTRL_BRT (1 << 12) | ||
37 | #define SYS_CNTRL_TEN (1 << 11) | ||
38 | #define SYS_CNTRL_BTT (1 << 10) | ||
39 | #define SYS_CNTRL_E0 (1 << 8) | ||
40 | #define SYS_CNTRL_ETS (1 << 7) | ||
41 | #define SYS_CNTRL_32S (1 << 5) | ||
42 | #define SYS_CNTRL_TTS (1 << 4) | ||
43 | #define SYS_CNTRL_TM2 (1 << 3) | ||
44 | #define SYS_CNTRL_TM1 (1 << 2) | ||
45 | #define SYS_CNTRL_TM0 (1 << 1) | ||
46 | #define SYS_CNTRL_TS (1 << 0) | ||
47 | |||
48 | /* Programmable Counter 0 Registers */ | ||
49 | #define SYS_TOYTRIM (LS1X_RTC_REGS(0)) | ||
50 | #define SYS_TOYWRITE0 (LS1X_RTC_REGS(4)) | ||
51 | #define SYS_TOYWRITE1 (LS1X_RTC_REGS(8)) | ||
52 | #define SYS_TOYREAD0 (LS1X_RTC_REGS(0xC)) | ||
53 | #define SYS_TOYREAD1 (LS1X_RTC_REGS(0x10)) | ||
54 | #define SYS_TOYMATCH0 (LS1X_RTC_REGS(0x14)) | ||
55 | #define SYS_TOYMATCH1 (LS1X_RTC_REGS(0x18)) | ||
56 | #define SYS_TOYMATCH2 (LS1X_RTC_REGS(0x1C)) | ||
57 | |||
58 | /* Programmable Counter 1 Registers */ | ||
59 | #define SYS_RTCTRIM (LS1X_RTC_REGS(0x40)) | ||
60 | #define SYS_RTCWRITE0 (LS1X_RTC_REGS(0x44)) | ||
61 | #define SYS_RTCREAD0 (LS1X_RTC_REGS(0x48)) | ||
62 | #define SYS_RTCMATCH0 (LS1X_RTC_REGS(0x4C)) | ||
63 | #define SYS_RTCMATCH1 (LS1X_RTC_REGS(0x50)) | ||
64 | #define SYS_RTCMATCH2 (LS1X_RTC_REGS(0x54)) | ||
65 | |||
66 | #define LS1X_SEC_OFFSET (4) | ||
67 | #define LS1X_MIN_OFFSET (10) | ||
68 | #define LS1X_HOUR_OFFSET (16) | ||
69 | #define LS1X_DAY_OFFSET (21) | ||
70 | #define LS1X_MONTH_OFFSET (26) | ||
71 | |||
72 | |||
73 | #define LS1X_SEC_MASK (0x3f) | ||
74 | #define LS1X_MIN_MASK (0x3f) | ||
75 | #define LS1X_HOUR_MASK (0x1f) | ||
76 | #define LS1X_DAY_MASK (0x1f) | ||
77 | #define LS1X_MONTH_MASK (0x3f) | ||
78 | #define LS1X_YEAR_MASK (0xffffffff) | ||
79 | |||
80 | #define ls1x_get_sec(t) (((t) >> LS1X_SEC_OFFSET) & LS1X_SEC_MASK) | ||
81 | #define ls1x_get_min(t) (((t) >> LS1X_MIN_OFFSET) & LS1X_MIN_MASK) | ||
82 | #define ls1x_get_hour(t) (((t) >> LS1X_HOUR_OFFSET) & LS1X_HOUR_MASK) | ||
83 | #define ls1x_get_day(t) (((t) >> LS1X_DAY_OFFSET) & LS1X_DAY_MASK) | ||
84 | #define ls1x_get_month(t) (((t) >> LS1X_MONTH_OFFSET) & LS1X_MONTH_MASK) | ||
85 | |||
86 | #define RTC_CNTR_OK (SYS_CNTRL_E0 | SYS_CNTRL_32S) | ||
87 | |||
88 | static int ls1x_rtc_read_time(struct device *dev, struct rtc_time *rtm) | ||
89 | { | ||
90 | unsigned long v, t; | ||
91 | |||
92 | v = readl(SYS_TOYREAD0); | ||
93 | t = readl(SYS_TOYREAD1); | ||
94 | |||
95 | memset(rtm, 0, sizeof(struct rtc_time)); | ||
96 | t = mktime((t & LS1X_YEAR_MASK), ls1x_get_month(v), | ||
97 | ls1x_get_day(v), ls1x_get_hour(v), | ||
98 | ls1x_get_min(v), ls1x_get_sec(v)); | ||
99 | rtc_time_to_tm(t, rtm); | ||
100 | |||
101 | return rtc_valid_tm(rtm); | ||
102 | } | ||
103 | |||
104 | static int ls1x_rtc_set_time(struct device *dev, struct rtc_time *rtm) | ||
105 | { | ||
106 | unsigned long v, t, c; | ||
107 | int ret = -ETIMEDOUT; | ||
108 | |||
109 | v = ((rtm->tm_mon + 1) << LS1X_MONTH_OFFSET) | ||
110 | | (rtm->tm_mday << LS1X_DAY_OFFSET) | ||
111 | | (rtm->tm_hour << LS1X_HOUR_OFFSET) | ||
112 | | (rtm->tm_min << LS1X_MIN_OFFSET) | ||
113 | | (rtm->tm_sec << LS1X_SEC_OFFSET); | ||
114 | |||
115 | writel(v, SYS_TOYWRITE0); | ||
116 | c = 0x10000; | ||
117 | /* add timeout check counter, for more safe */ | ||
118 | while ((readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TS) && --c) | ||
119 | usleep_range(1000, 3000); | ||
120 | |||
121 | if (!c) { | ||
122 | dev_err(dev, "set time timeout!\n"); | ||
123 | goto err; | ||
124 | } | ||
125 | |||
126 | t = rtm->tm_year + 1900; | ||
127 | writel(t, SYS_TOYWRITE1); | ||
128 | c = 0x10000; | ||
129 | while ((readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TS) && --c) | ||
130 | usleep_range(1000, 3000); | ||
131 | |||
132 | if (!c) { | ||
133 | dev_err(dev, "set time timeout!\n"); | ||
134 | goto err; | ||
135 | } | ||
136 | return 0; | ||
137 | err: | ||
138 | return ret; | ||
139 | } | ||
140 | |||
141 | static struct rtc_class_ops ls1x_rtc_ops = { | ||
142 | .read_time = ls1x_rtc_read_time, | ||
143 | .set_time = ls1x_rtc_set_time, | ||
144 | }; | ||
145 | |||
146 | static int ls1x_rtc_probe(struct platform_device *pdev) | ||
147 | { | ||
148 | struct rtc_device *rtcdev; | ||
149 | unsigned long v; | ||
150 | int ret; | ||
151 | |||
152 | v = readl(SYS_COUNTER_CNTRL); | ||
153 | if (!(v & RTC_CNTR_OK)) { | ||
154 | dev_err(&pdev->dev, "rtc counters not working\n"); | ||
155 | ret = -ENODEV; | ||
156 | goto err; | ||
157 | } | ||
158 | ret = -ETIMEDOUT; | ||
159 | /* set to 1 HZ if needed */ | ||
160 | if (readl(SYS_TOYTRIM) != 32767) { | ||
161 | v = 0x100000; | ||
162 | while ((readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TTS) && --v) | ||
163 | usleep_range(1000, 3000); | ||
164 | |||
165 | if (!v) { | ||
166 | dev_err(&pdev->dev, "time out\n"); | ||
167 | goto err; | ||
168 | } | ||
169 | writel(32767, SYS_TOYTRIM); | ||
170 | } | ||
171 | /* this loop coundn't be endless */ | ||
172 | while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TTS) | ||
173 | usleep_range(1000, 3000); | ||
174 | |||
175 | rtcdev = rtc_device_register("ls1x-rtc", &pdev->dev, | ||
176 | &ls1x_rtc_ops , THIS_MODULE); | ||
177 | if (IS_ERR(rtcdev)) { | ||
178 | ret = PTR_ERR(rtcdev); | ||
179 | goto err; | ||
180 | } | ||
181 | |||
182 | platform_set_drvdata(pdev, rtcdev); | ||
183 | return 0; | ||
184 | err: | ||
185 | return ret; | ||
186 | } | ||
187 | |||
188 | static int ls1x_rtc_remove(struct platform_device *pdev) | ||
189 | { | ||
190 | struct rtc_device *rtcdev = platform_get_drvdata(pdev); | ||
191 | |||
192 | rtc_device_unregister(rtcdev); | ||
193 | platform_set_drvdata(pdev, NULL); | ||
194 | |||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static struct platform_driver ls1x_rtc_driver = { | ||
199 | .driver = { | ||
200 | .name = "ls1x-rtc", | ||
201 | .owner = THIS_MODULE, | ||
202 | }, | ||
203 | .remove = ls1x_rtc_remove, | ||
204 | .probe = ls1x_rtc_probe, | ||
205 | }; | ||
206 | |||
207 | module_platform_driver(ls1x_rtc_driver); | ||
208 | |||
209 | MODULE_AUTHOR("zhao zhang <zhzhl555@gmail.com>"); | ||
210 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index b885bcd0890..64aedd8cc09 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c | |||
@@ -213,14 +213,163 @@ static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
213 | return m41t80_set_datetime(to_i2c_client(dev), tm); | 213 | return m41t80_set_datetime(to_i2c_client(dev), tm); |
214 | } | 214 | } |
215 | 215 | ||
216 | /* | 216 | static int m41t80_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) |
217 | * XXX - m41t80 alarm functionality is reported broken. | 217 | { |
218 | * until it is fixed, don't register alarm functions. | 218 | struct i2c_client *client = to_i2c_client(dev); |
219 | */ | 219 | int rc; |
220 | |||
221 | rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON); | ||
222 | if (rc < 0) | ||
223 | goto err; | ||
224 | |||
225 | if (enabled) | ||
226 | rc |= M41T80_ALMON_AFE; | ||
227 | else | ||
228 | rc &= ~M41T80_ALMON_AFE; | ||
229 | |||
230 | if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, rc) < 0) | ||
231 | goto err; | ||
232 | |||
233 | return 0; | ||
234 | err: | ||
235 | return -EIO; | ||
236 | } | ||
237 | |||
238 | static int m41t80_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t) | ||
239 | { | ||
240 | struct i2c_client *client = to_i2c_client(dev); | ||
241 | u8 wbuf[1 + M41T80_ALARM_REG_SIZE]; | ||
242 | u8 *buf = &wbuf[1]; | ||
243 | u8 *reg = buf - M41T80_REG_ALARM_MON; | ||
244 | u8 dt_addr[1] = { M41T80_REG_ALARM_MON }; | ||
245 | struct i2c_msg msgs_in[] = { | ||
246 | { | ||
247 | .addr = client->addr, | ||
248 | .flags = 0, | ||
249 | .len = 1, | ||
250 | .buf = dt_addr, | ||
251 | }, | ||
252 | { | ||
253 | .addr = client->addr, | ||
254 | .flags = I2C_M_RD, | ||
255 | .len = M41T80_ALARM_REG_SIZE, | ||
256 | .buf = buf, | ||
257 | }, | ||
258 | }; | ||
259 | struct i2c_msg msgs[] = { | ||
260 | { | ||
261 | .addr = client->addr, | ||
262 | .flags = 0, | ||
263 | .len = 1 + M41T80_ALARM_REG_SIZE, | ||
264 | .buf = wbuf, | ||
265 | }, | ||
266 | }; | ||
267 | |||
268 | if (i2c_transfer(client->adapter, msgs_in, 2) < 0) { | ||
269 | dev_err(&client->dev, "read error\n"); | ||
270 | return -EIO; | ||
271 | } | ||
272 | reg[M41T80_REG_ALARM_MON] &= ~(0x1f | M41T80_ALMON_AFE); | ||
273 | reg[M41T80_REG_ALARM_DAY] = 0; | ||
274 | reg[M41T80_REG_ALARM_HOUR] &= ~(0x3f | 0x80); | ||
275 | reg[M41T80_REG_ALARM_MIN] = 0; | ||
276 | reg[M41T80_REG_ALARM_SEC] = 0; | ||
277 | |||
278 | wbuf[0] = M41T80_REG_ALARM_MON; /* offset into rtc's regs */ | ||
279 | reg[M41T80_REG_ALARM_SEC] |= t->time.tm_sec >= 0 ? | ||
280 | bin2bcd(t->time.tm_sec) : 0x80; | ||
281 | reg[M41T80_REG_ALARM_MIN] |= t->time.tm_min >= 0 ? | ||
282 | bin2bcd(t->time.tm_min) : 0x80; | ||
283 | reg[M41T80_REG_ALARM_HOUR] |= t->time.tm_hour >= 0 ? | ||
284 | bin2bcd(t->time.tm_hour) : 0x80; | ||
285 | reg[M41T80_REG_ALARM_DAY] |= t->time.tm_mday >= 0 ? | ||
286 | bin2bcd(t->time.tm_mday) : 0x80; | ||
287 | if (t->time.tm_mon >= 0) | ||
288 | reg[M41T80_REG_ALARM_MON] |= bin2bcd(t->time.tm_mon + 1); | ||
289 | else | ||
290 | reg[M41T80_REG_ALARM_DAY] |= 0x40; | ||
291 | |||
292 | if (i2c_transfer(client->adapter, msgs, 1) != 1) { | ||
293 | dev_err(&client->dev, "write error\n"); | ||
294 | return -EIO; | ||
295 | } | ||
296 | |||
297 | if (t->enabled) { | ||
298 | reg[M41T80_REG_ALARM_MON] |= M41T80_ALMON_AFE; | ||
299 | if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, | ||
300 | reg[M41T80_REG_ALARM_MON]) < 0) { | ||
301 | dev_err(&client->dev, "write error\n"); | ||
302 | return -EIO; | ||
303 | } | ||
304 | } | ||
305 | return 0; | ||
306 | } | ||
307 | |||
308 | static int m41t80_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *t) | ||
309 | { | ||
310 | struct i2c_client *client = to_i2c_client(dev); | ||
311 | u8 buf[M41T80_ALARM_REG_SIZE + 1]; /* all alarm regs and flags */ | ||
312 | u8 dt_addr[1] = { M41T80_REG_ALARM_MON }; | ||
313 | u8 *reg = buf - M41T80_REG_ALARM_MON; | ||
314 | struct i2c_msg msgs[] = { | ||
315 | { | ||
316 | .addr = client->addr, | ||
317 | .flags = 0, | ||
318 | .len = 1, | ||
319 | .buf = dt_addr, | ||
320 | }, | ||
321 | { | ||
322 | .addr = client->addr, | ||
323 | .flags = I2C_M_RD, | ||
324 | .len = M41T80_ALARM_REG_SIZE + 1, | ||
325 | .buf = buf, | ||
326 | }, | ||
327 | }; | ||
328 | |||
329 | if (i2c_transfer(client->adapter, msgs, 2) < 0) { | ||
330 | dev_err(&client->dev, "read error\n"); | ||
331 | return -EIO; | ||
332 | } | ||
333 | t->time.tm_sec = -1; | ||
334 | t->time.tm_min = -1; | ||
335 | t->time.tm_hour = -1; | ||
336 | t->time.tm_mday = -1; | ||
337 | t->time.tm_mon = -1; | ||
338 | if (!(reg[M41T80_REG_ALARM_SEC] & 0x80)) | ||
339 | t->time.tm_sec = bcd2bin(reg[M41T80_REG_ALARM_SEC] & 0x7f); | ||
340 | if (!(reg[M41T80_REG_ALARM_MIN] & 0x80)) | ||
341 | t->time.tm_min = bcd2bin(reg[M41T80_REG_ALARM_MIN] & 0x7f); | ||
342 | if (!(reg[M41T80_REG_ALARM_HOUR] & 0x80)) | ||
343 | t->time.tm_hour = bcd2bin(reg[M41T80_REG_ALARM_HOUR] & 0x3f); | ||
344 | if (!(reg[M41T80_REG_ALARM_DAY] & 0x80)) | ||
345 | t->time.tm_mday = bcd2bin(reg[M41T80_REG_ALARM_DAY] & 0x3f); | ||
346 | if (!(reg[M41T80_REG_ALARM_DAY] & 0x40)) | ||
347 | t->time.tm_mon = bcd2bin(reg[M41T80_REG_ALARM_MON] & 0x1f) - 1; | ||
348 | t->time.tm_year = -1; | ||
349 | t->time.tm_wday = -1; | ||
350 | t->time.tm_yday = -1; | ||
351 | t->time.tm_isdst = -1; | ||
352 | t->enabled = !!(reg[M41T80_REG_ALARM_MON] & M41T80_ALMON_AFE); | ||
353 | t->pending = !!(reg[M41T80_REG_FLAGS] & M41T80_FLAGS_AF); | ||
354 | return 0; | ||
355 | } | ||
356 | |||
220 | static struct rtc_class_ops m41t80_rtc_ops = { | 357 | static struct rtc_class_ops m41t80_rtc_ops = { |
221 | .read_time = m41t80_rtc_read_time, | 358 | .read_time = m41t80_rtc_read_time, |
222 | .set_time = m41t80_rtc_set_time, | 359 | .set_time = m41t80_rtc_set_time, |
360 | /* | ||
361 | * XXX - m41t80 alarm functionality is reported broken. | ||
362 | * until it is fixed, don't register alarm functions. | ||
363 | * | ||
364 | .read_alarm = m41t80_rtc_read_alarm, | ||
365 | .set_alarm = m41t80_rtc_set_alarm, | ||
366 | */ | ||
223 | .proc = m41t80_rtc_proc, | 367 | .proc = m41t80_rtc_proc, |
368 | /* | ||
369 | * See above comment on broken alarm | ||
370 | * | ||
371 | .alarm_irq_enable = m41t80_rtc_alarm_irq_enable, | ||
372 | */ | ||
224 | }; | 373 | }; |
225 | 374 | ||
226 | #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) | 375 | #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) |
@@ -751,9 +900,20 @@ static struct i2c_driver m41t80_driver = { | |||
751 | .id_table = m41t80_id, | 900 | .id_table = m41t80_id, |
752 | }; | 901 | }; |
753 | 902 | ||
754 | module_i2c_driver(m41t80_driver); | 903 | static int __init m41t80_rtc_init(void) |
904 | { | ||
905 | return i2c_add_driver(&m41t80_driver); | ||
906 | } | ||
907 | |||
908 | static void __exit m41t80_rtc_exit(void) | ||
909 | { | ||
910 | i2c_del_driver(&m41t80_driver); | ||
911 | } | ||
755 | 912 | ||
756 | MODULE_AUTHOR("Alexander Bigga <ab@mycable.de>"); | 913 | MODULE_AUTHOR("Alexander Bigga <ab@mycable.de>"); |
757 | MODULE_DESCRIPTION("ST Microelectronics M41T80 series RTC I2C Client Driver"); | 914 | MODULE_DESCRIPTION("ST Microelectronics M41T80 series RTC I2C Client Driver"); |
758 | MODULE_LICENSE("GPL"); | 915 | MODULE_LICENSE("GPL"); |
759 | MODULE_VERSION(DRV_VERSION); | 916 | MODULE_VERSION(DRV_VERSION); |
917 | |||
918 | module_init(m41t80_rtc_init); | ||
919 | module_exit(m41t80_rtc_exit); | ||
diff --git a/drivers/rtc/rtc-m41t93.c b/drivers/rtc/rtc-m41t93.c index 49169680786..7317d3b9a3d 100644 --- a/drivers/rtc/rtc-m41t93.c +++ b/drivers/rtc/rtc-m41t93.c | |||
@@ -48,7 +48,6 @@ static inline int m41t93_set_reg(struct spi_device *spi, u8 addr, u8 data) | |||
48 | static int m41t93_set_time(struct device *dev, struct rtc_time *tm) | 48 | static int m41t93_set_time(struct device *dev, struct rtc_time *tm) |
49 | { | 49 | { |
50 | struct spi_device *spi = to_spi_device(dev); | 50 | struct spi_device *spi = to_spi_device(dev); |
51 | int tmp; | ||
52 | u8 buf[9] = {0x80}; /* write cmd + 8 data bytes */ | 51 | u8 buf[9] = {0x80}; /* write cmd + 8 data bytes */ |
53 | u8 * const data = &buf[1]; /* ptr to first data byte */ | 52 | u8 * const data = &buf[1]; /* ptr to first data byte */ |
54 | 53 | ||
@@ -63,30 +62,6 @@ static int m41t93_set_time(struct device *dev, struct rtc_time *tm) | |||
63 | return -EINVAL; | 62 | return -EINVAL; |
64 | } | 63 | } |
65 | 64 | ||
66 | tmp = spi_w8r8(spi, M41T93_REG_FLAGS); | ||
67 | if (tmp < 0) | ||
68 | return tmp; | ||
69 | |||
70 | if (tmp & M41T93_FLAG_OF) { | ||
71 | dev_warn(&spi->dev, "OF bit is set, resetting.\n"); | ||
72 | m41t93_set_reg(spi, M41T93_REG_FLAGS, tmp & ~M41T93_FLAG_OF); | ||
73 | |||
74 | tmp = spi_w8r8(spi, M41T93_REG_FLAGS); | ||
75 | if (tmp < 0) { | ||
76 | return tmp; | ||
77 | } else if (tmp & M41T93_FLAG_OF) { | ||
78 | /* OF cannot be immediately reset: oscillator has to be | ||
79 | * restarted. */ | ||
80 | u8 reset_osc = buf[M41T93_REG_ST_SEC] | M41T93_FLAG_ST; | ||
81 | |||
82 | dev_warn(&spi->dev, | ||
83 | "OF bit is still set, kickstarting clock.\n"); | ||
84 | m41t93_set_reg(spi, M41T93_REG_ST_SEC, reset_osc); | ||
85 | reset_osc &= ~M41T93_FLAG_ST; | ||
86 | m41t93_set_reg(spi, M41T93_REG_ST_SEC, reset_osc); | ||
87 | } | ||
88 | } | ||
89 | |||
90 | data[M41T93_REG_SSEC] = 0; | 65 | data[M41T93_REG_SSEC] = 0; |
91 | data[M41T93_REG_ST_SEC] = bin2bcd(tm->tm_sec); | 66 | data[M41T93_REG_ST_SEC] = bin2bcd(tm->tm_sec); |
92 | data[M41T93_REG_MIN] = bin2bcd(tm->tm_min); | 67 | data[M41T93_REG_MIN] = bin2bcd(tm->tm_min); |
@@ -114,7 +89,10 @@ static int m41t93_get_time(struct device *dev, struct rtc_time *tm) | |||
114 | 1. halt bit (HT) is set: the clock is running but update of readout | 89 | 1. halt bit (HT) is set: the clock is running but update of readout |
115 | registers has been disabled due to power failure. This is normal | 90 | registers has been disabled due to power failure. This is normal |
116 | case after poweron. Time is valid after resetting HT bit. | 91 | case after poweron. Time is valid after resetting HT bit. |
117 | 2. oscillator fail bit (OF) is set: time is invalid. | 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. | ||
118 | */ | 96 | */ |
119 | tmp = spi_w8r8(spi, M41T93_REG_ALM_HOUR_HT); | 97 | tmp = spi_w8r8(spi, M41T93_REG_ALM_HOUR_HT); |
120 | if (tmp < 0) | 98 | if (tmp < 0) |
@@ -132,7 +110,21 @@ static int m41t93_get_time(struct device *dev, struct rtc_time *tm) | |||
132 | 110 | ||
133 | if (tmp & M41T93_FLAG_OF) { | 111 | if (tmp & M41T93_FLAG_OF) { |
134 | ret = -EINVAL; | 112 | ret = -EINVAL; |
135 | dev_warn(&spi->dev, "OF bit is set, write time to restart.\n"); | 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 | } | ||
136 | } | 128 | } |
137 | 129 | ||
138 | if (tmp & M41T93_FLAG_BL) | 130 | if (tmp & M41T93_FLAG_BL) |
@@ -170,7 +162,7 @@ static const struct rtc_class_ops m41t93_rtc_ops = { | |||
170 | 162 | ||
171 | static struct spi_driver m41t93_driver; | 163 | static struct spi_driver m41t93_driver; |
172 | 164 | ||
173 | static int m41t93_probe(struct spi_device *spi) | 165 | static int __devinit m41t93_probe(struct spi_device *spi) |
174 | { | 166 | { |
175 | struct rtc_device *rtc; | 167 | struct rtc_device *rtc; |
176 | int res; | 168 | int res; |
@@ -195,7 +187,7 @@ static int m41t93_probe(struct spi_device *spi) | |||
195 | } | 187 | } |
196 | 188 | ||
197 | 189 | ||
198 | static int m41t93_remove(struct spi_device *spi) | 190 | static int __devexit m41t93_remove(struct spi_device *spi) |
199 | { | 191 | { |
200 | struct rtc_device *rtc = spi_get_drvdata(spi); | 192 | struct rtc_device *rtc = spi_get_drvdata(spi); |
201 | 193 | ||
@@ -208,13 +200,24 @@ static int m41t93_remove(struct spi_device *spi) | |||
208 | static struct spi_driver m41t93_driver = { | 200 | static struct spi_driver m41t93_driver = { |
209 | .driver = { | 201 | .driver = { |
210 | .name = "rtc-m41t93", | 202 | .name = "rtc-m41t93", |
203 | .bus = &spi_bus_type, | ||
211 | .owner = THIS_MODULE, | 204 | .owner = THIS_MODULE, |
212 | }, | 205 | }, |
213 | .probe = m41t93_probe, | 206 | .probe = m41t93_probe, |
214 | .remove = m41t93_remove, | 207 | .remove = __devexit_p(m41t93_remove), |
215 | }; | 208 | }; |
216 | 209 | ||
217 | module_spi_driver(m41t93_driver); | 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); | ||
218 | 221 | ||
219 | MODULE_AUTHOR("Nikolaus Voss <n.voss@weinmann.de>"); | 222 | MODULE_AUTHOR("Nikolaus Voss <n.voss@weinmann.de>"); |
220 | MODULE_DESCRIPTION("Driver for ST M41T93 SPI RTC"); | 223 | MODULE_DESCRIPTION("Driver for ST M41T93 SPI RTC"); |
diff --git a/drivers/rtc/rtc-m41t94.c b/drivers/rtc/rtc-m41t94.c index 89266c6764b..e259ed76ae8 100644 --- a/drivers/rtc/rtc-m41t94.c +++ b/drivers/rtc/rtc-m41t94.c | |||
@@ -110,7 +110,7 @@ static const struct rtc_class_ops m41t94_rtc_ops = { | |||
110 | 110 | ||
111 | static struct spi_driver m41t94_driver; | 111 | static struct spi_driver m41t94_driver; |
112 | 112 | ||
113 | static int m41t94_probe(struct spi_device *spi) | 113 | static int __devinit m41t94_probe(struct spi_device *spi) |
114 | { | 114 | { |
115 | struct rtc_device *rtc; | 115 | struct rtc_device *rtc; |
116 | int res; | 116 | int res; |
@@ -134,7 +134,7 @@ static int m41t94_probe(struct spi_device *spi) | |||
134 | return 0; | 134 | return 0; |
135 | } | 135 | } |
136 | 136 | ||
137 | static int m41t94_remove(struct spi_device *spi) | 137 | static int __devexit m41t94_remove(struct spi_device *spi) |
138 | { | 138 | { |
139 | struct rtc_device *rtc = spi_get_drvdata(spi); | 139 | struct rtc_device *rtc = spi_get_drvdata(spi); |
140 | 140 | ||
@@ -147,13 +147,26 @@ static int m41t94_remove(struct spi_device *spi) | |||
147 | static struct spi_driver m41t94_driver = { | 147 | static struct spi_driver m41t94_driver = { |
148 | .driver = { | 148 | .driver = { |
149 | .name = "rtc-m41t94", | 149 | .name = "rtc-m41t94", |
150 | .bus = &spi_bus_type, | ||
150 | .owner = THIS_MODULE, | 151 | .owner = THIS_MODULE, |
151 | }, | 152 | }, |
152 | .probe = m41t94_probe, | 153 | .probe = m41t94_probe, |
153 | .remove = m41t94_remove, | 154 | .remove = __devexit_p(m41t94_remove), |
154 | }; | 155 | }; |
155 | 156 | ||
156 | module_spi_driver(m41t94_driver); | 157 | static __init int m41t94_init(void) |
158 | { | ||
159 | return spi_register_driver(&m41t94_driver); | ||
160 | } | ||
161 | |||
162 | module_init(m41t94_init); | ||
163 | |||
164 | static __exit void m41t94_exit(void) | ||
165 | { | ||
166 | spi_unregister_driver(&m41t94_driver); | ||
167 | } | ||
168 | |||
169 | module_exit(m41t94_exit); | ||
157 | 170 | ||
158 | MODULE_AUTHOR("Kim B. Heino <Kim.Heino@bluegiga.com>"); | 171 | MODULE_AUTHOR("Kim B. Heino <Kim.Heino@bluegiga.com>"); |
159 | MODULE_DESCRIPTION("Driver for ST M41T94 SPI RTC"); | 172 | MODULE_DESCRIPTION("Driver for ST M41T94 SPI RTC"); |
diff --git a/drivers/rtc/rtc-m48t35.c b/drivers/rtc/rtc-m48t35.c index 31c9190a1fc..8e2a24e33ed 100644 --- a/drivers/rtc/rtc-m48t35.c +++ b/drivers/rtc/rtc-m48t35.c | |||
@@ -141,7 +141,7 @@ static const struct rtc_class_ops m48t35_ops = { | |||
141 | .set_time = m48t35_set_time, | 141 | .set_time = m48t35_set_time, |
142 | }; | 142 | }; |
143 | 143 | ||
144 | static int m48t35_probe(struct platform_device *pdev) | 144 | static int __devinit m48t35_probe(struct platform_device *pdev) |
145 | { | 145 | { |
146 | struct resource *res; | 146 | struct resource *res; |
147 | struct m48t35_priv *priv; | 147 | struct m48t35_priv *priv; |
@@ -194,7 +194,7 @@ out: | |||
194 | return ret; | 194 | return ret; |
195 | } | 195 | } |
196 | 196 | ||
197 | static int m48t35_remove(struct platform_device *pdev) | 197 | static int __devexit m48t35_remove(struct platform_device *pdev) |
198 | { | 198 | { |
199 | struct m48t35_priv *priv = platform_get_drvdata(pdev); | 199 | struct m48t35_priv *priv = platform_get_drvdata(pdev); |
200 | 200 | ||
@@ -213,13 +213,24 @@ static struct platform_driver m48t35_platform_driver = { | |||
213 | .owner = THIS_MODULE, | 213 | .owner = THIS_MODULE, |
214 | }, | 214 | }, |
215 | .probe = m48t35_probe, | 215 | .probe = m48t35_probe, |
216 | .remove = m48t35_remove, | 216 | .remove = __devexit_p(m48t35_remove), |
217 | }; | 217 | }; |
218 | 218 | ||
219 | module_platform_driver(m48t35_platform_driver); | 219 | static int __init m48t35_init(void) |
220 | { | ||
221 | return platform_driver_register(&m48t35_platform_driver); | ||
222 | } | ||
223 | |||
224 | static void __exit m48t35_exit(void) | ||
225 | { | ||
226 | platform_driver_unregister(&m48t35_platform_driver); | ||
227 | } | ||
220 | 228 | ||
221 | MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>"); | 229 | MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>"); |
222 | MODULE_DESCRIPTION("M48T35 RTC driver"); | 230 | MODULE_DESCRIPTION("M48T35 RTC driver"); |
223 | MODULE_LICENSE("GPL"); | 231 | MODULE_LICENSE("GPL"); |
224 | MODULE_VERSION(DRV_VERSION); | 232 | MODULE_VERSION(DRV_VERSION); |
225 | MODULE_ALIAS("platform:rtc-m48t35"); | 233 | MODULE_ALIAS("platform:rtc-m48t35"); |
234 | |||
235 | module_init(m48t35_init); | ||
236 | module_exit(m48t35_exit); | ||
diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c index 130f29af386..28365388fb6 100644 --- a/drivers/rtc/rtc-m48t59.c +++ b/drivers/rtc/rtc-m48t59.c | |||
@@ -383,7 +383,7 @@ static struct bin_attribute m48t59_nvram_attr = { | |||
383 | .write = m48t59_nvram_write, | 383 | .write = m48t59_nvram_write, |
384 | }; | 384 | }; |
385 | 385 | ||
386 | static int m48t59_rtc_probe(struct platform_device *pdev) | 386 | static int __devinit m48t59_rtc_probe(struct platform_device *pdev) |
387 | { | 387 | { |
388 | struct m48t59_plat_data *pdata = pdev->dev.platform_data; | 388 | struct m48t59_plat_data *pdata = pdev->dev.platform_data; |
389 | struct m48t59_private *m48t59 = NULL; | 389 | struct m48t59_private *m48t59 = NULL; |
@@ -501,7 +501,7 @@ out: | |||
501 | return ret; | 501 | return ret; |
502 | } | 502 | } |
503 | 503 | ||
504 | static int m48t59_rtc_remove(struct platform_device *pdev) | 504 | static int __devexit m48t59_rtc_remove(struct platform_device *pdev) |
505 | { | 505 | { |
506 | struct m48t59_private *m48t59 = platform_get_drvdata(pdev); | 506 | struct m48t59_private *m48t59 = platform_get_drvdata(pdev); |
507 | struct m48t59_plat_data *pdata = pdev->dev.platform_data; | 507 | struct m48t59_plat_data *pdata = pdev->dev.platform_data; |
@@ -527,10 +527,21 @@ static struct platform_driver m48t59_rtc_driver = { | |||
527 | .owner = THIS_MODULE, | 527 | .owner = THIS_MODULE, |
528 | }, | 528 | }, |
529 | .probe = m48t59_rtc_probe, | 529 | .probe = m48t59_rtc_probe, |
530 | .remove = m48t59_rtc_remove, | 530 | .remove = __devexit_p(m48t59_rtc_remove), |
531 | }; | 531 | }; |
532 | 532 | ||
533 | module_platform_driver(m48t59_rtc_driver); | 533 | static int __init m48t59_rtc_init(void) |
534 | { | ||
535 | return platform_driver_register(&m48t59_rtc_driver); | ||
536 | } | ||
537 | |||
538 | static void __exit m48t59_rtc_exit(void) | ||
539 | { | ||
540 | platform_driver_unregister(&m48t59_rtc_driver); | ||
541 | } | ||
542 | |||
543 | module_init(m48t59_rtc_init); | ||
544 | module_exit(m48t59_rtc_exit); | ||
534 | 545 | ||
535 | MODULE_AUTHOR("Mark Zhan <rongkai.zhan@windriver.com>"); | 546 | MODULE_AUTHOR("Mark Zhan <rongkai.zhan@windriver.com>"); |
536 | MODULE_DESCRIPTION("M48T59/M48T02/M48T08 RTC driver"); | 547 | MODULE_DESCRIPTION("M48T59/M48T02/M48T08 RTC driver"); |
diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c index 2ffbcacd243..f981287d582 100644 --- a/drivers/rtc/rtc-m48t86.c +++ b/drivers/rtc/rtc-m48t86.c | |||
@@ -144,7 +144,7 @@ static const struct rtc_class_ops m48t86_rtc_ops = { | |||
144 | .proc = m48t86_rtc_proc, | 144 | .proc = m48t86_rtc_proc, |
145 | }; | 145 | }; |
146 | 146 | ||
147 | static int m48t86_rtc_probe(struct platform_device *dev) | 147 | static int __devinit m48t86_rtc_probe(struct platform_device *dev) |
148 | { | 148 | { |
149 | unsigned char reg; | 149 | unsigned char reg; |
150 | struct m48t86_ops *ops = dev->dev.platform_data; | 150 | struct m48t86_ops *ops = dev->dev.platform_data; |
@@ -164,7 +164,7 @@ static int m48t86_rtc_probe(struct platform_device *dev) | |||
164 | return 0; | 164 | return 0; |
165 | } | 165 | } |
166 | 166 | ||
167 | static int m48t86_rtc_remove(struct platform_device *dev) | 167 | static int __devexit m48t86_rtc_remove(struct platform_device *dev) |
168 | { | 168 | { |
169 | struct rtc_device *rtc = platform_get_drvdata(dev); | 169 | struct rtc_device *rtc = platform_get_drvdata(dev); |
170 | 170 | ||
@@ -182,13 +182,24 @@ static struct platform_driver m48t86_rtc_platform_driver = { | |||
182 | .owner = THIS_MODULE, | 182 | .owner = THIS_MODULE, |
183 | }, | 183 | }, |
184 | .probe = m48t86_rtc_probe, | 184 | .probe = m48t86_rtc_probe, |
185 | .remove = m48t86_rtc_remove, | 185 | .remove = __devexit_p(m48t86_rtc_remove), |
186 | }; | 186 | }; |
187 | 187 | ||
188 | module_platform_driver(m48t86_rtc_platform_driver); | 188 | static int __init m48t86_rtc_init(void) |
189 | { | ||
190 | return platform_driver_register(&m48t86_rtc_platform_driver); | ||
191 | } | ||
192 | |||
193 | static void __exit m48t86_rtc_exit(void) | ||
194 | { | ||
195 | platform_driver_unregister(&m48t86_rtc_platform_driver); | ||
196 | } | ||
189 | 197 | ||
190 | MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); | 198 | MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); |
191 | MODULE_DESCRIPTION("M48T86 RTC driver"); | 199 | MODULE_DESCRIPTION("M48T86 RTC driver"); |
192 | MODULE_LICENSE("GPL"); | 200 | MODULE_LICENSE("GPL"); |
193 | MODULE_VERSION(DRV_VERSION); | 201 | MODULE_VERSION(DRV_VERSION); |
194 | MODULE_ALIAS("platform:rtc-m48t86"); | 202 | MODULE_ALIAS("platform:rtc-m48t86"); |
203 | |||
204 | module_init(m48t86_rtc_init); | ||
205 | module_exit(m48t86_rtc_exit); | ||
diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c index a00e33204b9..486142c2637 100644 --- a/drivers/rtc/rtc-max6900.c +++ b/drivers/rtc/rtc-max6900.c | |||
@@ -261,9 +261,20 @@ static struct i2c_driver max6900_driver = { | |||
261 | .id_table = max6900_id, | 261 | .id_table = max6900_id, |
262 | }; | 262 | }; |
263 | 263 | ||
264 | module_i2c_driver(max6900_driver); | 264 | static int __init max6900_init(void) |
265 | { | ||
266 | return i2c_add_driver(&max6900_driver); | ||
267 | } | ||
268 | |||
269 | static void __exit max6900_exit(void) | ||
270 | { | ||
271 | i2c_del_driver(&max6900_driver); | ||
272 | } | ||
265 | 273 | ||
266 | MODULE_DESCRIPTION("Maxim MAX6900 RTC driver"); | 274 | MODULE_DESCRIPTION("Maxim MAX6900 RTC driver"); |
267 | MODULE_AUTHOR("Dale Farnsworth <dale@farnsworth.org>"); | 275 | MODULE_AUTHOR("Dale Farnsworth <dale@farnsworth.org>"); |
268 | MODULE_LICENSE("GPL"); | 276 | MODULE_LICENSE("GPL"); |
269 | MODULE_VERSION(DRV_VERSION); | 277 | MODULE_VERSION(DRV_VERSION); |
278 | |||
279 | module_init(max6900_init); | ||
280 | module_exit(max6900_exit); | ||
diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c index 7d0bf698b79..0ec3f588a25 100644 --- a/drivers/rtc/rtc-max6902.c +++ b/drivers/rtc/rtc-max6902.c | |||
@@ -120,7 +120,7 @@ static const struct rtc_class_ops max6902_rtc_ops = { | |||
120 | .set_time = max6902_set_time, | 120 | .set_time = max6902_set_time, |
121 | }; | 121 | }; |
122 | 122 | ||
123 | static int max6902_probe(struct spi_device *spi) | 123 | static int __devinit max6902_probe(struct spi_device *spi) |
124 | { | 124 | { |
125 | struct rtc_device *rtc; | 125 | struct rtc_device *rtc; |
126 | unsigned char tmp; | 126 | unsigned char tmp; |
@@ -143,7 +143,7 @@ static int max6902_probe(struct spi_device *spi) | |||
143 | return 0; | 143 | return 0; |
144 | } | 144 | } |
145 | 145 | ||
146 | static int max6902_remove(struct spi_device *spi) | 146 | static int __devexit max6902_remove(struct spi_device *spi) |
147 | { | 147 | { |
148 | struct rtc_device *rtc = dev_get_drvdata(&spi->dev); | 148 | struct rtc_device *rtc = dev_get_drvdata(&spi->dev); |
149 | 149 | ||
@@ -154,13 +154,24 @@ static int max6902_remove(struct spi_device *spi) | |||
154 | static struct spi_driver max6902_driver = { | 154 | static struct spi_driver max6902_driver = { |
155 | .driver = { | 155 | .driver = { |
156 | .name = "rtc-max6902", | 156 | .name = "rtc-max6902", |
157 | .bus = &spi_bus_type, | ||
157 | .owner = THIS_MODULE, | 158 | .owner = THIS_MODULE, |
158 | }, | 159 | }, |
159 | .probe = max6902_probe, | 160 | .probe = max6902_probe, |
160 | .remove = max6902_remove, | 161 | .remove = __devexit_p(max6902_remove), |
161 | }; | 162 | }; |
162 | 163 | ||
163 | module_spi_driver(max6902_driver); | 164 | static __init int max6902_init(void) |
165 | { | ||
166 | return spi_register_driver(&max6902_driver); | ||
167 | } | ||
168 | module_init(max6902_init); | ||
169 | |||
170 | static __exit void max6902_exit(void) | ||
171 | { | ||
172 | spi_unregister_driver(&max6902_driver); | ||
173 | } | ||
174 | module_exit(max6902_exit); | ||
164 | 175 | ||
165 | MODULE_DESCRIPTION ("max6902 spi RTC driver"); | 176 | MODULE_DESCRIPTION ("max6902 spi RTC driver"); |
166 | MODULE_AUTHOR ("Raphael Assenat"); | 177 | MODULE_AUTHOR ("Raphael Assenat"); |
diff --git a/drivers/rtc/rtc-max8907.c b/drivers/rtc/rtc-max8907.c deleted file mode 100644 index 1d049da16c8..00000000000 --- a/drivers/rtc/rtc-max8907.c +++ /dev/null | |||
@@ -1,244 +0,0 @@ | |||
1 | /* | ||
2 | * RTC driver for Maxim MAX8907 | ||
3 | * | ||
4 | * Copyright (c) 2011-2012, NVIDIA Corporation. | ||
5 | * | ||
6 | * Based on drivers/rtc/rtc-max8925.c, | ||
7 | * Copyright (C) 2009-2010 Marvell International Ltd. | ||
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/bcd.h> | ||
15 | #include <linux/i2c.h> | ||
16 | #include <linux/mfd/max8907.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/regmap.h> | ||
20 | #include <linux/rtc.h> | ||
21 | #include <linux/slab.h> | ||
22 | |||
23 | enum { | ||
24 | RTC_SEC = 0, | ||
25 | RTC_MIN, | ||
26 | RTC_HOUR, | ||
27 | RTC_WEEKDAY, | ||
28 | RTC_DATE, | ||
29 | RTC_MONTH, | ||
30 | RTC_YEAR1, | ||
31 | RTC_YEAR2, | ||
32 | }; | ||
33 | |||
34 | #define TIME_NUM 8 | ||
35 | #define ALARM_1SEC (1 << 7) | ||
36 | #define HOUR_12 (1 << 7) | ||
37 | #define HOUR_AM_PM (1 << 5) | ||
38 | #define ALARM0_IRQ (1 << 3) | ||
39 | #define ALARM1_IRQ (1 << 2) | ||
40 | #define ALARM0_STATUS (1 << 2) | ||
41 | #define ALARM1_STATUS (1 << 1) | ||
42 | |||
43 | struct max8907_rtc { | ||
44 | struct max8907 *max8907; | ||
45 | struct regmap *regmap; | ||
46 | struct rtc_device *rtc_dev; | ||
47 | int irq; | ||
48 | }; | ||
49 | |||
50 | static irqreturn_t max8907_irq_handler(int irq, void *data) | ||
51 | { | ||
52 | struct max8907_rtc *rtc = data; | ||
53 | |||
54 | regmap_update_bits(rtc->regmap, MAX8907_REG_ALARM0_CNTL, 0x7f, 0); | ||
55 | |||
56 | rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF); | ||
57 | |||
58 | return IRQ_HANDLED; | ||
59 | } | ||
60 | |||
61 | static void regs_to_tm(u8 *regs, struct rtc_time *tm) | ||
62 | { | ||
63 | tm->tm_year = bcd2bin(regs[RTC_YEAR2]) * 100 + | ||
64 | bcd2bin(regs[RTC_YEAR1]) - 1900; | ||
65 | tm->tm_mon = bcd2bin(regs[RTC_MONTH] & 0x1f) - 1; | ||
66 | tm->tm_mday = bcd2bin(regs[RTC_DATE] & 0x3f); | ||
67 | tm->tm_wday = (regs[RTC_WEEKDAY] & 0x07) - 1; | ||
68 | if (regs[RTC_HOUR] & HOUR_12) { | ||
69 | tm->tm_hour = bcd2bin(regs[RTC_HOUR] & 0x01f); | ||
70 | if (tm->tm_hour == 12) | ||
71 | tm->tm_hour = 0; | ||
72 | if (regs[RTC_HOUR] & HOUR_AM_PM) | ||
73 | tm->tm_hour += 12; | ||
74 | } else { | ||
75 | tm->tm_hour = bcd2bin(regs[RTC_HOUR] & 0x03f); | ||
76 | } | ||
77 | tm->tm_min = bcd2bin(regs[RTC_MIN] & 0x7f); | ||
78 | tm->tm_sec = bcd2bin(regs[RTC_SEC] & 0x7f); | ||
79 | } | ||
80 | |||
81 | static void tm_to_regs(struct rtc_time *tm, u8 *regs) | ||
82 | { | ||
83 | u8 high, low; | ||
84 | |||
85 | high = (tm->tm_year + 1900) / 100; | ||
86 | low = tm->tm_year % 100; | ||
87 | regs[RTC_YEAR2] = bin2bcd(high); | ||
88 | regs[RTC_YEAR1] = bin2bcd(low); | ||
89 | regs[RTC_MONTH] = bin2bcd(tm->tm_mon + 1); | ||
90 | regs[RTC_DATE] = bin2bcd(tm->tm_mday); | ||
91 | regs[RTC_WEEKDAY] = tm->tm_wday + 1; | ||
92 | regs[RTC_HOUR] = bin2bcd(tm->tm_hour); | ||
93 | regs[RTC_MIN] = bin2bcd(tm->tm_min); | ||
94 | regs[RTC_SEC] = bin2bcd(tm->tm_sec); | ||
95 | } | ||
96 | |||
97 | static int max8907_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
98 | { | ||
99 | struct max8907_rtc *rtc = dev_get_drvdata(dev); | ||
100 | u8 regs[TIME_NUM]; | ||
101 | int ret; | ||
102 | |||
103 | ret = regmap_bulk_read(rtc->regmap, MAX8907_REG_RTC_SEC, regs, | ||
104 | TIME_NUM); | ||
105 | if (ret < 0) | ||
106 | return ret; | ||
107 | |||
108 | regs_to_tm(regs, tm); | ||
109 | |||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | static int max8907_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
114 | { | ||
115 | struct max8907_rtc *rtc = dev_get_drvdata(dev); | ||
116 | u8 regs[TIME_NUM]; | ||
117 | |||
118 | tm_to_regs(tm, regs); | ||
119 | |||
120 | return regmap_bulk_write(rtc->regmap, MAX8907_REG_RTC_SEC, regs, | ||
121 | TIME_NUM); | ||
122 | } | ||
123 | |||
124 | static int max8907_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
125 | { | ||
126 | struct max8907_rtc *rtc = dev_get_drvdata(dev); | ||
127 | u8 regs[TIME_NUM]; | ||
128 | unsigned int val; | ||
129 | int ret; | ||
130 | |||
131 | ret = regmap_bulk_read(rtc->regmap, MAX8907_REG_ALARM0_SEC, regs, | ||
132 | TIME_NUM); | ||
133 | if (ret < 0) | ||
134 | return ret; | ||
135 | |||
136 | regs_to_tm(regs, &alrm->time); | ||
137 | |||
138 | ret = regmap_read(rtc->regmap, MAX8907_REG_ALARM0_CNTL, &val); | ||
139 | if (ret < 0) | ||
140 | return ret; | ||
141 | |||
142 | alrm->enabled = !!(val & 0x7f); | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | static int max8907_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
148 | { | ||
149 | struct max8907_rtc *rtc = dev_get_drvdata(dev); | ||
150 | u8 regs[TIME_NUM]; | ||
151 | int ret; | ||
152 | |||
153 | tm_to_regs(&alrm->time, regs); | ||
154 | |||
155 | /* Disable alarm while we update the target time */ | ||
156 | ret = regmap_update_bits(rtc->regmap, MAX8907_REG_ALARM0_CNTL, 0x7f, 0); | ||
157 | if (ret < 0) | ||
158 | return ret; | ||
159 | |||
160 | ret = regmap_bulk_write(rtc->regmap, MAX8907_REG_ALARM0_SEC, regs, | ||
161 | TIME_NUM); | ||
162 | if (ret < 0) | ||
163 | return ret; | ||
164 | |||
165 | if (alrm->enabled) | ||
166 | ret = regmap_update_bits(rtc->regmap, MAX8907_REG_ALARM0_CNTL, | ||
167 | 0x7f, 0x7f); | ||
168 | |||
169 | return ret; | ||
170 | } | ||
171 | |||
172 | static const struct rtc_class_ops max8907_rtc_ops = { | ||
173 | .read_time = max8907_rtc_read_time, | ||
174 | .set_time = max8907_rtc_set_time, | ||
175 | .read_alarm = max8907_rtc_read_alarm, | ||
176 | .set_alarm = max8907_rtc_set_alarm, | ||
177 | }; | ||
178 | |||
179 | static int max8907_rtc_probe(struct platform_device *pdev) | ||
180 | { | ||
181 | struct max8907 *max8907 = dev_get_drvdata(pdev->dev.parent); | ||
182 | struct max8907_rtc *rtc; | ||
183 | int ret; | ||
184 | |||
185 | rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); | ||
186 | if (!rtc) | ||
187 | return -ENOMEM; | ||
188 | platform_set_drvdata(pdev, rtc); | ||
189 | |||
190 | rtc->max8907 = max8907; | ||
191 | rtc->regmap = max8907->regmap_rtc; | ||
192 | |||
193 | rtc->rtc_dev = rtc_device_register("max8907-rtc", &pdev->dev, | ||
194 | &max8907_rtc_ops, THIS_MODULE); | ||
195 | if (IS_ERR(rtc->rtc_dev)) { | ||
196 | ret = PTR_ERR(rtc->rtc_dev); | ||
197 | dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); | ||
198 | return ret; | ||
199 | } | ||
200 | |||
201 | rtc->irq = regmap_irq_get_virq(max8907->irqc_rtc, | ||
202 | MAX8907_IRQ_RTC_ALARM0); | ||
203 | if (rtc->irq < 0) { | ||
204 | ret = rtc->irq; | ||
205 | goto err_unregister; | ||
206 | } | ||
207 | |||
208 | ret = request_threaded_irq(rtc->irq, NULL, max8907_irq_handler, | ||
209 | IRQF_ONESHOT, "max8907-alarm0", rtc); | ||
210 | if (ret < 0) { | ||
211 | dev_err(&pdev->dev, "Failed to request IRQ%d: %d\n", | ||
212 | rtc->irq, ret); | ||
213 | goto err_unregister; | ||
214 | } | ||
215 | |||
216 | return 0; | ||
217 | |||
218 | err_unregister: | ||
219 | rtc_device_unregister(rtc->rtc_dev); | ||
220 | return ret; | ||
221 | } | ||
222 | |||
223 | static int max8907_rtc_remove(struct platform_device *pdev) | ||
224 | { | ||
225 | struct max8907_rtc *rtc = platform_get_drvdata(pdev); | ||
226 | |||
227 | free_irq(rtc->irq, rtc); | ||
228 | rtc_device_unregister(rtc->rtc_dev); | ||
229 | |||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | static struct platform_driver max8907_rtc_driver = { | ||
234 | .driver = { | ||
235 | .name = "max8907-rtc", | ||
236 | .owner = THIS_MODULE, | ||
237 | }, | ||
238 | .probe = max8907_rtc_probe, | ||
239 | .remove = max8907_rtc_remove, | ||
240 | }; | ||
241 | module_platform_driver(max8907_rtc_driver); | ||
242 | |||
243 | MODULE_DESCRIPTION("Maxim MAX8907 RTC driver"); | ||
244 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/rtc/rtc-max8925.c b/drivers/rtc/rtc-max8925.c index a0c8265646d..3bc046f427e 100644 --- a/drivers/rtc/rtc-max8925.c +++ b/drivers/rtc/rtc-max8925.c | |||
@@ -69,7 +69,6 @@ struct max8925_rtc_info { | |||
69 | struct max8925_chip *chip; | 69 | struct max8925_chip *chip; |
70 | struct i2c_client *rtc; | 70 | struct i2c_client *rtc; |
71 | struct device *dev; | 71 | struct device *dev; |
72 | int irq; | ||
73 | }; | 72 | }; |
74 | 73 | ||
75 | static irqreturn_t rtc_update_handler(int irq, void *data) | 74 | static irqreturn_t rtc_update_handler(int irq, void *data) |
@@ -194,17 +193,10 @@ static int max8925_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
194 | ret = max8925_reg_read(info->rtc, MAX8925_RTC_IRQ_MASK); | 193 | ret = max8925_reg_read(info->rtc, MAX8925_RTC_IRQ_MASK); |
195 | if (ret < 0) | 194 | if (ret < 0) |
196 | goto out; | 195 | goto out; |
197 | if (ret & ALARM0_IRQ) { | 196 | if ((ret & ALARM0_IRQ) == 0) |
197 | alrm->enabled = 1; | ||
198 | else | ||
198 | alrm->enabled = 0; | 199 | alrm->enabled = 0; |
199 | } else { | ||
200 | ret = max8925_reg_read(info->rtc, MAX8925_ALARM0_CNTL); | ||
201 | if (ret < 0) | ||
202 | goto out; | ||
203 | if (!ret) | ||
204 | alrm->enabled = 0; | ||
205 | else | ||
206 | alrm->enabled = 1; | ||
207 | } | ||
208 | ret = max8925_reg_read(info->rtc, MAX8925_RTC_STATUS); | 200 | ret = max8925_reg_read(info->rtc, MAX8925_RTC_STATUS); |
209 | if (ret < 0) | 201 | if (ret < 0) |
210 | goto out; | 202 | goto out; |
@@ -212,7 +204,6 @@ static int max8925_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
212 | alrm->pending = 1; | 204 | alrm->pending = 1; |
213 | else | 205 | else |
214 | alrm->pending = 0; | 206 | alrm->pending = 0; |
215 | return 0; | ||
216 | out: | 207 | out: |
217 | return ret; | 208 | return ret; |
218 | } | 209 | } |
@@ -229,11 +220,8 @@ static int max8925_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
229 | ret = max8925_bulk_write(info->rtc, MAX8925_ALARM0_SEC, TIME_NUM, buf); | 220 | ret = max8925_bulk_write(info->rtc, MAX8925_ALARM0_SEC, TIME_NUM, buf); |
230 | if (ret < 0) | 221 | if (ret < 0) |
231 | goto out; | 222 | goto out; |
232 | if (alrm->enabled) | 223 | /* only enable alarm on year/month/day/hour/min/sec */ |
233 | /* only enable alarm on year/month/day/hour/min/sec */ | 224 | ret = max8925_reg_write(info->rtc, MAX8925_ALARM0_CNTL, 0x77); |
234 | ret = max8925_reg_write(info->rtc, MAX8925_ALARM0_CNTL, 0x77); | ||
235 | else | ||
236 | ret = max8925_reg_write(info->rtc, MAX8925_ALARM0_CNTL, 0x0); | ||
237 | if (ret < 0) | 225 | if (ret < 0) |
238 | goto out; | 226 | goto out; |
239 | out: | 227 | out: |
@@ -247,11 +235,11 @@ static const struct rtc_class_ops max8925_rtc_ops = { | |||
247 | .set_alarm = max8925_rtc_set_alarm, | 235 | .set_alarm = max8925_rtc_set_alarm, |
248 | }; | 236 | }; |
249 | 237 | ||
250 | static int max8925_rtc_probe(struct platform_device *pdev) | 238 | static int __devinit max8925_rtc_probe(struct platform_device *pdev) |
251 | { | 239 | { |
252 | struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); | 240 | struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); |
253 | struct max8925_rtc_info *info; | 241 | struct max8925_rtc_info *info; |
254 | int ret; | 242 | int irq, ret; |
255 | 243 | ||
256 | info = kzalloc(sizeof(struct max8925_rtc_info), GFP_KERNEL); | 244 | info = kzalloc(sizeof(struct max8925_rtc_info), GFP_KERNEL); |
257 | if (!info) | 245 | if (!info) |
@@ -259,13 +247,13 @@ static int max8925_rtc_probe(struct platform_device *pdev) | |||
259 | info->chip = chip; | 247 | info->chip = chip; |
260 | info->rtc = chip->rtc; | 248 | info->rtc = chip->rtc; |
261 | info->dev = &pdev->dev; | 249 | info->dev = &pdev->dev; |
262 | info->irq = platform_get_irq(pdev, 0); | 250 | irq = chip->irq_base + MAX8925_IRQ_RTC_ALARM0; |
263 | 251 | ||
264 | ret = request_threaded_irq(info->irq, NULL, rtc_update_handler, | 252 | ret = request_threaded_irq(irq, NULL, rtc_update_handler, |
265 | IRQF_ONESHOT, "rtc-alarm0", info); | 253 | IRQF_ONESHOT, "rtc-alarm0", info); |
266 | if (ret < 0) { | 254 | if (ret < 0) { |
267 | dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", | 255 | dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", |
268 | info->irq, ret); | 256 | irq, ret); |
269 | goto out_irq; | 257 | goto out_irq; |
270 | } | 258 | } |
271 | 259 | ||
@@ -273,8 +261,6 @@ static int max8925_rtc_probe(struct platform_device *pdev) | |||
273 | /* XXX - isn't this redundant? */ | 261 | /* XXX - isn't this redundant? */ |
274 | platform_set_drvdata(pdev, info); | 262 | platform_set_drvdata(pdev, info); |
275 | 263 | ||
276 | device_init_wakeup(&pdev->dev, 1); | ||
277 | |||
278 | info->rtc_dev = rtc_device_register("max8925-rtc", &pdev->dev, | 264 | info->rtc_dev = rtc_device_register("max8925-rtc", &pdev->dev, |
279 | &max8925_rtc_ops, THIS_MODULE); | 265 | &max8925_rtc_ops, THIS_MODULE); |
280 | ret = PTR_ERR(info->rtc_dev); | 266 | ret = PTR_ERR(info->rtc_dev); |
@@ -286,58 +272,44 @@ static int max8925_rtc_probe(struct platform_device *pdev) | |||
286 | return 0; | 272 | return 0; |
287 | out_rtc: | 273 | out_rtc: |
288 | platform_set_drvdata(pdev, NULL); | 274 | platform_set_drvdata(pdev, NULL); |
289 | free_irq(info->irq, info); | 275 | free_irq(chip->irq_base + MAX8925_IRQ_RTC_ALARM0, info); |
290 | out_irq: | 276 | out_irq: |
291 | kfree(info); | 277 | kfree(info); |
292 | return ret; | 278 | return ret; |
293 | } | 279 | } |
294 | 280 | ||
295 | static int max8925_rtc_remove(struct platform_device *pdev) | 281 | static int __devexit max8925_rtc_remove(struct platform_device *pdev) |
296 | { | 282 | { |
297 | struct max8925_rtc_info *info = platform_get_drvdata(pdev); | 283 | struct max8925_rtc_info *info = platform_get_drvdata(pdev); |
298 | 284 | ||
299 | if (info) { | 285 | if (info) { |
300 | free_irq(info->irq, info); | 286 | free_irq(info->chip->irq_base + MAX8925_IRQ_RTC_ALARM0, info); |
301 | rtc_device_unregister(info->rtc_dev); | 287 | rtc_device_unregister(info->rtc_dev); |
302 | kfree(info); | 288 | kfree(info); |
303 | } | 289 | } |
304 | return 0; | 290 | return 0; |
305 | } | 291 | } |
306 | 292 | ||
307 | #ifdef CONFIG_PM_SLEEP | ||
308 | static int max8925_rtc_suspend(struct device *dev) | ||
309 | { | ||
310 | struct platform_device *pdev = to_platform_device(dev); | ||
311 | struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); | ||
312 | |||
313 | if (device_may_wakeup(dev)) | ||
314 | chip->wakeup_flag |= 1 << MAX8925_IRQ_RTC_ALARM0; | ||
315 | return 0; | ||
316 | } | ||
317 | static int max8925_rtc_resume(struct device *dev) | ||
318 | { | ||
319 | struct platform_device *pdev = to_platform_device(dev); | ||
320 | struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); | ||
321 | |||
322 | if (device_may_wakeup(dev)) | ||
323 | chip->wakeup_flag &= ~(1 << MAX8925_IRQ_RTC_ALARM0); | ||
324 | return 0; | ||
325 | } | ||
326 | #endif | ||
327 | |||
328 | static SIMPLE_DEV_PM_OPS(max8925_rtc_pm_ops, max8925_rtc_suspend, max8925_rtc_resume); | ||
329 | |||
330 | static struct platform_driver max8925_rtc_driver = { | 293 | static struct platform_driver max8925_rtc_driver = { |
331 | .driver = { | 294 | .driver = { |
332 | .name = "max8925-rtc", | 295 | .name = "max8925-rtc", |
333 | .owner = THIS_MODULE, | 296 | .owner = THIS_MODULE, |
334 | .pm = &max8925_rtc_pm_ops, | ||
335 | }, | 297 | }, |
336 | .probe = max8925_rtc_probe, | 298 | .probe = max8925_rtc_probe, |
337 | .remove = max8925_rtc_remove, | 299 | .remove = __devexit_p(max8925_rtc_remove), |
338 | }; | 300 | }; |
339 | 301 | ||
340 | module_platform_driver(max8925_rtc_driver); | 302 | static int __init max8925_rtc_init(void) |
303 | { | ||
304 | return platform_driver_register(&max8925_rtc_driver); | ||
305 | } | ||
306 | module_init(max8925_rtc_init); | ||
307 | |||
308 | static void __exit max8925_rtc_exit(void) | ||
309 | { | ||
310 | platform_driver_unregister(&max8925_rtc_driver); | ||
311 | } | ||
312 | module_exit(max8925_rtc_exit); | ||
341 | 313 | ||
342 | MODULE_DESCRIPTION("Maxim MAX8925 RTC driver"); | 314 | MODULE_DESCRIPTION("Maxim MAX8925 RTC driver"); |
343 | MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); | 315 | MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); |
diff --git a/drivers/rtc/rtc-max8998.c b/drivers/rtc/rtc-max8998.c index 8f234a075e8..2e48aa60427 100644 --- a/drivers/rtc/rtc-max8998.c +++ b/drivers/rtc/rtc-max8998.c | |||
@@ -249,7 +249,7 @@ static const struct rtc_class_ops max8998_rtc_ops = { | |||
249 | .alarm_irq_enable = max8998_rtc_alarm_irq_enable, | 249 | .alarm_irq_enable = max8998_rtc_alarm_irq_enable, |
250 | }; | 250 | }; |
251 | 251 | ||
252 | static int max8998_rtc_probe(struct platform_device *pdev) | 252 | static int __devinit max8998_rtc_probe(struct platform_device *pdev) |
253 | { | 253 | { |
254 | struct max8998_dev *max8998 = dev_get_drvdata(pdev->dev.parent); | 254 | struct max8998_dev *max8998 = dev_get_drvdata(pdev->dev.parent); |
255 | struct max8998_platform_data *pdata = dev_get_platdata(max8998->dev); | 255 | struct max8998_platform_data *pdata = dev_get_platdata(max8998->dev); |
@@ -298,7 +298,7 @@ out_rtc: | |||
298 | return ret; | 298 | return ret; |
299 | } | 299 | } |
300 | 300 | ||
301 | static int max8998_rtc_remove(struct platform_device *pdev) | 301 | static int __devexit max8998_rtc_remove(struct platform_device *pdev) |
302 | { | 302 | { |
303 | struct max8998_rtc_info *info = platform_get_drvdata(pdev); | 303 | struct max8998_rtc_info *info = platform_get_drvdata(pdev); |
304 | 304 | ||
@@ -323,11 +323,21 @@ static struct platform_driver max8998_rtc_driver = { | |||
323 | .owner = THIS_MODULE, | 323 | .owner = THIS_MODULE, |
324 | }, | 324 | }, |
325 | .probe = max8998_rtc_probe, | 325 | .probe = max8998_rtc_probe, |
326 | .remove = max8998_rtc_remove, | 326 | .remove = __devexit_p(max8998_rtc_remove), |
327 | .id_table = max8998_rtc_id, | 327 | .id_table = max8998_rtc_id, |
328 | }; | 328 | }; |
329 | 329 | ||
330 | module_platform_driver(max8998_rtc_driver); | 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); | ||
331 | 341 | ||
332 | MODULE_AUTHOR("Minkyu Kang <mk7.kang@samsung.com>"); | 342 | MODULE_AUTHOR("Minkyu Kang <mk7.kang@samsung.com>"); |
333 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); | 343 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); |
diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c index 2643d887492..a1a278bc340 100644 --- a/drivers/rtc/rtc-mc13xxx.c +++ b/drivers/rtc/rtc-mc13xxx.c | |||
@@ -309,7 +309,7 @@ static irqreturn_t mc13xxx_rtc_reset_handler(int irq, void *dev) | |||
309 | return IRQ_HANDLED; | 309 | return IRQ_HANDLED; |
310 | } | 310 | } |
311 | 311 | ||
312 | static int __init mc13xxx_rtc_probe(struct platform_device *pdev) | 312 | static int __devinit mc13xxx_rtc_probe(struct platform_device *pdev) |
313 | { | 313 | { |
314 | int ret; | 314 | int ret; |
315 | struct mc13xxx_rtc *priv; | 315 | struct mc13xxx_rtc *priv; |
@@ -378,7 +378,7 @@ err_reset_irq_request: | |||
378 | return ret; | 378 | return ret; |
379 | } | 379 | } |
380 | 380 | ||
381 | static int __exit mc13xxx_rtc_remove(struct platform_device *pdev) | 381 | static int __devexit mc13xxx_rtc_remove(struct platform_device *pdev) |
382 | { | 382 | { |
383 | struct mc13xxx_rtc *priv = platform_get_drvdata(pdev); | 383 | struct mc13xxx_rtc *priv = platform_get_drvdata(pdev); |
384 | 384 | ||
@@ -399,21 +399,18 @@ static int __exit mc13xxx_rtc_remove(struct platform_device *pdev) | |||
399 | return 0; | 399 | return 0; |
400 | } | 400 | } |
401 | 401 | ||
402 | static const struct platform_device_id mc13xxx_rtc_idtable[] = { | 402 | const struct platform_device_id mc13xxx_rtc_idtable[] = { |
403 | { | 403 | { |
404 | .name = "mc13783-rtc", | 404 | .name = "mc13783-rtc", |
405 | }, { | 405 | }, { |
406 | .name = "mc13892-rtc", | 406 | .name = "mc13892-rtc", |
407 | }, { | ||
408 | .name = "mc34708-rtc", | ||
409 | }, | 407 | }, |
410 | { /* sentinel */ } | 408 | { } |
411 | }; | 409 | }; |
412 | MODULE_DEVICE_TABLE(platform, mc13xxx_rtc_idtable); | ||
413 | 410 | ||
414 | static struct platform_driver mc13xxx_rtc_driver = { | 411 | static struct platform_driver mc13xxx_rtc_driver = { |
415 | .id_table = mc13xxx_rtc_idtable, | 412 | .id_table = mc13xxx_rtc_idtable, |
416 | .remove = __exit_p(mc13xxx_rtc_remove), | 413 | .remove = __devexit_p(mc13xxx_rtc_remove), |
417 | .driver = { | 414 | .driver = { |
418 | .name = DRIVER_NAME, | 415 | .name = DRIVER_NAME, |
419 | .owner = THIS_MODULE, | 416 | .owner = THIS_MODULE, |
@@ -435,3 +432,4 @@ module_exit(mc13xxx_rtc_exit); | |||
435 | MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); | 432 | MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); |
436 | MODULE_DESCRIPTION("RTC driver for Freescale MC13XXX PMIC"); | 433 | MODULE_DESCRIPTION("RTC driver for Freescale MC13XXX PMIC"); |
437 | MODULE_LICENSE("GPL v2"); | 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 bec10be96f8..da60915818b 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c | |||
@@ -306,7 +306,7 @@ static const struct rtc_class_ops mpc5200_rtc_ops = { | |||
306 | .alarm_irq_enable = mpc5121_rtc_alarm_irq_enable, | 306 | .alarm_irq_enable = mpc5121_rtc_alarm_irq_enable, |
307 | }; | 307 | }; |
308 | 308 | ||
309 | static int mpc5121_rtc_probe(struct platform_device *op) | 309 | static int __devinit mpc5121_rtc_probe(struct platform_device *op) |
310 | { | 310 | { |
311 | struct mpc5121_rtc_data *rtc; | 311 | struct mpc5121_rtc_data *rtc; |
312 | int err = 0; | 312 | int err = 0; |
@@ -327,7 +327,7 @@ static int mpc5121_rtc_probe(struct platform_device *op) | |||
327 | dev_set_drvdata(&op->dev, rtc); | 327 | dev_set_drvdata(&op->dev, rtc); |
328 | 328 | ||
329 | rtc->irq = irq_of_parse_and_map(op->dev.of_node, 1); | 329 | rtc->irq = irq_of_parse_and_map(op->dev.of_node, 1); |
330 | err = request_irq(rtc->irq, mpc5121_rtc_handler, 0, | 330 | err = request_irq(rtc->irq, mpc5121_rtc_handler, IRQF_DISABLED, |
331 | "mpc5121-rtc", &op->dev); | 331 | "mpc5121-rtc", &op->dev); |
332 | if (err) { | 332 | if (err) { |
333 | dev_err(&op->dev, "%s: could not request irq: %i\n", | 333 | dev_err(&op->dev, "%s: could not request irq: %i\n", |
@@ -337,7 +337,7 @@ static int mpc5121_rtc_probe(struct platform_device *op) | |||
337 | 337 | ||
338 | rtc->irq_periodic = irq_of_parse_and_map(op->dev.of_node, 0); | 338 | rtc->irq_periodic = irq_of_parse_and_map(op->dev.of_node, 0); |
339 | err = request_irq(rtc->irq_periodic, mpc5121_rtc_handler_upd, | 339 | err = request_irq(rtc->irq_periodic, mpc5121_rtc_handler_upd, |
340 | 0, "mpc5121-rtc_upd", &op->dev); | 340 | IRQF_DISABLED, "mpc5121-rtc_upd", &op->dev); |
341 | if (err) { | 341 | if (err) { |
342 | dev_err(&op->dev, "%s: could not request irq: %i\n", | 342 | dev_err(&op->dev, "%s: could not request irq: %i\n", |
343 | __func__, rtc->irq_periodic); | 343 | __func__, rtc->irq_periodic); |
@@ -364,7 +364,6 @@ static int mpc5121_rtc_probe(struct platform_device *op) | |||
364 | err = PTR_ERR(rtc->rtc); | 364 | err = PTR_ERR(rtc->rtc); |
365 | goto out_free_irq; | 365 | goto out_free_irq; |
366 | } | 366 | } |
367 | rtc->rtc->uie_unsupported = 1; | ||
368 | 367 | ||
369 | return 0; | 368 | return 0; |
370 | 369 | ||
@@ -382,7 +381,7 @@ out_free: | |||
382 | return err; | 381 | return err; |
383 | } | 382 | } |
384 | 383 | ||
385 | static int mpc5121_rtc_remove(struct platform_device *op) | 384 | static int __devexit mpc5121_rtc_remove(struct platform_device *op) |
386 | { | 385 | { |
387 | struct mpc5121_rtc_data *rtc = dev_get_drvdata(&op->dev); | 386 | struct mpc5121_rtc_data *rtc = dev_get_drvdata(&op->dev); |
388 | struct mpc5121_rtc_regs __iomem *regs = rtc->regs; | 387 | struct mpc5121_rtc_regs __iomem *regs = rtc->regs; |
@@ -403,7 +402,7 @@ static int mpc5121_rtc_remove(struct platform_device *op) | |||
403 | return 0; | 402 | return 0; |
404 | } | 403 | } |
405 | 404 | ||
406 | static struct of_device_id mpc5121_rtc_match[] = { | 405 | static struct of_device_id mpc5121_rtc_match[] __devinitdata = { |
407 | { .compatible = "fsl,mpc5121-rtc", }, | 406 | { .compatible = "fsl,mpc5121-rtc", }, |
408 | { .compatible = "fsl,mpc5200-rtc", }, | 407 | { .compatible = "fsl,mpc5200-rtc", }, |
409 | {}, | 408 | {}, |
@@ -416,10 +415,20 @@ static struct platform_driver mpc5121_rtc_driver = { | |||
416 | .of_match_table = mpc5121_rtc_match, | 415 | .of_match_table = mpc5121_rtc_match, |
417 | }, | 416 | }, |
418 | .probe = mpc5121_rtc_probe, | 417 | .probe = mpc5121_rtc_probe, |
419 | .remove = mpc5121_rtc_remove, | 418 | .remove = __devexit_p(mpc5121_rtc_remove), |
420 | }; | 419 | }; |
421 | 420 | ||
422 | module_platform_driver(mpc5121_rtc_driver); | 421 | static int __init mpc5121_rtc_init(void) |
422 | { | ||
423 | return platform_driver_register(&mpc5121_rtc_driver); | ||
424 | } | ||
425 | module_init(mpc5121_rtc_init); | ||
426 | |||
427 | static void __exit mpc5121_rtc_exit(void) | ||
428 | { | ||
429 | platform_driver_unregister(&mpc5121_rtc_driver); | ||
430 | } | ||
431 | module_exit(mpc5121_rtc_exit); | ||
423 | 432 | ||
424 | MODULE_LICENSE("GPL"); | 433 | MODULE_LICENSE("GPL"); |
425 | MODULE_AUTHOR("John Rigby <jcrigby@gmail.com>"); | 434 | MODULE_AUTHOR("John Rigby <jcrigby@gmail.com>"); |
diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c index 578baf9d972..d33544802a2 100644 --- a/drivers/rtc/rtc-mrst.c +++ b/drivers/rtc/rtc-mrst.c | |||
@@ -76,15 +76,12 @@ static inline unsigned char vrtc_is_updating(void) | |||
76 | /* | 76 | /* |
77 | * rtc_time's year contains the increment over 1900, but vRTC's YEAR | 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 | 78 | * register can't be programmed to value larger than 0x64, so vRTC |
79 | * driver chose to use 1972 (1970 is UNIX time start point) as the base, | 79 | * driver chose to use 1960 (1970 is UNIX time start point) as the base, |
80 | * and does the translation at read/write time. | 80 | * and does the translation at read/write time. |
81 | * | 81 | * |
82 | * Why not just use 1970 as the offset? it's because using 1972 will | 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 | 83 | * make it consistent in leap year setting for both vrtc and low-level |
84 | * physical rtc devices. Then why not use 1960 as the offset? If we use | 84 | * physical rtc devices. |
85 | * 1960, for a device's first use, its YEAR register is 0 and the system | ||
86 | * year will be parsed as 1960 which is not a valid UNIX time and will | ||
87 | * cause many applications to fail mysteriously. | ||
88 | */ | 85 | */ |
89 | static int mrst_read_time(struct device *dev, struct rtc_time *time) | 86 | static int mrst_read_time(struct device *dev, struct rtc_time *time) |
90 | { | 87 | { |
@@ -102,10 +99,10 @@ static int mrst_read_time(struct device *dev, struct rtc_time *time) | |||
102 | time->tm_year = vrtc_cmos_read(RTC_YEAR); | 99 | time->tm_year = vrtc_cmos_read(RTC_YEAR); |
103 | spin_unlock_irqrestore(&rtc_lock, flags); | 100 | spin_unlock_irqrestore(&rtc_lock, flags); |
104 | 101 | ||
105 | /* Adjust for the 1972/1900 */ | 102 | /* Adjust for the 1960/1900 */ |
106 | time->tm_year += 72; | 103 | time->tm_year += 60; |
107 | time->tm_mon--; | 104 | time->tm_mon--; |
108 | return rtc_valid_tm(time); | 105 | return RTC_24H; |
109 | } | 106 | } |
110 | 107 | ||
111 | static int mrst_set_time(struct device *dev, struct rtc_time *time) | 108 | static int mrst_set_time(struct device *dev, struct rtc_time *time) |
@@ -122,9 +119,9 @@ static int mrst_set_time(struct device *dev, struct rtc_time *time) | |||
122 | min = time->tm_min; | 119 | min = time->tm_min; |
123 | sec = time->tm_sec; | 120 | sec = time->tm_sec; |
124 | 121 | ||
125 | if (yrs < 72 || yrs > 138) | 122 | if (yrs < 70 || yrs > 138) |
126 | return -EINVAL; | 123 | return -EINVAL; |
127 | yrs -= 72; | 124 | yrs -= 60; |
128 | 125 | ||
129 | spin_lock_irqsave(&rtc_lock, flags); | 126 | spin_lock_irqsave(&rtc_lock, flags); |
130 | 127 | ||
@@ -322,8 +319,8 @@ static irqreturn_t mrst_rtc_irq(int irq, void *p) | |||
322 | return IRQ_NONE; | 319 | return IRQ_NONE; |
323 | } | 320 | } |
324 | 321 | ||
325 | static int vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, | 322 | static int __devinit |
326 | int rtc_irq) | 323 | vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq) |
327 | { | 324 | { |
328 | int retval = 0; | 325 | int retval = 0; |
329 | unsigned char rtc_control; | 326 | unsigned char rtc_control; |
@@ -366,7 +363,7 @@ static int vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, | |||
366 | 363 | ||
367 | if (rtc_irq) { | 364 | if (rtc_irq) { |
368 | retval = request_irq(rtc_irq, mrst_rtc_irq, | 365 | retval = request_irq(rtc_irq, mrst_rtc_irq, |
369 | 0, dev_name(&mrst_rtc.rtc->dev), | 366 | IRQF_DISABLED, dev_name(&mrst_rtc.rtc->dev), |
370 | mrst_rtc.rtc); | 367 | mrst_rtc.rtc); |
371 | if (retval < 0) { | 368 | if (retval < 0) { |
372 | dev_dbg(dev, "IRQ %d is already in use, err %d\n", | 369 | dev_dbg(dev, "IRQ %d is already in use, err %d\n", |
@@ -394,7 +391,7 @@ static void rtc_mrst_do_shutdown(void) | |||
394 | spin_unlock_irq(&rtc_lock); | 391 | spin_unlock_irq(&rtc_lock); |
395 | } | 392 | } |
396 | 393 | ||
397 | static void rtc_mrst_do_remove(struct device *dev) | 394 | static void __devexit rtc_mrst_do_remove(struct device *dev) |
398 | { | 395 | { |
399 | struct mrst_rtc *mrst = dev_get_drvdata(dev); | 396 | struct mrst_rtc *mrst = dev_get_drvdata(dev); |
400 | struct resource *iomem; | 397 | struct resource *iomem; |
@@ -503,14 +500,14 @@ static inline int mrst_poweroff(struct device *dev) | |||
503 | 500 | ||
504 | #endif | 501 | #endif |
505 | 502 | ||
506 | static int vrtc_mrst_platform_probe(struct platform_device *pdev) | 503 | static int __devinit vrtc_mrst_platform_probe(struct platform_device *pdev) |
507 | { | 504 | { |
508 | return vrtc_mrst_do_probe(&pdev->dev, | 505 | return vrtc_mrst_do_probe(&pdev->dev, |
509 | platform_get_resource(pdev, IORESOURCE_MEM, 0), | 506 | platform_get_resource(pdev, IORESOURCE_MEM, 0), |
510 | platform_get_irq(pdev, 0)); | 507 | platform_get_irq(pdev, 0)); |
511 | } | 508 | } |
512 | 509 | ||
513 | static int vrtc_mrst_platform_remove(struct platform_device *pdev) | 510 | static int __devexit vrtc_mrst_platform_remove(struct platform_device *pdev) |
514 | { | 511 | { |
515 | rtc_mrst_do_remove(&pdev->dev); | 512 | rtc_mrst_do_remove(&pdev->dev); |
516 | return 0; | 513 | return 0; |
@@ -528,7 +525,7 @@ MODULE_ALIAS("platform:vrtc_mrst"); | |||
528 | 525 | ||
529 | static struct platform_driver vrtc_mrst_platform_driver = { | 526 | static struct platform_driver vrtc_mrst_platform_driver = { |
530 | .probe = vrtc_mrst_platform_probe, | 527 | .probe = vrtc_mrst_platform_probe, |
531 | .remove = vrtc_mrst_platform_remove, | 528 | .remove = __devexit_p(vrtc_mrst_platform_remove), |
532 | .shutdown = vrtc_mrst_platform_shutdown, | 529 | .shutdown = vrtc_mrst_platform_shutdown, |
533 | .driver = { | 530 | .driver = { |
534 | .name = (char *) driver_name, | 531 | .name = (char *) driver_name, |
@@ -537,7 +534,18 @@ static struct platform_driver vrtc_mrst_platform_driver = { | |||
537 | } | 534 | } |
538 | }; | 535 | }; |
539 | 536 | ||
540 | module_platform_driver(vrtc_mrst_platform_driver); | 537 | static int __init vrtc_mrst_init(void) |
538 | { | ||
539 | return platform_driver_register(&vrtc_mrst_platform_driver); | ||
540 | } | ||
541 | |||
542 | static void __exit vrtc_mrst_exit(void) | ||
543 | { | ||
544 | platform_driver_unregister(&vrtc_mrst_platform_driver); | ||
545 | } | ||
546 | |||
547 | module_init(vrtc_mrst_init); | ||
548 | module_exit(vrtc_mrst_exit); | ||
541 | 549 | ||
542 | MODULE_AUTHOR("Jacob Pan; Feng Tang"); | 550 | MODULE_AUTHOR("Jacob Pan; Feng Tang"); |
543 | MODULE_DESCRIPTION("Driver for Moorestown virtual RTC"); | 551 | MODULE_DESCRIPTION("Driver for Moorestown virtual RTC"); |
diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c index 57233c88599..60627a76451 100644 --- a/drivers/rtc/rtc-mv.c +++ b/drivers/rtc/rtc-mv.c | |||
@@ -12,10 +12,8 @@ | |||
12 | #include <linux/bcd.h> | 12 | #include <linux/bcd.h> |
13 | #include <linux/io.h> | 13 | #include <linux/io.h> |
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/of.h> | ||
16 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
17 | #include <linux/gfp.h> | 16 | #include <linux/gfp.h> |
18 | #include <linux/module.h> | ||
19 | 17 | ||
20 | 18 | ||
21 | #define RTC_TIME_REG_OFFS 0 | 19 | #define RTC_TIME_REG_OFFS 0 |
@@ -215,7 +213,7 @@ static const struct rtc_class_ops mv_rtc_alarm_ops = { | |||
215 | .alarm_irq_enable = mv_rtc_alarm_irq_enable, | 213 | .alarm_irq_enable = mv_rtc_alarm_irq_enable, |
216 | }; | 214 | }; |
217 | 215 | ||
218 | static int mv_rtc_probe(struct platform_device *pdev) | 216 | static int __devinit mv_rtc_probe(struct platform_device *pdev) |
219 | { | 217 | { |
220 | struct resource *res; | 218 | struct resource *res; |
221 | struct rtc_plat_data *pdata; | 219 | struct rtc_plat_data *pdata; |
@@ -274,7 +272,7 @@ static int mv_rtc_probe(struct platform_device *pdev) | |||
274 | if (pdata->irq >= 0) { | 272 | if (pdata->irq >= 0) { |
275 | writel(0, pdata->ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS); | 273 | writel(0, pdata->ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS); |
276 | if (devm_request_irq(&pdev->dev, pdata->irq, mv_rtc_interrupt, | 274 | if (devm_request_irq(&pdev->dev, pdata->irq, mv_rtc_interrupt, |
277 | IRQF_SHARED, | 275 | IRQF_DISABLED | IRQF_SHARED, |
278 | pdev->name, pdata) < 0) { | 276 | pdev->name, pdata) < 0) { |
279 | dev_warn(&pdev->dev, "interrupt not available.\n"); | 277 | dev_warn(&pdev->dev, "interrupt not available.\n"); |
280 | pdata->irq = -1; | 278 | pdata->irq = -1; |
@@ -295,19 +293,11 @@ static int __exit mv_rtc_remove(struct platform_device *pdev) | |||
295 | return 0; | 293 | return 0; |
296 | } | 294 | } |
297 | 295 | ||
298 | #ifdef CONFIG_OF | ||
299 | static struct of_device_id rtc_mv_of_match_table[] = { | ||
300 | { .compatible = "marvell,orion-rtc", }, | ||
301 | {} | ||
302 | }; | ||
303 | #endif | ||
304 | |||
305 | static struct platform_driver mv_rtc_driver = { | 296 | static struct platform_driver mv_rtc_driver = { |
306 | .remove = __exit_p(mv_rtc_remove), | 297 | .remove = __exit_p(mv_rtc_remove), |
307 | .driver = { | 298 | .driver = { |
308 | .name = "rtc-mv", | 299 | .name = "rtc-mv", |
309 | .owner = THIS_MODULE, | 300 | .owner = THIS_MODULE, |
310 | .of_match_table = of_match_ptr(rtc_mv_of_match_table), | ||
311 | }, | 301 | }, |
312 | }; | 302 | }; |
313 | 303 | ||
diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index 1c3ef728956..39e41fbdf08 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
19 | 19 | ||
20 | #include <mach/hardware.h> | ||
21 | |||
20 | #define RTC_INPUT_CLK_32768HZ (0x00 << 5) | 22 | #define RTC_INPUT_CLK_32768HZ (0x00 << 5) |
21 | #define RTC_INPUT_CLK_32000HZ (0x01 << 5) | 23 | #define RTC_INPUT_CLK_32000HZ (0x01 << 5) |
22 | #define RTC_INPUT_CLK_38400HZ (0x02 << 5) | 24 | #define RTC_INPUT_CLK_38400HZ (0x02 << 5) |
@@ -70,37 +72,13 @@ static const u32 PIE_BIT_DEF[MAX_PIE_NUM][2] = { | |||
70 | #define RTC_TEST2 0x2C /* 32bit rtc test reg 2 */ | 72 | #define RTC_TEST2 0x2C /* 32bit rtc test reg 2 */ |
71 | #define RTC_TEST3 0x30 /* 32bit rtc test reg 3 */ | 73 | #define RTC_TEST3 0x30 /* 32bit rtc test reg 3 */ |
72 | 74 | ||
73 | enum imx_rtc_type { | ||
74 | IMX1_RTC, | ||
75 | IMX21_RTC, | ||
76 | }; | ||
77 | |||
78 | struct rtc_plat_data { | 75 | struct rtc_plat_data { |
79 | struct rtc_device *rtc; | 76 | struct rtc_device *rtc; |
80 | void __iomem *ioaddr; | 77 | void __iomem *ioaddr; |
81 | int irq; | 78 | int irq; |
82 | struct clk *clk; | 79 | struct clk *clk; |
83 | struct rtc_time g_rtc_alarm; | 80 | struct rtc_time g_rtc_alarm; |
84 | enum imx_rtc_type devtype; | ||
85 | }; | ||
86 | |||
87 | static struct platform_device_id imx_rtc_devtype[] = { | ||
88 | { | ||
89 | .name = "imx1-rtc", | ||
90 | .driver_data = IMX1_RTC, | ||
91 | }, { | ||
92 | .name = "imx21-rtc", | ||
93 | .driver_data = IMX21_RTC, | ||
94 | }, { | ||
95 | /* sentinel */ | ||
96 | } | ||
97 | }; | 81 | }; |
98 | MODULE_DEVICE_TABLE(platform, imx_rtc_devtype); | ||
99 | |||
100 | static inline int is_imx1_rtc(struct rtc_plat_data *data) | ||
101 | { | ||
102 | return data->devtype == IMX1_RTC; | ||
103 | } | ||
104 | 82 | ||
105 | /* | 83 | /* |
106 | * This function is used to obtain the RTC time or the alarm value in | 84 | * This function is used to obtain the RTC time or the alarm value in |
@@ -177,6 +155,7 @@ static int rtc_update_alarm(struct device *dev, struct rtc_time *alrm) | |||
177 | { | 155 | { |
178 | struct rtc_time alarm_tm, now_tm; | 156 | struct rtc_time alarm_tm, now_tm; |
179 | unsigned long now, time; | 157 | unsigned long now, time; |
158 | int ret; | ||
180 | struct platform_device *pdev = to_platform_device(dev); | 159 | struct platform_device *pdev = to_platform_device(dev); |
181 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 160 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
182 | void __iomem *ioaddr = pdata->ioaddr; | 161 | void __iomem *ioaddr = pdata->ioaddr; |
@@ -189,33 +168,21 @@ static int rtc_update_alarm(struct device *dev, struct rtc_time *alrm) | |||
189 | alarm_tm.tm_hour = alrm->tm_hour; | 168 | alarm_tm.tm_hour = alrm->tm_hour; |
190 | alarm_tm.tm_min = alrm->tm_min; | 169 | alarm_tm.tm_min = alrm->tm_min; |
191 | alarm_tm.tm_sec = alrm->tm_sec; | 170 | alarm_tm.tm_sec = alrm->tm_sec; |
171 | rtc_tm_to_time(&now_tm, &now); | ||
192 | rtc_tm_to_time(&alarm_tm, &time); | 172 | rtc_tm_to_time(&alarm_tm, &time); |
193 | 173 | ||
174 | if (time < now) { | ||
175 | time += 60 * 60 * 24; | ||
176 | rtc_time_to_tm(time, &alarm_tm); | ||
177 | } | ||
178 | |||
179 | ret = rtc_tm_to_time(&alarm_tm, &time); | ||
180 | |||
194 | /* clear all the interrupt status bits */ | 181 | /* clear all the interrupt status bits */ |
195 | writew(readw(ioaddr + RTC_RTCISR), ioaddr + RTC_RTCISR); | 182 | writew(readw(ioaddr + RTC_RTCISR), ioaddr + RTC_RTCISR); |
196 | set_alarm_or_time(dev, MXC_RTC_ALARM, time); | 183 | set_alarm_or_time(dev, MXC_RTC_ALARM, time); |
197 | 184 | ||
198 | return 0; | 185 | return ret; |
199 | } | ||
200 | |||
201 | static void mxc_rtc_irq_enable(struct device *dev, unsigned int bit, | ||
202 | unsigned int enabled) | ||
203 | { | ||
204 | struct platform_device *pdev = to_platform_device(dev); | ||
205 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | ||
206 | void __iomem *ioaddr = pdata->ioaddr; | ||
207 | u32 reg; | ||
208 | |||
209 | spin_lock_irq(&pdata->rtc->irq_lock); | ||
210 | reg = readw(ioaddr + RTC_RTCIENR); | ||
211 | |||
212 | if (enabled) | ||
213 | reg |= bit; | ||
214 | else | ||
215 | reg &= ~bit; | ||
216 | |||
217 | writew(reg, ioaddr + RTC_RTCIENR); | ||
218 | spin_unlock_irq(&pdata->rtc->irq_lock); | ||
219 | } | 186 | } |
220 | 187 | ||
221 | /* This function is the RTC interrupt service routine. */ | 188 | /* This function is the RTC interrupt service routine. */ |
@@ -224,21 +191,21 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id) | |||
224 | struct platform_device *pdev = dev_id; | 191 | struct platform_device *pdev = dev_id; |
225 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 192 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
226 | void __iomem *ioaddr = pdata->ioaddr; | 193 | void __iomem *ioaddr = pdata->ioaddr; |
227 | unsigned long flags; | ||
228 | u32 status; | 194 | u32 status; |
229 | u32 events = 0; | 195 | u32 events = 0; |
230 | 196 | ||
231 | spin_lock_irqsave(&pdata->rtc->irq_lock, flags); | 197 | spin_lock_irq(&pdata->rtc->irq_lock); |
232 | status = readw(ioaddr + RTC_RTCISR) & readw(ioaddr + RTC_RTCIENR); | 198 | status = readw(ioaddr + RTC_RTCISR) & readw(ioaddr + RTC_RTCIENR); |
233 | /* clear interrupt sources */ | 199 | /* clear interrupt sources */ |
234 | writew(status, ioaddr + RTC_RTCISR); | 200 | writew(status, ioaddr + RTC_RTCISR); |
235 | 201 | ||
202 | /* clear alarm interrupt if it has occurred */ | ||
203 | if (status & RTC_ALM_BIT) | ||
204 | status &= ~RTC_ALM_BIT; | ||
205 | |||
236 | /* update irq data & counter */ | 206 | /* update irq data & counter */ |
237 | if (status & RTC_ALM_BIT) { | 207 | if (status & RTC_ALM_BIT) |
238 | events |= (RTC_AF | RTC_IRQF); | 208 | events |= (RTC_AF | RTC_IRQF); |
239 | /* RTC alarm should be one-shot */ | ||
240 | mxc_rtc_irq_enable(&pdev->dev, RTC_ALM_BIT, 0); | ||
241 | } | ||
242 | 209 | ||
243 | if (status & RTC_1HZ_BIT) | 210 | if (status & RTC_1HZ_BIT) |
244 | events |= (RTC_UF | RTC_IRQF); | 211 | events |= (RTC_UF | RTC_IRQF); |
@@ -246,8 +213,11 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id) | |||
246 | if (status & PIT_ALL_ON) | 213 | if (status & PIT_ALL_ON) |
247 | events |= (RTC_PF | RTC_IRQF); | 214 | events |= (RTC_PF | RTC_IRQF); |
248 | 215 | ||
216 | if ((status & RTC_ALM_BIT) && rtc_valid_tm(&pdata->g_rtc_alarm)) | ||
217 | rtc_update_alarm(&pdev->dev, &pdata->g_rtc_alarm); | ||
218 | |||
249 | rtc_update_irq(pdata->rtc, 1, events); | 219 | rtc_update_irq(pdata->rtc, 1, events); |
250 | spin_unlock_irqrestore(&pdata->rtc->irq_lock, flags); | 220 | spin_unlock_irq(&pdata->rtc->irq_lock); |
251 | 221 | ||
252 | return IRQ_HANDLED; | 222 | return IRQ_HANDLED; |
253 | } | 223 | } |
@@ -272,6 +242,26 @@ static void mxc_rtc_release(struct device *dev) | |||
272 | spin_unlock_irq(&pdata->rtc->irq_lock); | 242 | spin_unlock_irq(&pdata->rtc->irq_lock); |
273 | } | 243 | } |
274 | 244 | ||
245 | static void mxc_rtc_irq_enable(struct device *dev, unsigned int bit, | ||
246 | unsigned int enabled) | ||
247 | { | ||
248 | struct platform_device *pdev = to_platform_device(dev); | ||
249 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | ||
250 | void __iomem *ioaddr = pdata->ioaddr; | ||
251 | u32 reg; | ||
252 | |||
253 | spin_lock_irq(&pdata->rtc->irq_lock); | ||
254 | reg = readw(ioaddr + RTC_RTCIENR); | ||
255 | |||
256 | if (enabled) | ||
257 | reg |= bit; | ||
258 | else | ||
259 | reg &= ~bit; | ||
260 | |||
261 | writew(reg, ioaddr + RTC_RTCIENR); | ||
262 | spin_unlock_irq(&pdata->rtc->irq_lock); | ||
263 | } | ||
264 | |||
275 | static int mxc_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | 265 | static int mxc_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) |
276 | { | 266 | { |
277 | mxc_rtc_irq_enable(dev, RTC_ALM_BIT, enabled); | 267 | mxc_rtc_irq_enable(dev, RTC_ALM_BIT, enabled); |
@@ -300,20 +290,6 @@ static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
300 | */ | 290 | */ |
301 | static int mxc_rtc_set_mmss(struct device *dev, unsigned long time) | 291 | static int mxc_rtc_set_mmss(struct device *dev, unsigned long time) |
302 | { | 292 | { |
303 | struct platform_device *pdev = to_platform_device(dev); | ||
304 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | ||
305 | |||
306 | /* | ||
307 | * TTC_DAYR register is 9-bit in MX1 SoC, save time and day of year only | ||
308 | */ | ||
309 | if (is_imx1_rtc(pdata)) { | ||
310 | struct rtc_time tm; | ||
311 | |||
312 | rtc_time_to_tm(time, &tm); | ||
313 | tm.tm_year = 70; | ||
314 | rtc_tm_to_time(&tm, &time); | ||
315 | } | ||
316 | |||
317 | /* Avoid roll-over from reading the different registers */ | 293 | /* Avoid roll-over from reading the different registers */ |
318 | do { | 294 | do { |
319 | set_alarm_or_time(dev, MXC_RTC_TIME, time); | 295 | set_alarm_or_time(dev, MXC_RTC_TIME, time); |
@@ -348,7 +324,21 @@ static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
348 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 324 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
349 | int ret; | 325 | int ret; |
350 | 326 | ||
351 | ret = rtc_update_alarm(dev, &alrm->time); | 327 | if (rtc_valid_tm(&alrm->time)) { |
328 | if (alrm->time.tm_sec > 59 || | ||
329 | alrm->time.tm_hour > 23 || | ||
330 | alrm->time.tm_min > 59) | ||
331 | return -EINVAL; | ||
332 | |||
333 | ret = rtc_update_alarm(dev, &alrm->time); | ||
334 | } else { | ||
335 | ret = rtc_valid_tm(&alrm->time); | ||
336 | if (ret) | ||
337 | return ret; | ||
338 | |||
339 | ret = rtc_update_alarm(dev, &alrm->time); | ||
340 | } | ||
341 | |||
352 | if (ret) | 342 | if (ret) |
353 | return ret; | 343 | return ret; |
354 | 344 | ||
@@ -368,7 +358,7 @@ static struct rtc_class_ops mxc_rtc_ops = { | |||
368 | .alarm_irq_enable = mxc_rtc_alarm_irq_enable, | 358 | .alarm_irq_enable = mxc_rtc_alarm_irq_enable, |
369 | }; | 359 | }; |
370 | 360 | ||
371 | static int mxc_rtc_probe(struct platform_device *pdev) | 361 | static int __init mxc_rtc_probe(struct platform_device *pdev) |
372 | { | 362 | { |
373 | struct resource *res; | 363 | struct resource *res; |
374 | struct rtc_device *rtc; | 364 | struct rtc_device *rtc; |
@@ -385,8 +375,6 @@ static int mxc_rtc_probe(struct platform_device *pdev) | |||
385 | if (!pdata) | 375 | if (!pdata) |
386 | return -ENOMEM; | 376 | return -ENOMEM; |
387 | 377 | ||
388 | pdata->devtype = pdev->id_entry->driver_data; | ||
389 | |||
390 | if (!devm_request_mem_region(&pdev->dev, res->start, | 378 | if (!devm_request_mem_region(&pdev->dev, res->start, |
391 | resource_size(res), pdev->name)) | 379 | resource_size(res), pdev->name)) |
392 | return -EBUSY; | 380 | return -EBUSY; |
@@ -394,14 +382,14 @@ static int mxc_rtc_probe(struct platform_device *pdev) | |||
394 | pdata->ioaddr = devm_ioremap(&pdev->dev, res->start, | 382 | pdata->ioaddr = devm_ioremap(&pdev->dev, res->start, |
395 | resource_size(res)); | 383 | resource_size(res)); |
396 | 384 | ||
397 | pdata->clk = devm_clk_get(&pdev->dev, NULL); | 385 | pdata->clk = clk_get(&pdev->dev, "rtc"); |
398 | if (IS_ERR(pdata->clk)) { | 386 | if (IS_ERR(pdata->clk)) { |
399 | dev_err(&pdev->dev, "unable to get clock!\n"); | 387 | dev_err(&pdev->dev, "unable to get clock!\n"); |
400 | ret = PTR_ERR(pdata->clk); | 388 | ret = PTR_ERR(pdata->clk); |
401 | goto exit_free_pdata; | 389 | goto exit_free_pdata; |
402 | } | 390 | } |
403 | 391 | ||
404 | clk_prepare_enable(pdata->clk); | 392 | clk_enable(pdata->clk); |
405 | rate = clk_get_rate(pdata->clk); | 393 | rate = clk_get_rate(pdata->clk); |
406 | 394 | ||
407 | if (rate == 32768) | 395 | if (rate == 32768) |
@@ -436,9 +424,6 @@ static int mxc_rtc_probe(struct platform_device *pdev) | |||
436 | pdata->irq = -1; | 424 | pdata->irq = -1; |
437 | } | 425 | } |
438 | 426 | ||
439 | if (pdata->irq >=0) | ||
440 | device_init_wakeup(&pdev->dev, 1); | ||
441 | |||
442 | rtc = rtc_device_register(pdev->name, &pdev->dev, &mxc_rtc_ops, | 427 | rtc = rtc_device_register(pdev->name, &pdev->dev, &mxc_rtc_ops, |
443 | THIS_MODULE); | 428 | THIS_MODULE); |
444 | if (IS_ERR(rtc)) { | 429 | if (IS_ERR(rtc)) { |
@@ -453,66 +438,47 @@ static int mxc_rtc_probe(struct platform_device *pdev) | |||
453 | exit_clr_drvdata: | 438 | exit_clr_drvdata: |
454 | platform_set_drvdata(pdev, NULL); | 439 | platform_set_drvdata(pdev, NULL); |
455 | exit_put_clk: | 440 | exit_put_clk: |
456 | clk_disable_unprepare(pdata->clk); | 441 | clk_disable(pdata->clk); |
442 | clk_put(pdata->clk); | ||
457 | 443 | ||
458 | exit_free_pdata: | 444 | exit_free_pdata: |
459 | 445 | ||
460 | return ret; | 446 | return ret; |
461 | } | 447 | } |
462 | 448 | ||
463 | static int mxc_rtc_remove(struct platform_device *pdev) | 449 | static int __exit mxc_rtc_remove(struct platform_device *pdev) |
464 | { | 450 | { |
465 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 451 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
466 | 452 | ||
467 | rtc_device_unregister(pdata->rtc); | 453 | rtc_device_unregister(pdata->rtc); |
468 | 454 | ||
469 | clk_disable_unprepare(pdata->clk); | 455 | clk_disable(pdata->clk); |
456 | clk_put(pdata->clk); | ||
470 | platform_set_drvdata(pdev, NULL); | 457 | platform_set_drvdata(pdev, NULL); |
471 | 458 | ||
472 | return 0; | 459 | return 0; |
473 | } | 460 | } |
474 | 461 | ||
475 | #ifdef CONFIG_PM | ||
476 | static int mxc_rtc_suspend(struct device *dev) | ||
477 | { | ||
478 | struct rtc_plat_data *pdata = dev_get_drvdata(dev); | ||
479 | |||
480 | if (device_may_wakeup(dev)) | ||
481 | enable_irq_wake(pdata->irq); | ||
482 | |||
483 | return 0; | ||
484 | } | ||
485 | |||
486 | static int mxc_rtc_resume(struct device *dev) | ||
487 | { | ||
488 | struct rtc_plat_data *pdata = dev_get_drvdata(dev); | ||
489 | |||
490 | if (device_may_wakeup(dev)) | ||
491 | disable_irq_wake(pdata->irq); | ||
492 | |||
493 | return 0; | ||
494 | } | ||
495 | |||
496 | static struct dev_pm_ops mxc_rtc_pm_ops = { | ||
497 | .suspend = mxc_rtc_suspend, | ||
498 | .resume = mxc_rtc_resume, | ||
499 | }; | ||
500 | #endif | ||
501 | |||
502 | static struct platform_driver mxc_rtc_driver = { | 462 | static struct platform_driver mxc_rtc_driver = { |
503 | .driver = { | 463 | .driver = { |
504 | .name = "mxc_rtc", | 464 | .name = "mxc_rtc", |
505 | #ifdef CONFIG_PM | ||
506 | .pm = &mxc_rtc_pm_ops, | ||
507 | #endif | ||
508 | .owner = THIS_MODULE, | 465 | .owner = THIS_MODULE, |
509 | }, | 466 | }, |
510 | .id_table = imx_rtc_devtype, | 467 | .remove = __exit_p(mxc_rtc_remove), |
511 | .probe = mxc_rtc_probe, | ||
512 | .remove = mxc_rtc_remove, | ||
513 | }; | 468 | }; |
514 | 469 | ||
515 | module_platform_driver(mxc_rtc_driver) | 470 | static int __init mxc_rtc_init(void) |
471 | { | ||
472 | return platform_driver_probe(&mxc_rtc_driver, mxc_rtc_probe); | ||
473 | } | ||
474 | |||
475 | static void __exit mxc_rtc_exit(void) | ||
476 | { | ||
477 | platform_driver_unregister(&mxc_rtc_driver); | ||
478 | } | ||
479 | |||
480 | module_init(mxc_rtc_init); | ||
481 | module_exit(mxc_rtc_exit); | ||
516 | 482 | ||
517 | MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); | 483 | MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); |
518 | MODULE_DESCRIPTION("RTC driver for Freescale MXC"); | 484 | MODULE_DESCRIPTION("RTC driver for Freescale MXC"); |
diff --git a/drivers/rtc/rtc-nuc900.c b/drivers/rtc/rtc-nuc900.c index a63680850fe..781068d62f2 100644 --- a/drivers/rtc/rtc-nuc900.c +++ b/drivers/rtc/rtc-nuc900.c | |||
@@ -222,7 +222,7 @@ static struct rtc_class_ops nuc900_rtc_ops = { | |||
222 | .alarm_irq_enable = nuc900_alarm_irq_enable, | 222 | .alarm_irq_enable = nuc900_alarm_irq_enable, |
223 | }; | 223 | }; |
224 | 224 | ||
225 | static int nuc900_rtc_probe(struct platform_device *pdev) | 225 | static int __devinit nuc900_rtc_probe(struct platform_device *pdev) |
226 | { | 226 | { |
227 | struct resource *res; | 227 | struct resource *res; |
228 | struct nuc900_rtc *nuc900_rtc; | 228 | struct nuc900_rtc *nuc900_rtc; |
@@ -269,7 +269,7 @@ static int nuc900_rtc_probe(struct platform_device *pdev) | |||
269 | 269 | ||
270 | nuc900_rtc->irq_num = platform_get_irq(pdev, 0); | 270 | nuc900_rtc->irq_num = platform_get_irq(pdev, 0); |
271 | if (request_irq(nuc900_rtc->irq_num, nuc900_rtc_interrupt, | 271 | if (request_irq(nuc900_rtc->irq_num, nuc900_rtc_interrupt, |
272 | 0, "nuc900rtc", nuc900_rtc)) { | 272 | IRQF_DISABLED, "nuc900rtc", nuc900_rtc)) { |
273 | dev_err(&pdev->dev, "NUC900 RTC request irq failed\n"); | 273 | dev_err(&pdev->dev, "NUC900 RTC request irq failed\n"); |
274 | err = -EBUSY; | 274 | err = -EBUSY; |
275 | goto fail4; | 275 | goto fail4; |
@@ -284,7 +284,7 @@ fail1: kfree(nuc900_rtc); | |||
284 | return err; | 284 | return err; |
285 | } | 285 | } |
286 | 286 | ||
287 | static int nuc900_rtc_remove(struct platform_device *pdev) | 287 | static int __devexit nuc900_rtc_remove(struct platform_device *pdev) |
288 | { | 288 | { |
289 | struct nuc900_rtc *nuc900_rtc = platform_get_drvdata(pdev); | 289 | struct nuc900_rtc *nuc900_rtc = platform_get_drvdata(pdev); |
290 | struct resource *res; | 290 | struct resource *res; |
@@ -304,7 +304,7 @@ static int nuc900_rtc_remove(struct platform_device *pdev) | |||
304 | } | 304 | } |
305 | 305 | ||
306 | static struct platform_driver nuc900_rtc_driver = { | 306 | static struct platform_driver nuc900_rtc_driver = { |
307 | .remove = nuc900_rtc_remove, | 307 | .remove = __devexit_p(nuc900_rtc_remove), |
308 | .driver = { | 308 | .driver = { |
309 | .name = "nuc900-rtc", | 309 | .name = "nuc900-rtc", |
310 | .owner = THIS_MODULE, | 310 | .owner = THIS_MODULE, |
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index 600971407aa..7789002bdd5 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c | |||
@@ -20,9 +20,6 @@ | |||
20 | #include <linux/rtc.h> | 20 | #include <linux/rtc.h> |
21 | #include <linux/bcd.h> | 21 | #include <linux/bcd.h> |
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/of.h> | ||
24 | #include <linux/of_device.h> | ||
25 | #include <linux/pm_runtime.h> | ||
26 | 23 | ||
27 | #include <asm/io.h> | 24 | #include <asm/io.h> |
28 | 25 | ||
@@ -41,8 +38,6 @@ | |||
41 | * the SoC). See the BOARD-SPECIFIC CUSTOMIZATION comment. | 38 | * the SoC). See the BOARD-SPECIFIC CUSTOMIZATION comment. |
42 | */ | 39 | */ |
43 | 40 | ||
44 | #define DRIVER_NAME "omap_rtc" | ||
45 | |||
46 | #define OMAP_RTC_BASE 0xfffb4800 | 41 | #define OMAP_RTC_BASE 0xfffb4800 |
47 | 42 | ||
48 | /* RTC registers */ | 43 | /* RTC registers */ |
@@ -69,9 +64,6 @@ | |||
69 | #define OMAP_RTC_COMP_MSB_REG 0x50 | 64 | #define OMAP_RTC_COMP_MSB_REG 0x50 |
70 | #define OMAP_RTC_OSC_REG 0x54 | 65 | #define OMAP_RTC_OSC_REG 0x54 |
71 | 66 | ||
72 | #define OMAP_RTC_KICK0_REG 0x6c | ||
73 | #define OMAP_RTC_KICK1_REG 0x70 | ||
74 | |||
75 | /* OMAP_RTC_CTRL_REG bit fields: */ | 67 | /* OMAP_RTC_CTRL_REG bit fields: */ |
76 | #define OMAP_RTC_CTRL_SPLIT (1<<7) | 68 | #define OMAP_RTC_CTRL_SPLIT (1<<7) |
77 | #define OMAP_RTC_CTRL_DISABLE (1<<6) | 69 | #define OMAP_RTC_CTRL_DISABLE (1<<6) |
@@ -96,18 +88,10 @@ | |||
96 | #define OMAP_RTC_INTERRUPTS_IT_ALARM (1<<3) | 88 | #define OMAP_RTC_INTERRUPTS_IT_ALARM (1<<3) |
97 | #define OMAP_RTC_INTERRUPTS_IT_TIMER (1<<2) | 89 | #define OMAP_RTC_INTERRUPTS_IT_TIMER (1<<2) |
98 | 90 | ||
99 | /* OMAP_RTC_KICKER values */ | ||
100 | #define KICK0_VALUE 0x83e70b13 | ||
101 | #define KICK1_VALUE 0x95a4f1e0 | ||
102 | |||
103 | #define OMAP_RTC_HAS_KICKER 0x1 | ||
104 | |||
105 | static void __iomem *rtc_base; | 91 | static void __iomem *rtc_base; |
106 | 92 | ||
107 | #define rtc_read(addr) readb(rtc_base + (addr)) | 93 | #define rtc_read(addr) __raw_readb(rtc_base + (addr)) |
108 | #define rtc_write(val, addr) writeb(val, rtc_base + (addr)) | 94 | #define rtc_write(val, addr) __raw_writeb(val, rtc_base + (addr)) |
109 | |||
110 | #define rtc_writel(val, addr) writel(val, rtc_base + (addr)) | ||
111 | 95 | ||
112 | 96 | ||
113 | /* we rely on the rtc framework to handle locking (rtc->ops_lock), | 97 | /* we rely on the rtc framework to handle locking (rtc->ops_lock), |
@@ -301,38 +285,11 @@ static struct rtc_class_ops omap_rtc_ops = { | |||
301 | static int omap_rtc_alarm; | 285 | static int omap_rtc_alarm; |
302 | static int omap_rtc_timer; | 286 | static int omap_rtc_timer; |
303 | 287 | ||
304 | #define OMAP_RTC_DATA_DA830_IDX 1 | ||
305 | |||
306 | static struct platform_device_id omap_rtc_devtype[] = { | ||
307 | { | ||
308 | .name = DRIVER_NAME, | ||
309 | }, { | ||
310 | .name = "da830-rtc", | ||
311 | .driver_data = OMAP_RTC_HAS_KICKER, | ||
312 | }, | ||
313 | {}, | ||
314 | }; | ||
315 | MODULE_DEVICE_TABLE(platform, omap_rtc_devtype); | ||
316 | |||
317 | static const struct of_device_id omap_rtc_of_match[] = { | ||
318 | { .compatible = "ti,da830-rtc", | ||
319 | .data = &omap_rtc_devtype[OMAP_RTC_DATA_DA830_IDX], | ||
320 | }, | ||
321 | {}, | ||
322 | }; | ||
323 | MODULE_DEVICE_TABLE(of, omap_rtc_of_match); | ||
324 | |||
325 | static int __init omap_rtc_probe(struct platform_device *pdev) | 288 | static int __init omap_rtc_probe(struct platform_device *pdev) |
326 | { | 289 | { |
327 | struct resource *res, *mem; | 290 | struct resource *res, *mem; |
328 | struct rtc_device *rtc; | 291 | struct rtc_device *rtc; |
329 | u8 reg, new_ctrl; | 292 | u8 reg, new_ctrl; |
330 | const struct platform_device_id *id_entry; | ||
331 | const struct of_device_id *of_id; | ||
332 | |||
333 | of_id = of_match_device(omap_rtc_of_match, &pdev->dev); | ||
334 | if (of_id) | ||
335 | pdev->id_entry = of_id->data; | ||
336 | 293 | ||
337 | omap_rtc_timer = platform_get_irq(pdev, 0); | 294 | omap_rtc_timer = platform_get_irq(pdev, 0); |
338 | if (omap_rtc_timer <= 0) { | 295 | if (omap_rtc_timer <= 0) { |
@@ -365,16 +322,6 @@ static int __init omap_rtc_probe(struct platform_device *pdev) | |||
365 | goto fail; | 322 | goto fail; |
366 | } | 323 | } |
367 | 324 | ||
368 | /* Enable the clock/module so that we can access the registers */ | ||
369 | pm_runtime_enable(&pdev->dev); | ||
370 | pm_runtime_get_sync(&pdev->dev); | ||
371 | |||
372 | id_entry = platform_get_device_id(pdev); | ||
373 | if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER)) { | ||
374 | rtc_writel(KICK0_VALUE, OMAP_RTC_KICK0_REG); | ||
375 | rtc_writel(KICK1_VALUE, OMAP_RTC_KICK1_REG); | ||
376 | } | ||
377 | |||
378 | rtc = rtc_device_register(pdev->name, &pdev->dev, | 325 | rtc = rtc_device_register(pdev->name, &pdev->dev, |
379 | &omap_rtc_ops, THIS_MODULE); | 326 | &omap_rtc_ops, THIS_MODULE); |
380 | if (IS_ERR(rtc)) { | 327 | if (IS_ERR(rtc)) { |
@@ -401,14 +348,14 @@ static int __init omap_rtc_probe(struct platform_device *pdev) | |||
401 | rtc_write(OMAP_RTC_STATUS_ALARM, OMAP_RTC_STATUS_REG); | 348 | rtc_write(OMAP_RTC_STATUS_ALARM, OMAP_RTC_STATUS_REG); |
402 | 349 | ||
403 | /* handle periodic and alarm irqs */ | 350 | /* handle periodic and alarm irqs */ |
404 | if (request_irq(omap_rtc_timer, rtc_irq, 0, | 351 | if (request_irq(omap_rtc_timer, rtc_irq, IRQF_DISABLED, |
405 | dev_name(&rtc->dev), rtc)) { | 352 | dev_name(&rtc->dev), rtc)) { |
406 | pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n", | 353 | pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n", |
407 | pdev->name, omap_rtc_timer); | 354 | pdev->name, omap_rtc_timer); |
408 | goto fail1; | 355 | goto fail1; |
409 | } | 356 | } |
410 | if ((omap_rtc_timer != omap_rtc_alarm) && | 357 | if ((omap_rtc_timer != omap_rtc_alarm) && |
411 | (request_irq(omap_rtc_alarm, rtc_irq, 0, | 358 | (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED, |
412 | dev_name(&rtc->dev), rtc))) { | 359 | dev_name(&rtc->dev), rtc))) { |
413 | pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n", | 360 | pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n", |
414 | pdev->name, omap_rtc_alarm); | 361 | pdev->name, omap_rtc_alarm); |
@@ -451,10 +398,6 @@ fail2: | |||
451 | fail1: | 398 | fail1: |
452 | rtc_device_unregister(rtc); | 399 | rtc_device_unregister(rtc); |
453 | fail0: | 400 | fail0: |
454 | if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER)) | ||
455 | rtc_writel(0, OMAP_RTC_KICK0_REG); | ||
456 | pm_runtime_put_sync(&pdev->dev); | ||
457 | pm_runtime_disable(&pdev->dev); | ||
458 | iounmap(rtc_base); | 401 | iounmap(rtc_base); |
459 | fail: | 402 | fail: |
460 | release_mem_region(mem->start, resource_size(mem)); | 403 | release_mem_region(mem->start, resource_size(mem)); |
@@ -465,8 +408,6 @@ static int __exit omap_rtc_remove(struct platform_device *pdev) | |||
465 | { | 408 | { |
466 | struct rtc_device *rtc = platform_get_drvdata(pdev); | 409 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
467 | struct resource *mem = dev_get_drvdata(&rtc->dev); | 410 | struct resource *mem = dev_get_drvdata(&rtc->dev); |
468 | const struct platform_device_id *id_entry = | ||
469 | platform_get_device_id(pdev); | ||
470 | 411 | ||
471 | device_init_wakeup(&pdev->dev, 0); | 412 | device_init_wakeup(&pdev->dev, 0); |
472 | 413 | ||
@@ -479,13 +420,6 @@ static int __exit omap_rtc_remove(struct platform_device *pdev) | |||
479 | free_irq(omap_rtc_alarm, rtc); | 420 | free_irq(omap_rtc_alarm, rtc); |
480 | 421 | ||
481 | rtc_device_unregister(rtc); | 422 | rtc_device_unregister(rtc); |
482 | if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER)) | ||
483 | rtc_writel(0, OMAP_RTC_KICK0_REG); | ||
484 | |||
485 | /* Disable the clock/module */ | ||
486 | pm_runtime_put_sync(&pdev->dev); | ||
487 | pm_runtime_disable(&pdev->dev); | ||
488 | |||
489 | iounmap(rtc_base); | 423 | iounmap(rtc_base); |
490 | release_mem_region(mem->start, resource_size(mem)); | 424 | release_mem_region(mem->start, resource_size(mem)); |
491 | return 0; | 425 | return 0; |
@@ -508,17 +442,11 @@ static int omap_rtc_suspend(struct platform_device *pdev, pm_message_t state) | |||
508 | else | 442 | else |
509 | rtc_write(0, OMAP_RTC_INTERRUPTS_REG); | 443 | rtc_write(0, OMAP_RTC_INTERRUPTS_REG); |
510 | 444 | ||
511 | /* Disable the clock/module */ | ||
512 | pm_runtime_put_sync(&pdev->dev); | ||
513 | |||
514 | return 0; | 445 | return 0; |
515 | } | 446 | } |
516 | 447 | ||
517 | static int omap_rtc_resume(struct platform_device *pdev) | 448 | static int omap_rtc_resume(struct platform_device *pdev) |
518 | { | 449 | { |
519 | /* Enable the clock/module so that we can access the registers */ | ||
520 | pm_runtime_get_sync(&pdev->dev); | ||
521 | |||
522 | if (device_may_wakeup(&pdev->dev)) | 450 | if (device_may_wakeup(&pdev->dev)) |
523 | disable_irq_wake(omap_rtc_alarm); | 451 | disable_irq_wake(omap_rtc_alarm); |
524 | else | 452 | else |
@@ -543,11 +471,9 @@ static struct platform_driver omap_rtc_driver = { | |||
543 | .resume = omap_rtc_resume, | 471 | .resume = omap_rtc_resume, |
544 | .shutdown = omap_rtc_shutdown, | 472 | .shutdown = omap_rtc_shutdown, |
545 | .driver = { | 473 | .driver = { |
546 | .name = DRIVER_NAME, | 474 | .name = "omap_rtc", |
547 | .owner = THIS_MODULE, | 475 | .owner = THIS_MODULE, |
548 | .of_match_table = of_match_ptr(omap_rtc_of_match), | ||
549 | }, | 476 | }, |
550 | .id_table = omap_rtc_devtype, | ||
551 | }; | 477 | }; |
552 | 478 | ||
553 | static int __init rtc_init(void) | 479 | static int __init rtc_init(void) |
diff --git a/drivers/rtc/rtc-pcap.c b/drivers/rtc/rtc-pcap.c index e0019cd0bf7..cd4f198cc2e 100644 --- a/drivers/rtc/rtc-pcap.c +++ b/drivers/rtc/rtc-pcap.c | |||
@@ -139,7 +139,7 @@ static const struct rtc_class_ops pcap_rtc_ops = { | |||
139 | .alarm_irq_enable = pcap_rtc_alarm_irq_enable, | 139 | .alarm_irq_enable = pcap_rtc_alarm_irq_enable, |
140 | }; | 140 | }; |
141 | 141 | ||
142 | static int pcap_rtc_probe(struct platform_device *pdev) | 142 | static int __devinit pcap_rtc_probe(struct platform_device *pdev) |
143 | { | 143 | { |
144 | struct pcap_rtc *pcap_rtc; | 144 | struct pcap_rtc *pcap_rtc; |
145 | int timer_irq, alarm_irq; | 145 | int timer_irq, alarm_irq; |
@@ -183,7 +183,7 @@ fail_rtc: | |||
183 | return err; | 183 | return err; |
184 | } | 184 | } |
185 | 185 | ||
186 | static int pcap_rtc_remove(struct platform_device *pdev) | 186 | static int __devexit pcap_rtc_remove(struct platform_device *pdev) |
187 | { | 187 | { |
188 | struct pcap_rtc *pcap_rtc = platform_get_drvdata(pdev); | 188 | struct pcap_rtc *pcap_rtc = platform_get_drvdata(pdev); |
189 | 189 | ||
@@ -196,7 +196,7 @@ static int pcap_rtc_remove(struct platform_device *pdev) | |||
196 | } | 196 | } |
197 | 197 | ||
198 | static struct platform_driver pcap_rtc_driver = { | 198 | static struct platform_driver pcap_rtc_driver = { |
199 | .remove = pcap_rtc_remove, | 199 | .remove = __devexit_p(pcap_rtc_remove), |
200 | .driver = { | 200 | .driver = { |
201 | .name = "pcap-rtc", | 201 | .name = "pcap-rtc", |
202 | .owner = THIS_MODULE, | 202 | .owner = THIS_MODULE, |
diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c index 02b742afa76..71bab0ef544 100644 --- a/drivers/rtc/rtc-pcf2123.c +++ b/drivers/rtc/rtc-pcf2123.c | |||
@@ -42,8 +42,6 @@ | |||
42 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
43 | #include <linux/rtc.h> | 43 | #include <linux/rtc.h> |
44 | #include <linux/spi/spi.h> | 44 | #include <linux/spi/spi.h> |
45 | #include <linux/module.h> | ||
46 | #include <linux/sysfs.h> | ||
47 | 45 | ||
48 | #define DRV_VERSION "0.6" | 46 | #define DRV_VERSION "0.6" |
49 | 47 | ||
@@ -219,7 +217,7 @@ static const struct rtc_class_ops pcf2123_rtc_ops = { | |||
219 | .set_time = pcf2123_rtc_set_time, | 217 | .set_time = pcf2123_rtc_set_time, |
220 | }; | 218 | }; |
221 | 219 | ||
222 | static int pcf2123_probe(struct spi_device *spi) | 220 | static int __devinit pcf2123_probe(struct spi_device *spi) |
223 | { | 221 | { |
224 | struct rtc_device *rtc; | 222 | struct rtc_device *rtc; |
225 | struct pcf2123_plat_data *pdata; | 223 | struct pcf2123_plat_data *pdata; |
@@ -293,7 +291,6 @@ static int pcf2123_probe(struct spi_device *spi) | |||
293 | pdata->rtc = rtc; | 291 | pdata->rtc = rtc; |
294 | 292 | ||
295 | for (i = 0; i < 16; i++) { | 293 | for (i = 0; i < 16; i++) { |
296 | sysfs_attr_init(&pdata->regs[i].attr.attr); | ||
297 | sprintf(pdata->regs[i].name, "%1x", i); | 294 | sprintf(pdata->regs[i].name, "%1x", i); |
298 | pdata->regs[i].attr.attr.mode = S_IRUGO | S_IWUSR; | 295 | pdata->regs[i].attr.attr.mode = S_IRUGO | S_IWUSR; |
299 | pdata->regs[i].attr.attr.name = pdata->regs[i].name; | 296 | pdata->regs[i].attr.attr.name = pdata->regs[i].name; |
@@ -319,7 +316,7 @@ kfree_exit: | |||
319 | return ret; | 316 | return ret; |
320 | } | 317 | } |
321 | 318 | ||
322 | static int pcf2123_remove(struct spi_device *spi) | 319 | static int __devexit pcf2123_remove(struct spi_device *spi) |
323 | { | 320 | { |
324 | struct pcf2123_plat_data *pdata = spi->dev.platform_data; | 321 | struct pcf2123_plat_data *pdata = spi->dev.platform_data; |
325 | int i; | 322 | int i; |
@@ -342,15 +339,27 @@ static int pcf2123_remove(struct spi_device *spi) | |||
342 | static struct spi_driver pcf2123_driver = { | 339 | static struct spi_driver pcf2123_driver = { |
343 | .driver = { | 340 | .driver = { |
344 | .name = "rtc-pcf2123", | 341 | .name = "rtc-pcf2123", |
342 | .bus = &spi_bus_type, | ||
345 | .owner = THIS_MODULE, | 343 | .owner = THIS_MODULE, |
346 | }, | 344 | }, |
347 | .probe = pcf2123_probe, | 345 | .probe = pcf2123_probe, |
348 | .remove = pcf2123_remove, | 346 | .remove = __devexit_p(pcf2123_remove), |
349 | }; | 347 | }; |
350 | 348 | ||
351 | module_spi_driver(pcf2123_driver); | 349 | static int __init pcf2123_init(void) |
350 | { | ||
351 | return spi_register_driver(&pcf2123_driver); | ||
352 | } | ||
353 | |||
354 | static void __exit pcf2123_exit(void) | ||
355 | { | ||
356 | spi_unregister_driver(&pcf2123_driver); | ||
357 | } | ||
352 | 358 | ||
353 | MODULE_AUTHOR("Chris Verges <chrisv@cyberswitching.com>"); | 359 | MODULE_AUTHOR("Chris Verges <chrisv@cyberswitching.com>"); |
354 | MODULE_DESCRIPTION("NXP PCF2123 RTC driver"); | 360 | MODULE_DESCRIPTION("NXP PCF2123 RTC driver"); |
355 | MODULE_LICENSE("GPL"); | 361 | MODULE_LICENSE("GPL"); |
356 | MODULE_VERSION(DRV_VERSION); | 362 | MODULE_VERSION(DRV_VERSION); |
363 | |||
364 | module_init(pcf2123_init); | ||
365 | module_exit(pcf2123_exit); | ||
diff --git a/drivers/rtc/rtc-pcf50633.c b/drivers/rtc/rtc-pcf50633.c index e9f3135d305..0c423892923 100644 --- a/drivers/rtc/rtc-pcf50633.c +++ b/drivers/rtc/rtc-pcf50633.c | |||
@@ -248,7 +248,7 @@ static void pcf50633_rtc_irq(int irq, void *data) | |||
248 | rtc->alarm_pending = 1; | 248 | rtc->alarm_pending = 1; |
249 | } | 249 | } |
250 | 250 | ||
251 | static int pcf50633_rtc_probe(struct platform_device *pdev) | 251 | static int __devinit pcf50633_rtc_probe(struct platform_device *pdev) |
252 | { | 252 | { |
253 | struct pcf50633_rtc *rtc; | 253 | struct pcf50633_rtc *rtc; |
254 | 254 | ||
@@ -272,7 +272,7 @@ static int pcf50633_rtc_probe(struct platform_device *pdev) | |||
272 | return 0; | 272 | return 0; |
273 | } | 273 | } |
274 | 274 | ||
275 | static int pcf50633_rtc_remove(struct platform_device *pdev) | 275 | static int __devexit pcf50633_rtc_remove(struct platform_device *pdev) |
276 | { | 276 | { |
277 | struct pcf50633_rtc *rtc; | 277 | struct pcf50633_rtc *rtc; |
278 | 278 | ||
@@ -291,10 +291,20 @@ static struct platform_driver pcf50633_rtc_driver = { | |||
291 | .name = "pcf50633-rtc", | 291 | .name = "pcf50633-rtc", |
292 | }, | 292 | }, |
293 | .probe = pcf50633_rtc_probe, | 293 | .probe = pcf50633_rtc_probe, |
294 | .remove = pcf50633_rtc_remove, | 294 | .remove = __devexit_p(pcf50633_rtc_remove), |
295 | }; | 295 | }; |
296 | 296 | ||
297 | module_platform_driver(pcf50633_rtc_driver); | 297 | static int __init pcf50633_rtc_init(void) |
298 | { | ||
299 | return platform_driver_register(&pcf50633_rtc_driver); | ||
300 | } | ||
301 | module_init(pcf50633_rtc_init); | ||
302 | |||
303 | static void __exit pcf50633_rtc_exit(void) | ||
304 | { | ||
305 | platform_driver_unregister(&pcf50633_rtc_driver); | ||
306 | } | ||
307 | module_exit(pcf50633_rtc_exit); | ||
298 | 308 | ||
299 | MODULE_DESCRIPTION("PCF50633 RTC driver"); | 309 | MODULE_DESCRIPTION("PCF50633 RTC driver"); |
300 | MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>"); | 310 | MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>"); |
diff --git a/drivers/rtc/rtc-pcf8523.c b/drivers/rtc/rtc-pcf8523.c deleted file mode 100644 index be05a645f99..00000000000 --- a/drivers/rtc/rtc-pcf8523.c +++ /dev/null | |||
@@ -1,326 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Avionic Design GmbH | ||
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 version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/bcd.h> | ||
10 | #include <linux/i2c.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/rtc.h> | ||
13 | #include <linux/of.h> | ||
14 | |||
15 | #define DRIVER_NAME "rtc-pcf8523" | ||
16 | |||
17 | #define REG_CONTROL1 0x00 | ||
18 | #define REG_CONTROL1_CAP_SEL (1 << 7) | ||
19 | #define REG_CONTROL1_STOP (1 << 5) | ||
20 | |||
21 | #define REG_CONTROL3 0x02 | ||
22 | #define REG_CONTROL3_PM_BLD (1 << 7) /* battery low detection disabled */ | ||
23 | #define REG_CONTROL3_PM_VDD (1 << 6) /* switch-over disabled */ | ||
24 | #define REG_CONTROL3_PM_DSM (1 << 5) /* direct switching mode */ | ||
25 | #define REG_CONTROL3_PM_MASK 0xe0 | ||
26 | |||
27 | #define REG_SECONDS 0x03 | ||
28 | #define REG_SECONDS_OS (1 << 7) | ||
29 | |||
30 | #define REG_MINUTES 0x04 | ||
31 | #define REG_HOURS 0x05 | ||
32 | #define REG_DAYS 0x06 | ||
33 | #define REG_WEEKDAYS 0x07 | ||
34 | #define REG_MONTHS 0x08 | ||
35 | #define REG_YEARS 0x09 | ||
36 | |||
37 | struct pcf8523 { | ||
38 | struct rtc_device *rtc; | ||
39 | }; | ||
40 | |||
41 | static int pcf8523_read(struct i2c_client *client, u8 reg, u8 *valuep) | ||
42 | { | ||
43 | struct i2c_msg msgs[2]; | ||
44 | u8 value = 0; | ||
45 | int err; | ||
46 | |||
47 | msgs[0].addr = client->addr; | ||
48 | msgs[0].flags = 0; | ||
49 | msgs[0].len = sizeof(reg); | ||
50 | msgs[0].buf = ® | ||
51 | |||
52 | msgs[1].addr = client->addr; | ||
53 | msgs[1].flags = I2C_M_RD; | ||
54 | msgs[1].len = sizeof(value); | ||
55 | msgs[1].buf = &value; | ||
56 | |||
57 | err = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); | ||
58 | if (err < 0) | ||
59 | return err; | ||
60 | |||
61 | *valuep = value; | ||
62 | |||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | static int pcf8523_write(struct i2c_client *client, u8 reg, u8 value) | ||
67 | { | ||
68 | u8 buffer[2] = { reg, value }; | ||
69 | struct i2c_msg msg; | ||
70 | int err; | ||
71 | |||
72 | msg.addr = client->addr; | ||
73 | msg.flags = 0; | ||
74 | msg.len = sizeof(buffer); | ||
75 | msg.buf = buffer; | ||
76 | |||
77 | err = i2c_transfer(client->adapter, &msg, 1); | ||
78 | if (err < 0) | ||
79 | return err; | ||
80 | |||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | static int pcf8523_select_capacitance(struct i2c_client *client, bool high) | ||
85 | { | ||
86 | u8 value; | ||
87 | int err; | ||
88 | |||
89 | err = pcf8523_read(client, REG_CONTROL1, &value); | ||
90 | if (err < 0) | ||
91 | return err; | ||
92 | |||
93 | if (!high) | ||
94 | value &= ~REG_CONTROL1_CAP_SEL; | ||
95 | else | ||
96 | value |= REG_CONTROL1_CAP_SEL; | ||
97 | |||
98 | err = pcf8523_write(client, REG_CONTROL1, value); | ||
99 | if (err < 0) | ||
100 | return err; | ||
101 | |||
102 | return err; | ||
103 | } | ||
104 | |||
105 | static int pcf8523_set_pm(struct i2c_client *client, u8 pm) | ||
106 | { | ||
107 | u8 value; | ||
108 | int err; | ||
109 | |||
110 | err = pcf8523_read(client, REG_CONTROL3, &value); | ||
111 | if (err < 0) | ||
112 | return err; | ||
113 | |||
114 | value = (value & ~REG_CONTROL3_PM_MASK) | pm; | ||
115 | |||
116 | err = pcf8523_write(client, REG_CONTROL3, value); | ||
117 | if (err < 0) | ||
118 | return err; | ||
119 | |||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | static int pcf8523_stop_rtc(struct i2c_client *client) | ||
124 | { | ||
125 | u8 value; | ||
126 | int err; | ||
127 | |||
128 | err = pcf8523_read(client, REG_CONTROL1, &value); | ||
129 | if (err < 0) | ||
130 | return err; | ||
131 | |||
132 | value |= REG_CONTROL1_STOP; | ||
133 | |||
134 | err = pcf8523_write(client, REG_CONTROL1, value); | ||
135 | if (err < 0) | ||
136 | return err; | ||
137 | |||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | static int pcf8523_start_rtc(struct i2c_client *client) | ||
142 | { | ||
143 | u8 value; | ||
144 | int err; | ||
145 | |||
146 | err = pcf8523_read(client, REG_CONTROL1, &value); | ||
147 | if (err < 0) | ||
148 | return err; | ||
149 | |||
150 | value &= ~REG_CONTROL1_STOP; | ||
151 | |||
152 | err = pcf8523_write(client, REG_CONTROL1, value); | ||
153 | if (err < 0) | ||
154 | return err; | ||
155 | |||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | static int pcf8523_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
160 | { | ||
161 | struct i2c_client *client = to_i2c_client(dev); | ||
162 | u8 start = REG_SECONDS, regs[7]; | ||
163 | struct i2c_msg msgs[2]; | ||
164 | int err; | ||
165 | |||
166 | msgs[0].addr = client->addr; | ||
167 | msgs[0].flags = 0; | ||
168 | msgs[0].len = 1; | ||
169 | msgs[0].buf = &start; | ||
170 | |||
171 | msgs[1].addr = client->addr; | ||
172 | msgs[1].flags = I2C_M_RD; | ||
173 | msgs[1].len = sizeof(regs); | ||
174 | msgs[1].buf = regs; | ||
175 | |||
176 | err = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); | ||
177 | if (err < 0) | ||
178 | return err; | ||
179 | |||
180 | if (regs[0] & REG_SECONDS_OS) { | ||
181 | /* | ||
182 | * If the oscillator was stopped, try to clear the flag. Upon | ||
183 | * power-up the flag is always set, but if we cannot clear it | ||
184 | * the oscillator isn't running properly for some reason. The | ||
185 | * sensible thing therefore is to return an error, signalling | ||
186 | * that the clock cannot be assumed to be correct. | ||
187 | */ | ||
188 | |||
189 | regs[0] &= ~REG_SECONDS_OS; | ||
190 | |||
191 | err = pcf8523_write(client, REG_SECONDS, regs[0]); | ||
192 | if (err < 0) | ||
193 | return err; | ||
194 | |||
195 | err = pcf8523_read(client, REG_SECONDS, ®s[0]); | ||
196 | if (err < 0) | ||
197 | return err; | ||
198 | |||
199 | if (regs[0] & REG_SECONDS_OS) | ||
200 | return -EAGAIN; | ||
201 | } | ||
202 | |||
203 | tm->tm_sec = bcd2bin(regs[0] & 0x7f); | ||
204 | tm->tm_min = bcd2bin(regs[1] & 0x7f); | ||
205 | tm->tm_hour = bcd2bin(regs[2] & 0x3f); | ||
206 | tm->tm_mday = bcd2bin(regs[3] & 0x3f); | ||
207 | tm->tm_wday = regs[4] & 0x7; | ||
208 | tm->tm_mon = bcd2bin(regs[5] & 0x1f); | ||
209 | tm->tm_year = bcd2bin(regs[6]) + 100; | ||
210 | |||
211 | return rtc_valid_tm(tm); | ||
212 | } | ||
213 | |||
214 | static int pcf8523_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
215 | { | ||
216 | struct i2c_client *client = to_i2c_client(dev); | ||
217 | struct i2c_msg msg; | ||
218 | u8 regs[8]; | ||
219 | int err; | ||
220 | |||
221 | err = pcf8523_stop_rtc(client); | ||
222 | if (err < 0) | ||
223 | return err; | ||
224 | |||
225 | regs[0] = REG_SECONDS; | ||
226 | regs[1] = bin2bcd(tm->tm_sec); | ||
227 | regs[2] = bin2bcd(tm->tm_min); | ||
228 | regs[3] = bin2bcd(tm->tm_hour); | ||
229 | regs[4] = bin2bcd(tm->tm_mday); | ||
230 | regs[5] = tm->tm_wday; | ||
231 | regs[6] = bin2bcd(tm->tm_mon); | ||
232 | regs[7] = bin2bcd(tm->tm_year - 100); | ||
233 | |||
234 | msg.addr = client->addr; | ||
235 | msg.flags = 0; | ||
236 | msg.len = sizeof(regs); | ||
237 | msg.buf = regs; | ||
238 | |||
239 | err = i2c_transfer(client->adapter, &msg, 1); | ||
240 | if (err < 0) { | ||
241 | /* | ||
242 | * If the time cannot be set, restart the RTC anyway. Note | ||
243 | * that errors are ignored if the RTC cannot be started so | ||
244 | * that we have a chance to propagate the original error. | ||
245 | */ | ||
246 | pcf8523_start_rtc(client); | ||
247 | return err; | ||
248 | } | ||
249 | |||
250 | return pcf8523_start_rtc(client); | ||
251 | } | ||
252 | |||
253 | static const struct rtc_class_ops pcf8523_rtc_ops = { | ||
254 | .read_time = pcf8523_rtc_read_time, | ||
255 | .set_time = pcf8523_rtc_set_time, | ||
256 | }; | ||
257 | |||
258 | static int pcf8523_probe(struct i2c_client *client, | ||
259 | const struct i2c_device_id *id) | ||
260 | { | ||
261 | struct pcf8523 *pcf; | ||
262 | int err; | ||
263 | |||
264 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) | ||
265 | return -ENODEV; | ||
266 | |||
267 | pcf = devm_kzalloc(&client->dev, sizeof(*pcf), GFP_KERNEL); | ||
268 | if (!pcf) | ||
269 | return -ENOMEM; | ||
270 | |||
271 | err = pcf8523_select_capacitance(client, true); | ||
272 | if (err < 0) | ||
273 | return err; | ||
274 | |||
275 | err = pcf8523_set_pm(client, 0); | ||
276 | if (err < 0) | ||
277 | return err; | ||
278 | |||
279 | pcf->rtc = rtc_device_register(DRIVER_NAME, &client->dev, | ||
280 | &pcf8523_rtc_ops, THIS_MODULE); | ||
281 | if (IS_ERR(pcf->rtc)) | ||
282 | return PTR_ERR(pcf->rtc); | ||
283 | |||
284 | i2c_set_clientdata(client, pcf); | ||
285 | |||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static int pcf8523_remove(struct i2c_client *client) | ||
290 | { | ||
291 | struct pcf8523 *pcf = i2c_get_clientdata(client); | ||
292 | |||
293 | rtc_device_unregister(pcf->rtc); | ||
294 | |||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | static const struct i2c_device_id pcf8523_id[] = { | ||
299 | { "pcf8523", 0 }, | ||
300 | { } | ||
301 | }; | ||
302 | MODULE_DEVICE_TABLE(i2c, pcf8523_id); | ||
303 | |||
304 | #ifdef CONFIG_OF | ||
305 | static const struct of_device_id pcf8523_of_match[] = { | ||
306 | { .compatible = "nxp,pcf8523" }, | ||
307 | { } | ||
308 | }; | ||
309 | MODULE_DEVICE_TABLE(of, pcf8523_of_match); | ||
310 | #endif | ||
311 | |||
312 | static struct i2c_driver pcf8523_driver = { | ||
313 | .driver = { | ||
314 | .name = DRIVER_NAME, | ||
315 | .owner = THIS_MODULE, | ||
316 | .of_match_table = of_match_ptr(pcf8523_of_match), | ||
317 | }, | ||
318 | .probe = pcf8523_probe, | ||
319 | .remove = pcf8523_remove, | ||
320 | .id_table = pcf8523_id, | ||
321 | }; | ||
322 | module_i2c_driver(pcf8523_driver); | ||
323 | |||
324 | MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>"); | ||
325 | MODULE_DESCRIPTION("NXP PCF8523 RTC driver"); | ||
326 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 7098ee89bd2..b42c0c67926 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c | |||
@@ -18,8 +18,6 @@ | |||
18 | #include <linux/bcd.h> | 18 | #include <linux/bcd.h> |
19 | #include <linux/rtc.h> | 19 | #include <linux/rtc.h> |
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/module.h> | ||
22 | #include <linux/of.h> | ||
23 | 21 | ||
24 | #define DRV_VERSION "0.4.3" | 22 | #define DRV_VERSION "0.4.3" |
25 | 23 | ||
@@ -65,7 +63,6 @@ struct pcf8563 { | |||
65 | * 1970...2069. | 63 | * 1970...2069. |
66 | */ | 64 | */ |
67 | int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */ | 65 | int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */ |
68 | int voltage_low; /* incicates if a low_voltage was detected */ | ||
69 | }; | 66 | }; |
70 | 67 | ||
71 | /* | 68 | /* |
@@ -78,17 +75,8 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
78 | unsigned char buf[13] = { PCF8563_REG_ST1 }; | 75 | unsigned char buf[13] = { PCF8563_REG_ST1 }; |
79 | 76 | ||
80 | struct i2c_msg msgs[] = { | 77 | struct i2c_msg msgs[] = { |
81 | {/* setup read ptr */ | 78 | { client->addr, 0, 1, buf }, /* setup read ptr */ |
82 | .addr = client->addr, | 79 | { client->addr, I2C_M_RD, 13, buf }, /* read status + date */ |
83 | .len = 1, | ||
84 | .buf = buf | ||
85 | }, | ||
86 | {/* read status + date */ | ||
87 | .addr = client->addr, | ||
88 | .flags = I2C_M_RD, | ||
89 | .len = 13, | ||
90 | .buf = buf | ||
91 | }, | ||
92 | }; | 80 | }; |
93 | 81 | ||
94 | /* read registers */ | 82 | /* read registers */ |
@@ -97,11 +85,9 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
97 | return -EIO; | 85 | return -EIO; |
98 | } | 86 | } |
99 | 87 | ||
100 | if (buf[PCF8563_REG_SC] & PCF8563_SC_LV) { | 88 | if (buf[PCF8563_REG_SC] & PCF8563_SC_LV) |
101 | pcf8563->voltage_low = 1; | ||
102 | dev_info(&client->dev, | 89 | dev_info(&client->dev, |
103 | "low voltage detected, date/time is not reliable.\n"); | 90 | "low voltage detected, date/time is not reliable.\n"); |
104 | } | ||
105 | 91 | ||
106 | dev_dbg(&client->dev, | 92 | dev_dbg(&client->dev, |
107 | "%s: raw data is st1=%02x, st2=%02x, sec=%02x, min=%02x, hr=%02x, " | 93 | "%s: raw data is st1=%02x, st2=%02x, sec=%02x, min=%02x, hr=%02x, " |
@@ -186,44 +172,6 @@ static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
186 | return 0; | 172 | return 0; |
187 | } | 173 | } |
188 | 174 | ||
189 | #ifdef CONFIG_RTC_INTF_DEV | ||
190 | static int pcf8563_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | ||
191 | { | ||
192 | struct pcf8563 *pcf8563 = i2c_get_clientdata(to_i2c_client(dev)); | ||
193 | struct rtc_time tm; | ||
194 | |||
195 | switch (cmd) { | ||
196 | case RTC_VL_READ: | ||
197 | if (pcf8563->voltage_low) | ||
198 | dev_info(dev, "low voltage detected, date/time is not reliable.\n"); | ||
199 | |||
200 | if (copy_to_user((void __user *)arg, &pcf8563->voltage_low, | ||
201 | sizeof(int))) | ||
202 | return -EFAULT; | ||
203 | return 0; | ||
204 | case RTC_VL_CLR: | ||
205 | /* | ||
206 | * Clear the VL bit in the seconds register in case | ||
207 | * the time has not been set already (which would | ||
208 | * have cleared it). This does not really matter | ||
209 | * because of the cached voltage_low value but do it | ||
210 | * anyway for consistency. | ||
211 | */ | ||
212 | if (pcf8563_get_datetime(to_i2c_client(dev), &tm)) | ||
213 | pcf8563_set_datetime(to_i2c_client(dev), &tm); | ||
214 | |||
215 | /* Clear the cached value. */ | ||
216 | pcf8563->voltage_low = 0; | ||
217 | |||
218 | return 0; | ||
219 | default: | ||
220 | return -ENOIOCTLCMD; | ||
221 | } | ||
222 | } | ||
223 | #else | ||
224 | #define pcf8563_rtc_ioctl NULL | ||
225 | #endif | ||
226 | |||
227 | static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm) | 175 | static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm) |
228 | { | 176 | { |
229 | return pcf8563_get_datetime(to_i2c_client(dev), tm); | 177 | return pcf8563_get_datetime(to_i2c_client(dev), tm); |
@@ -235,7 +183,6 @@ static int pcf8563_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
235 | } | 183 | } |
236 | 184 | ||
237 | static const struct rtc_class_ops pcf8563_rtc_ops = { | 185 | static const struct rtc_class_ops pcf8563_rtc_ops = { |
238 | .ioctl = pcf8563_rtc_ioctl, | ||
239 | .read_time = pcf8563_rtc_read_time, | 186 | .read_time = pcf8563_rtc_read_time, |
240 | .set_time = pcf8563_rtc_set_time, | 187 | .set_time = pcf8563_rtc_set_time, |
241 | }; | 188 | }; |
@@ -295,28 +242,29 @@ static const struct i2c_device_id pcf8563_id[] = { | |||
295 | }; | 242 | }; |
296 | MODULE_DEVICE_TABLE(i2c, pcf8563_id); | 243 | MODULE_DEVICE_TABLE(i2c, pcf8563_id); |
297 | 244 | ||
298 | #ifdef CONFIG_OF | ||
299 | static const struct of_device_id pcf8563_of_match[] = { | ||
300 | { .compatible = "nxp,pcf8563" }, | ||
301 | {} | ||
302 | }; | ||
303 | MODULE_DEVICE_TABLE(of, pcf8563_of_match); | ||
304 | #endif | ||
305 | |||
306 | static struct i2c_driver pcf8563_driver = { | 245 | static struct i2c_driver pcf8563_driver = { |
307 | .driver = { | 246 | .driver = { |
308 | .name = "rtc-pcf8563", | 247 | .name = "rtc-pcf8563", |
309 | .owner = THIS_MODULE, | ||
310 | .of_match_table = of_match_ptr(pcf8563_of_match), | ||
311 | }, | 248 | }, |
312 | .probe = pcf8563_probe, | 249 | .probe = pcf8563_probe, |
313 | .remove = pcf8563_remove, | 250 | .remove = pcf8563_remove, |
314 | .id_table = pcf8563_id, | 251 | .id_table = pcf8563_id, |
315 | }; | 252 | }; |
316 | 253 | ||
317 | module_i2c_driver(pcf8563_driver); | 254 | static int __init pcf8563_init(void) |
255 | { | ||
256 | return i2c_add_driver(&pcf8563_driver); | ||
257 | } | ||
258 | |||
259 | static void __exit pcf8563_exit(void) | ||
260 | { | ||
261 | i2c_del_driver(&pcf8563_driver); | ||
262 | } | ||
318 | 263 | ||
319 | MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); | 264 | MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); |
320 | MODULE_DESCRIPTION("Philips PCF8563/Epson RTC8564 RTC driver"); | 265 | MODULE_DESCRIPTION("Philips PCF8563/Epson RTC8564 RTC driver"); |
321 | MODULE_LICENSE("GPL"); | 266 | MODULE_LICENSE("GPL"); |
322 | MODULE_VERSION(DRV_VERSION); | 267 | MODULE_VERSION(DRV_VERSION); |
268 | |||
269 | module_init(pcf8563_init); | ||
270 | module_exit(pcf8563_exit); | ||
diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c index 3415b8f1855..2d201afead3 100644 --- a/drivers/rtc/rtc-pcf8583.c +++ b/drivers/rtc/rtc-pcf8583.c | |||
@@ -294,7 +294,7 @@ exit_kfree: | |||
294 | return err; | 294 | return err; |
295 | } | 295 | } |
296 | 296 | ||
297 | static int pcf8583_remove(struct i2c_client *client) | 297 | static int __devexit pcf8583_remove(struct i2c_client *client) |
298 | { | 298 | { |
299 | struct pcf8583 *pcf8583 = i2c_get_clientdata(client); | 299 | struct pcf8583 *pcf8583 = i2c_get_clientdata(client); |
300 | 300 | ||
@@ -316,11 +316,22 @@ static struct i2c_driver pcf8583_driver = { | |||
316 | .owner = THIS_MODULE, | 316 | .owner = THIS_MODULE, |
317 | }, | 317 | }, |
318 | .probe = pcf8583_probe, | 318 | .probe = pcf8583_probe, |
319 | .remove = pcf8583_remove, | 319 | .remove = __devexit_p(pcf8583_remove), |
320 | .id_table = pcf8583_id, | 320 | .id_table = pcf8583_id, |
321 | }; | 321 | }; |
322 | 322 | ||
323 | module_i2c_driver(pcf8583_driver); | 323 | static __init int pcf8583_init(void) |
324 | { | ||
325 | return i2c_add_driver(&pcf8583_driver); | ||
326 | } | ||
327 | |||
328 | static __exit void pcf8583_exit(void) | ||
329 | { | ||
330 | i2c_del_driver(&pcf8583_driver); | ||
331 | } | ||
332 | |||
333 | module_init(pcf8583_init); | ||
334 | module_exit(pcf8583_exit); | ||
324 | 335 | ||
325 | MODULE_AUTHOR("Russell King"); | 336 | MODULE_AUTHOR("Russell King"); |
326 | MODULE_DESCRIPTION("PCF8583 I2C RTC driver"); | 337 | MODULE_DESCRIPTION("PCF8583 I2C RTC driver"); |
diff --git a/drivers/rtc/rtc-pl030.c b/drivers/rtc/rtc-pl030.c index 22bacdbf913..1d28d4451da 100644 --- a/drivers/rtc/rtc-pl030.c +++ b/drivers/rtc/rtc-pl030.c | |||
@@ -123,7 +123,7 @@ static int pl030_probe(struct amba_device *dev, const struct amba_id *id) | |||
123 | 123 | ||
124 | amba_set_drvdata(dev, rtc); | 124 | amba_set_drvdata(dev, rtc); |
125 | 125 | ||
126 | ret = request_irq(dev->irq[0], pl030_interrupt, 0, | 126 | ret = request_irq(dev->irq[0], pl030_interrupt, IRQF_DISABLED, |
127 | "rtc-pl030", rtc); | 127 | "rtc-pl030", rtc); |
128 | if (ret) | 128 | if (ret) |
129 | goto err_irq; | 129 | goto err_irq; |
@@ -174,8 +174,6 @@ static struct amba_id pl030_ids[] = { | |||
174 | { 0, 0 }, | 174 | { 0, 0 }, |
175 | }; | 175 | }; |
176 | 176 | ||
177 | MODULE_DEVICE_TABLE(amba, pl030_ids); | ||
178 | |||
179 | static struct amba_driver pl030_driver = { | 177 | static struct amba_driver pl030_driver = { |
180 | .drv = { | 178 | .drv = { |
181 | .name = "rtc-pl030", | 179 | .name = "rtc-pl030", |
@@ -185,7 +183,18 @@ static struct amba_driver pl030_driver = { | |||
185 | .id_table = pl030_ids, | 183 | .id_table = pl030_ids, |
186 | }; | 184 | }; |
187 | 185 | ||
188 | module_amba_driver(pl030_driver); | 186 | static int __init pl030_init(void) |
187 | { | ||
188 | return amba_driver_register(&pl030_driver); | ||
189 | } | ||
190 | |||
191 | static void __exit pl030_exit(void) | ||
192 | { | ||
193 | amba_driver_unregister(&pl030_driver); | ||
194 | } | ||
195 | |||
196 | module_init(pl030_init); | ||
197 | module_exit(pl030_exit); | ||
189 | 198 | ||
190 | MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>"); | 199 | MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>"); |
191 | MODULE_DESCRIPTION("ARM AMBA PL030 RTC Driver"); | 200 | MODULE_DESCRIPTION("ARM AMBA PL030 RTC Driver"); |
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 08378e3cc21..ff1b84bd9bb 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c | |||
@@ -68,26 +68,11 @@ | |||
68 | 68 | ||
69 | #define RTC_TIMER_FREQ 32768 | 69 | #define RTC_TIMER_FREQ 32768 |
70 | 70 | ||
71 | /** | ||
72 | * struct pl031_vendor_data - per-vendor variations | ||
73 | * @ops: the vendor-specific operations used on this silicon version | ||
74 | * @clockwatch: if this is an ST Microelectronics silicon version with a | ||
75 | * clockwatch function | ||
76 | * @st_weekday: if this is an ST Microelectronics silicon version that need | ||
77 | * the weekday fix | ||
78 | * @irqflags: special IRQ flags per variant | ||
79 | */ | ||
80 | struct pl031_vendor_data { | ||
81 | struct rtc_class_ops ops; | ||
82 | bool clockwatch; | ||
83 | bool st_weekday; | ||
84 | unsigned long irqflags; | ||
85 | }; | ||
86 | |||
87 | struct pl031_local { | 71 | struct pl031_local { |
88 | struct pl031_vendor_data *vendor; | ||
89 | struct rtc_device *rtc; | 72 | struct rtc_device *rtc; |
90 | void __iomem *base; | 73 | void __iomem *base; |
74 | u8 hw_designer; | ||
75 | u8 hw_revision:4; | ||
91 | }; | 76 | }; |
92 | 77 | ||
93 | static int pl031_alarm_irq_enable(struct device *dev, | 78 | static int pl031_alarm_irq_enable(struct device *dev, |
@@ -235,9 +220,17 @@ static irqreturn_t pl031_interrupt(int irq, void *dev_id) | |||
235 | unsigned long events = 0; | 220 | unsigned long events = 0; |
236 | 221 | ||
237 | rtcmis = readl(ldata->base + RTC_MIS); | 222 | rtcmis = readl(ldata->base + RTC_MIS); |
238 | if (rtcmis & RTC_BIT_AI) { | 223 | if (rtcmis) { |
239 | writel(RTC_BIT_AI, ldata->base + RTC_ICR); | 224 | writel(rtcmis, ldata->base + RTC_ICR); |
240 | events |= (RTC_AF | RTC_IRQF); | 225 | |
226 | if (rtcmis & RTC_BIT_AI) | ||
227 | events |= (RTC_AF | RTC_IRQF); | ||
228 | |||
229 | /* Timer interrupt is only available in ST variants */ | ||
230 | if ((rtcmis & RTC_BIT_PI) && | ||
231 | (ldata->hw_designer == AMBA_VENDOR_ST)) | ||
232 | events |= (RTC_PF | RTC_IRQF); | ||
233 | |||
241 | rtc_update_irq(ldata->rtc, 1, events); | 234 | rtc_update_irq(ldata->rtc, 1, events); |
242 | 235 | ||
243 | return IRQ_HANDLED; | 236 | return IRQ_HANDLED; |
@@ -318,9 +311,7 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) | |||
318 | { | 311 | { |
319 | int ret; | 312 | int ret; |
320 | struct pl031_local *ldata; | 313 | struct pl031_local *ldata; |
321 | struct pl031_vendor_data *vendor = id->data; | 314 | struct rtc_class_ops *ops = id->data; |
322 | struct rtc_class_ops *ops = &vendor->ops; | ||
323 | unsigned long time; | ||
324 | 315 | ||
325 | ret = amba_request_regions(adev, NULL); | 316 | ret = amba_request_regions(adev, NULL); |
326 | if (ret) | 317 | if (ret) |
@@ -331,7 +322,6 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) | |||
331 | ret = -ENOMEM; | 322 | ret = -ENOMEM; |
332 | goto out; | 323 | goto out; |
333 | } | 324 | } |
334 | ldata->vendor = vendor; | ||
335 | 325 | ||
336 | ldata->base = ioremap(adev->res.start, resource_size(&adev->res)); | 326 | ldata->base = ioremap(adev->res.start, resource_size(&adev->res)); |
337 | 327 | ||
@@ -342,31 +332,18 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) | |||
342 | 332 | ||
343 | amba_set_drvdata(adev, ldata); | 333 | amba_set_drvdata(adev, ldata); |
344 | 334 | ||
345 | dev_dbg(&adev->dev, "designer ID = 0x%02x\n", amba_manf(adev)); | 335 | ldata->hw_designer = amba_manf(adev); |
346 | dev_dbg(&adev->dev, "revision = 0x%01x\n", amba_rev(adev)); | 336 | ldata->hw_revision = amba_rev(adev); |
337 | |||
338 | dev_dbg(&adev->dev, "designer ID = 0x%02x\n", ldata->hw_designer); | ||
339 | dev_dbg(&adev->dev, "revision = 0x%01x\n", ldata->hw_revision); | ||
347 | 340 | ||
348 | /* Enable the clockwatch on ST Variants */ | 341 | /* Enable the clockwatch on ST Variants */ |
349 | if (vendor->clockwatch) | 342 | if ((ldata->hw_designer == AMBA_VENDOR_ST) && |
343 | (ldata->hw_revision > 1)) | ||
350 | writel(readl(ldata->base + RTC_CR) | RTC_CR_CWEN, | 344 | writel(readl(ldata->base + RTC_CR) | RTC_CR_CWEN, |
351 | ldata->base + RTC_CR); | 345 | ldata->base + RTC_CR); |
352 | 346 | ||
353 | /* | ||
354 | * On ST PL031 variants, the RTC reset value does not provide correct | ||
355 | * weekday for 2000-01-01. Correct the erroneous sunday to saturday. | ||
356 | */ | ||
357 | if (vendor->st_weekday) { | ||
358 | if (readl(ldata->base + RTC_YDR) == 0x2000) { | ||
359 | time = readl(ldata->base + RTC_DR); | ||
360 | if ((time & | ||
361 | (RTC_MON_MASK | RTC_MDAY_MASK | RTC_WDAY_MASK)) | ||
362 | == 0x02120000) { | ||
363 | time = time | (0x7 << RTC_WDAY_SHIFT); | ||
364 | writel(0x2000, ldata->base + RTC_YLR); | ||
365 | writel(time, ldata->base + RTC_LR); | ||
366 | } | ||
367 | } | ||
368 | } | ||
369 | |||
370 | ldata->rtc = rtc_device_register("pl031", &adev->dev, ops, | 347 | ldata->rtc = rtc_device_register("pl031", &adev->dev, ops, |
371 | THIS_MODULE); | 348 | THIS_MODULE); |
372 | if (IS_ERR(ldata->rtc)) { | 349 | if (IS_ERR(ldata->rtc)) { |
@@ -375,7 +352,7 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) | |||
375 | } | 352 | } |
376 | 353 | ||
377 | if (request_irq(adev->irq[0], pl031_interrupt, | 354 | if (request_irq(adev->irq[0], pl031_interrupt, |
378 | vendor->irqflags, "rtc-pl031", ldata)) { | 355 | IRQF_DISABLED, "rtc-pl031", ldata)) { |
379 | ret = -EIO; | 356 | ret = -EIO; |
380 | goto out_no_irq; | 357 | goto out_no_irq; |
381 | } | 358 | } |
@@ -397,71 +374,52 @@ err_req: | |||
397 | } | 374 | } |
398 | 375 | ||
399 | /* Operations for the original ARM version */ | 376 | /* Operations for the original ARM version */ |
400 | static struct pl031_vendor_data arm_pl031 = { | 377 | static struct rtc_class_ops arm_pl031_ops = { |
401 | .ops = { | 378 | .read_time = pl031_read_time, |
402 | .read_time = pl031_read_time, | 379 | .set_time = pl031_set_time, |
403 | .set_time = pl031_set_time, | 380 | .read_alarm = pl031_read_alarm, |
404 | .read_alarm = pl031_read_alarm, | 381 | .set_alarm = pl031_set_alarm, |
405 | .set_alarm = pl031_set_alarm, | 382 | .alarm_irq_enable = pl031_alarm_irq_enable, |
406 | .alarm_irq_enable = pl031_alarm_irq_enable, | ||
407 | }, | ||
408 | .irqflags = IRQF_NO_SUSPEND, | ||
409 | }; | 383 | }; |
410 | 384 | ||
411 | /* The First ST derivative */ | 385 | /* The First ST derivative */ |
412 | static struct pl031_vendor_data stv1_pl031 = { | 386 | static struct rtc_class_ops stv1_pl031_ops = { |
413 | .ops = { | 387 | .read_time = pl031_read_time, |
414 | .read_time = pl031_read_time, | 388 | .set_time = pl031_set_time, |
415 | .set_time = pl031_set_time, | 389 | .read_alarm = pl031_read_alarm, |
416 | .read_alarm = pl031_read_alarm, | 390 | .set_alarm = pl031_set_alarm, |
417 | .set_alarm = pl031_set_alarm, | 391 | .alarm_irq_enable = pl031_alarm_irq_enable, |
418 | .alarm_irq_enable = pl031_alarm_irq_enable, | ||
419 | }, | ||
420 | .clockwatch = true, | ||
421 | .st_weekday = true, | ||
422 | .irqflags = IRQF_NO_SUSPEND, | ||
423 | }; | 392 | }; |
424 | 393 | ||
425 | /* And the second ST derivative */ | 394 | /* And the second ST derivative */ |
426 | static struct pl031_vendor_data stv2_pl031 = { | 395 | static struct rtc_class_ops stv2_pl031_ops = { |
427 | .ops = { | 396 | .read_time = pl031_stv2_read_time, |
428 | .read_time = pl031_stv2_read_time, | 397 | .set_time = pl031_stv2_set_time, |
429 | .set_time = pl031_stv2_set_time, | 398 | .read_alarm = pl031_stv2_read_alarm, |
430 | .read_alarm = pl031_stv2_read_alarm, | 399 | .set_alarm = pl031_stv2_set_alarm, |
431 | .set_alarm = pl031_stv2_set_alarm, | 400 | .alarm_irq_enable = pl031_alarm_irq_enable, |
432 | .alarm_irq_enable = pl031_alarm_irq_enable, | ||
433 | }, | ||
434 | .clockwatch = true, | ||
435 | .st_weekday = true, | ||
436 | /* | ||
437 | * This variant shares the IRQ with another block and must not | ||
438 | * suspend that IRQ line. | ||
439 | */ | ||
440 | .irqflags = IRQF_SHARED | IRQF_NO_SUSPEND, | ||
441 | }; | 401 | }; |
442 | 402 | ||
443 | static struct amba_id pl031_ids[] = { | 403 | static struct amba_id pl031_ids[] = { |
444 | { | 404 | { |
445 | .id = 0x00041031, | 405 | .id = 0x00041031, |
446 | .mask = 0x000fffff, | 406 | .mask = 0x000fffff, |
447 | .data = &arm_pl031, | 407 | .data = &arm_pl031_ops, |
448 | }, | 408 | }, |
449 | /* ST Micro variants */ | 409 | /* ST Micro variants */ |
450 | { | 410 | { |
451 | .id = 0x00180031, | 411 | .id = 0x00180031, |
452 | .mask = 0x00ffffff, | 412 | .mask = 0x00ffffff, |
453 | .data = &stv1_pl031, | 413 | .data = &stv1_pl031_ops, |
454 | }, | 414 | }, |
455 | { | 415 | { |
456 | .id = 0x00280031, | 416 | .id = 0x00280031, |
457 | .mask = 0x00ffffff, | 417 | .mask = 0x00ffffff, |
458 | .data = &stv2_pl031, | 418 | .data = &stv2_pl031_ops, |
459 | }, | 419 | }, |
460 | {0, 0}, | 420 | {0, 0}, |
461 | }; | 421 | }; |
462 | 422 | ||
463 | MODULE_DEVICE_TABLE(amba, pl031_ids); | ||
464 | |||
465 | static struct amba_driver pl031_driver = { | 423 | static struct amba_driver pl031_driver = { |
466 | .drv = { | 424 | .drv = { |
467 | .name = "rtc-pl031", | 425 | .name = "rtc-pl031", |
@@ -471,7 +429,18 @@ static struct amba_driver pl031_driver = { | |||
471 | .remove = pl031_remove, | 429 | .remove = pl031_remove, |
472 | }; | 430 | }; |
473 | 431 | ||
474 | module_amba_driver(pl031_driver); | 432 | static int __init pl031_init(void) |
433 | { | ||
434 | return amba_driver_register(&pl031_driver); | ||
435 | } | ||
436 | |||
437 | static void __exit pl031_exit(void) | ||
438 | { | ||
439 | amba_driver_unregister(&pl031_driver); | ||
440 | } | ||
441 | |||
442 | module_init(pl031_init); | ||
443 | module_exit(pl031_exit); | ||
475 | 444 | ||
476 | MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net"); | 445 | MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net"); |
477 | MODULE_DESCRIPTION("ARM AMBA PL031 RTC Driver"); | 446 | MODULE_DESCRIPTION("ARM AMBA PL031 RTC Driver"); |
diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c index f1a6557261f..d420e9d877e 100644 --- a/drivers/rtc/rtc-pm8xxx.c +++ b/drivers/rtc/rtc-pm8xxx.c | |||
@@ -382,7 +382,7 @@ rtc_alarm_handled: | |||
382 | return IRQ_HANDLED; | 382 | return IRQ_HANDLED; |
383 | } | 383 | } |
384 | 384 | ||
385 | static int pm8xxx_rtc_probe(struct platform_device *pdev) | 385 | static int __devinit pm8xxx_rtc_probe(struct platform_device *pdev) |
386 | { | 386 | { |
387 | int rc; | 387 | int rc; |
388 | u8 ctrl_reg; | 388 | u8 ctrl_reg; |
@@ -485,7 +485,7 @@ fail_rtc_enable: | |||
485 | return rc; | 485 | return rc; |
486 | } | 486 | } |
487 | 487 | ||
488 | static int pm8xxx_rtc_remove(struct platform_device *pdev) | 488 | static int __devexit pm8xxx_rtc_remove(struct platform_device *pdev) |
489 | { | 489 | { |
490 | struct pm8xxx_rtc *rtc_dd = platform_get_drvdata(pdev); | 490 | struct pm8xxx_rtc *rtc_dd = platform_get_drvdata(pdev); |
491 | 491 | ||
@@ -520,11 +520,11 @@ static int pm8xxx_rtc_suspend(struct device *dev) | |||
520 | } | 520 | } |
521 | #endif | 521 | #endif |
522 | 522 | ||
523 | static SIMPLE_DEV_PM_OPS(pm8xxx_rtc_pm_ops, pm8xxx_rtc_suspend, pm8xxx_rtc_resume); | 523 | SIMPLE_DEV_PM_OPS(pm8xxx_rtc_pm_ops, pm8xxx_rtc_suspend, pm8xxx_rtc_resume); |
524 | 524 | ||
525 | static struct platform_driver pm8xxx_rtc_driver = { | 525 | static struct platform_driver pm8xxx_rtc_driver = { |
526 | .probe = pm8xxx_rtc_probe, | 526 | .probe = pm8xxx_rtc_probe, |
527 | .remove = pm8xxx_rtc_remove, | 527 | .remove = __devexit_p(pm8xxx_rtc_remove), |
528 | .driver = { | 528 | .driver = { |
529 | .name = PM8XXX_RTC_DEV_NAME, | 529 | .name = PM8XXX_RTC_DEV_NAME, |
530 | .owner = THIS_MODULE, | 530 | .owner = THIS_MODULE, |
@@ -532,7 +532,17 @@ static struct platform_driver pm8xxx_rtc_driver = { | |||
532 | }, | 532 | }, |
533 | }; | 533 | }; |
534 | 534 | ||
535 | module_platform_driver(pm8xxx_rtc_driver); | 535 | static int __init pm8xxx_rtc_init(void) |
536 | { | ||
537 | return platform_driver_register(&pm8xxx_rtc_driver); | ||
538 | } | ||
539 | module_init(pm8xxx_rtc_init); | ||
540 | |||
541 | static void __exit pm8xxx_rtc_exit(void) | ||
542 | { | ||
543 | platform_driver_unregister(&pm8xxx_rtc_driver); | ||
544 | } | ||
545 | module_exit(pm8xxx_rtc_exit); | ||
536 | 546 | ||
537 | MODULE_ALIAS("platform:rtc-pm8xxx"); | 547 | MODULE_ALIAS("platform:rtc-pm8xxx"); |
538 | MODULE_DESCRIPTION("PMIC8xxx RTC driver"); | 548 | MODULE_DESCRIPTION("PMIC8xxx RTC driver"); |
diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c index e96236ac2e7..0a59fda5c09 100644 --- a/drivers/rtc/rtc-proc.c +++ b/drivers/rtc/rtc-proc.c | |||
@@ -18,26 +18,6 @@ | |||
18 | 18 | ||
19 | #include "rtc-core.h" | 19 | #include "rtc-core.h" |
20 | 20 | ||
21 | #define NAME_SIZE 10 | ||
22 | |||
23 | #if defined(CONFIG_RTC_HCTOSYS_DEVICE) | ||
24 | static bool is_rtc_hctosys(struct rtc_device *rtc) | ||
25 | { | ||
26 | int size; | ||
27 | char name[NAME_SIZE]; | ||
28 | |||
29 | size = scnprintf(name, NAME_SIZE, "rtc%d", rtc->id); | ||
30 | if (size > NAME_SIZE) | ||
31 | return false; | ||
32 | |||
33 | return !strncmp(name, CONFIG_RTC_HCTOSYS_DEVICE, NAME_SIZE); | ||
34 | } | ||
35 | #else | ||
36 | static bool is_rtc_hctosys(struct rtc_device *rtc) | ||
37 | { | ||
38 | return (rtc->id == 0); | ||
39 | } | ||
40 | #endif | ||
41 | 21 | ||
42 | static int rtc_proc_show(struct seq_file *seq, void *offset) | 22 | static int rtc_proc_show(struct seq_file *seq, void *offset) |
43 | { | 23 | { |
@@ -137,12 +117,12 @@ static const struct file_operations rtc_proc_fops = { | |||
137 | 117 | ||
138 | void rtc_proc_add_device(struct rtc_device *rtc) | 118 | void rtc_proc_add_device(struct rtc_device *rtc) |
139 | { | 119 | { |
140 | if (is_rtc_hctosys(rtc)) | 120 | if (rtc->id == 0) |
141 | proc_create_data("driver/rtc", 0, NULL, &rtc_proc_fops, rtc); | 121 | proc_create_data("driver/rtc", 0, NULL, &rtc_proc_fops, rtc); |
142 | } | 122 | } |
143 | 123 | ||
144 | void rtc_proc_del_device(struct rtc_device *rtc) | 124 | void rtc_proc_del_device(struct rtc_device *rtc) |
145 | { | 125 | { |
146 | if (is_rtc_hctosys(rtc)) | 126 | if (rtc->id == 0) |
147 | remove_proc_entry("driver/rtc", NULL); | 127 | remove_proc_entry("driver/rtc", NULL); |
148 | } | 128 | } |
diff --git a/drivers/rtc/rtc-puv3.c b/drivers/rtc/rtc-puv3.c index 0407e13d4de..b3eba3cddd4 100644 --- a/drivers/rtc/rtc-puv3.c +++ b/drivers/rtc/rtc-puv3.c | |||
@@ -164,7 +164,7 @@ static int puv3_rtc_open(struct device *dev) | |||
164 | int ret; | 164 | int ret; |
165 | 165 | ||
166 | ret = request_irq(puv3_rtc_alarmno, puv3_rtc_alarmirq, | 166 | ret = request_irq(puv3_rtc_alarmno, puv3_rtc_alarmirq, |
167 | 0, "pkunity-rtc alarm", rtc_dev); | 167 | IRQF_DISABLED, "pkunity-rtc alarm", rtc_dev); |
168 | 168 | ||
169 | if (ret) { | 169 | if (ret) { |
170 | dev_err(dev, "IRQ%d error %d\n", puv3_rtc_alarmno, ret); | 170 | dev_err(dev, "IRQ%d error %d\n", puv3_rtc_alarmno, ret); |
@@ -172,7 +172,7 @@ static int puv3_rtc_open(struct device *dev) | |||
172 | } | 172 | } |
173 | 173 | ||
174 | ret = request_irq(puv3_rtc_tickno, puv3_rtc_tickirq, | 174 | ret = request_irq(puv3_rtc_tickno, puv3_rtc_tickirq, |
175 | 0, "pkunity-rtc tick", rtc_dev); | 175 | IRQF_DISABLED, "pkunity-rtc tick", rtc_dev); |
176 | 176 | ||
177 | if (ret) { | 177 | if (ret) { |
178 | dev_err(dev, "IRQ%d error %d\n", puv3_rtc_tickno, ret); | 178 | dev_err(dev, "IRQ%d error %d\n", puv3_rtc_tickno, ret); |
@@ -326,9 +326,9 @@ static int puv3_rtc_resume(struct platform_device *pdev) | |||
326 | #define puv3_rtc_resume NULL | 326 | #define puv3_rtc_resume NULL |
327 | #endif | 327 | #endif |
328 | 328 | ||
329 | static struct platform_driver puv3_rtc_driver = { | 329 | static struct platform_driver puv3_rtcdrv = { |
330 | .probe = puv3_rtc_probe, | 330 | .probe = puv3_rtc_probe, |
331 | .remove = puv3_rtc_remove, | 331 | .remove = __devexit_p(puv3_rtc_remove), |
332 | .suspend = puv3_rtc_suspend, | 332 | .suspend = puv3_rtc_suspend, |
333 | .resume = puv3_rtc_resume, | 333 | .resume = puv3_rtc_resume, |
334 | .driver = { | 334 | .driver = { |
@@ -337,7 +337,21 @@ static struct platform_driver puv3_rtc_driver = { | |||
337 | } | 337 | } |
338 | }; | 338 | }; |
339 | 339 | ||
340 | module_platform_driver(puv3_rtc_driver); | 340 | static char __initdata banner[] = "PKUnity-v3 RTC, (c) 2009 PKUnity Co.\n"; |
341 | |||
342 | static int __init puv3_rtc_init(void) | ||
343 | { | ||
344 | printk(banner); | ||
345 | return platform_driver_register(&puv3_rtcdrv); | ||
346 | } | ||
347 | |||
348 | static void __exit puv3_rtc_exit(void) | ||
349 | { | ||
350 | platform_driver_unregister(&puv3_rtcdrv); | ||
351 | } | ||
352 | |||
353 | module_init(puv3_rtc_init); | ||
354 | module_exit(puv3_rtc_exit); | ||
341 | 355 | ||
342 | MODULE_DESCRIPTION("RTC Driver for the PKUnity v3 chip"); | 356 | MODULE_DESCRIPTION("RTC Driver for the PKUnity v3 chip"); |
343 | MODULE_AUTHOR("Hu Dongliang"); | 357 | MODULE_AUTHOR("Hu Dongliang"); |
diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c index f771b2ee4b1..fc9f4991574 100644 --- a/drivers/rtc/rtc-pxa.c +++ b/drivers/rtc/rtc-pxa.c | |||
@@ -27,8 +27,6 @@ | |||
27 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
28 | #include <linux/io.h> | 28 | #include <linux/io.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/of.h> | ||
31 | #include <linux/of_device.h> | ||
32 | 30 | ||
33 | #include <mach/hardware.h> | 31 | #include <mach/hardware.h> |
34 | 32 | ||
@@ -176,14 +174,14 @@ static int pxa_rtc_open(struct device *dev) | |||
176 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | 174 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); |
177 | int ret; | 175 | int ret; |
178 | 176 | ||
179 | ret = request_irq(pxa_rtc->irq_1Hz, pxa_rtc_irq, 0, | 177 | ret = request_irq(pxa_rtc->irq_1Hz, pxa_rtc_irq, IRQF_DISABLED, |
180 | "rtc 1Hz", dev); | 178 | "rtc 1Hz", dev); |
181 | if (ret < 0) { | 179 | if (ret < 0) { |
182 | dev_err(dev, "can't get irq %i, err %d\n", pxa_rtc->irq_1Hz, | 180 | dev_err(dev, "can't get irq %i, err %d\n", pxa_rtc->irq_1Hz, |
183 | ret); | 181 | ret); |
184 | goto err_irq_1Hz; | 182 | goto err_irq_1Hz; |
185 | } | 183 | } |
186 | ret = request_irq(pxa_rtc->irq_Alrm, pxa_rtc_irq, 0, | 184 | ret = request_irq(pxa_rtc->irq_Alrm, pxa_rtc_irq, IRQF_DISABLED, |
187 | "rtc Alrm", dev); | 185 | "rtc Alrm", dev); |
188 | if (ret < 0) { | 186 | if (ret < 0) { |
189 | dev_err(dev, "can't get irq %i, err %d\n", pxa_rtc->irq_Alrm, | 187 | dev_err(dev, "can't get irq %i, err %d\n", pxa_rtc->irq_Alrm, |
@@ -398,14 +396,6 @@ static int __exit pxa_rtc_remove(struct platform_device *pdev) | |||
398 | return 0; | 396 | return 0; |
399 | } | 397 | } |
400 | 398 | ||
401 | #ifdef CONFIG_OF | ||
402 | static struct of_device_id pxa_rtc_dt_ids[] = { | ||
403 | { .compatible = "marvell,pxa-rtc" }, | ||
404 | {} | ||
405 | }; | ||
406 | MODULE_DEVICE_TABLE(of, pxa_rtc_dt_ids); | ||
407 | #endif | ||
408 | |||
409 | #ifdef CONFIG_PM | 399 | #ifdef CONFIG_PM |
410 | static int pxa_rtc_suspend(struct device *dev) | 400 | static int pxa_rtc_suspend(struct device *dev) |
411 | { | 401 | { |
@@ -435,7 +425,6 @@ static struct platform_driver pxa_rtc_driver = { | |||
435 | .remove = __exit_p(pxa_rtc_remove), | 425 | .remove = __exit_p(pxa_rtc_remove), |
436 | .driver = { | 426 | .driver = { |
437 | .name = "pxa-rtc", | 427 | .name = "pxa-rtc", |
438 | .of_match_table = of_match_ptr(pxa_rtc_dt_ids), | ||
439 | #ifdef CONFIG_PM | 428 | #ifdef CONFIG_PM |
440 | .pm = &pxa_rtc_pm_ops, | 429 | .pm = &pxa_rtc_pm_ops, |
441 | #endif | 430 | #endif |
diff --git a/drivers/rtc/rtc-r9701.c b/drivers/rtc/rtc-r9701.c index 7726f4a4f2d..9beba49c3c5 100644 --- a/drivers/rtc/rtc-r9701.c +++ b/drivers/rtc/rtc-r9701.c | |||
@@ -119,41 +119,12 @@ static const struct rtc_class_ops r9701_rtc_ops = { | |||
119 | .set_time = r9701_set_datetime, | 119 | .set_time = r9701_set_datetime, |
120 | }; | 120 | }; |
121 | 121 | ||
122 | static int r9701_probe(struct spi_device *spi) | 122 | static int __devinit r9701_probe(struct spi_device *spi) |
123 | { | 123 | { |
124 | struct rtc_device *rtc; | 124 | struct rtc_device *rtc; |
125 | struct rtc_time dt; | ||
126 | unsigned char tmp; | 125 | unsigned char tmp; |
127 | int res; | 126 | int res; |
128 | 127 | ||
129 | tmp = R100CNT; | ||
130 | res = read_regs(&spi->dev, &tmp, 1); | ||
131 | if (res || tmp != 0x20) { | ||
132 | dev_err(&spi->dev, "cannot read RTC register\n"); | ||
133 | return -ENODEV; | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | * The device seems to be present. Now check if the registers | ||
138 | * contain invalid values. If so, try to write a default date: | ||
139 | * 2000/1/1 00:00:00 | ||
140 | */ | ||
141 | if (r9701_get_datetime(&spi->dev, &dt)) { | ||
142 | dev_info(&spi->dev, "trying to repair invalid date/time\n"); | ||
143 | dt.tm_sec = 0; | ||
144 | dt.tm_min = 0; | ||
145 | dt.tm_hour = 0; | ||
146 | dt.tm_mday = 1; | ||
147 | dt.tm_mon = 0; | ||
148 | dt.tm_year = 100; | ||
149 | |||
150 | if (r9701_set_datetime(&spi->dev, &dt) || | ||
151 | r9701_get_datetime(&spi->dev, &dt)) { | ||
152 | dev_err(&spi->dev, "cannot repair RTC register\n"); | ||
153 | return -ENODEV; | ||
154 | } | ||
155 | } | ||
156 | |||
157 | rtc = rtc_device_register("r9701", | 128 | rtc = rtc_device_register("r9701", |
158 | &spi->dev, &r9701_rtc_ops, THIS_MODULE); | 129 | &spi->dev, &r9701_rtc_ops, THIS_MODULE); |
159 | if (IS_ERR(rtc)) | 130 | if (IS_ERR(rtc)) |
@@ -161,10 +132,17 @@ static int r9701_probe(struct spi_device *spi) | |||
161 | 132 | ||
162 | dev_set_drvdata(&spi->dev, rtc); | 133 | dev_set_drvdata(&spi->dev, rtc); |
163 | 134 | ||
135 | tmp = R100CNT; | ||
136 | res = read_regs(&spi->dev, &tmp, 1); | ||
137 | if (res || tmp != 0x20) { | ||
138 | rtc_device_unregister(rtc); | ||
139 | return res; | ||
140 | } | ||
141 | |||
164 | return 0; | 142 | return 0; |
165 | } | 143 | } |
166 | 144 | ||
167 | static int r9701_remove(struct spi_device *spi) | 145 | static int __devexit r9701_remove(struct spi_device *spi) |
168 | { | 146 | { |
169 | struct rtc_device *rtc = dev_get_drvdata(&spi->dev); | 147 | struct rtc_device *rtc = dev_get_drvdata(&spi->dev); |
170 | 148 | ||
@@ -178,10 +156,20 @@ static struct spi_driver r9701_driver = { | |||
178 | .owner = THIS_MODULE, | 156 | .owner = THIS_MODULE, |
179 | }, | 157 | }, |
180 | .probe = r9701_probe, | 158 | .probe = r9701_probe, |
181 | .remove = r9701_remove, | 159 | .remove = __devexit_p(r9701_remove), |
182 | }; | 160 | }; |
183 | 161 | ||
184 | module_spi_driver(r9701_driver); | 162 | static __init int r9701_init(void) |
163 | { | ||
164 | return spi_register_driver(&r9701_driver); | ||
165 | } | ||
166 | module_init(r9701_init); | ||
167 | |||
168 | static __exit void r9701_exit(void) | ||
169 | { | ||
170 | spi_unregister_driver(&r9701_driver); | ||
171 | } | ||
172 | module_exit(r9701_exit); | ||
185 | 173 | ||
186 | MODULE_DESCRIPTION("r9701 spi RTC driver"); | 174 | MODULE_DESCRIPTION("r9701 spi RTC driver"); |
187 | MODULE_AUTHOR("Magnus Damm <damm@opensource.se>"); | 175 | MODULE_AUTHOR("Magnus Damm <damm@opensource.se>"); |
diff --git a/drivers/rtc/rtc-rc5t583.c b/drivers/rtc/rtc-rc5t583.c deleted file mode 100644 index eb3194d664a..00000000000 --- a/drivers/rtc/rtc-rc5t583.c +++ /dev/null | |||
@@ -1,331 +0,0 @@ | |||
1 | /* | ||
2 | * rtc-rc5t583.c -- RICOH RC5T583 Real Time Clock | ||
3 | * | ||
4 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
5 | * Author: Venu Byravarasu <vbyravarasu@nvidia.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms and conditions of the GNU General Public License, | ||
9 | * version 2, as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope 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 | ||
17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/types.h> | ||
24 | #include <linux/rtc.h> | ||
25 | #include <linux/bcd.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/mfd/rc5t583.h> | ||
29 | |||
30 | struct rc5t583_rtc { | ||
31 | struct rtc_device *rtc; | ||
32 | /* To store the list of enabled interrupts, during system suspend */ | ||
33 | u32 irqen; | ||
34 | }; | ||
35 | |||
36 | /* Total number of RTC registers needed to set time*/ | ||
37 | #define NUM_TIME_REGS (RC5T583_RTC_YEAR - RC5T583_RTC_SEC + 1) | ||
38 | |||
39 | /* Total number of RTC registers needed to set Y-Alarm*/ | ||
40 | #define NUM_YAL_REGS (RC5T583_RTC_AY_YEAR - RC5T583_RTC_AY_MIN + 1) | ||
41 | |||
42 | /* Set Y-Alarm interrupt */ | ||
43 | #define SET_YAL BIT(5) | ||
44 | |||
45 | /* Get Y-Alarm interrupt status*/ | ||
46 | #define GET_YAL_STATUS BIT(3) | ||
47 | |||
48 | static int rc5t583_rtc_alarm_irq_enable(struct device *dev, unsigned enabled) | ||
49 | { | ||
50 | struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); | ||
51 | u8 val; | ||
52 | |||
53 | /* Set Y-Alarm, based on 'enabled' */ | ||
54 | val = enabled ? SET_YAL : 0; | ||
55 | |||
56 | return regmap_update_bits(rc5t583->regmap, RC5T583_RTC_CTL1, SET_YAL, | ||
57 | val); | ||
58 | } | ||
59 | |||
60 | /* | ||
61 | * Gets current rc5t583 RTC time and date parameters. | ||
62 | * | ||
63 | * The RTC's time/alarm representation is not what gmtime(3) requires | ||
64 | * Linux to use: | ||
65 | * | ||
66 | * - Months are 1..12 vs Linux 0-11 | ||
67 | * - Years are 0..99 vs Linux 1900..N (we assume 21st century) | ||
68 | */ | ||
69 | static int rc5t583_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
70 | { | ||
71 | struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); | ||
72 | u8 rtc_data[NUM_TIME_REGS]; | ||
73 | int ret; | ||
74 | |||
75 | ret = regmap_bulk_read(rc5t583->regmap, RC5T583_RTC_SEC, rtc_data, | ||
76 | NUM_TIME_REGS); | ||
77 | if (ret < 0) { | ||
78 | dev_err(dev, "RTC read time failed with err:%d\n", ret); | ||
79 | return ret; | ||
80 | } | ||
81 | |||
82 | tm->tm_sec = bcd2bin(rtc_data[0]); | ||
83 | tm->tm_min = bcd2bin(rtc_data[1]); | ||
84 | tm->tm_hour = bcd2bin(rtc_data[2]); | ||
85 | tm->tm_wday = bcd2bin(rtc_data[3]); | ||
86 | tm->tm_mday = bcd2bin(rtc_data[4]); | ||
87 | tm->tm_mon = bcd2bin(rtc_data[5]) - 1; | ||
88 | tm->tm_year = bcd2bin(rtc_data[6]) + 100; | ||
89 | |||
90 | return ret; | ||
91 | } | ||
92 | |||
93 | static int rc5t583_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
94 | { | ||
95 | struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); | ||
96 | unsigned char rtc_data[NUM_TIME_REGS]; | ||
97 | int ret; | ||
98 | |||
99 | rtc_data[0] = bin2bcd(tm->tm_sec); | ||
100 | rtc_data[1] = bin2bcd(tm->tm_min); | ||
101 | rtc_data[2] = bin2bcd(tm->tm_hour); | ||
102 | rtc_data[3] = bin2bcd(tm->tm_wday); | ||
103 | rtc_data[4] = bin2bcd(tm->tm_mday); | ||
104 | rtc_data[5] = bin2bcd(tm->tm_mon + 1); | ||
105 | rtc_data[6] = bin2bcd(tm->tm_year - 100); | ||
106 | |||
107 | ret = regmap_bulk_write(rc5t583->regmap, RC5T583_RTC_SEC, rtc_data, | ||
108 | NUM_TIME_REGS); | ||
109 | if (ret < 0) { | ||
110 | dev_err(dev, "RTC set time failed with error %d\n", ret); | ||
111 | return ret; | ||
112 | } | ||
113 | |||
114 | return ret; | ||
115 | } | ||
116 | |||
117 | static int rc5t583_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | ||
118 | { | ||
119 | struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); | ||
120 | unsigned char alarm_data[NUM_YAL_REGS]; | ||
121 | u32 interrupt_enable; | ||
122 | int ret; | ||
123 | |||
124 | ret = regmap_bulk_read(rc5t583->regmap, RC5T583_RTC_AY_MIN, alarm_data, | ||
125 | NUM_YAL_REGS); | ||
126 | if (ret < 0) { | ||
127 | dev_err(dev, "rtc_read_alarm error %d\n", ret); | ||
128 | return ret; | ||
129 | } | ||
130 | |||
131 | alm->time.tm_min = bcd2bin(alarm_data[0]); | ||
132 | alm->time.tm_hour = bcd2bin(alarm_data[1]); | ||
133 | alm->time.tm_mday = bcd2bin(alarm_data[2]); | ||
134 | alm->time.tm_mon = bcd2bin(alarm_data[3]) - 1; | ||
135 | alm->time.tm_year = bcd2bin(alarm_data[4]) + 100; | ||
136 | |||
137 | ret = regmap_read(rc5t583->regmap, RC5T583_RTC_CTL1, &interrupt_enable); | ||
138 | if (ret < 0) | ||
139 | return ret; | ||
140 | |||
141 | /* check if YALE is set */ | ||
142 | if (interrupt_enable & SET_YAL) | ||
143 | alm->enabled = 1; | ||
144 | |||
145 | return ret; | ||
146 | } | ||
147 | |||
148 | static int rc5t583_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | ||
149 | { | ||
150 | struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); | ||
151 | unsigned char alarm_data[NUM_YAL_REGS]; | ||
152 | int ret; | ||
153 | |||
154 | ret = rc5t583_rtc_alarm_irq_enable(dev, 0); | ||
155 | if (ret) | ||
156 | return ret; | ||
157 | |||
158 | alarm_data[0] = bin2bcd(alm->time.tm_min); | ||
159 | alarm_data[1] = bin2bcd(alm->time.tm_hour); | ||
160 | alarm_data[2] = bin2bcd(alm->time.tm_mday); | ||
161 | alarm_data[3] = bin2bcd(alm->time.tm_mon + 1); | ||
162 | alarm_data[4] = bin2bcd(alm->time.tm_year - 100); | ||
163 | |||
164 | ret = regmap_bulk_write(rc5t583->regmap, RC5T583_RTC_AY_MIN, alarm_data, | ||
165 | NUM_YAL_REGS); | ||
166 | if (ret) { | ||
167 | dev_err(dev, "rtc_set_alarm error %d\n", ret); | ||
168 | return ret; | ||
169 | } | ||
170 | |||
171 | if (alm->enabled) | ||
172 | ret = rc5t583_rtc_alarm_irq_enable(dev, 1); | ||
173 | |||
174 | return ret; | ||
175 | } | ||
176 | |||
177 | static irqreturn_t rc5t583_rtc_interrupt(int irq, void *rtc) | ||
178 | { | ||
179 | struct device *dev = rtc; | ||
180 | struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); | ||
181 | struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(dev); | ||
182 | unsigned long events = 0; | ||
183 | int ret; | ||
184 | u32 rtc_reg; | ||
185 | |||
186 | ret = regmap_read(rc5t583->regmap, RC5T583_RTC_CTL2, &rtc_reg); | ||
187 | if (ret < 0) | ||
188 | return IRQ_NONE; | ||
189 | |||
190 | if (rtc_reg & GET_YAL_STATUS) { | ||
191 | events = RTC_IRQF | RTC_AF; | ||
192 | /* clear pending Y-alarm interrupt bit */ | ||
193 | rtc_reg &= ~GET_YAL_STATUS; | ||
194 | } | ||
195 | |||
196 | ret = regmap_write(rc5t583->regmap, RC5T583_RTC_CTL2, rtc_reg); | ||
197 | if (ret) | ||
198 | return IRQ_NONE; | ||
199 | |||
200 | /* Notify RTC core on event */ | ||
201 | rtc_update_irq(rc5t583_rtc->rtc, 1, events); | ||
202 | |||
203 | return IRQ_HANDLED; | ||
204 | } | ||
205 | |||
206 | static const struct rtc_class_ops rc5t583_rtc_ops = { | ||
207 | .read_time = rc5t583_rtc_read_time, | ||
208 | .set_time = rc5t583_rtc_set_time, | ||
209 | .read_alarm = rc5t583_rtc_read_alarm, | ||
210 | .set_alarm = rc5t583_rtc_set_alarm, | ||
211 | .alarm_irq_enable = rc5t583_rtc_alarm_irq_enable, | ||
212 | }; | ||
213 | |||
214 | static int rc5t583_rtc_probe(struct platform_device *pdev) | ||
215 | { | ||
216 | struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent); | ||
217 | struct rc5t583_rtc *ricoh_rtc; | ||
218 | struct rc5t583_platform_data *pmic_plat_data; | ||
219 | int ret; | ||
220 | int irq; | ||
221 | |||
222 | ricoh_rtc = devm_kzalloc(&pdev->dev, sizeof(struct rc5t583_rtc), | ||
223 | GFP_KERNEL); | ||
224 | if (!ricoh_rtc) | ||
225 | return -ENOMEM; | ||
226 | |||
227 | platform_set_drvdata(pdev, ricoh_rtc); | ||
228 | |||
229 | /* Clear pending interrupts */ | ||
230 | ret = regmap_write(rc5t583->regmap, RC5T583_RTC_CTL2, 0); | ||
231 | if (ret < 0) | ||
232 | return ret; | ||
233 | |||
234 | /* clear RTC Adjust register */ | ||
235 | ret = regmap_write(rc5t583->regmap, RC5T583_RTC_ADJ, 0); | ||
236 | if (ret < 0) { | ||
237 | dev_err(&pdev->dev, "unable to program rtc_adjust reg\n"); | ||
238 | return -EBUSY; | ||
239 | } | ||
240 | |||
241 | pmic_plat_data = dev_get_platdata(rc5t583->dev); | ||
242 | irq = pmic_plat_data->irq_base; | ||
243 | if (irq <= 0) { | ||
244 | dev_warn(&pdev->dev, "Wake up is not possible as irq = %d\n", | ||
245 | irq); | ||
246 | return ret; | ||
247 | } | ||
248 | |||
249 | irq += RC5T583_IRQ_YALE; | ||
250 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, | ||
251 | rc5t583_rtc_interrupt, IRQF_TRIGGER_LOW, | ||
252 | "rtc-rc5t583", &pdev->dev); | ||
253 | if (ret < 0) { | ||
254 | dev_err(&pdev->dev, "IRQ is not free.\n"); | ||
255 | return ret; | ||
256 | } | ||
257 | device_init_wakeup(&pdev->dev, 1); | ||
258 | |||
259 | ricoh_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, | ||
260 | &rc5t583_rtc_ops, THIS_MODULE); | ||
261 | if (IS_ERR(ricoh_rtc->rtc)) { | ||
262 | ret = PTR_ERR(ricoh_rtc->rtc); | ||
263 | dev_err(&pdev->dev, "RTC device register: err %d\n", ret); | ||
264 | return ret; | ||
265 | } | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | /* | ||
271 | * Disable rc5t583 RTC interrupts. | ||
272 | * Sets status flag to free. | ||
273 | */ | ||
274 | static int rc5t583_rtc_remove(struct platform_device *pdev) | ||
275 | { | ||
276 | struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(&pdev->dev); | ||
277 | |||
278 | rc5t583_rtc_alarm_irq_enable(&rc5t583_rtc->rtc->dev, 0); | ||
279 | |||
280 | rtc_device_unregister(rc5t583_rtc->rtc); | ||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | #ifdef CONFIG_PM_SLEEP | ||
285 | |||
286 | static int rc5t583_rtc_suspend(struct device *dev) | ||
287 | { | ||
288 | struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); | ||
289 | struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(dev); | ||
290 | int ret; | ||
291 | |||
292 | /* Store current list of enabled interrupts*/ | ||
293 | ret = regmap_read(rc5t583->regmap, RC5T583_RTC_CTL1, | ||
294 | &rc5t583_rtc->irqen); | ||
295 | return ret; | ||
296 | } | ||
297 | |||
298 | static int rc5t583_rtc_resume(struct device *dev) | ||
299 | { | ||
300 | struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); | ||
301 | struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(dev); | ||
302 | |||
303 | /* Restore list of enabled interrupts before suspend */ | ||
304 | return regmap_write(rc5t583->regmap, RC5T583_RTC_CTL1, | ||
305 | rc5t583_rtc->irqen); | ||
306 | } | ||
307 | |||
308 | static const struct dev_pm_ops rc5t583_rtc_pm_ops = { | ||
309 | .suspend = rc5t583_rtc_suspend, | ||
310 | .resume = rc5t583_rtc_resume, | ||
311 | }; | ||
312 | |||
313 | #define DEV_PM_OPS (&rc5t583_rtc_pm_ops) | ||
314 | #else | ||
315 | #define DEV_PM_OPS NULL | ||
316 | #endif | ||
317 | |||
318 | static struct platform_driver rc5t583_rtc_driver = { | ||
319 | .probe = rc5t583_rtc_probe, | ||
320 | .remove = rc5t583_rtc_remove, | ||
321 | .driver = { | ||
322 | .owner = THIS_MODULE, | ||
323 | .name = "rtc-rc5t583", | ||
324 | .pm = DEV_PM_OPS, | ||
325 | }, | ||
326 | }; | ||
327 | |||
328 | module_platform_driver(rc5t583_rtc_driver); | ||
329 | MODULE_ALIAS("platform:rtc-rc5t583"); | ||
330 | MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>"); | ||
331 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/rtc/rtc-rs5c313.c b/drivers/rtc/rtc-rs5c313.c index d1aee793ecc..e3ff179b99c 100644 --- a/drivers/rtc/rtc-rs5c313.c +++ b/drivers/rtc/rtc-rs5c313.c | |||
@@ -377,7 +377,7 @@ static int rs5c313_rtc_probe(struct platform_device *pdev) | |||
377 | return 0; | 377 | return 0; |
378 | } | 378 | } |
379 | 379 | ||
380 | static int rs5c313_rtc_remove(struct platform_device *pdev) | 380 | static int __devexit rs5c313_rtc_remove(struct platform_device *pdev) |
381 | { | 381 | { |
382 | struct rtc_device *rtc = platform_get_drvdata( pdev ); | 382 | struct rtc_device *rtc = platform_get_drvdata( pdev ); |
383 | 383 | ||
@@ -392,7 +392,7 @@ static struct platform_driver rs5c313_rtc_platform_driver = { | |||
392 | .owner = THIS_MODULE, | 392 | .owner = THIS_MODULE, |
393 | }, | 393 | }, |
394 | .probe = rs5c313_rtc_probe, | 394 | .probe = rs5c313_rtc_probe, |
395 | .remove = rs5c313_rtc_remove, | 395 | .remove = __devexit_p( rs5c313_rtc_remove ), |
396 | }; | 396 | }; |
397 | 397 | ||
398 | static int __init rs5c313_rtc_init(void) | 398 | static int __init rs5c313_rtc_init(void) |
diff --git a/drivers/rtc/rtc-rs5c348.c b/drivers/rtc/rtc-rs5c348.c index 72ef10be866..368d0e63cf8 100644 --- a/drivers/rtc/rtc-rs5c348.c +++ b/drivers/rtc/rtc-rs5c348.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/rtc.h> | 23 | #include <linux/rtc.h> |
24 | #include <linux/workqueue.h> | 24 | #include <linux/workqueue.h> |
25 | #include <linux/spi/spi.h> | 25 | #include <linux/spi/spi.h> |
26 | #include <linux/module.h> | ||
27 | 26 | ||
28 | #define DRV_VERSION "0.2" | 27 | #define DRV_VERSION "0.2" |
29 | 28 | ||
@@ -122,12 +121,9 @@ rs5c348_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
122 | tm->tm_min = bcd2bin(rxbuf[RS5C348_REG_MINS] & RS5C348_MINS_MASK); | 121 | tm->tm_min = bcd2bin(rxbuf[RS5C348_REG_MINS] & RS5C348_MINS_MASK); |
123 | tm->tm_hour = bcd2bin(rxbuf[RS5C348_REG_HOURS] & RS5C348_HOURS_MASK); | 122 | tm->tm_hour = bcd2bin(rxbuf[RS5C348_REG_HOURS] & RS5C348_HOURS_MASK); |
124 | if (!pdata->rtc_24h) { | 123 | if (!pdata->rtc_24h) { |
125 | if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM) { | 124 | tm->tm_hour %= 12; |
126 | tm->tm_hour -= 20; | 125 | if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM) |
127 | tm->tm_hour %= 12; | ||
128 | tm->tm_hour += 12; | 126 | tm->tm_hour += 12; |
129 | } else | ||
130 | tm->tm_hour %= 12; | ||
131 | } | 127 | } |
132 | tm->tm_wday = bcd2bin(rxbuf[RS5C348_REG_WDAY] & RS5C348_WDAY_MASK); | 128 | tm->tm_wday = bcd2bin(rxbuf[RS5C348_REG_WDAY] & RS5C348_WDAY_MASK); |
133 | tm->tm_mday = bcd2bin(rxbuf[RS5C348_REG_DAY] & RS5C348_DAY_MASK); | 129 | tm->tm_mday = bcd2bin(rxbuf[RS5C348_REG_DAY] & RS5C348_DAY_MASK); |
@@ -152,7 +148,7 @@ static const struct rtc_class_ops rs5c348_rtc_ops = { | |||
152 | 148 | ||
153 | static struct spi_driver rs5c348_driver; | 149 | static struct spi_driver rs5c348_driver; |
154 | 150 | ||
155 | static int rs5c348_probe(struct spi_device *spi) | 151 | static int __devinit rs5c348_probe(struct spi_device *spi) |
156 | { | 152 | { |
157 | int ret; | 153 | int ret; |
158 | struct rtc_device *rtc; | 154 | struct rtc_device *rtc; |
@@ -218,7 +214,7 @@ static int rs5c348_probe(struct spi_device *spi) | |||
218 | return ret; | 214 | return ret; |
219 | } | 215 | } |
220 | 216 | ||
221 | static int rs5c348_remove(struct spi_device *spi) | 217 | static int __devexit rs5c348_remove(struct spi_device *spi) |
222 | { | 218 | { |
223 | struct rs5c348_plat_data *pdata = spi->dev.platform_data; | 219 | struct rs5c348_plat_data *pdata = spi->dev.platform_data; |
224 | struct rtc_device *rtc = pdata->rtc; | 220 | struct rtc_device *rtc = pdata->rtc; |
@@ -232,13 +228,25 @@ static int rs5c348_remove(struct spi_device *spi) | |||
232 | static struct spi_driver rs5c348_driver = { | 228 | static struct spi_driver rs5c348_driver = { |
233 | .driver = { | 229 | .driver = { |
234 | .name = "rtc-rs5c348", | 230 | .name = "rtc-rs5c348", |
231 | .bus = &spi_bus_type, | ||
235 | .owner = THIS_MODULE, | 232 | .owner = THIS_MODULE, |
236 | }, | 233 | }, |
237 | .probe = rs5c348_probe, | 234 | .probe = rs5c348_probe, |
238 | .remove = rs5c348_remove, | 235 | .remove = __devexit_p(rs5c348_remove), |
239 | }; | 236 | }; |
240 | 237 | ||
241 | module_spi_driver(rs5c348_driver); | 238 | static __init int rs5c348_init(void) |
239 | { | ||
240 | return spi_register_driver(&rs5c348_driver); | ||
241 | } | ||
242 | |||
243 | static __exit void rs5c348_exit(void) | ||
244 | { | ||
245 | spi_unregister_driver(&rs5c348_driver); | ||
246 | } | ||
247 | |||
248 | module_init(rs5c348_init); | ||
249 | module_exit(rs5c348_exit); | ||
242 | 250 | ||
243 | MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); | 251 | MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); |
244 | MODULE_DESCRIPTION("Ricoh RS5C348 RTC driver"); | 252 | MODULE_DESCRIPTION("Ricoh RS5C348 RTC driver"); |
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index 76f565ae384..85c1b848dd7 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/rtc.h> | 14 | #include <linux/rtc.h> |
15 | #include <linux/bcd.h> | 15 | #include <linux/bcd.h> |
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/module.h> | ||
18 | 17 | ||
19 | #define DRV_VERSION "0.6" | 18 | #define DRV_VERSION "0.6" |
20 | 19 | ||
@@ -104,12 +103,7 @@ static int rs5c_get_regs(struct rs5c372 *rs5c) | |||
104 | { | 103 | { |
105 | struct i2c_client *client = rs5c->client; | 104 | struct i2c_client *client = rs5c->client; |
106 | struct i2c_msg msgs[] = { | 105 | struct i2c_msg msgs[] = { |
107 | { | 106 | { client->addr, I2C_M_RD, sizeof rs5c->buf, rs5c->buf }, |
108 | .addr = client->addr, | ||
109 | .flags = I2C_M_RD, | ||
110 | .len = sizeof(rs5c->buf), | ||
111 | .buf = rs5c->buf | ||
112 | }, | ||
113 | }; | 107 | }; |
114 | 108 | ||
115 | /* This implements the third reading method from the datasheet, using | 109 | /* This implements the third reading method from the datasheet, using |
@@ -694,7 +688,18 @@ static struct i2c_driver rs5c372_driver = { | |||
694 | .id_table = rs5c372_id, | 688 | .id_table = rs5c372_id, |
695 | }; | 689 | }; |
696 | 690 | ||
697 | module_i2c_driver(rs5c372_driver); | 691 | static __init int rs5c372_init(void) |
692 | { | ||
693 | return i2c_add_driver(&rs5c372_driver); | ||
694 | } | ||
695 | |||
696 | static __exit void rs5c372_exit(void) | ||
697 | { | ||
698 | i2c_del_driver(&rs5c372_driver); | ||
699 | } | ||
700 | |||
701 | module_init(rs5c372_init); | ||
702 | module_exit(rs5c372_exit); | ||
698 | 703 | ||
699 | MODULE_AUTHOR( | 704 | MODULE_AUTHOR( |
700 | "Pavel Mironchik <pmironchik@optifacio.net>, " | 705 | "Pavel Mironchik <pmironchik@optifacio.net>, " |
diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c index f8ee8ad7825..ea09ff211dc 100644 --- a/drivers/rtc/rtc-rv3029c2.c +++ b/drivers/rtc/rtc-rv3029c2.c | |||
@@ -385,8 +385,8 @@ static struct i2c_device_id rv3029c2_id[] = { | |||
385 | }; | 385 | }; |
386 | MODULE_DEVICE_TABLE(i2c, rv3029c2_id); | 386 | MODULE_DEVICE_TABLE(i2c, rv3029c2_id); |
387 | 387 | ||
388 | static int rv3029c2_probe(struct i2c_client *client, | 388 | static int __devinit |
389 | const struct i2c_device_id *id) | 389 | rv3029c2_probe(struct i2c_client *client, const struct i2c_device_id *id) |
390 | { | 390 | { |
391 | struct rtc_device *rtc; | 391 | struct rtc_device *rtc; |
392 | int rc = 0; | 392 | int rc = 0; |
@@ -418,7 +418,7 @@ exit_unregister: | |||
418 | return rc; | 418 | return rc; |
419 | } | 419 | } |
420 | 420 | ||
421 | static int rv3029c2_remove(struct i2c_client *client) | 421 | static int __devexit rv3029c2_remove(struct i2c_client *client) |
422 | { | 422 | { |
423 | struct rtc_device *rtc = i2c_get_clientdata(client); | 423 | struct rtc_device *rtc = i2c_get_clientdata(client); |
424 | 424 | ||
@@ -432,11 +432,22 @@ static struct i2c_driver rv3029c2_driver = { | |||
432 | .name = "rtc-rv3029c2", | 432 | .name = "rtc-rv3029c2", |
433 | }, | 433 | }, |
434 | .probe = rv3029c2_probe, | 434 | .probe = rv3029c2_probe, |
435 | .remove = rv3029c2_remove, | 435 | .remove = __devexit_p(rv3029c2_remove), |
436 | .id_table = rv3029c2_id, | 436 | .id_table = rv3029c2_id, |
437 | }; | 437 | }; |
438 | 438 | ||
439 | module_i2c_driver(rv3029c2_driver); | 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); | ||
440 | 451 | ||
441 | MODULE_AUTHOR("Gregory Hermant <gregory.hermant@calao-systems.com>"); | 452 | MODULE_AUTHOR("Gregory Hermant <gregory.hermant@calao-systems.com>"); |
442 | MODULE_DESCRIPTION("Micro Crystal RV3029C2 RTC driver"); | 453 | MODULE_DESCRIPTION("Micro Crystal RV3029C2 RTC driver"); |
diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c index 0722d36b9c9..fde172fb2ab 100644 --- a/drivers/rtc/rtc-rx8025.c +++ b/drivers/rtc/rtc-rx8025.c | |||
@@ -534,8 +534,8 @@ static void rx8025_sysfs_unregister(struct device *dev) | |||
534 | device_remove_file(dev, &dev_attr_clock_adjust_ppb); | 534 | device_remove_file(dev, &dev_attr_clock_adjust_ppb); |
535 | } | 535 | } |
536 | 536 | ||
537 | static int rx8025_probe(struct i2c_client *client, | 537 | static int __devinit rx8025_probe(struct i2c_client *client, |
538 | const struct i2c_device_id *id) | 538 | const struct i2c_device_id *id) |
539 | { | 539 | { |
540 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 540 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
541 | struct rx8025_data *rx8025; | 541 | struct rx8025_data *rx8025; |
@@ -614,7 +614,7 @@ errout: | |||
614 | return err; | 614 | return err; |
615 | } | 615 | } |
616 | 616 | ||
617 | static int rx8025_remove(struct i2c_client *client) | 617 | static int __devexit rx8025_remove(struct i2c_client *client) |
618 | { | 618 | { |
619 | struct rx8025_data *rx8025 = i2c_get_clientdata(client); | 619 | struct rx8025_data *rx8025 = i2c_get_clientdata(client); |
620 | struct mutex *lock = &rx8025->rtc->ops_lock; | 620 | struct mutex *lock = &rx8025->rtc->ops_lock; |
@@ -640,12 +640,23 @@ static struct i2c_driver rx8025_driver = { | |||
640 | .owner = THIS_MODULE, | 640 | .owner = THIS_MODULE, |
641 | }, | 641 | }, |
642 | .probe = rx8025_probe, | 642 | .probe = rx8025_probe, |
643 | .remove = rx8025_remove, | 643 | .remove = __devexit_p(rx8025_remove), |
644 | .id_table = rx8025_id, | 644 | .id_table = rx8025_id, |
645 | }; | 645 | }; |
646 | 646 | ||
647 | module_i2c_driver(rx8025_driver); | 647 | static int __init rx8025_init(void) |
648 | { | ||
649 | return i2c_add_driver(&rx8025_driver); | ||
650 | } | ||
651 | |||
652 | static void __exit rx8025_exit(void) | ||
653 | { | ||
654 | i2c_del_driver(&rx8025_driver); | ||
655 | } | ||
648 | 656 | ||
649 | MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>"); | 657 | MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>"); |
650 | MODULE_DESCRIPTION("RX-8025 SA/NB RTC driver"); | 658 | MODULE_DESCRIPTION("RX-8025 SA/NB RTC driver"); |
651 | MODULE_LICENSE("GPL"); | 659 | MODULE_LICENSE("GPL"); |
660 | |||
661 | module_init(rx8025_init); | ||
662 | module_exit(rx8025_exit); | ||
diff --git a/drivers/rtc/rtc-rx8581.c b/drivers/rtc/rtc-rx8581.c index b0c272658fa..600b890a3c1 100644 --- a/drivers/rtc/rtc-rx8581.c +++ b/drivers/rtc/rtc-rx8581.c | |||
@@ -228,8 +228,8 @@ static const struct rtc_class_ops rx8581_rtc_ops = { | |||
228 | .set_time = rx8581_rtc_set_time, | 228 | .set_time = rx8581_rtc_set_time, |
229 | }; | 229 | }; |
230 | 230 | ||
231 | static int rx8581_probe(struct i2c_client *client, | 231 | static int __devinit rx8581_probe(struct i2c_client *client, |
232 | const struct i2c_device_id *id) | 232 | const struct i2c_device_id *id) |
233 | { | 233 | { |
234 | struct rtc_device *rtc; | 234 | struct rtc_device *rtc; |
235 | 235 | ||
@@ -251,7 +251,7 @@ static int rx8581_probe(struct i2c_client *client, | |||
251 | return 0; | 251 | return 0; |
252 | } | 252 | } |
253 | 253 | ||
254 | static int rx8581_remove(struct i2c_client *client) | 254 | static int __devexit rx8581_remove(struct i2c_client *client) |
255 | { | 255 | { |
256 | struct rtc_device *rtc = i2c_get_clientdata(client); | 256 | struct rtc_device *rtc = i2c_get_clientdata(client); |
257 | 257 | ||
@@ -272,13 +272,24 @@ static struct i2c_driver rx8581_driver = { | |||
272 | .owner = THIS_MODULE, | 272 | .owner = THIS_MODULE, |
273 | }, | 273 | }, |
274 | .probe = rx8581_probe, | 274 | .probe = rx8581_probe, |
275 | .remove = rx8581_remove, | 275 | .remove = __devexit_p(rx8581_remove), |
276 | .id_table = rx8581_id, | 276 | .id_table = rx8581_id, |
277 | }; | 277 | }; |
278 | 278 | ||
279 | module_i2c_driver(rx8581_driver); | 279 | static int __init rx8581_init(void) |
280 | { | ||
281 | return i2c_add_driver(&rx8581_driver); | ||
282 | } | ||
283 | |||
284 | static void __exit rx8581_exit(void) | ||
285 | { | ||
286 | i2c_del_driver(&rx8581_driver); | ||
287 | } | ||
280 | 288 | ||
281 | MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com>"); | 289 | MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com>"); |
282 | MODULE_DESCRIPTION("Epson RX-8581 RTC driver"); | 290 | MODULE_DESCRIPTION("Epson RX-8581 RTC driver"); |
283 | MODULE_LICENSE("GPL"); | 291 | MODULE_LICENSE("GPL"); |
284 | MODULE_VERSION(DRV_VERSION); | 292 | MODULE_VERSION(DRV_VERSION); |
293 | |||
294 | module_init(rx8581_init); | ||
295 | module_exit(rx8581_exit); | ||
diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index 8a092325188..f789e002c9b 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c | |||
@@ -19,8 +19,6 @@ | |||
19 | #define S35390A_CMD_STATUS1 0 | 19 | #define S35390A_CMD_STATUS1 0 |
20 | #define S35390A_CMD_STATUS2 1 | 20 | #define S35390A_CMD_STATUS2 1 |
21 | #define S35390A_CMD_TIME1 2 | 21 | #define S35390A_CMD_TIME1 2 |
22 | #define S35390A_CMD_TIME2 3 | ||
23 | #define S35390A_CMD_INT2_REG1 5 | ||
24 | 22 | ||
25 | #define S35390A_BYTE_YEAR 0 | 23 | #define S35390A_BYTE_YEAR 0 |
26 | #define S35390A_BYTE_MONTH 1 | 24 | #define S35390A_BYTE_MONTH 1 |
@@ -30,23 +28,12 @@ | |||
30 | #define S35390A_BYTE_MINS 5 | 28 | #define S35390A_BYTE_MINS 5 |
31 | #define S35390A_BYTE_SECS 6 | 29 | #define S35390A_BYTE_SECS 6 |
32 | 30 | ||
33 | #define S35390A_ALRM_BYTE_WDAY 0 | ||
34 | #define S35390A_ALRM_BYTE_HOURS 1 | ||
35 | #define S35390A_ALRM_BYTE_MINS 2 | ||
36 | |||
37 | #define S35390A_FLAG_POC 0x01 | 31 | #define S35390A_FLAG_POC 0x01 |
38 | #define S35390A_FLAG_BLD 0x02 | 32 | #define S35390A_FLAG_BLD 0x02 |
39 | #define S35390A_FLAG_24H 0x40 | 33 | #define S35390A_FLAG_24H 0x40 |
40 | #define S35390A_FLAG_RESET 0x80 | 34 | #define S35390A_FLAG_RESET 0x80 |
41 | #define S35390A_FLAG_TEST 0x01 | 35 | #define S35390A_FLAG_TEST 0x01 |
42 | 36 | ||
43 | #define S35390A_INT2_MODE_MASK 0xF0 | ||
44 | |||
45 | #define S35390A_INT2_MODE_NOINTR 0x00 | ||
46 | #define S35390A_INT2_MODE_FREQ 0x10 | ||
47 | #define S35390A_INT2_MODE_ALARM 0x40 | ||
48 | #define S35390A_INT2_MODE_PMIN_EDG 0x20 | ||
49 | |||
50 | static const struct i2c_device_id s35390a_id[] = { | 37 | static const struct i2c_device_id s35390a_id[] = { |
51 | { "s35390a", 0 }, | 38 | { "s35390a", 0 }, |
52 | { } | 39 | { } |
@@ -63,11 +50,7 @@ static int s35390a_set_reg(struct s35390a *s35390a, int reg, char *buf, int len) | |||
63 | { | 50 | { |
64 | struct i2c_client *client = s35390a->client[reg]; | 51 | struct i2c_client *client = s35390a->client[reg]; |
65 | struct i2c_msg msg[] = { | 52 | struct i2c_msg msg[] = { |
66 | { | 53 | { client->addr, 0, len, buf }, |
67 | .addr = client->addr, | ||
68 | .len = len, | ||
69 | .buf = buf | ||
70 | }, | ||
71 | }; | 54 | }; |
72 | 55 | ||
73 | if ((i2c_transfer(client->adapter, msg, 1)) != 1) | 56 | if ((i2c_transfer(client->adapter, msg, 1)) != 1) |
@@ -80,12 +63,7 @@ static int s35390a_get_reg(struct s35390a *s35390a, int reg, char *buf, int len) | |||
80 | { | 63 | { |
81 | struct i2c_client *client = s35390a->client[reg]; | 64 | struct i2c_client *client = s35390a->client[reg]; |
82 | struct i2c_msg msg[] = { | 65 | struct i2c_msg msg[] = { |
83 | { | 66 | { client->addr, I2C_M_RD, len, buf }, |
84 | .addr = client->addr, | ||
85 | .flags = I2C_M_RD, | ||
86 | .len = len, | ||
87 | .buf = buf | ||
88 | }, | ||
89 | }; | 67 | }; |
90 | 68 | ||
91 | if ((i2c_transfer(client->adapter, msg, 1)) != 1) | 69 | if ((i2c_transfer(client->adapter, msg, 1)) != 1) |
@@ -206,104 +184,6 @@ static int s35390a_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
206 | return rtc_valid_tm(tm); | 184 | return rtc_valid_tm(tm); |
207 | } | 185 | } |
208 | 186 | ||
209 | static int s35390a_set_alarm(struct i2c_client *client, struct rtc_wkalrm *alm) | ||
210 | { | ||
211 | struct s35390a *s35390a = i2c_get_clientdata(client); | ||
212 | char buf[3], sts = 0; | ||
213 | int err, i; | ||
214 | |||
215 | dev_dbg(&client->dev, "%s: alm is secs=%d, mins=%d, hours=%d mday=%d, "\ | ||
216 | "mon=%d, year=%d, wday=%d\n", __func__, alm->time.tm_sec, | ||
217 | alm->time.tm_min, alm->time.tm_hour, alm->time.tm_mday, | ||
218 | alm->time.tm_mon, alm->time.tm_year, alm->time.tm_wday); | ||
219 | |||
220 | /* disable interrupt */ | ||
221 | err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts)); | ||
222 | if (err < 0) | ||
223 | return err; | ||
224 | |||
225 | /* clear pending interrupt, if any */ | ||
226 | err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, &sts, sizeof(sts)); | ||
227 | if (err < 0) | ||
228 | return err; | ||
229 | |||
230 | if (alm->enabled) | ||
231 | sts = S35390A_INT2_MODE_ALARM; | ||
232 | else | ||
233 | sts = S35390A_INT2_MODE_NOINTR; | ||
234 | |||
235 | /* This chip expects the bits of each byte to be in reverse order */ | ||
236 | sts = bitrev8(sts); | ||
237 | |||
238 | /* set interupt mode*/ | ||
239 | err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts)); | ||
240 | if (err < 0) | ||
241 | return err; | ||
242 | |||
243 | if (alm->time.tm_wday != -1) | ||
244 | buf[S35390A_ALRM_BYTE_WDAY] = bin2bcd(alm->time.tm_wday) | 0x80; | ||
245 | |||
246 | buf[S35390A_ALRM_BYTE_HOURS] = s35390a_hr2reg(s35390a, | ||
247 | alm->time.tm_hour) | 0x80; | ||
248 | buf[S35390A_ALRM_BYTE_MINS] = bin2bcd(alm->time.tm_min) | 0x80; | ||
249 | |||
250 | if (alm->time.tm_hour >= 12) | ||
251 | buf[S35390A_ALRM_BYTE_HOURS] |= 0x40; | ||
252 | |||
253 | for (i = 0; i < 3; ++i) | ||
254 | buf[i] = bitrev8(buf[i]); | ||
255 | |||
256 | err = s35390a_set_reg(s35390a, S35390A_CMD_INT2_REG1, buf, | ||
257 | sizeof(buf)); | ||
258 | |||
259 | return err; | ||
260 | } | ||
261 | |||
262 | static int s35390a_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alm) | ||
263 | { | ||
264 | struct s35390a *s35390a = i2c_get_clientdata(client); | ||
265 | char buf[3], sts; | ||
266 | int i, err; | ||
267 | |||
268 | err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts)); | ||
269 | if (err < 0) | ||
270 | return err; | ||
271 | |||
272 | if (bitrev8(sts) != S35390A_INT2_MODE_ALARM) | ||
273 | return -EINVAL; | ||
274 | |||
275 | err = s35390a_get_reg(s35390a, S35390A_CMD_INT2_REG1, buf, sizeof(buf)); | ||
276 | if (err < 0) | ||
277 | return err; | ||
278 | |||
279 | /* This chip returns the bits of each byte in reverse order */ | ||
280 | for (i = 0; i < 3; ++i) { | ||
281 | buf[i] = bitrev8(buf[i]); | ||
282 | buf[i] &= ~0x80; | ||
283 | } | ||
284 | |||
285 | alm->time.tm_wday = bcd2bin(buf[S35390A_ALRM_BYTE_WDAY]); | ||
286 | alm->time.tm_hour = s35390a_reg2hr(s35390a, | ||
287 | buf[S35390A_ALRM_BYTE_HOURS]); | ||
288 | alm->time.tm_min = bcd2bin(buf[S35390A_ALRM_BYTE_MINS]); | ||
289 | |||
290 | dev_dbg(&client->dev, "%s: alm is mins=%d, hours=%d, wday=%d\n", | ||
291 | __func__, alm->time.tm_min, alm->time.tm_hour, | ||
292 | alm->time.tm_wday); | ||
293 | |||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | static int s35390a_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | ||
298 | { | ||
299 | return s35390a_read_alarm(to_i2c_client(dev), alm); | ||
300 | } | ||
301 | |||
302 | static int s35390a_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | ||
303 | { | ||
304 | return s35390a_set_alarm(to_i2c_client(dev), alm); | ||
305 | } | ||
306 | |||
307 | static int s35390a_rtc_read_time(struct device *dev, struct rtc_time *tm) | 187 | static int s35390a_rtc_read_time(struct device *dev, struct rtc_time *tm) |
308 | { | 188 | { |
309 | return s35390a_get_datetime(to_i2c_client(dev), tm); | 189 | return s35390a_get_datetime(to_i2c_client(dev), tm); |
@@ -317,9 +197,6 @@ static int s35390a_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
317 | static const struct rtc_class_ops s35390a_rtc_ops = { | 197 | static const struct rtc_class_ops s35390a_rtc_ops = { |
318 | .read_time = s35390a_rtc_read_time, | 198 | .read_time = s35390a_rtc_read_time, |
319 | .set_time = s35390a_rtc_set_time, | 199 | .set_time = s35390a_rtc_set_time, |
320 | .set_alarm = s35390a_rtc_set_alarm, | ||
321 | .read_alarm = s35390a_rtc_read_alarm, | ||
322 | |||
323 | }; | 200 | }; |
324 | 201 | ||
325 | static struct i2c_driver s35390a_driver; | 202 | static struct i2c_driver s35390a_driver; |
@@ -384,8 +261,6 @@ static int s35390a_probe(struct i2c_client *client, | |||
384 | if (s35390a_get_datetime(client, &tm) < 0) | 261 | if (s35390a_get_datetime(client, &tm) < 0) |
385 | dev_warn(&client->dev, "clock needs to be set\n"); | 262 | dev_warn(&client->dev, "clock needs to be set\n"); |
386 | 263 | ||
387 | device_set_wakeup_capable(&client->dev, 1); | ||
388 | |||
389 | s35390a->rtc = rtc_device_register(s35390a_driver.driver.name, | 264 | s35390a->rtc = rtc_device_register(s35390a_driver.driver.name, |
390 | &client->dev, &s35390a_rtc_ops, THIS_MODULE); | 265 | &client->dev, &s35390a_rtc_ops, THIS_MODULE); |
391 | 266 | ||
@@ -429,8 +304,19 @@ static struct i2c_driver s35390a_driver = { | |||
429 | .id_table = s35390a_id, | 304 | .id_table = s35390a_id, |
430 | }; | 305 | }; |
431 | 306 | ||
432 | module_i2c_driver(s35390a_driver); | 307 | static int __init s35390a_rtc_init(void) |
308 | { | ||
309 | return i2c_add_driver(&s35390a_driver); | ||
310 | } | ||
311 | |||
312 | static void __exit s35390a_rtc_exit(void) | ||
313 | { | ||
314 | i2c_del_driver(&s35390a_driver); | ||
315 | } | ||
433 | 316 | ||
434 | MODULE_AUTHOR("Byron Bradley <byron.bbradley@gmail.com>"); | 317 | MODULE_AUTHOR("Byron Bradley <byron.bbradley@gmail.com>"); |
435 | MODULE_DESCRIPTION("S35390A RTC driver"); | 318 | MODULE_DESCRIPTION("S35390A RTC driver"); |
436 | MODULE_LICENSE("GPL"); | 319 | MODULE_LICENSE("GPL"); |
320 | |||
321 | module_init(s35390a_rtc_init); | ||
322 | module_exit(s35390a_rtc_exit); | ||
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 404651464d4..5b979d9cc33 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -25,28 +25,23 @@ | |||
25 | #include <linux/clk.h> | 25 | #include <linux/clk.h> |
26 | #include <linux/log2.h> | 26 | #include <linux/log2.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/of.h> | ||
29 | #include <linux/uaccess.h> | ||
30 | #include <linux/io.h> | ||
31 | 28 | ||
32 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
30 | #include <asm/uaccess.h> | ||
31 | #include <asm/io.h> | ||
33 | #include <asm/irq.h> | 32 | #include <asm/irq.h> |
34 | #include <plat/regs-rtc.h> | 33 | #include <plat/regs-rtc.h> |
35 | 34 | ||
36 | enum s3c_cpu_type { | 35 | enum s3c_cpu_type { |
37 | TYPE_S3C2410, | 36 | TYPE_S3C2410, |
38 | TYPE_S3C2416, | ||
39 | TYPE_S3C2443, | ||
40 | TYPE_S3C64XX, | 37 | TYPE_S3C64XX, |
41 | }; | 38 | }; |
42 | 39 | ||
43 | struct s3c_rtc_drv_data { | ||
44 | int cpu_type; | ||
45 | }; | ||
46 | |||
47 | /* I have yet to find an S3C implementation with more than one | 40 | /* I have yet to find an S3C implementation with more than one |
48 | * of these rtc blocks in */ | 41 | * of these rtc blocks in */ |
49 | 42 | ||
43 | static struct resource *s3c_rtc_mem; | ||
44 | |||
50 | static struct clk *rtc_clk; | 45 | static struct clk *rtc_clk; |
51 | static void __iomem *s3c_rtc_base; | 46 | static void __iomem *s3c_rtc_base; |
52 | static int s3c_rtc_alarmno = NO_IRQ; | 47 | static int s3c_rtc_alarmno = NO_IRQ; |
@@ -136,7 +131,6 @@ static int s3c_rtc_setfreq(struct device *dev, int freq) | |||
136 | struct platform_device *pdev = to_platform_device(dev); | 131 | struct platform_device *pdev = to_platform_device(dev); |
137 | struct rtc_device *rtc_dev = platform_get_drvdata(pdev); | 132 | struct rtc_device *rtc_dev = platform_get_drvdata(pdev); |
138 | unsigned int tmp = 0; | 133 | unsigned int tmp = 0; |
139 | int val; | ||
140 | 134 | ||
141 | if (!is_power_of_2(freq)) | 135 | if (!is_power_of_2(freq)) |
142 | return -EINVAL; | 136 | return -EINVAL; |
@@ -144,22 +138,12 @@ static int s3c_rtc_setfreq(struct device *dev, int freq) | |||
144 | clk_enable(rtc_clk); | 138 | clk_enable(rtc_clk); |
145 | spin_lock_irq(&s3c_rtc_pie_lock); | 139 | spin_lock_irq(&s3c_rtc_pie_lock); |
146 | 140 | ||
147 | if (s3c_rtc_cpu_type != TYPE_S3C64XX) { | 141 | if (s3c_rtc_cpu_type == TYPE_S3C2410) { |
148 | tmp = readb(s3c_rtc_base + S3C2410_TICNT); | 142 | tmp = readb(s3c_rtc_base + S3C2410_TICNT); |
149 | tmp &= S3C2410_TICNT_ENABLE; | 143 | tmp &= S3C2410_TICNT_ENABLE; |
150 | } | 144 | } |
151 | 145 | ||
152 | val = (rtc_dev->max_user_freq / freq) - 1; | 146 | tmp |= (rtc_dev->max_user_freq / freq)-1; |
153 | |||
154 | if (s3c_rtc_cpu_type == TYPE_S3C2416 || s3c_rtc_cpu_type == TYPE_S3C2443) { | ||
155 | tmp |= S3C2443_TICNT_PART(val); | ||
156 | writel(S3C2443_TICNT1_PART(val), s3c_rtc_base + S3C2443_TICNT1); | ||
157 | |||
158 | if (s3c_rtc_cpu_type == TYPE_S3C2416) | ||
159 | writel(S3C2416_TICNT2_PART(val), s3c_rtc_base + S3C2416_TICNT2); | ||
160 | } else { | ||
161 | tmp |= val; | ||
162 | } | ||
163 | 147 | ||
164 | writel(tmp, s3c_rtc_base + S3C2410_TICNT); | 148 | writel(tmp, s3c_rtc_base + S3C2410_TICNT); |
165 | spin_unlock_irq(&s3c_rtc_pie_lock); | 149 | spin_unlock_irq(&s3c_rtc_pie_lock); |
@@ -184,7 +168,7 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) | |||
184 | rtc_tm->tm_year = readb(base + S3C2410_RTCYEAR); | 168 | rtc_tm->tm_year = readb(base + S3C2410_RTCYEAR); |
185 | rtc_tm->tm_sec = readb(base + S3C2410_RTCSEC); | 169 | rtc_tm->tm_sec = readb(base + S3C2410_RTCSEC); |
186 | 170 | ||
187 | /* the only way to work out whether the system was mid-update | 171 | /* the only way to work out wether the system was mid-update |
188 | * when we read it is to check the second counter, and if it | 172 | * when we read it is to check the second counter, and if it |
189 | * is zero, then we re-try the entire read | 173 | * is zero, then we re-try the entire read |
190 | */ | 174 | */ |
@@ -386,7 +370,7 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en) | |||
386 | tmp &= ~S3C2410_RTCCON_RTCEN; | 370 | tmp &= ~S3C2410_RTCCON_RTCEN; |
387 | writew(tmp, base + S3C2410_RTCCON); | 371 | writew(tmp, base + S3C2410_RTCCON); |
388 | 372 | ||
389 | if (s3c_rtc_cpu_type != TYPE_S3C64XX) { | 373 | if (s3c_rtc_cpu_type == TYPE_S3C2410) { |
390 | tmp = readb(base + S3C2410_TICNT); | 374 | tmp = readb(base + S3C2410_TICNT); |
391 | tmp &= ~S3C2410_TICNT_ENABLE; | 375 | tmp &= ~S3C2410_TICNT_ENABLE; |
392 | writeb(tmp, base + S3C2410_TICNT); | 376 | writeb(tmp, base + S3C2410_TICNT); |
@@ -421,43 +405,34 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en) | |||
421 | clk_disable(rtc_clk); | 405 | clk_disable(rtc_clk); |
422 | } | 406 | } |
423 | 407 | ||
424 | static int s3c_rtc_remove(struct platform_device *dev) | 408 | static int __devexit s3c_rtc_remove(struct platform_device *dev) |
425 | { | 409 | { |
426 | struct rtc_device *rtc = platform_get_drvdata(dev); | 410 | struct rtc_device *rtc = platform_get_drvdata(dev); |
427 | 411 | ||
412 | free_irq(s3c_rtc_alarmno, rtc); | ||
413 | free_irq(s3c_rtc_tickno, rtc); | ||
414 | |||
428 | platform_set_drvdata(dev, NULL); | 415 | platform_set_drvdata(dev, NULL); |
429 | rtc_device_unregister(rtc); | 416 | rtc_device_unregister(rtc); |
430 | 417 | ||
431 | s3c_rtc_setaie(&dev->dev, 0); | 418 | s3c_rtc_setaie(&dev->dev, 0); |
432 | 419 | ||
420 | clk_put(rtc_clk); | ||
433 | rtc_clk = NULL; | 421 | rtc_clk = NULL; |
434 | 422 | ||
435 | return 0; | 423 | iounmap(s3c_rtc_base); |
436 | } | 424 | release_resource(s3c_rtc_mem); |
437 | 425 | kfree(s3c_rtc_mem); | |
438 | static const struct of_device_id s3c_rtc_dt_match[]; | ||
439 | 426 | ||
440 | static inline int s3c_rtc_get_driver_data(struct platform_device *pdev) | 427 | return 0; |
441 | { | ||
442 | #ifdef CONFIG_OF | ||
443 | struct s3c_rtc_drv_data *data; | ||
444 | if (pdev->dev.of_node) { | ||
445 | const struct of_device_id *match; | ||
446 | match = of_match_node(s3c_rtc_dt_match, pdev->dev.of_node); | ||
447 | data = (struct s3c_rtc_drv_data *) match->data; | ||
448 | return data->cpu_type; | ||
449 | } | ||
450 | #endif | ||
451 | return platform_get_device_id(pdev)->driver_data; | ||
452 | } | 428 | } |
453 | 429 | ||
454 | static int s3c_rtc_probe(struct platform_device *pdev) | 430 | static int __devinit s3c_rtc_probe(struct platform_device *pdev) |
455 | { | 431 | { |
456 | struct rtc_device *rtc; | 432 | struct rtc_device *rtc; |
457 | struct rtc_time rtc_tm; | 433 | struct rtc_time rtc_tm; |
458 | struct resource *res; | 434 | struct resource *res; |
459 | int ret; | 435 | int ret; |
460 | int tmp; | ||
461 | 436 | ||
462 | pr_debug("%s: probe=%p\n", __func__, pdev); | 437 | pr_debug("%s: probe=%p\n", __func__, pdev); |
463 | 438 | ||
@@ -466,13 +441,13 @@ static int s3c_rtc_probe(struct platform_device *pdev) | |||
466 | s3c_rtc_tickno = platform_get_irq(pdev, 1); | 441 | s3c_rtc_tickno = platform_get_irq(pdev, 1); |
467 | if (s3c_rtc_tickno < 0) { | 442 | if (s3c_rtc_tickno < 0) { |
468 | dev_err(&pdev->dev, "no irq for rtc tick\n"); | 443 | dev_err(&pdev->dev, "no irq for rtc tick\n"); |
469 | return s3c_rtc_tickno; | 444 | return -ENOENT; |
470 | } | 445 | } |
471 | 446 | ||
472 | s3c_rtc_alarmno = platform_get_irq(pdev, 0); | 447 | s3c_rtc_alarmno = platform_get_irq(pdev, 0); |
473 | if (s3c_rtc_alarmno < 0) { | 448 | if (s3c_rtc_alarmno < 0) { |
474 | dev_err(&pdev->dev, "no irq for alarm\n"); | 449 | dev_err(&pdev->dev, "no irq for alarm\n"); |
475 | return s3c_rtc_alarmno; | 450 | return -ENOENT; |
476 | } | 451 | } |
477 | 452 | ||
478 | pr_debug("s3c2410_rtc: tick irq %d, alarm irq %d\n", | 453 | pr_debug("s3c2410_rtc: tick irq %d, alarm irq %d\n", |
@@ -486,18 +461,28 @@ static int s3c_rtc_probe(struct platform_device *pdev) | |||
486 | return -ENOENT; | 461 | return -ENOENT; |
487 | } | 462 | } |
488 | 463 | ||
489 | s3c_rtc_base = devm_request_and_ioremap(&pdev->dev, res); | 464 | s3c_rtc_mem = request_mem_region(res->start, resource_size(res), |
465 | pdev->name); | ||
466 | |||
467 | if (s3c_rtc_mem == NULL) { | ||
468 | dev_err(&pdev->dev, "failed to reserve memory region\n"); | ||
469 | ret = -ENOENT; | ||
470 | goto err_nores; | ||
471 | } | ||
472 | |||
473 | s3c_rtc_base = ioremap(res->start, resource_size(res)); | ||
490 | if (s3c_rtc_base == NULL) { | 474 | if (s3c_rtc_base == NULL) { |
491 | dev_err(&pdev->dev, "failed to ioremap memory region\n"); | 475 | dev_err(&pdev->dev, "failed ioremap()\n"); |
492 | return -EINVAL; | 476 | ret = -EINVAL; |
477 | goto err_nomap; | ||
493 | } | 478 | } |
494 | 479 | ||
495 | rtc_clk = devm_clk_get(&pdev->dev, "rtc"); | 480 | rtc_clk = clk_get(&pdev->dev, "rtc"); |
496 | if (IS_ERR(rtc_clk)) { | 481 | if (IS_ERR(rtc_clk)) { |
497 | dev_err(&pdev->dev, "failed to find rtc clock source\n"); | 482 | dev_err(&pdev->dev, "failed to find rtc clock source\n"); |
498 | ret = PTR_ERR(rtc_clk); | 483 | ret = PTR_ERR(rtc_clk); |
499 | rtc_clk = NULL; | 484 | rtc_clk = NULL; |
500 | return ret; | 485 | goto err_clk; |
501 | } | 486 | } |
502 | 487 | ||
503 | clk_enable(rtc_clk); | 488 | clk_enable(rtc_clk); |
@@ -522,7 +507,7 @@ static int s3c_rtc_probe(struct platform_device *pdev) | |||
522 | goto err_nortc; | 507 | goto err_nortc; |
523 | } | 508 | } |
524 | 509 | ||
525 | s3c_rtc_cpu_type = s3c_rtc_get_driver_data(pdev); | 510 | s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data; |
526 | 511 | ||
527 | /* Check RTC Time */ | 512 | /* Check RTC Time */ |
528 | 513 | ||
@@ -541,39 +526,37 @@ static int s3c_rtc_probe(struct platform_device *pdev) | |||
541 | dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n"); | 526 | dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n"); |
542 | } | 527 | } |
543 | 528 | ||
544 | if (s3c_rtc_cpu_type != TYPE_S3C2410) | 529 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) |
545 | rtc->max_user_freq = 32768; | 530 | rtc->max_user_freq = 32768; |
546 | else | 531 | else |
547 | rtc->max_user_freq = 128; | 532 | rtc->max_user_freq = 128; |
548 | 533 | ||
549 | if (s3c_rtc_cpu_type == TYPE_S3C2416 || s3c_rtc_cpu_type == TYPE_S3C2443) { | ||
550 | tmp = readw(s3c_rtc_base + S3C2410_RTCCON); | ||
551 | tmp |= S3C2443_RTCCON_TICSEL; | ||
552 | writew(tmp, s3c_rtc_base + S3C2410_RTCCON); | ||
553 | } | ||
554 | |||
555 | platform_set_drvdata(pdev, rtc); | 534 | platform_set_drvdata(pdev, rtc); |
556 | 535 | ||
557 | s3c_rtc_setfreq(&pdev->dev, 1); | 536 | s3c_rtc_setfreq(&pdev->dev, 1); |
558 | 537 | ||
559 | ret = devm_request_irq(&pdev->dev, s3c_rtc_alarmno, s3c_rtc_alarmirq, | 538 | ret = request_irq(s3c_rtc_alarmno, s3c_rtc_alarmirq, |
560 | 0, "s3c2410-rtc alarm", rtc); | 539 | IRQF_DISABLED, "s3c2410-rtc alarm", rtc); |
561 | if (ret) { | 540 | if (ret) { |
562 | dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_alarmno, ret); | 541 | dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_alarmno, ret); |
563 | goto err_alarm_irq; | 542 | goto err_alarm_irq; |
564 | } | 543 | } |
565 | 544 | ||
566 | ret = devm_request_irq(&pdev->dev, s3c_rtc_tickno, s3c_rtc_tickirq, | 545 | ret = request_irq(s3c_rtc_tickno, s3c_rtc_tickirq, |
567 | 0, "s3c2410-rtc tick", rtc); | 546 | IRQF_DISABLED, "s3c2410-rtc tick", rtc); |
568 | if (ret) { | 547 | if (ret) { |
569 | dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret); | 548 | dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret); |
570 | goto err_alarm_irq; | 549 | free_irq(s3c_rtc_alarmno, rtc); |
550 | goto err_tick_irq; | ||
571 | } | 551 | } |
572 | 552 | ||
573 | clk_disable(rtc_clk); | 553 | clk_disable(rtc_clk); |
574 | 554 | ||
575 | return 0; | 555 | return 0; |
576 | 556 | ||
557 | err_tick_irq: | ||
558 | free_irq(s3c_rtc_alarmno, rtc); | ||
559 | |||
577 | err_alarm_irq: | 560 | err_alarm_irq: |
578 | platform_set_drvdata(pdev, NULL); | 561 | platform_set_drvdata(pdev, NULL); |
579 | rtc_device_unregister(rtc); | 562 | rtc_device_unregister(rtc); |
@@ -581,7 +564,15 @@ static int s3c_rtc_probe(struct platform_device *pdev) | |||
581 | err_nortc: | 564 | err_nortc: |
582 | s3c_rtc_enable(pdev, 0); | 565 | s3c_rtc_enable(pdev, 0); |
583 | clk_disable(rtc_clk); | 566 | clk_disable(rtc_clk); |
567 | clk_put(rtc_clk); | ||
584 | 568 | ||
569 | err_clk: | ||
570 | iounmap(s3c_rtc_base); | ||
571 | |||
572 | err_nomap: | ||
573 | release_resource(s3c_rtc_mem); | ||
574 | |||
575 | err_nores: | ||
585 | return ret; | 576 | return ret; |
586 | } | 577 | } |
587 | 578 | ||
@@ -638,44 +629,11 @@ static int s3c_rtc_resume(struct platform_device *pdev) | |||
638 | #define s3c_rtc_resume NULL | 629 | #define s3c_rtc_resume NULL |
639 | #endif | 630 | #endif |
640 | 631 | ||
641 | #ifdef CONFIG_OF | ||
642 | static struct s3c_rtc_drv_data s3c_rtc_drv_data_array[] = { | ||
643 | [TYPE_S3C2410] = { TYPE_S3C2410 }, | ||
644 | [TYPE_S3C2416] = { TYPE_S3C2416 }, | ||
645 | [TYPE_S3C2443] = { TYPE_S3C2443 }, | ||
646 | [TYPE_S3C64XX] = { TYPE_S3C64XX }, | ||
647 | }; | ||
648 | |||
649 | static const struct of_device_id s3c_rtc_dt_match[] = { | ||
650 | { | ||
651 | .compatible = "samsung,s3c2410-rtc", | ||
652 | .data = &s3c_rtc_drv_data_array[TYPE_S3C2410], | ||
653 | }, { | ||
654 | .compatible = "samsung,s3c2416-rtc", | ||
655 | .data = &s3c_rtc_drv_data_array[TYPE_S3C2416], | ||
656 | }, { | ||
657 | .compatible = "samsung,s3c2443-rtc", | ||
658 | .data = &s3c_rtc_drv_data_array[TYPE_S3C2443], | ||
659 | }, { | ||
660 | .compatible = "samsung,s3c6410-rtc", | ||
661 | .data = &s3c_rtc_drv_data_array[TYPE_S3C64XX], | ||
662 | }, | ||
663 | {}, | ||
664 | }; | ||
665 | MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match); | ||
666 | #endif | ||
667 | |||
668 | static struct platform_device_id s3c_rtc_driver_ids[] = { | 632 | static struct platform_device_id s3c_rtc_driver_ids[] = { |
669 | { | 633 | { |
670 | .name = "s3c2410-rtc", | 634 | .name = "s3c2410-rtc", |
671 | .driver_data = TYPE_S3C2410, | 635 | .driver_data = TYPE_S3C2410, |
672 | }, { | 636 | }, { |
673 | .name = "s3c2416-rtc", | ||
674 | .driver_data = TYPE_S3C2416, | ||
675 | }, { | ||
676 | .name = "s3c2443-rtc", | ||
677 | .driver_data = TYPE_S3C2443, | ||
678 | }, { | ||
679 | .name = "s3c64xx-rtc", | 637 | .name = "s3c64xx-rtc", |
680 | .driver_data = TYPE_S3C64XX, | 638 | .driver_data = TYPE_S3C64XX, |
681 | }, | 639 | }, |
@@ -686,18 +644,31 @@ MODULE_DEVICE_TABLE(platform, s3c_rtc_driver_ids); | |||
686 | 644 | ||
687 | static struct platform_driver s3c_rtc_driver = { | 645 | static struct platform_driver s3c_rtc_driver = { |
688 | .probe = s3c_rtc_probe, | 646 | .probe = s3c_rtc_probe, |
689 | .remove = s3c_rtc_remove, | 647 | .remove = __devexit_p(s3c_rtc_remove), |
690 | .suspend = s3c_rtc_suspend, | 648 | .suspend = s3c_rtc_suspend, |
691 | .resume = s3c_rtc_resume, | 649 | .resume = s3c_rtc_resume, |
692 | .id_table = s3c_rtc_driver_ids, | 650 | .id_table = s3c_rtc_driver_ids, |
693 | .driver = { | 651 | .driver = { |
694 | .name = "s3c-rtc", | 652 | .name = "s3c-rtc", |
695 | .owner = THIS_MODULE, | 653 | .owner = THIS_MODULE, |
696 | .of_match_table = of_match_ptr(s3c_rtc_dt_match), | ||
697 | }, | 654 | }, |
698 | }; | 655 | }; |
699 | 656 | ||
700 | module_platform_driver(s3c_rtc_driver); | 657 | static char __initdata banner[] = "S3C24XX RTC, (c) 2004,2006 Simtec Electronics\n"; |
658 | |||
659 | static int __init s3c_rtc_init(void) | ||
660 | { | ||
661 | printk(banner); | ||
662 | return platform_driver_register(&s3c_rtc_driver); | ||
663 | } | ||
664 | |||
665 | static void __exit s3c_rtc_exit(void) | ||
666 | { | ||
667 | platform_driver_unregister(&s3c_rtc_driver); | ||
668 | } | ||
669 | |||
670 | module_init(s3c_rtc_init); | ||
671 | module_exit(s3c_rtc_exit); | ||
701 | 672 | ||
702 | MODULE_DESCRIPTION("Samsung S3C RTC Driver"); | 673 | MODULE_DESCRIPTION("Samsung S3C RTC Driver"); |
703 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); | 674 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); |
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index 50a5c4adee4..0b40bb88a88 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c | |||
@@ -23,45 +23,95 @@ | |||
23 | 23 | ||
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/clk.h> | ||
27 | #include <linux/rtc.h> | 26 | #include <linux/rtc.h> |
28 | #include <linux/init.h> | 27 | #include <linux/init.h> |
29 | #include <linux/fs.h> | 28 | #include <linux/fs.h> |
30 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
31 | #include <linux/slab.h> | ||
32 | #include <linux/string.h> | 30 | #include <linux/string.h> |
33 | #include <linux/of.h> | ||
34 | #include <linux/pm.h> | 31 | #include <linux/pm.h> |
35 | #include <linux/bitops.h> | 32 | #include <linux/bitops.h> |
36 | #include <linux/io.h> | ||
37 | 33 | ||
38 | #include <mach/hardware.h> | 34 | #include <mach/hardware.h> |
39 | #include <mach/irqs.h> | 35 | #include <asm/irq.h> |
40 | 36 | ||
41 | #if defined(CONFIG_ARCH_PXA) || defined(CONFIG_ARCH_MMP) | 37 | #ifdef CONFIG_ARCH_PXA |
42 | #include <mach/regs-rtc.h> | 38 | #include <mach/regs-rtc.h> |
39 | #include <mach/regs-ost.h> | ||
43 | #endif | 40 | #endif |
44 | 41 | ||
45 | #define RTC_DEF_DIVIDER (32768 - 1) | 42 | #define RTC_DEF_DIVIDER (32768 - 1) |
46 | #define RTC_DEF_TRIM 0 | 43 | #define RTC_DEF_TRIM 0 |
47 | #define RTC_FREQ 1024 | 44 | |
48 | 45 | static const unsigned long RTC_FREQ = 1024; | |
49 | struct sa1100_rtc { | 46 | static struct rtc_time rtc_alarm; |
50 | spinlock_t lock; | 47 | static DEFINE_SPINLOCK(sa1100_rtc_lock); |
51 | int irq_1hz; | 48 | |
52 | int irq_alarm; | 49 | static inline int rtc_periodic_alarm(struct rtc_time *tm) |
53 | struct rtc_device *rtc; | 50 | { |
54 | struct clk *clk; | 51 | return (tm->tm_year == -1) || |
55 | }; | 52 | ((unsigned)tm->tm_mon >= 12) || |
53 | ((unsigned)(tm->tm_mday - 1) >= 31) || | ||
54 | ((unsigned)tm->tm_hour > 23) || | ||
55 | ((unsigned)tm->tm_min > 59) || | ||
56 | ((unsigned)tm->tm_sec > 59); | ||
57 | } | ||
58 | |||
59 | /* | ||
60 | * Calculate the next alarm time given the requested alarm time mask | ||
61 | * and the current time. | ||
62 | */ | ||
63 | static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, | ||
64 | struct rtc_time *alrm) | ||
65 | { | ||
66 | unsigned long next_time; | ||
67 | unsigned long now_time; | ||
68 | |||
69 | next->tm_year = now->tm_year; | ||
70 | next->tm_mon = now->tm_mon; | ||
71 | next->tm_mday = now->tm_mday; | ||
72 | next->tm_hour = alrm->tm_hour; | ||
73 | next->tm_min = alrm->tm_min; | ||
74 | next->tm_sec = alrm->tm_sec; | ||
75 | |||
76 | rtc_tm_to_time(now, &now_time); | ||
77 | rtc_tm_to_time(next, &next_time); | ||
78 | |||
79 | if (next_time < now_time) { | ||
80 | /* Advance one day */ | ||
81 | next_time += 60 * 60 * 24; | ||
82 | rtc_time_to_tm(next_time, next); | ||
83 | } | ||
84 | } | ||
85 | |||
86 | static int rtc_update_alarm(struct rtc_time *alrm) | ||
87 | { | ||
88 | struct rtc_time alarm_tm, now_tm; | ||
89 | unsigned long now, time; | ||
90 | int ret; | ||
91 | |||
92 | do { | ||
93 | now = RCNR; | ||
94 | rtc_time_to_tm(now, &now_tm); | ||
95 | rtc_next_alarm_time(&alarm_tm, &now_tm, alrm); | ||
96 | ret = rtc_tm_to_time(&alarm_tm, &time); | ||
97 | if (ret != 0) | ||
98 | break; | ||
99 | |||
100 | RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL); | ||
101 | RTAR = time; | ||
102 | } while (now != RCNR); | ||
103 | |||
104 | return ret; | ||
105 | } | ||
56 | 106 | ||
57 | static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) | 107 | static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) |
58 | { | 108 | { |
59 | struct sa1100_rtc *info = dev_get_drvdata(dev_id); | 109 | struct platform_device *pdev = to_platform_device(dev_id); |
60 | struct rtc_device *rtc = info->rtc; | 110 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
61 | unsigned int rtsr; | 111 | unsigned int rtsr; |
62 | unsigned long events = 0; | 112 | unsigned long events = 0; |
63 | 113 | ||
64 | spin_lock(&info->lock); | 114 | spin_lock(&sa1100_rtc_lock); |
65 | 115 | ||
66 | rtsr = RTSR; | 116 | rtsr = RTSR; |
67 | /* clear interrupt sources */ | 117 | /* clear interrupt sources */ |
@@ -97,28 +147,30 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) | |||
97 | 147 | ||
98 | rtc_update_irq(rtc, 1, events); | 148 | rtc_update_irq(rtc, 1, events); |
99 | 149 | ||
100 | spin_unlock(&info->lock); | 150 | if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm)) |
151 | rtc_update_alarm(&rtc_alarm); | ||
152 | |||
153 | spin_unlock(&sa1100_rtc_lock); | ||
101 | 154 | ||
102 | return IRQ_HANDLED; | 155 | return IRQ_HANDLED; |
103 | } | 156 | } |
104 | 157 | ||
105 | static int sa1100_rtc_open(struct device *dev) | 158 | static int sa1100_rtc_open(struct device *dev) |
106 | { | 159 | { |
107 | struct sa1100_rtc *info = dev_get_drvdata(dev); | ||
108 | struct rtc_device *rtc = info->rtc; | ||
109 | 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); | ||
110 | 163 | ||
111 | ret = clk_prepare_enable(info->clk); | 164 | ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, IRQF_DISABLED, |
112 | if (ret) | 165 | "rtc 1Hz", dev); |
113 | goto fail_clk; | ||
114 | ret = request_irq(info->irq_1hz, sa1100_rtc_interrupt, 0, "rtc 1Hz", dev); | ||
115 | if (ret) { | 166 | if (ret) { |
116 | dev_err(dev, "IRQ %d already in use.\n", info->irq_1hz); | 167 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz); |
117 | goto fail_ui; | 168 | goto fail_ui; |
118 | } | 169 | } |
119 | ret = request_irq(info->irq_alarm, sa1100_rtc_interrupt, 0, "rtc Alrm", dev); | 170 | ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, IRQF_DISABLED, |
171 | "rtc Alrm", dev); | ||
120 | if (ret) { | 172 | if (ret) { |
121 | dev_err(dev, "IRQ %d already in use.\n", info->irq_alarm); | 173 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm); |
122 | goto fail_ai; | 174 | goto fail_ai; |
123 | } | 175 | } |
124 | rtc->max_user_freq = RTC_FREQ; | 176 | rtc->max_user_freq = RTC_FREQ; |
@@ -127,36 +179,31 @@ static int sa1100_rtc_open(struct device *dev) | |||
127 | return 0; | 179 | return 0; |
128 | 180 | ||
129 | fail_ai: | 181 | fail_ai: |
130 | free_irq(info->irq_1hz, dev); | 182 | free_irq(IRQ_RTC1Hz, dev); |
131 | fail_ui: | 183 | fail_ui: |
132 | clk_disable_unprepare(info->clk); | ||
133 | fail_clk: | ||
134 | return ret; | 184 | return ret; |
135 | } | 185 | } |
136 | 186 | ||
137 | static void sa1100_rtc_release(struct device *dev) | 187 | static void sa1100_rtc_release(struct device *dev) |
138 | { | 188 | { |
139 | struct sa1100_rtc *info = dev_get_drvdata(dev); | 189 | spin_lock_irq(&sa1100_rtc_lock); |
140 | |||
141 | spin_lock_irq(&info->lock); | ||
142 | RTSR = 0; | 190 | RTSR = 0; |
143 | spin_unlock_irq(&info->lock); | 191 | OIER &= ~OIER_E1; |
192 | OSSR = OSSR_M1; | ||
193 | spin_unlock_irq(&sa1100_rtc_lock); | ||
144 | 194 | ||
145 | free_irq(info->irq_alarm, dev); | 195 | free_irq(IRQ_RTCAlrm, dev); |
146 | free_irq(info->irq_1hz, dev); | 196 | free_irq(IRQ_RTC1Hz, dev); |
147 | clk_disable_unprepare(info->clk); | ||
148 | } | 197 | } |
149 | 198 | ||
150 | static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | 199 | static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) |
151 | { | 200 | { |
152 | struct sa1100_rtc *info = dev_get_drvdata(dev); | 201 | spin_lock_irq(&sa1100_rtc_lock); |
153 | |||
154 | spin_lock_irq(&info->lock); | ||
155 | if (enabled) | 202 | if (enabled) |
156 | RTSR |= RTSR_ALE; | 203 | RTSR |= RTSR_ALE; |
157 | else | 204 | else |
158 | RTSR &= ~RTSR_ALE; | 205 | RTSR &= ~RTSR_ALE; |
159 | spin_unlock_irq(&info->lock); | 206 | spin_unlock_irq(&sa1100_rtc_lock); |
160 | return 0; | 207 | return 0; |
161 | } | 208 | } |
162 | 209 | ||
@@ -181,6 +228,7 @@ static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
181 | { | 228 | { |
182 | u32 rtsr; | 229 | u32 rtsr; |
183 | 230 | ||
231 | memcpy(&alrm->time, &rtc_alarm, sizeof(struct rtc_time)); | ||
184 | rtsr = RTSR; | 232 | rtsr = RTSR; |
185 | alrm->enabled = (rtsr & RTSR_ALE) ? 1 : 0; | 233 | alrm->enabled = (rtsr & RTSR_ALE) ? 1 : 0; |
186 | alrm->pending = (rtsr & RTSR_AL) ? 1 : 0; | 234 | alrm->pending = (rtsr & RTSR_AL) ? 1 : 0; |
@@ -189,22 +237,17 @@ static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
189 | 237 | ||
190 | static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | 238 | static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
191 | { | 239 | { |
192 | struct sa1100_rtc *info = dev_get_drvdata(dev); | ||
193 | unsigned long time; | ||
194 | int ret; | 240 | int ret; |
195 | 241 | ||
196 | spin_lock_irq(&info->lock); | 242 | spin_lock_irq(&sa1100_rtc_lock); |
197 | ret = rtc_tm_to_time(&alrm->time, &time); | 243 | ret = rtc_update_alarm(&alrm->time); |
198 | if (ret != 0) | 244 | if (ret == 0) { |
199 | goto out; | 245 | if (alrm->enabled) |
200 | RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL); | 246 | RTSR |= RTSR_ALE; |
201 | RTAR = time; | 247 | else |
202 | if (alrm->enabled) | 248 | RTSR &= ~RTSR_ALE; |
203 | RTSR |= RTSR_ALE; | 249 | } |
204 | else | 250 | spin_unlock_irq(&sa1100_rtc_lock); |
205 | RTSR &= ~RTSR_ALE; | ||
206 | out: | ||
207 | spin_unlock_irq(&info->lock); | ||
208 | 251 | ||
209 | return ret; | 252 | return ret; |
210 | } | 253 | } |
@@ -231,27 +274,6 @@ static const struct rtc_class_ops sa1100_rtc_ops = { | |||
231 | static int sa1100_rtc_probe(struct platform_device *pdev) | 274 | static int sa1100_rtc_probe(struct platform_device *pdev) |
232 | { | 275 | { |
233 | struct rtc_device *rtc; | 276 | struct rtc_device *rtc; |
234 | struct sa1100_rtc *info; | ||
235 | int irq_1hz, irq_alarm, ret = 0; | ||
236 | |||
237 | irq_1hz = platform_get_irq_byname(pdev, "rtc 1Hz"); | ||
238 | irq_alarm = platform_get_irq_byname(pdev, "rtc alarm"); | ||
239 | if (irq_1hz < 0 || irq_alarm < 0) | ||
240 | return -ENODEV; | ||
241 | |||
242 | info = kzalloc(sizeof(struct sa1100_rtc), GFP_KERNEL); | ||
243 | if (!info) | ||
244 | return -ENOMEM; | ||
245 | info->clk = clk_get(&pdev->dev, NULL); | ||
246 | if (IS_ERR(info->clk)) { | ||
247 | dev_err(&pdev->dev, "failed to find rtc clock source\n"); | ||
248 | ret = PTR_ERR(info->clk); | ||
249 | goto err_clk; | ||
250 | } | ||
251 | info->irq_1hz = irq_1hz; | ||
252 | info->irq_alarm = irq_alarm; | ||
253 | spin_lock_init(&info->lock); | ||
254 | platform_set_drvdata(pdev, info); | ||
255 | 277 | ||
256 | /* | 278 | /* |
257 | * 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 |
@@ -273,11 +295,10 @@ static int sa1100_rtc_probe(struct platform_device *pdev) | |||
273 | rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, | 295 | rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, |
274 | THIS_MODULE); | 296 | THIS_MODULE); |
275 | 297 | ||
276 | if (IS_ERR(rtc)) { | 298 | if (IS_ERR(rtc)) |
277 | ret = PTR_ERR(rtc); | 299 | return PTR_ERR(rtc); |
278 | goto err_dev; | 300 | |
279 | } | 301 | platform_set_drvdata(pdev, rtc); |
280 | info->rtc = rtc; | ||
281 | 302 | ||
282 | /* Fix for a nasty initialization problem the in SA11xx RTSR register. | 303 | /* Fix for a nasty initialization problem the in SA11xx RTSR register. |
283 | * See also the comments in sa1100_rtc_interrupt(). | 304 | * See also the comments in sa1100_rtc_interrupt(). |
@@ -304,24 +325,14 @@ static int sa1100_rtc_probe(struct platform_device *pdev) | |||
304 | RTSR = RTSR_AL | RTSR_HZ; | 325 | RTSR = RTSR_AL | RTSR_HZ; |
305 | 326 | ||
306 | return 0; | 327 | return 0; |
307 | err_dev: | ||
308 | platform_set_drvdata(pdev, NULL); | ||
309 | clk_put(info->clk); | ||
310 | err_clk: | ||
311 | kfree(info); | ||
312 | return ret; | ||
313 | } | 328 | } |
314 | 329 | ||
315 | static int sa1100_rtc_remove(struct platform_device *pdev) | 330 | static int sa1100_rtc_remove(struct platform_device *pdev) |
316 | { | 331 | { |
317 | struct sa1100_rtc *info = platform_get_drvdata(pdev); | 332 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
318 | 333 | ||
319 | if (info) { | 334 | if (rtc) |
320 | rtc_device_unregister(info->rtc); | 335 | rtc_device_unregister(rtc); |
321 | clk_put(info->clk); | ||
322 | platform_set_drvdata(pdev, NULL); | ||
323 | kfree(info); | ||
324 | } | ||
325 | 336 | ||
326 | return 0; | 337 | return 0; |
327 | } | 338 | } |
@@ -329,17 +340,15 @@ static int sa1100_rtc_remove(struct platform_device *pdev) | |||
329 | #ifdef CONFIG_PM | 340 | #ifdef CONFIG_PM |
330 | static int sa1100_rtc_suspend(struct device *dev) | 341 | static int sa1100_rtc_suspend(struct device *dev) |
331 | { | 342 | { |
332 | struct sa1100_rtc *info = dev_get_drvdata(dev); | ||
333 | if (device_may_wakeup(dev)) | 343 | if (device_may_wakeup(dev)) |
334 | enable_irq_wake(info->irq_alarm); | 344 | enable_irq_wake(IRQ_RTCAlrm); |
335 | return 0; | 345 | return 0; |
336 | } | 346 | } |
337 | 347 | ||
338 | static int sa1100_rtc_resume(struct device *dev) | 348 | static int sa1100_rtc_resume(struct device *dev) |
339 | { | 349 | { |
340 | struct sa1100_rtc *info = dev_get_drvdata(dev); | ||
341 | if (device_may_wakeup(dev)) | 350 | if (device_may_wakeup(dev)) |
342 | disable_irq_wake(info->irq_alarm); | 351 | disable_irq_wake(IRQ_RTCAlrm); |
343 | return 0; | 352 | return 0; |
344 | } | 353 | } |
345 | 354 | ||
@@ -349,13 +358,6 @@ static const struct dev_pm_ops sa1100_rtc_pm_ops = { | |||
349 | }; | 358 | }; |
350 | #endif | 359 | #endif |
351 | 360 | ||
352 | static struct of_device_id sa1100_rtc_dt_ids[] = { | ||
353 | { .compatible = "mrvl,sa1100-rtc", }, | ||
354 | { .compatible = "mrvl,mmp-rtc", }, | ||
355 | {} | ||
356 | }; | ||
357 | MODULE_DEVICE_TABLE(of, sa1100_rtc_dt_ids); | ||
358 | |||
359 | static struct platform_driver sa1100_rtc_driver = { | 361 | static struct platform_driver sa1100_rtc_driver = { |
360 | .probe = sa1100_rtc_probe, | 362 | .probe = sa1100_rtc_probe, |
361 | .remove = sa1100_rtc_remove, | 363 | .remove = sa1100_rtc_remove, |
@@ -364,11 +366,21 @@ static struct platform_driver sa1100_rtc_driver = { | |||
364 | #ifdef CONFIG_PM | 366 | #ifdef CONFIG_PM |
365 | .pm = &sa1100_rtc_pm_ops, | 367 | .pm = &sa1100_rtc_pm_ops, |
366 | #endif | 368 | #endif |
367 | .of_match_table = sa1100_rtc_dt_ids, | ||
368 | }, | 369 | }, |
369 | }; | 370 | }; |
370 | 371 | ||
371 | module_platform_driver(sa1100_rtc_driver); | 372 | static int __init sa1100_rtc_init(void) |
373 | { | ||
374 | return platform_driver_register(&sa1100_rtc_driver); | ||
375 | } | ||
376 | |||
377 | static void __exit sa1100_rtc_exit(void) | ||
378 | { | ||
379 | platform_driver_unregister(&sa1100_rtc_driver); | ||
380 | } | ||
381 | |||
382 | module_init(sa1100_rtc_init); | ||
383 | module_exit(sa1100_rtc_exit); | ||
372 | 384 | ||
373 | MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); | 385 | MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); |
374 | MODULE_DESCRIPTION("SA11x0/PXA2xx Realtime Clock Driver (RTC)"); | 386 | MODULE_DESCRIPTION("SA11x0/PXA2xx Realtime Clock Driver (RTC)"); |
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index e55a7635ae5..6ac55fd4841 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c | |||
@@ -666,7 +666,7 @@ static int __init sh_rtc_probe(struct platform_device *pdev) | |||
666 | if (rtc->carry_irq <= 0) { | 666 | if (rtc->carry_irq <= 0) { |
667 | /* register shared periodic/carry/alarm irq */ | 667 | /* register shared periodic/carry/alarm irq */ |
668 | ret = request_irq(rtc->periodic_irq, sh_rtc_shared, | 668 | ret = request_irq(rtc->periodic_irq, sh_rtc_shared, |
669 | 0, "sh-rtc", rtc); | 669 | IRQF_DISABLED, "sh-rtc", rtc); |
670 | if (unlikely(ret)) { | 670 | if (unlikely(ret)) { |
671 | dev_err(&pdev->dev, | 671 | dev_err(&pdev->dev, |
672 | "request IRQ failed with %d, IRQ %d\n", ret, | 672 | "request IRQ failed with %d, IRQ %d\n", ret, |
@@ -676,7 +676,7 @@ static int __init sh_rtc_probe(struct platform_device *pdev) | |||
676 | } else { | 676 | } else { |
677 | /* register periodic/carry/alarm irqs */ | 677 | /* register periodic/carry/alarm irqs */ |
678 | ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, | 678 | ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, |
679 | 0, "sh-rtc period", rtc); | 679 | IRQF_DISABLED, "sh-rtc period", rtc); |
680 | if (unlikely(ret)) { | 680 | if (unlikely(ret)) { |
681 | dev_err(&pdev->dev, | 681 | dev_err(&pdev->dev, |
682 | "request period IRQ failed with %d, IRQ %d\n", | 682 | "request period IRQ failed with %d, IRQ %d\n", |
@@ -685,7 +685,7 @@ static int __init sh_rtc_probe(struct platform_device *pdev) | |||
685 | } | 685 | } |
686 | 686 | ||
687 | ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, | 687 | ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, |
688 | 0, "sh-rtc carry", rtc); | 688 | IRQF_DISABLED, "sh-rtc carry", rtc); |
689 | if (unlikely(ret)) { | 689 | if (unlikely(ret)) { |
690 | dev_err(&pdev->dev, | 690 | dev_err(&pdev->dev, |
691 | "request carry IRQ failed with %d, IRQ %d\n", | 691 | "request carry IRQ failed with %d, IRQ %d\n", |
@@ -695,7 +695,7 @@ static int __init sh_rtc_probe(struct platform_device *pdev) | |||
695 | } | 695 | } |
696 | 696 | ||
697 | ret = request_irq(rtc->alarm_irq, sh_rtc_alarm, | 697 | ret = request_irq(rtc->alarm_irq, sh_rtc_alarm, |
698 | 0, "sh-rtc alarm", rtc); | 698 | IRQF_DISABLED, "sh-rtc alarm", rtc); |
699 | if (unlikely(ret)) { | 699 | if (unlikely(ret)) { |
700 | dev_err(&pdev->dev, | 700 | dev_err(&pdev->dev, |
701 | "request alarm IRQ failed with %d, IRQ %d\n", | 701 | "request alarm IRQ failed with %d, IRQ %d\n", |
diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c deleted file mode 100644 index d5ec7854a65..00000000000 --- a/drivers/rtc/rtc-snvs.c +++ /dev/null | |||
@@ -1,350 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. | ||
3 | * | ||
4 | * The code contained herein is licensed under the GNU General Public | ||
5 | * License. You may obtain a copy of the GNU General Public License | ||
6 | * Version 2 or later at the following locations: | ||
7 | * | ||
8 | * http://www.opensource.org/licenses/gpl-license.html | ||
9 | * http://www.gnu.org/copyleft/gpl.html | ||
10 | */ | ||
11 | |||
12 | #include <linux/init.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/of.h> | ||
17 | #include <linux/of_device.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/rtc.h> | ||
20 | |||
21 | /* These register offsets are relative to LP (Low Power) range */ | ||
22 | #define SNVS_LPCR 0x04 | ||
23 | #define SNVS_LPSR 0x18 | ||
24 | #define SNVS_LPSRTCMR 0x1c | ||
25 | #define SNVS_LPSRTCLR 0x20 | ||
26 | #define SNVS_LPTAR 0x24 | ||
27 | #define SNVS_LPPGDR 0x30 | ||
28 | |||
29 | #define SNVS_LPCR_SRTC_ENV (1 << 0) | ||
30 | #define SNVS_LPCR_LPTA_EN (1 << 1) | ||
31 | #define SNVS_LPCR_LPWUI_EN (1 << 3) | ||
32 | #define SNVS_LPSR_LPTA (1 << 0) | ||
33 | |||
34 | #define SNVS_LPPGDR_INIT 0x41736166 | ||
35 | #define CNTR_TO_SECS_SH 15 | ||
36 | |||
37 | struct snvs_rtc_data { | ||
38 | struct rtc_device *rtc; | ||
39 | void __iomem *ioaddr; | ||
40 | int irq; | ||
41 | spinlock_t lock; | ||
42 | }; | ||
43 | |||
44 | static u32 rtc_read_lp_counter(void __iomem *ioaddr) | ||
45 | { | ||
46 | u64 read1, read2; | ||
47 | |||
48 | do { | ||
49 | read1 = readl(ioaddr + SNVS_LPSRTCMR); | ||
50 | read1 <<= 32; | ||
51 | read1 |= readl(ioaddr + SNVS_LPSRTCLR); | ||
52 | |||
53 | read2 = readl(ioaddr + SNVS_LPSRTCMR); | ||
54 | read2 <<= 32; | ||
55 | read2 |= readl(ioaddr + SNVS_LPSRTCLR); | ||
56 | } while (read1 != read2); | ||
57 | |||
58 | /* Convert 47-bit counter to 32-bit raw second count */ | ||
59 | return (u32) (read1 >> CNTR_TO_SECS_SH); | ||
60 | } | ||
61 | |||
62 | static void rtc_write_sync_lp(void __iomem *ioaddr) | ||
63 | { | ||
64 | u32 count1, count2, count3; | ||
65 | int i; | ||
66 | |||
67 | /* Wait for 3 CKIL cycles */ | ||
68 | for (i = 0; i < 3; i++) { | ||
69 | do { | ||
70 | count1 = readl(ioaddr + SNVS_LPSRTCLR); | ||
71 | count2 = readl(ioaddr + SNVS_LPSRTCLR); | ||
72 | } while (count1 != count2); | ||
73 | |||
74 | /* Now wait until counter value changes */ | ||
75 | do { | ||
76 | do { | ||
77 | count2 = readl(ioaddr + SNVS_LPSRTCLR); | ||
78 | count3 = readl(ioaddr + SNVS_LPSRTCLR); | ||
79 | } while (count2 != count3); | ||
80 | } while (count3 == count1); | ||
81 | } | ||
82 | } | ||
83 | |||
84 | static int snvs_rtc_enable(struct snvs_rtc_data *data, bool enable) | ||
85 | { | ||
86 | unsigned long flags; | ||
87 | int timeout = 1000; | ||
88 | u32 lpcr; | ||
89 | |||
90 | spin_lock_irqsave(&data->lock, flags); | ||
91 | |||
92 | lpcr = readl(data->ioaddr + SNVS_LPCR); | ||
93 | if (enable) | ||
94 | lpcr |= SNVS_LPCR_SRTC_ENV; | ||
95 | else | ||
96 | lpcr &= ~SNVS_LPCR_SRTC_ENV; | ||
97 | writel(lpcr, data->ioaddr + SNVS_LPCR); | ||
98 | |||
99 | spin_unlock_irqrestore(&data->lock, flags); | ||
100 | |||
101 | while (--timeout) { | ||
102 | lpcr = readl(data->ioaddr + SNVS_LPCR); | ||
103 | |||
104 | if (enable) { | ||
105 | if (lpcr & SNVS_LPCR_SRTC_ENV) | ||
106 | break; | ||
107 | } else { | ||
108 | if (!(lpcr & SNVS_LPCR_SRTC_ENV)) | ||
109 | break; | ||
110 | } | ||
111 | } | ||
112 | |||
113 | if (!timeout) | ||
114 | return -ETIMEDOUT; | ||
115 | |||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | static int snvs_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
120 | { | ||
121 | struct snvs_rtc_data *data = dev_get_drvdata(dev); | ||
122 | unsigned long time = rtc_read_lp_counter(data->ioaddr); | ||
123 | |||
124 | rtc_time_to_tm(time, tm); | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int snvs_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
130 | { | ||
131 | struct snvs_rtc_data *data = dev_get_drvdata(dev); | ||
132 | unsigned long time; | ||
133 | |||
134 | rtc_tm_to_time(tm, &time); | ||
135 | |||
136 | /* Disable RTC first */ | ||
137 | snvs_rtc_enable(data, false); | ||
138 | |||
139 | /* Write 32-bit time to 47-bit timer, leaving 15 LSBs blank */ | ||
140 | writel(time << CNTR_TO_SECS_SH, data->ioaddr + SNVS_LPSRTCLR); | ||
141 | writel(time >> (32 - CNTR_TO_SECS_SH), data->ioaddr + SNVS_LPSRTCMR); | ||
142 | |||
143 | /* Enable RTC again */ | ||
144 | snvs_rtc_enable(data, true); | ||
145 | |||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
150 | { | ||
151 | struct snvs_rtc_data *data = dev_get_drvdata(dev); | ||
152 | u32 lptar, lpsr; | ||
153 | |||
154 | lptar = readl(data->ioaddr + SNVS_LPTAR); | ||
155 | rtc_time_to_tm(lptar, &alrm->time); | ||
156 | |||
157 | lpsr = readl(data->ioaddr + SNVS_LPSR); | ||
158 | alrm->pending = (lpsr & SNVS_LPSR_LPTA) ? 1 : 0; | ||
159 | |||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | static int snvs_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) | ||
164 | { | ||
165 | struct snvs_rtc_data *data = dev_get_drvdata(dev); | ||
166 | u32 lpcr; | ||
167 | unsigned long flags; | ||
168 | |||
169 | spin_lock_irqsave(&data->lock, flags); | ||
170 | |||
171 | lpcr = readl(data->ioaddr + SNVS_LPCR); | ||
172 | if (enable) | ||
173 | lpcr |= (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN); | ||
174 | else | ||
175 | lpcr &= ~(SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN); | ||
176 | writel(lpcr, data->ioaddr + SNVS_LPCR); | ||
177 | |||
178 | spin_unlock_irqrestore(&data->lock, flags); | ||
179 | |||
180 | rtc_write_sync_lp(data->ioaddr); | ||
181 | |||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
186 | { | ||
187 | struct snvs_rtc_data *data = dev_get_drvdata(dev); | ||
188 | struct rtc_time *alrm_tm = &alrm->time; | ||
189 | unsigned long time; | ||
190 | unsigned long flags; | ||
191 | u32 lpcr; | ||
192 | |||
193 | rtc_tm_to_time(alrm_tm, &time); | ||
194 | |||
195 | spin_lock_irqsave(&data->lock, flags); | ||
196 | |||
197 | /* Have to clear LPTA_EN before programming new alarm time in LPTAR */ | ||
198 | lpcr = readl(data->ioaddr + SNVS_LPCR); | ||
199 | lpcr &= ~SNVS_LPCR_LPTA_EN; | ||
200 | writel(lpcr, data->ioaddr + SNVS_LPCR); | ||
201 | |||
202 | spin_unlock_irqrestore(&data->lock, flags); | ||
203 | |||
204 | writel(time, data->ioaddr + SNVS_LPTAR); | ||
205 | |||
206 | /* Clear alarm interrupt status bit */ | ||
207 | writel(SNVS_LPSR_LPTA, data->ioaddr + SNVS_LPSR); | ||
208 | |||
209 | return snvs_rtc_alarm_irq_enable(dev, alrm->enabled); | ||
210 | } | ||
211 | |||
212 | static const struct rtc_class_ops snvs_rtc_ops = { | ||
213 | .read_time = snvs_rtc_read_time, | ||
214 | .set_time = snvs_rtc_set_time, | ||
215 | .read_alarm = snvs_rtc_read_alarm, | ||
216 | .set_alarm = snvs_rtc_set_alarm, | ||
217 | .alarm_irq_enable = snvs_rtc_alarm_irq_enable, | ||
218 | }; | ||
219 | |||
220 | static irqreturn_t snvs_rtc_irq_handler(int irq, void *dev_id) | ||
221 | { | ||
222 | struct device *dev = dev_id; | ||
223 | struct snvs_rtc_data *data = dev_get_drvdata(dev); | ||
224 | u32 lpsr; | ||
225 | u32 events = 0; | ||
226 | |||
227 | lpsr = readl(data->ioaddr + SNVS_LPSR); | ||
228 | |||
229 | if (lpsr & SNVS_LPSR_LPTA) { | ||
230 | events |= (RTC_AF | RTC_IRQF); | ||
231 | |||
232 | /* RTC alarm should be one-shot */ | ||
233 | snvs_rtc_alarm_irq_enable(dev, 0); | ||
234 | |||
235 | rtc_update_irq(data->rtc, 1, events); | ||
236 | } | ||
237 | |||
238 | /* clear interrupt status */ | ||
239 | writel(lpsr, data->ioaddr + SNVS_LPSR); | ||
240 | |||
241 | return events ? IRQ_HANDLED : IRQ_NONE; | ||
242 | } | ||
243 | |||
244 | static int snvs_rtc_probe(struct platform_device *pdev) | ||
245 | { | ||
246 | struct snvs_rtc_data *data; | ||
247 | struct resource *res; | ||
248 | int ret; | ||
249 | |||
250 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | ||
251 | if (!data) | ||
252 | return -ENOMEM; | ||
253 | |||
254 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
255 | data->ioaddr = devm_request_and_ioremap(&pdev->dev, res); | ||
256 | if (!data->ioaddr) | ||
257 | return -EADDRNOTAVAIL; | ||
258 | |||
259 | data->irq = platform_get_irq(pdev, 0); | ||
260 | if (data->irq < 0) | ||
261 | return data->irq; | ||
262 | |||
263 | platform_set_drvdata(pdev, data); | ||
264 | |||
265 | spin_lock_init(&data->lock); | ||
266 | |||
267 | /* Initialize glitch detect */ | ||
268 | writel(SNVS_LPPGDR_INIT, data->ioaddr + SNVS_LPPGDR); | ||
269 | |||
270 | /* Clear interrupt status */ | ||
271 | writel(0xffffffff, data->ioaddr + SNVS_LPSR); | ||
272 | |||
273 | /* Enable RTC */ | ||
274 | snvs_rtc_enable(data, true); | ||
275 | |||
276 | device_init_wakeup(&pdev->dev, true); | ||
277 | |||
278 | ret = devm_request_irq(&pdev->dev, data->irq, snvs_rtc_irq_handler, | ||
279 | IRQF_SHARED, "rtc alarm", &pdev->dev); | ||
280 | if (ret) { | ||
281 | dev_err(&pdev->dev, "failed to request irq %d: %d\n", | ||
282 | data->irq, ret); | ||
283 | return ret; | ||
284 | } | ||
285 | |||
286 | data->rtc = rtc_device_register(pdev->name, &pdev->dev, | ||
287 | &snvs_rtc_ops, THIS_MODULE); | ||
288 | if (IS_ERR(data->rtc)) { | ||
289 | ret = PTR_ERR(data->rtc); | ||
290 | dev_err(&pdev->dev, "failed to register rtc: %d\n", ret); | ||
291 | return ret; | ||
292 | } | ||
293 | |||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | static int snvs_rtc_remove(struct platform_device *pdev) | ||
298 | { | ||
299 | struct snvs_rtc_data *data = platform_get_drvdata(pdev); | ||
300 | |||
301 | rtc_device_unregister(data->rtc); | ||
302 | |||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | #ifdef CONFIG_PM_SLEEP | ||
307 | static int snvs_rtc_suspend(struct device *dev) | ||
308 | { | ||
309 | struct snvs_rtc_data *data = dev_get_drvdata(dev); | ||
310 | |||
311 | if (device_may_wakeup(dev)) | ||
312 | enable_irq_wake(data->irq); | ||
313 | |||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | static int snvs_rtc_resume(struct device *dev) | ||
318 | { | ||
319 | struct snvs_rtc_data *data = dev_get_drvdata(dev); | ||
320 | |||
321 | if (device_may_wakeup(dev)) | ||
322 | disable_irq_wake(data->irq); | ||
323 | |||
324 | return 0; | ||
325 | } | ||
326 | #endif | ||
327 | |||
328 | static SIMPLE_DEV_PM_OPS(snvs_rtc_pm_ops, snvs_rtc_suspend, snvs_rtc_resume); | ||
329 | |||
330 | static const struct of_device_id snvs_dt_ids[] = { | ||
331 | { .compatible = "fsl,sec-v4.0-mon-rtc-lp", }, | ||
332 | { /* sentinel */ } | ||
333 | }; | ||
334 | MODULE_DEVICE_TABLE(of, snvs_dt_ids); | ||
335 | |||
336 | static struct platform_driver snvs_rtc_driver = { | ||
337 | .driver = { | ||
338 | .name = "snvs_rtc", | ||
339 | .owner = THIS_MODULE, | ||
340 | .pm = &snvs_rtc_pm_ops, | ||
341 | .of_match_table = snvs_dt_ids, | ||
342 | }, | ||
343 | .probe = snvs_rtc_probe, | ||
344 | .remove = snvs_rtc_remove, | ||
345 | }; | ||
346 | module_platform_driver(snvs_rtc_driver); | ||
347 | |||
348 | MODULE_AUTHOR("Freescale Semiconductor, Inc."); | ||
349 | MODULE_DESCRIPTION("Freescale SNVS RTC Driver"); | ||
350 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c index c2121b5a01f..893bac2bb21 100644 --- a/drivers/rtc/rtc-spear.c +++ b/drivers/rtc/rtc-spear.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
17 | #include <linux/irq.h> | 17 | #include <linux/irq.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/of.h> | ||
20 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
21 | #include <linux/rtc.h> | 20 | #include <linux/rtc.h> |
22 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
@@ -78,11 +77,9 @@ | |||
78 | #define STATUS_FAIL (LOST_WR_TIME | LOST_WR_DATE) | 77 | #define STATUS_FAIL (LOST_WR_TIME | LOST_WR_DATE) |
79 | 78 | ||
80 | struct spear_rtc_config { | 79 | struct spear_rtc_config { |
81 | struct rtc_device *rtc; | ||
82 | struct clk *clk; | 80 | struct clk *clk; |
83 | spinlock_t lock; | 81 | spinlock_t lock; |
84 | void __iomem *ioaddr; | 82 | void __iomem *ioaddr; |
85 | unsigned int irq_wake; | ||
86 | }; | 83 | }; |
87 | 84 | ||
88 | static inline void spear_rtc_clear_interrupt(struct spear_rtc_config *config) | 85 | static inline void spear_rtc_clear_interrupt(struct spear_rtc_config *config) |
@@ -152,7 +149,8 @@ static void rtc_wait_not_busy(struct spear_rtc_config *config) | |||
152 | 149 | ||
153 | static irqreturn_t spear_rtc_irq(int irq, void *dev_id) | 150 | static irqreturn_t spear_rtc_irq(int irq, void *dev_id) |
154 | { | 151 | { |
155 | struct spear_rtc_config *config = dev_id; | 152 | struct rtc_device *rtc = (struct rtc_device *)dev_id; |
153 | struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); | ||
156 | unsigned long flags, events = 0; | 154 | unsigned long flags, events = 0; |
157 | unsigned int irq_data; | 155 | unsigned int irq_data; |
158 | 156 | ||
@@ -163,7 +161,7 @@ static irqreturn_t spear_rtc_irq(int irq, void *dev_id) | |||
163 | if ((irq_data & RTC_INT_MASK)) { | 161 | if ((irq_data & RTC_INT_MASK)) { |
164 | spear_rtc_clear_interrupt(config); | 162 | spear_rtc_clear_interrupt(config); |
165 | events = RTC_IRQF | RTC_AF; | 163 | events = RTC_IRQF | RTC_AF; |
166 | rtc_update_irq(config->rtc, 1, events); | 164 | rtc_update_irq(rtc, 1, events); |
167 | return IRQ_HANDLED; | 165 | return IRQ_HANDLED; |
168 | } else | 166 | } else |
169 | return IRQ_NONE; | 167 | return IRQ_NONE; |
@@ -205,7 +203,9 @@ static void bcd2tm(struct rtc_time *tm) | |||
205 | */ | 203 | */ |
206 | static int spear_rtc_read_time(struct device *dev, struct rtc_time *tm) | 204 | static int spear_rtc_read_time(struct device *dev, struct rtc_time *tm) |
207 | { | 205 | { |
208 | struct spear_rtc_config *config = dev_get_drvdata(dev); | 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; | 209 | unsigned int time, date; |
210 | 210 | ||
211 | /* we don't report wday/yday/isdst ... */ | 211 | /* we don't report wday/yday/isdst ... */ |
@@ -234,8 +234,10 @@ static int spear_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
234 | */ | 234 | */ |
235 | static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm) | 235 | static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm) |
236 | { | 236 | { |
237 | struct spear_rtc_config *config = dev_get_drvdata(dev); | 237 | struct platform_device *pdev = to_platform_device(dev); |
238 | unsigned int time, date; | 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; | ||
239 | 241 | ||
240 | if (tm2bcd(tm) < 0) | 242 | if (tm2bcd(tm) < 0) |
241 | return -EINVAL; | 243 | return -EINVAL; |
@@ -247,8 +249,11 @@ static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
247 | (tm->tm_year << YEAR_SHIFT); | 249 | (tm->tm_year << YEAR_SHIFT); |
248 | writel(time, config->ioaddr + TIME_REG); | 250 | writel(time, config->ioaddr + TIME_REG); |
249 | writel(date, config->ioaddr + DATE_REG); | 251 | writel(date, config->ioaddr + DATE_REG); |
252 | err = is_write_complete(config); | ||
253 | if (err < 0) | ||
254 | return err; | ||
250 | 255 | ||
251 | return is_write_complete(config); | 256 | return 0; |
252 | } | 257 | } |
253 | 258 | ||
254 | /* | 259 | /* |
@@ -261,7 +266,9 @@ static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
261 | */ | 266 | */ |
262 | static int spear_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | 267 | static int spear_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) |
263 | { | 268 | { |
264 | struct spear_rtc_config *config = dev_get_drvdata(dev); | 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); | ||
265 | unsigned int time, date; | 272 | unsigned int time, date; |
266 | 273 | ||
267 | rtc_wait_not_busy(config); | 274 | rtc_wait_not_busy(config); |
@@ -291,9 +298,10 @@ static int spear_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
291 | */ | 298 | */ |
292 | static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | 299 | static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) |
293 | { | 300 | { |
294 | struct spear_rtc_config *config = dev_get_drvdata(dev); | 301 | struct platform_device *pdev = to_platform_device(dev); |
295 | unsigned int time, date; | 302 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
296 | int err; | 303 | struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); |
304 | unsigned int time, date, err = 0; | ||
297 | 305 | ||
298 | if (tm2bcd(&alm->time) < 0) | 306 | if (tm2bcd(&alm->time) < 0) |
299 | return -EINVAL; | 307 | return -EINVAL; |
@@ -318,44 +326,19 @@ static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
318 | 326 | ||
319 | return 0; | 327 | return 0; |
320 | } | 328 | } |
321 | |||
322 | static int spear_alarm_irq_enable(struct device *dev, unsigned int enabled) | ||
323 | { | ||
324 | struct spear_rtc_config *config = dev_get_drvdata(dev); | ||
325 | int ret = 0; | ||
326 | |||
327 | spear_rtc_clear_interrupt(config); | ||
328 | |||
329 | switch (enabled) { | ||
330 | case 0: | ||
331 | /* alarm off */ | ||
332 | spear_rtc_disable_interrupt(config); | ||
333 | break; | ||
334 | case 1: | ||
335 | /* alarm on */ | ||
336 | spear_rtc_enable_interrupt(config); | ||
337 | break; | ||
338 | default: | ||
339 | ret = -EINVAL; | ||
340 | break; | ||
341 | } | ||
342 | |||
343 | return ret; | ||
344 | } | ||
345 | |||
346 | static struct rtc_class_ops spear_rtc_ops = { | 329 | static struct rtc_class_ops spear_rtc_ops = { |
347 | .read_time = spear_rtc_read_time, | 330 | .read_time = spear_rtc_read_time, |
348 | .set_time = spear_rtc_set_time, | 331 | .set_time = spear_rtc_set_time, |
349 | .read_alarm = spear_rtc_read_alarm, | 332 | .read_alarm = spear_rtc_read_alarm, |
350 | .set_alarm = spear_rtc_set_alarm, | 333 | .set_alarm = spear_rtc_set_alarm, |
351 | .alarm_irq_enable = spear_alarm_irq_enable, | ||
352 | }; | 334 | }; |
353 | 335 | ||
354 | static int spear_rtc_probe(struct platform_device *pdev) | 336 | static int __devinit spear_rtc_probe(struct platform_device *pdev) |
355 | { | 337 | { |
356 | struct resource *res; | 338 | struct resource *res; |
339 | struct rtc_device *rtc; | ||
357 | struct spear_rtc_config *config; | 340 | struct spear_rtc_config *config; |
358 | int status = 0; | 341 | unsigned int status = 0; |
359 | int irq; | 342 | int irq; |
360 | 343 | ||
361 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 344 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -363,76 +346,110 @@ static int spear_rtc_probe(struct platform_device *pdev) | |||
363 | dev_err(&pdev->dev, "no resource defined\n"); | 346 | dev_err(&pdev->dev, "no resource defined\n"); |
364 | return -EBUSY; | 347 | return -EBUSY; |
365 | } | 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 | } | ||
366 | 353 | ||
367 | config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL); | 354 | config = kzalloc(sizeof(*config), GFP_KERNEL); |
368 | if (!config) { | 355 | if (!config) { |
369 | dev_err(&pdev->dev, "out of memory\n"); | 356 | dev_err(&pdev->dev, "out of memory\n"); |
370 | return -ENOMEM; | 357 | status = -ENOMEM; |
358 | goto err_release_region; | ||
371 | } | 359 | } |
372 | 360 | ||
373 | /* alarm irqs */ | 361 | config->clk = clk_get(&pdev->dev, NULL); |
374 | irq = platform_get_irq(pdev, 0); | 362 | if (IS_ERR(config->clk)) { |
375 | if (irq < 0) { | 363 | status = PTR_ERR(config->clk); |
376 | dev_err(&pdev->dev, "no update irq?\n"); | 364 | goto err_kfree; |
377 | return irq; | ||
378 | } | 365 | } |
379 | 366 | ||
380 | status = devm_request_irq(&pdev->dev, irq, spear_rtc_irq, 0, pdev->name, | 367 | status = clk_enable(config->clk); |
381 | config); | 368 | if (status < 0) |
382 | if (status) { | 369 | goto err_clk_put; |
383 | dev_err(&pdev->dev, "Alarm interrupt IRQ%d already claimed\n", | ||
384 | irq); | ||
385 | return status; | ||
386 | } | ||
387 | 370 | ||
388 | config->ioaddr = devm_request_and_ioremap(&pdev->dev, res); | 371 | config->ioaddr = ioremap(res->start, resource_size(res)); |
389 | if (!config->ioaddr) { | 372 | if (!config->ioaddr) { |
390 | dev_err(&pdev->dev, "request-ioremap fail\n"); | 373 | dev_err(&pdev->dev, "ioremap fail\n"); |
391 | return -ENOMEM; | 374 | status = -ENOMEM; |
375 | goto err_disable_clock; | ||
392 | } | 376 | } |
393 | 377 | ||
394 | config->clk = devm_clk_get(&pdev->dev, NULL); | ||
395 | if (IS_ERR(config->clk)) | ||
396 | return PTR_ERR(config->clk); | ||
397 | |||
398 | status = clk_prepare_enable(config->clk); | ||
399 | if (status < 0) | ||
400 | return status; | ||
401 | |||
402 | spin_lock_init(&config->lock); | 378 | spin_lock_init(&config->lock); |
403 | platform_set_drvdata(pdev, config); | ||
404 | 379 | ||
405 | config->rtc = rtc_device_register(pdev->name, &pdev->dev, | 380 | rtc = rtc_device_register(pdev->name, &pdev->dev, &spear_rtc_ops, |
406 | &spear_rtc_ops, THIS_MODULE); | 381 | THIS_MODULE); |
407 | if (IS_ERR(config->rtc)) { | 382 | if (IS_ERR(rtc)) { |
408 | dev_err(&pdev->dev, "can't register RTC device, err %ld\n", | 383 | dev_err(&pdev->dev, "can't register RTC device, err %ld\n", |
409 | PTR_ERR(config->rtc)); | 384 | PTR_ERR(rtc)); |
410 | status = PTR_ERR(config->rtc); | 385 | status = PTR_ERR(rtc); |
411 | goto err_disable_clock; | 386 | goto err_iounmap; |
412 | } | 387 | } |
413 | 388 | ||
414 | config->rtc->uie_unsupported = 1; | 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 | } | ||
415 | 406 | ||
416 | if (!device_can_wakeup(&pdev->dev)) | 407 | if (!device_can_wakeup(&pdev->dev)) |
417 | device_init_wakeup(&pdev->dev, 1); | 408 | device_init_wakeup(&pdev->dev, 1); |
418 | 409 | ||
419 | return 0; | 410 | return 0; |
420 | 411 | ||
421 | err_disable_clock: | 412 | err_clear_platdata: |
422 | platform_set_drvdata(pdev, NULL); | 413 | platform_set_drvdata(pdev, NULL); |
423 | clk_disable_unprepare(config->clk); | 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)); | ||
424 | 426 | ||
425 | return status; | 427 | return status; |
426 | } | 428 | } |
427 | 429 | ||
428 | static int spear_rtc_remove(struct platform_device *pdev) | 430 | static int __devexit spear_rtc_remove(struct platform_device *pdev) |
429 | { | 431 | { |
430 | struct spear_rtc_config *config = platform_get_drvdata(pdev); | 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; | ||
431 | 436 | ||
432 | rtc_device_unregister(config->rtc); | 437 | /* leave rtc running, but disable irqs */ |
433 | spear_rtc_disable_interrupt(config); | 438 | spear_rtc_disable_interrupt(config); |
434 | clk_disable_unprepare(config->clk); | ||
435 | device_init_wakeup(&pdev->dev, 0); | 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); | ||
436 | 453 | ||
437 | return 0; | 454 | return 0; |
438 | } | 455 | } |
@@ -441,14 +458,14 @@ static int spear_rtc_remove(struct platform_device *pdev) | |||
441 | 458 | ||
442 | static int spear_rtc_suspend(struct platform_device *pdev, pm_message_t state) | 459 | static int spear_rtc_suspend(struct platform_device *pdev, pm_message_t state) |
443 | { | 460 | { |
444 | struct spear_rtc_config *config = platform_get_drvdata(pdev); | 461 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
462 | struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); | ||
445 | int irq; | 463 | int irq; |
446 | 464 | ||
447 | irq = platform_get_irq(pdev, 0); | 465 | irq = platform_get_irq(pdev, 0); |
448 | if (device_may_wakeup(&pdev->dev)) { | 466 | if (device_may_wakeup(&pdev->dev)) |
449 | if (!enable_irq_wake(irq)) | 467 | enable_irq_wake(irq); |
450 | config->irq_wake = 1; | 468 | else { |
451 | } else { | ||
452 | spear_rtc_disable_interrupt(config); | 469 | spear_rtc_disable_interrupt(config); |
453 | clk_disable(config->clk); | 470 | clk_disable(config->clk); |
454 | } | 471 | } |
@@ -458,17 +475,15 @@ static int spear_rtc_suspend(struct platform_device *pdev, pm_message_t state) | |||
458 | 475 | ||
459 | static int spear_rtc_resume(struct platform_device *pdev) | 476 | static int spear_rtc_resume(struct platform_device *pdev) |
460 | { | 477 | { |
461 | struct spear_rtc_config *config = platform_get_drvdata(pdev); | 478 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
479 | struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); | ||
462 | int irq; | 480 | int irq; |
463 | 481 | ||
464 | irq = platform_get_irq(pdev, 0); | 482 | irq = platform_get_irq(pdev, 0); |
465 | 483 | ||
466 | if (device_may_wakeup(&pdev->dev)) { | 484 | if (device_may_wakeup(&pdev->dev)) |
467 | if (config->irq_wake) { | 485 | disable_irq_wake(irq); |
468 | disable_irq_wake(irq); | 486 | else { |
469 | config->irq_wake = 0; | ||
470 | } | ||
471 | } else { | ||
472 | clk_enable(config->clk); | 487 | clk_enable(config->clk); |
473 | spear_rtc_enable_interrupt(config); | 488 | spear_rtc_enable_interrupt(config); |
474 | } | 489 | } |
@@ -483,33 +498,35 @@ static int spear_rtc_resume(struct platform_device *pdev) | |||
483 | 498 | ||
484 | static void spear_rtc_shutdown(struct platform_device *pdev) | 499 | static void spear_rtc_shutdown(struct platform_device *pdev) |
485 | { | 500 | { |
486 | struct spear_rtc_config *config = platform_get_drvdata(pdev); | 501 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
502 | struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev); | ||
487 | 503 | ||
488 | spear_rtc_disable_interrupt(config); | 504 | spear_rtc_disable_interrupt(config); |
489 | clk_disable(config->clk); | 505 | clk_disable(config->clk); |
490 | } | 506 | } |
491 | 507 | ||
492 | #ifdef CONFIG_OF | ||
493 | static const struct of_device_id spear_rtc_id_table[] = { | ||
494 | { .compatible = "st,spear600-rtc" }, | ||
495 | {} | ||
496 | }; | ||
497 | MODULE_DEVICE_TABLE(of, spear_rtc_id_table); | ||
498 | #endif | ||
499 | |||
500 | static struct platform_driver spear_rtc_driver = { | 508 | static struct platform_driver spear_rtc_driver = { |
501 | .probe = spear_rtc_probe, | 509 | .probe = spear_rtc_probe, |
502 | .remove = spear_rtc_remove, | 510 | .remove = __devexit_p(spear_rtc_remove), |
503 | .suspend = spear_rtc_suspend, | 511 | .suspend = spear_rtc_suspend, |
504 | .resume = spear_rtc_resume, | 512 | .resume = spear_rtc_resume, |
505 | .shutdown = spear_rtc_shutdown, | 513 | .shutdown = spear_rtc_shutdown, |
506 | .driver = { | 514 | .driver = { |
507 | .name = "rtc-spear", | 515 | .name = "rtc-spear", |
508 | .of_match_table = of_match_ptr(spear_rtc_id_table), | ||
509 | }, | 516 | }, |
510 | }; | 517 | }; |
511 | 518 | ||
512 | module_platform_driver(spear_rtc_driver); | 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); | ||
513 | 530 | ||
514 | MODULE_ALIAS("platform:rtc-spear"); | 531 | MODULE_ALIAS("platform:rtc-spear"); |
515 | MODULE_AUTHOR("Rajeev Kumar <rajeev-dlh.kumar@st.com>"); | 532 | MODULE_AUTHOR("Rajeev Kumar <rajeev-dlh.kumar@st.com>"); |
diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c index 7e4a6f65cb9..3b943673cd3 100644 --- a/drivers/rtc/rtc-stk17ta8.c +++ b/drivers/rtc/rtc-stk17ta8.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/rtc.h> | 21 | #include <linux/rtc.h> |
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
24 | #include <linux/module.h> | ||
25 | 24 | ||
26 | #define DRV_VERSION "0.1" | 25 | #define DRV_VERSION "0.1" |
27 | 26 | ||
@@ -285,7 +284,7 @@ static struct bin_attribute stk17ta8_nvram_attr = { | |||
285 | .write = stk17ta8_nvram_write, | 284 | .write = stk17ta8_nvram_write, |
286 | }; | 285 | }; |
287 | 286 | ||
288 | static int stk17ta8_rtc_probe(struct platform_device *pdev) | 287 | static int __devinit stk17ta8_rtc_probe(struct platform_device *pdev) |
289 | { | 288 | { |
290 | struct resource *res; | 289 | struct resource *res; |
291 | unsigned int cal; | 290 | unsigned int cal; |
@@ -329,7 +328,7 @@ static int stk17ta8_rtc_probe(struct platform_device *pdev) | |||
329 | writeb(0, ioaddr + RTC_INTERRUPTS); | 328 | writeb(0, ioaddr + RTC_INTERRUPTS); |
330 | if (devm_request_irq(&pdev->dev, pdata->irq, | 329 | if (devm_request_irq(&pdev->dev, pdata->irq, |
331 | stk17ta8_rtc_interrupt, | 330 | stk17ta8_rtc_interrupt, |
332 | IRQF_SHARED, | 331 | IRQF_DISABLED | IRQF_SHARED, |
333 | pdev->name, pdev) < 0) { | 332 | pdev->name, pdev) < 0) { |
334 | dev_warn(&pdev->dev, "interrupt not available.\n"); | 333 | dev_warn(&pdev->dev, "interrupt not available.\n"); |
335 | pdata->irq = 0; | 334 | pdata->irq = 0; |
@@ -347,7 +346,7 @@ static int stk17ta8_rtc_probe(struct platform_device *pdev) | |||
347 | return ret; | 346 | return ret; |
348 | } | 347 | } |
349 | 348 | ||
350 | static int stk17ta8_rtc_remove(struct platform_device *pdev) | 349 | static int __devexit stk17ta8_rtc_remove(struct platform_device *pdev) |
351 | { | 350 | { |
352 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 351 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
353 | 352 | ||
@@ -363,14 +362,25 @@ MODULE_ALIAS("platform:stk17ta8"); | |||
363 | 362 | ||
364 | static struct platform_driver stk17ta8_rtc_driver = { | 363 | static struct platform_driver stk17ta8_rtc_driver = { |
365 | .probe = stk17ta8_rtc_probe, | 364 | .probe = stk17ta8_rtc_probe, |
366 | .remove = stk17ta8_rtc_remove, | 365 | .remove = __devexit_p(stk17ta8_rtc_remove), |
367 | .driver = { | 366 | .driver = { |
368 | .name = "stk17ta8", | 367 | .name = "stk17ta8", |
369 | .owner = THIS_MODULE, | 368 | .owner = THIS_MODULE, |
370 | }, | 369 | }, |
371 | }; | 370 | }; |
372 | 371 | ||
373 | module_platform_driver(stk17ta8_rtc_driver); | 372 | static __init int stk17ta8_init(void) |
373 | { | ||
374 | return platform_driver_register(&stk17ta8_rtc_driver); | ||
375 | } | ||
376 | |||
377 | static __exit void stk17ta8_exit(void) | ||
378 | { | ||
379 | platform_driver_unregister(&stk17ta8_rtc_driver); | ||
380 | } | ||
381 | |||
382 | module_init(stk17ta8_init); | ||
383 | module_exit(stk17ta8_exit); | ||
374 | 384 | ||
375 | MODULE_AUTHOR("Thomas Hommel <thomas.hommel@ge.com>"); | 385 | MODULE_AUTHOR("Thomas Hommel <thomas.hommel@ge.com>"); |
376 | MODULE_DESCRIPTION("Simtek STK17TA8 RTC driver"); | 386 | MODULE_DESCRIPTION("Simtek STK17TA8 RTC driver"); |
diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c index 739ef55694f..7315068daa5 100644 --- a/drivers/rtc/rtc-stmp3xxx.c +++ b/drivers/rtc/rtc-stmp3xxx.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
26 | #include <linux/rtc.h> | 26 | #include <linux/rtc.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/of_device.h> | ||
29 | 28 | ||
30 | #include <mach/common.h> | 29 | #include <mach/common.h> |
31 | 30 | ||
@@ -266,12 +265,6 @@ static int stmp3xxx_rtc_resume(struct platform_device *dev) | |||
266 | #define stmp3xxx_rtc_resume NULL | 265 | #define stmp3xxx_rtc_resume NULL |
267 | #endif | 266 | #endif |
268 | 267 | ||
269 | static const struct of_device_id rtc_dt_ids[] = { | ||
270 | { .compatible = "fsl,stmp3xxx-rtc", }, | ||
271 | { /* sentinel */ } | ||
272 | }; | ||
273 | MODULE_DEVICE_TABLE(of, rtc_dt_ids); | ||
274 | |||
275 | static struct platform_driver stmp3xxx_rtcdrv = { | 268 | static struct platform_driver stmp3xxx_rtcdrv = { |
276 | .probe = stmp3xxx_rtc_probe, | 269 | .probe = stmp3xxx_rtc_probe, |
277 | .remove = stmp3xxx_rtc_remove, | 270 | .remove = stmp3xxx_rtc_remove, |
@@ -280,11 +273,21 @@ static struct platform_driver stmp3xxx_rtcdrv = { | |||
280 | .driver = { | 273 | .driver = { |
281 | .name = "stmp3xxx-rtc", | 274 | .name = "stmp3xxx-rtc", |
282 | .owner = THIS_MODULE, | 275 | .owner = THIS_MODULE, |
283 | .of_match_table = rtc_dt_ids, | ||
284 | }, | 276 | }, |
285 | }; | 277 | }; |
286 | 278 | ||
287 | module_platform_driver(stmp3xxx_rtcdrv); | 279 | static int __init stmp3xxx_rtc_init(void) |
280 | { | ||
281 | return platform_driver_register(&stmp3xxx_rtcdrv); | ||
282 | } | ||
283 | |||
284 | static void __exit stmp3xxx_rtc_exit(void) | ||
285 | { | ||
286 | platform_driver_unregister(&stmp3xxx_rtcdrv); | ||
287 | } | ||
288 | |||
289 | module_init(stmp3xxx_rtc_init); | ||
290 | module_exit(stmp3xxx_rtc_exit); | ||
288 | 291 | ||
289 | MODULE_DESCRIPTION("STMP3xxx RTC Driver"); | 292 | MODULE_DESCRIPTION("STMP3xxx RTC Driver"); |
290 | MODULE_AUTHOR("dmitry pervushin <dpervushin@embeddedalley.com> and " | 293 | MODULE_AUTHOR("dmitry pervushin <dpervushin@embeddedalley.com> and " |
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c index b70e2bb6364..380083ca572 100644 --- a/drivers/rtc/rtc-sysfs.c +++ b/drivers/rtc/rtc-sysfs.c | |||
@@ -102,12 +102,6 @@ rtc_sysfs_set_max_user_freq(struct device *dev, struct device_attribute *attr, | |||
102 | return n; | 102 | return n; |
103 | } | 103 | } |
104 | 104 | ||
105 | /** | ||
106 | * rtc_sysfs_show_hctosys - indicate if the given RTC set the system time | ||
107 | * | ||
108 | * Returns 1 if the system clock was set by this RTC at the last | ||
109 | * boot or resume event. | ||
110 | */ | ||
111 | static ssize_t | 105 | static ssize_t |
112 | rtc_sysfs_show_hctosys(struct device *dev, struct device_attribute *attr, | 106 | rtc_sysfs_show_hctosys(struct device *dev, struct device_attribute *attr, |
113 | char *buf) | 107 | char *buf) |
diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c index c84ea6659f4..773adffac27 100644 --- a/drivers/rtc/rtc-tegra.c +++ b/drivers/rtc/rtc-tegra.c | |||
@@ -1,7 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * An RTC driver for the NVIDIA Tegra 200 series internal RTC. | 2 | * An RTC driver for the NVIDIA Tegra 200 series internal RTC. |
3 | * | 3 | * |
4 | * Copyright (c) 2010, NVIDIA Corporation. | 4 | * Copyright (c) 2010-2011, NVIDIA Corporation. |
5 | * Copyright (c) 2010 Jon Mayo <jmayo@nvidia.com> | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * 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 | * it under the terms of the GNU General Public License as published by |
@@ -303,20 +304,13 @@ static struct rtc_class_ops tegra_rtc_ops = { | |||
303 | .alarm_irq_enable = tegra_rtc_alarm_irq_enable, | 304 | .alarm_irq_enable = tegra_rtc_alarm_irq_enable, |
304 | }; | 305 | }; |
305 | 306 | ||
306 | static const struct of_device_id tegra_rtc_dt_match[] = { | 307 | static int __devinit tegra_rtc_probe(struct platform_device *pdev) |
307 | { .compatible = "nvidia,tegra20-rtc", }, | ||
308 | {} | ||
309 | }; | ||
310 | MODULE_DEVICE_TABLE(of, tegra_rtc_dt_match); | ||
311 | |||
312 | static int tegra_rtc_probe(struct platform_device *pdev) | ||
313 | { | 308 | { |
314 | struct tegra_rtc_info *info; | 309 | struct tegra_rtc_info *info; |
315 | struct resource *res; | 310 | struct resource *res; |
316 | int ret; | 311 | int ret; |
317 | 312 | ||
318 | info = devm_kzalloc(&pdev->dev, sizeof(struct tegra_rtc_info), | 313 | info = kzalloc(sizeof(struct tegra_rtc_info), GFP_KERNEL); |
319 | GFP_KERNEL); | ||
320 | if (!info) | 314 | if (!info) |
321 | return -ENOMEM; | 315 | return -ENOMEM; |
322 | 316 | ||
@@ -324,18 +318,29 @@ static int tegra_rtc_probe(struct platform_device *pdev) | |||
324 | if (!res) { | 318 | if (!res) { |
325 | dev_err(&pdev->dev, | 319 | dev_err(&pdev->dev, |
326 | "Unable to allocate resources for device.\n"); | 320 | "Unable to allocate resources for device.\n"); |
327 | return -EBUSY; | 321 | ret = -EBUSY; |
322 | goto err_free_info; | ||
328 | } | 323 | } |
329 | 324 | ||
330 | info->rtc_base = devm_request_and_ioremap(&pdev->dev, res); | 325 | if (!request_mem_region(res->start, resource_size(res), pdev->name)) { |
331 | if (!info->rtc_base) { | 326 | dev_err(&pdev->dev, |
332 | dev_err(&pdev->dev, "Unable to request mem region and grab IOs for device.\n"); | 327 | "Unable to request mem region for device.\n"); |
333 | return -EBUSY; | 328 | ret = -EBUSY; |
329 | goto err_free_info; | ||
334 | } | 330 | } |
335 | 331 | ||
336 | info->tegra_rtc_irq = platform_get_irq(pdev, 0); | 332 | info->tegra_rtc_irq = platform_get_irq(pdev, 0); |
337 | if (info->tegra_rtc_irq <= 0) | 333 | if (info->tegra_rtc_irq <= 0) { |
338 | return -EBUSY; | 334 | ret = -EBUSY; |
335 | goto err_release_mem_region; | ||
336 | } | ||
337 | |||
338 | info->rtc_base = ioremap_nocache(res->start, resource_size(res)); | ||
339 | if (!info->rtc_base) { | ||
340 | dev_err(&pdev->dev, "Unable to grab IOs for device.\n"); | ||
341 | ret = -EBUSY; | ||
342 | goto err_release_mem_region; | ||
343 | } | ||
339 | 344 | ||
340 | /* set context info. */ | 345 | /* set context info. */ |
341 | info->pdev = pdev; | 346 | info->pdev = pdev; |
@@ -358,12 +363,11 @@ static int tegra_rtc_probe(struct platform_device *pdev) | |||
358 | dev_err(&pdev->dev, | 363 | dev_err(&pdev->dev, |
359 | "Unable to register device (err=%d).\n", | 364 | "Unable to register device (err=%d).\n", |
360 | ret); | 365 | ret); |
361 | return ret; | 366 | goto err_iounmap; |
362 | } | 367 | } |
363 | 368 | ||
364 | ret = devm_request_irq(&pdev->dev, info->tegra_rtc_irq, | 369 | ret = request_irq(info->tegra_rtc_irq, tegra_rtc_irq_handler, |
365 | tegra_rtc_irq_handler, IRQF_TRIGGER_HIGH, | 370 | IRQF_TRIGGER_HIGH, "rtc alarm", &pdev->dev); |
366 | "rtc alarm", &pdev->dev); | ||
367 | if (ret) { | 371 | if (ret) { |
368 | dev_err(&pdev->dev, | 372 | dev_err(&pdev->dev, |
369 | "Unable to request interrupt for device (err=%d).\n", | 373 | "Unable to request interrupt for device (err=%d).\n", |
@@ -373,19 +377,64 @@ static int tegra_rtc_probe(struct platform_device *pdev) | |||
373 | 377 | ||
374 | dev_notice(&pdev->dev, "Tegra internal Real Time Clock\n"); | 378 | dev_notice(&pdev->dev, "Tegra internal Real Time Clock\n"); |
375 | 379 | ||
380 | #ifndef CONFIG_TEGRA_SILICON_PLATFORM | ||
381 | { | ||
382 | struct rtc_time tm; | ||
383 | |||
384 | /* Get the current time from the RTC. */ | ||
385 | ret = tegra_rtc_read_time(&pdev->dev, &tm); | ||
386 | if (ret) { | ||
387 | /* Report but ignore this error. */ | ||
388 | dev_err(&pdev->dev, | ||
389 | "Failed to get FPGA internal RTC time (err=%d)\n", | ||
390 | ret); | ||
391 | } else if (tm.tm_year < 2010) { | ||
392 | /* The RTC's default reset time is soooo last century. */ | ||
393 | tm.tm_year = 2010-1900; | ||
394 | tm.tm_mon = 0; | ||
395 | tm.tm_mday = 1; | ||
396 | tm.tm_hour = 0; | ||
397 | tm.tm_min = 0; | ||
398 | tm.tm_sec = 0; | ||
399 | ret = tegra_rtc_set_time(&pdev->dev, &tm); | ||
400 | if (ret) { | ||
401 | /* Report but ignore this error. */ | ||
402 | dev_err(&pdev->dev, | ||
403 | "Failed to set FPGA internal RTC time (err=%d)\n", | ||
404 | ret); | ||
405 | } | ||
406 | } | ||
407 | } | ||
408 | #endif | ||
409 | |||
376 | return 0; | 410 | return 0; |
377 | 411 | ||
378 | err_dev_unreg: | 412 | err_dev_unreg: |
379 | rtc_device_unregister(info->rtc_dev); | 413 | rtc_device_unregister(info->rtc_dev); |
414 | err_iounmap: | ||
415 | iounmap(info->rtc_base); | ||
416 | err_release_mem_region: | ||
417 | release_mem_region(res->start, resource_size(res)); | ||
418 | err_free_info: | ||
419 | kfree(info); | ||
380 | 420 | ||
381 | return ret; | 421 | return ret; |
382 | } | 422 | } |
383 | 423 | ||
384 | static int tegra_rtc_remove(struct platform_device *pdev) | 424 | static int __devexit tegra_rtc_remove(struct platform_device *pdev) |
385 | { | 425 | { |
386 | struct tegra_rtc_info *info = platform_get_drvdata(pdev); | 426 | struct tegra_rtc_info *info = platform_get_drvdata(pdev); |
427 | struct resource *res; | ||
428 | |||
429 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
430 | if (!res) | ||
431 | return -EBUSY; | ||
387 | 432 | ||
433 | free_irq(info->tegra_rtc_irq, &pdev->dev); | ||
388 | rtc_device_unregister(info->rtc_dev); | 434 | rtc_device_unregister(info->rtc_dev); |
435 | iounmap(info->rtc_base); | ||
436 | release_mem_region(res->start, resource_size(res)); | ||
437 | kfree(info); | ||
389 | 438 | ||
390 | platform_set_drvdata(pdev, NULL); | 439 | platform_set_drvdata(pdev, NULL); |
391 | 440 | ||
@@ -441,12 +490,11 @@ static void tegra_rtc_shutdown(struct platform_device *pdev) | |||
441 | 490 | ||
442 | MODULE_ALIAS("platform:tegra_rtc"); | 491 | MODULE_ALIAS("platform:tegra_rtc"); |
443 | static struct platform_driver tegra_rtc_driver = { | 492 | static struct platform_driver tegra_rtc_driver = { |
444 | .remove = tegra_rtc_remove, | 493 | .remove = __devexit_p(tegra_rtc_remove), |
445 | .shutdown = tegra_rtc_shutdown, | 494 | .shutdown = tegra_rtc_shutdown, |
446 | .driver = { | 495 | .driver = { |
447 | .name = "tegra_rtc", | 496 | .name = "tegra_rtc", |
448 | .owner = THIS_MODULE, | 497 | .owner = THIS_MODULE, |
449 | .of_match_table = tegra_rtc_dt_match, | ||
450 | }, | 498 | }, |
451 | #ifdef CONFIG_PM | 499 | #ifdef CONFIG_PM |
452 | .suspend = tegra_rtc_suspend, | 500 | .suspend = tegra_rtc_suspend, |
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c index b92e0f6383e..7e96254bd36 100644 --- a/drivers/rtc/rtc-test.c +++ b/drivers/rtc/rtc-test.c | |||
@@ -119,7 +119,7 @@ err: | |||
119 | return err; | 119 | return err; |
120 | } | 120 | } |
121 | 121 | ||
122 | static int test_remove(struct platform_device *plat_dev) | 122 | static int __devexit test_remove(struct platform_device *plat_dev) |
123 | { | 123 | { |
124 | struct rtc_device *rtc = platform_get_drvdata(plat_dev); | 124 | struct rtc_device *rtc = platform_get_drvdata(plat_dev); |
125 | 125 | ||
@@ -131,7 +131,7 @@ static int test_remove(struct platform_device *plat_dev) | |||
131 | 131 | ||
132 | static struct platform_driver test_driver = { | 132 | static struct platform_driver test_driver = { |
133 | .probe = test_probe, | 133 | .probe = test_probe, |
134 | .remove = test_remove, | 134 | .remove = __devexit_p(test_remove), |
135 | .driver = { | 135 | .driver = { |
136 | .name = "rtc-test", | 136 | .name = "rtc-test", |
137 | .owner = THIS_MODULE, | 137 | .owner = THIS_MODULE, |
@@ -152,24 +152,24 @@ static int __init test_init(void) | |||
152 | 152 | ||
153 | if ((test1 = platform_device_alloc("rtc-test", 1)) == NULL) { | 153 | if ((test1 = platform_device_alloc("rtc-test", 1)) == NULL) { |
154 | err = -ENOMEM; | 154 | err = -ENOMEM; |
155 | goto exit_put_test0; | 155 | goto exit_free_test0; |
156 | } | 156 | } |
157 | 157 | ||
158 | if ((err = platform_device_add(test0))) | 158 | if ((err = platform_device_add(test0))) |
159 | goto exit_put_test1; | 159 | goto exit_free_test1; |
160 | 160 | ||
161 | if ((err = platform_device_add(test1))) | 161 | if ((err = platform_device_add(test1))) |
162 | goto exit_del_test0; | 162 | goto exit_device_unregister; |
163 | 163 | ||
164 | return 0; | 164 | return 0; |
165 | 165 | ||
166 | exit_del_test0: | 166 | exit_device_unregister: |
167 | platform_device_del(test0); | 167 | platform_device_unregister(test0); |
168 | 168 | ||
169 | exit_put_test1: | 169 | exit_free_test1: |
170 | platform_device_put(test1); | 170 | platform_device_put(test1); |
171 | 171 | ||
172 | exit_put_test0: | 172 | exit_free_test0: |
173 | platform_device_put(test0); | 173 | platform_device_put(test0); |
174 | 174 | ||
175 | exit_driver_unregister: | 175 | exit_driver_unregister: |
diff --git a/drivers/rtc/rtc-tile.c b/drivers/rtc/rtc-tile.c index 62db4841078..eb65dafee66 100644 --- a/drivers/rtc/rtc-tile.c +++ b/drivers/rtc/rtc-tile.c | |||
@@ -76,7 +76,7 @@ static const struct rtc_class_ops tile_rtc_ops = { | |||
76 | /* | 76 | /* |
77 | * Device probe routine. | 77 | * Device probe routine. |
78 | */ | 78 | */ |
79 | static int tile_rtc_probe(struct platform_device *dev) | 79 | static int __devinit tile_rtc_probe(struct platform_device *dev) |
80 | { | 80 | { |
81 | struct rtc_device *rtc; | 81 | struct rtc_device *rtc; |
82 | 82 | ||
@@ -94,7 +94,7 @@ static int tile_rtc_probe(struct platform_device *dev) | |||
94 | /* | 94 | /* |
95 | * Device cleanup routine. | 95 | * Device cleanup routine. |
96 | */ | 96 | */ |
97 | static int tile_rtc_remove(struct platform_device *dev) | 97 | static int __devexit tile_rtc_remove(struct platform_device *dev) |
98 | { | 98 | { |
99 | struct rtc_device *rtc = platform_get_drvdata(dev); | 99 | struct rtc_device *rtc = platform_get_drvdata(dev); |
100 | 100 | ||
@@ -112,7 +112,7 @@ static struct platform_driver tile_rtc_platform_driver = { | |||
112 | .owner = THIS_MODULE, | 112 | .owner = THIS_MODULE, |
113 | }, | 113 | }, |
114 | .probe = tile_rtc_probe, | 114 | .probe = tile_rtc_probe, |
115 | .remove = tile_rtc_remove, | 115 | .remove = __devexit_p(tile_rtc_remove), |
116 | }; | 116 | }; |
117 | 117 | ||
118 | /* | 118 | /* |
diff --git a/drivers/rtc/rtc-tps6586x.c b/drivers/rtc/rtc-tps6586x.c index 70f61b8e9e6..c41edabf0b2 100644 --- a/drivers/rtc/rtc-tps6586x.c +++ b/drivers/rtc/rtc-tps6586x.c | |||
@@ -1,23 +1,23 @@ | |||
1 | /* | 1 | /* |
2 | * rtc-tps6586x.c: RTC driver for TI PMIC TPS6586X | 2 | * drivers/rtc/rtc-tps6586x.c |
3 | * | 3 | * |
4 | * Copyright (c) 2012, NVIDIA Corporation. | 4 | * RTC driver for TI TPS6586x |
5 | * | 5 | * |
6 | * Author: Laxman Dewangan <ldewangan@nvidia.com> | 6 | * Copyright (c) 2010, NVIDIA Corporation. |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * modify it under the terms of the GNU General Public License as | 9 | * it under the terms of the GNU General Public License as published by |
10 | * published by the Free Software Foundation version 2. | 10 | * the Free Software Foundation; either version 2 of the License, or |
11 | * (at your option) any later version. | ||
11 | * | 12 | * |
12 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, | 13 | * This program is distributed in the hope that it will be useful, but WITHOUT |
13 | * whether express or implied; without even the implied warranty of | 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
15 | * General Public License for more details. | 16 | * more details. |
16 | * | 17 | * |
17 | * You should have received a copy of the GNU General Public License | 18 | * You should have received a copy of the GNU General Public License along |
18 | * along with this program; if not, write to the Free Software | 19 | * with this program; if not, write to the Free Software Foundation, Inc., |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | 20 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
20 | * 02111-1307, USA | ||
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <linux/device.h> | 23 | #include <linux/device.h> |
@@ -25,40 +25,28 @@ | |||
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/mfd/tps6586x.h> | 27 | #include <linux/mfd/tps6586x.h> |
28 | #include <linux/module.h> | ||
29 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
30 | #include <linux/pm_runtime.h> | ||
31 | #include <linux/rtc.h> | 29 | #include <linux/rtc.h> |
32 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
33 | 31 | ||
34 | #define RTC_CTRL 0xc0 | 32 | #define RTC_CTRL 0xc0 |
35 | #define POR_RESET_N BIT(7) | 33 | #define POR_RESET_N BIT(7) |
36 | #define OSC_SRC_SEL BIT(6) | 34 | #define OSC_SRC_SEL BIT(6) |
37 | #define RTC_ENABLE BIT(5) /* enables alarm */ | 35 | #define RTC_ENABLE BIT(5) /* enables alarm */ |
38 | #define RTC_BUF_ENABLE BIT(4) /* 32 KHz buffer enable */ | 36 | #define RTC_BUF_ENABLE BIT(4) /* 32 KHz buffer enable */ |
39 | #define PRE_BYPASS BIT(3) /* 0=1KHz or 1=32KHz updates */ | 37 | #define PRE_BYPASS BIT(3) /* 0=1KHz or 1=32KHz updates */ |
40 | #define CL_SEL_MASK (BIT(2)|BIT(1)) | 38 | #define CL_SEL_MASK (BIT(2)|BIT(1)) |
41 | #define CL_SEL_POS 1 | 39 | #define CL_SEL_POS 1 |
42 | #define RTC_ALARM1_HI 0xc1 | 40 | #define RTC_ALARM1_HI 0xc1 |
43 | #define RTC_COUNT4 0xc6 | 41 | #define RTC_COUNT4 0xc6 |
44 | 42 | #define RTC_COUNT4_DUMMYREAD 0xc5 /* start a PMU RTC access by reading the register prior to the RTC_COUNT4 */ | |
45 | /* start a PMU RTC access by reading the register prior to the RTC_COUNT4 */ | 43 | #define ALM1_VALID_RANGE_IN_SEC 0x3FFF /*only 14-bits width in second*/ |
46 | #define RTC_COUNT4_DUMMYREAD 0xc5 | ||
47 | |||
48 | /*only 14-bits width in second*/ | ||
49 | #define ALM1_VALID_RANGE_IN_SEC 0x3FFF | ||
50 | |||
51 | #define TPS6586X_RTC_CL_SEL_1_5PF 0x0 | ||
52 | #define TPS6586X_RTC_CL_SEL_6_5PF 0x1 | ||
53 | #define TPS6586X_RTC_CL_SEL_7_5PF 0x2 | ||
54 | #define TPS6586X_RTC_CL_SEL_12_5PF 0x3 | ||
55 | 44 | ||
56 | struct tps6586x_rtc { | 45 | struct tps6586x_rtc { |
57 | struct device *dev; | 46 | unsigned long epoch_start; |
58 | struct rtc_device *rtc; | ||
59 | int irq; | 47 | int irq; |
48 | struct rtc_device *rtc; | ||
60 | bool irq_en; | 49 | bool irq_en; |
61 | unsigned long long epoch_start; | ||
62 | }; | 50 | }; |
63 | 51 | ||
64 | static inline struct device *to_tps6586x_dev(struct device *dev) | 52 | static inline struct device *to_tps6586x_dev(struct device *dev) |
@@ -73,13 +61,13 @@ static int tps6586x_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
73 | unsigned long long ticks = 0; | 61 | unsigned long long ticks = 0; |
74 | unsigned long seconds; | 62 | unsigned long seconds; |
75 | u8 buff[6]; | 63 | u8 buff[6]; |
76 | int ret; | 64 | int err; |
77 | int i; | 65 | int i; |
78 | 66 | ||
79 | ret = tps6586x_reads(tps_dev, RTC_COUNT4_DUMMYREAD, sizeof(buff), buff); | 67 | err = tps6586x_reads(tps_dev, RTC_COUNT4_DUMMYREAD, sizeof(buff), buff); |
80 | if (ret < 0) { | 68 | if (err < 0) { |
81 | dev_err(dev, "read counter failed with err %d\n", ret); | 69 | dev_err(dev, "failed to read counter\n"); |
82 | return ret; | 70 | return err; |
83 | } | 71 | } |
84 | 72 | ||
85 | for (i = 1; i < sizeof(buff); i++) { | 73 | for (i = 1; i < sizeof(buff); i++) { |
@@ -88,6 +76,7 @@ static int tps6586x_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
88 | } | 76 | } |
89 | 77 | ||
90 | seconds = ticks >> 10; | 78 | seconds = ticks >> 10; |
79 | |||
91 | seconds += rtc->epoch_start; | 80 | seconds += rtc->epoch_start; |
92 | rtc_time_to_tm(seconds, tm); | 81 | rtc_time_to_tm(seconds, tm); |
93 | return rtc_valid_tm(tm); | 82 | return rtc_valid_tm(tm); |
@@ -100,13 +89,15 @@ static int tps6586x_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
100 | unsigned long long ticks; | 89 | unsigned long long ticks; |
101 | unsigned long seconds; | 90 | unsigned long seconds; |
102 | u8 buff[5]; | 91 | u8 buff[5]; |
103 | int ret; | 92 | int err; |
104 | 93 | ||
105 | rtc_tm_to_time(tm, &seconds); | 94 | rtc_tm_to_time(tm, &seconds); |
106 | if (seconds < rtc->epoch_start) { | 95 | |
96 | if (WARN_ON(seconds < rtc->epoch_start)) { | ||
107 | dev_err(dev, "requested time unsupported\n"); | 97 | dev_err(dev, "requested time unsupported\n"); |
108 | return -EINVAL; | 98 | return -EINVAL; |
109 | } | 99 | } |
100 | |||
110 | seconds -= rtc->epoch_start; | 101 | seconds -= rtc->epoch_start; |
111 | 102 | ||
112 | ticks = (unsigned long long)seconds << 10; | 103 | ticks = (unsigned long long)seconds << 10; |
@@ -116,40 +107,24 @@ static int tps6586x_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
116 | buff[3] = (ticks >> 8) & 0xff; | 107 | buff[3] = (ticks >> 8) & 0xff; |
117 | buff[4] = ticks & 0xff; | 108 | buff[4] = ticks & 0xff; |
118 | 109 | ||
119 | /* Disable RTC before changing time */ | 110 | err = tps6586x_clr_bits(tps_dev, RTC_CTRL, RTC_ENABLE); |
120 | ret = tps6586x_clr_bits(tps_dev, RTC_CTRL, RTC_ENABLE); | 111 | if (err < 0) { |
121 | if (ret < 0) { | ||
122 | dev_err(dev, "failed to clear RTC_ENABLE\n"); | 112 | dev_err(dev, "failed to clear RTC_ENABLE\n"); |
123 | return ret; | 113 | return err; |
124 | } | 114 | } |
125 | 115 | ||
126 | ret = tps6586x_writes(tps_dev, RTC_COUNT4, sizeof(buff), buff); | 116 | err = tps6586x_writes(tps_dev, RTC_COUNT4, sizeof(buff), buff); |
127 | if (ret < 0) { | 117 | if (err < 0) { |
128 | dev_err(dev, "failed to program new time\n"); | 118 | dev_err(dev, "failed to program new time\n"); |
129 | return ret; | 119 | return err; |
130 | } | 120 | } |
131 | 121 | ||
132 | /* Enable RTC */ | 122 | err = tps6586x_set_bits(tps_dev, RTC_CTRL, RTC_ENABLE); |
133 | ret = tps6586x_set_bits(tps_dev, RTC_CTRL, RTC_ENABLE); | 123 | if (err < 0) { |
134 | if (ret < 0) { | ||
135 | dev_err(dev, "failed to set RTC_ENABLE\n"); | 124 | dev_err(dev, "failed to set RTC_ENABLE\n"); |
136 | return ret; | 125 | return err; |
137 | } | 126 | } |
138 | return 0; | ||
139 | } | ||
140 | 127 | ||
141 | static int tps6586x_rtc_alarm_irq_enable(struct device *dev, | ||
142 | unsigned int enabled) | ||
143 | { | ||
144 | struct tps6586x_rtc *rtc = dev_get_drvdata(dev); | ||
145 | |||
146 | if (enabled && !rtc->irq_en) { | ||
147 | enable_irq(rtc->irq); | ||
148 | rtc->irq_en = true; | ||
149 | } else if (!enabled && rtc->irq_en) { | ||
150 | disable_irq(rtc->irq); | ||
151 | rtc->irq_en = false; | ||
152 | } | ||
153 | return 0; | 128 | return 0; |
154 | } | 129 | } |
155 | 130 | ||
@@ -163,28 +138,33 @@ static int tps6586x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
163 | unsigned long long rticks = 0; | 138 | unsigned long long rticks = 0; |
164 | u8 buff[3]; | 139 | u8 buff[3]; |
165 | u8 rbuff[6]; | 140 | u8 rbuff[6]; |
166 | int ret; | 141 | int err; |
167 | int i; | 142 | int i; |
168 | 143 | ||
144 | if (rtc->irq == -1) | ||
145 | return -EIO; | ||
146 | |||
169 | rtc_tm_to_time(&alrm->time, &seconds); | 147 | rtc_tm_to_time(&alrm->time, &seconds); |
170 | 148 | ||
171 | if (alrm->enabled && (seconds < rtc->epoch_start)) { | 149 | if (WARN_ON(alrm->enabled && (seconds < rtc->epoch_start))) { |
172 | dev_err(dev, "can't set alarm to requested time\n"); | 150 | dev_err(dev, "can't set alarm to requested time\n"); |
173 | return -EINVAL; | 151 | return -EINVAL; |
174 | } | 152 | } |
175 | 153 | ||
176 | ret = tps6586x_rtc_alarm_irq_enable(dev, alrm->enabled); | 154 | if (alrm->enabled && !rtc->irq_en) { |
177 | if (ret < 0) { | 155 | enable_irq(rtc->irq); |
178 | dev_err(dev, "can't set alarm irq, err %d\n", ret); | 156 | rtc->irq_en = true; |
179 | return ret; | 157 | } else if (!alrm->enabled && rtc->irq_en) { |
158 | disable_irq(rtc->irq); | ||
159 | rtc->irq_en = false; | ||
180 | } | 160 | } |
181 | 161 | ||
182 | seconds -= rtc->epoch_start; | 162 | seconds -= rtc->epoch_start; |
183 | ret = tps6586x_reads(tps_dev, RTC_COUNT4_DUMMYREAD, | 163 | |
184 | sizeof(rbuff), rbuff); | 164 | err = tps6586x_reads(tps_dev, RTC_COUNT4_DUMMYREAD, sizeof(rbuff), rbuff); |
185 | if (ret < 0) { | 165 | if (err < 0) { |
186 | dev_err(dev, "read counter failed with err %d\n", ret); | 166 | dev_err(dev, "failed to read counter\n"); |
187 | return ret; | 167 | return err; |
188 | } | 168 | } |
189 | 169 | ||
190 | for (i = 1; i < sizeof(rbuff); i++) { | 170 | for (i = 1; i < sizeof(rbuff); i++) { |
@@ -197,15 +177,16 @@ static int tps6586x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
197 | seconds = rtc_current_time - 1; | 177 | seconds = rtc_current_time - 1; |
198 | 178 | ||
199 | ticks = (unsigned long long)seconds << 10; | 179 | ticks = (unsigned long long)seconds << 10; |
180 | |||
200 | buff[0] = (ticks >> 16) & 0xff; | 181 | buff[0] = (ticks >> 16) & 0xff; |
201 | buff[1] = (ticks >> 8) & 0xff; | 182 | buff[1] = (ticks >> 8) & 0xff; |
202 | buff[2] = ticks & 0xff; | 183 | buff[2] = ticks & 0xff; |
203 | 184 | ||
204 | ret = tps6586x_writes(tps_dev, RTC_ALARM1_HI, sizeof(buff), buff); | 185 | err = tps6586x_writes(tps_dev, RTC_ALARM1_HI, sizeof(buff), buff); |
205 | if (ret) | 186 | if (err) |
206 | dev_err(dev, "programming alarm failed with err %d\n", ret); | 187 | dev_err(tps_dev, "unable to program alarm\n"); |
207 | 188 | ||
208 | return ret; | 189 | return err; |
209 | } | 190 | } |
210 | 191 | ||
211 | static int tps6586x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | 192 | static int tps6586x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
@@ -215,19 +196,66 @@ static int tps6586x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
215 | unsigned long ticks; | 196 | unsigned long ticks; |
216 | unsigned long seconds; | 197 | unsigned long seconds; |
217 | u8 buff[3]; | 198 | u8 buff[3]; |
218 | int ret; | 199 | int err; |
219 | 200 | ||
220 | ret = tps6586x_reads(tps_dev, RTC_ALARM1_HI, sizeof(buff), buff); | 201 | err = tps6586x_reads(tps_dev, RTC_ALARM1_HI, sizeof(buff), buff); |
221 | if (ret) { | 202 | if (err) |
222 | dev_err(dev, "read RTC_ALARM1_HI failed with err %d\n", ret); | 203 | return err; |
223 | return ret; | ||
224 | } | ||
225 | 204 | ||
226 | ticks = (buff[0] << 16) | (buff[1] << 8) | buff[2]; | 205 | ticks = (buff[0] << 16) | (buff[1] << 8) | buff[2]; |
227 | seconds = ticks >> 10; | 206 | seconds = ticks >> 10; |
228 | seconds += rtc->epoch_start; | 207 | seconds += rtc->epoch_start; |
229 | 208 | ||
230 | rtc_time_to_tm(seconds, &alrm->time); | 209 | rtc_time_to_tm(seconds, &alrm->time); |
210 | |||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | static int tps6586x_rtc_alarm_irq_enable(struct device *dev, | ||
215 | unsigned int enabled) | ||
216 | { | ||
217 | struct tps6586x_rtc *rtc = dev_get_drvdata(dev); | ||
218 | struct device *tps_dev = to_tps6586x_dev(dev); | ||
219 | u8 buff; | ||
220 | int err; | ||
221 | |||
222 | if (rtc->irq == -1) | ||
223 | return -EIO; | ||
224 | |||
225 | err = tps6586x_read(tps_dev, RTC_CTRL, &buff); | ||
226 | if (err < 0) { | ||
227 | dev_err(dev, "failed to read RTC_CTRL\n"); | ||
228 | return err; | ||
229 | } | ||
230 | |||
231 | if ((enabled && (buff & RTC_ENABLE)) || | ||
232 | (!enabled && !(buff & RTC_ENABLE))) | ||
233 | return 0; | ||
234 | |||
235 | if (enabled) { | ||
236 | err = tps6586x_set_bits(tps_dev, RTC_CTRL, RTC_ENABLE); | ||
237 | if (err < 0) { | ||
238 | dev_err(dev, "failed to set RTC_ENABLE\n"); | ||
239 | return err; | ||
240 | } | ||
241 | |||
242 | if (!rtc->irq_en) { | ||
243 | enable_irq(rtc->irq); | ||
244 | rtc->irq_en = true; | ||
245 | } | ||
246 | } else { | ||
247 | err = tps6586x_clr_bits(tps_dev, RTC_CTRL, RTC_ENABLE); | ||
248 | if (err < 0) { | ||
249 | dev_err(dev, "failed to clear RTC_ENABLE\n"); | ||
250 | return err; | ||
251 | } | ||
252 | |||
253 | if (rtc->irq_en) { | ||
254 | disable_irq(rtc->irq); | ||
255 | rtc->irq_en = false; | ||
256 | } | ||
257 | } | ||
258 | |||
231 | return 0; | 259 | return 0; |
232 | } | 260 | } |
233 | 261 | ||
@@ -241,116 +269,119 @@ static const struct rtc_class_ops tps6586x_rtc_ops = { | |||
241 | 269 | ||
242 | static irqreturn_t tps6586x_rtc_irq(int irq, void *data) | 270 | static irqreturn_t tps6586x_rtc_irq(int irq, void *data) |
243 | { | 271 | { |
244 | struct tps6586x_rtc *rtc = data; | 272 | struct device *dev = data; |
273 | struct tps6586x_rtc *rtc = dev_get_drvdata(dev); | ||
245 | 274 | ||
246 | rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); | 275 | rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); |
247 | return IRQ_HANDLED; | 276 | return IRQ_HANDLED; |
248 | } | 277 | } |
249 | 278 | ||
250 | static int tps6586x_rtc_probe(struct platform_device *pdev) | 279 | static int __devinit tps6586x_rtc_probe(struct platform_device *pdev) |
251 | { | 280 | { |
281 | struct tps6586x_rtc_platform_data *pdata = pdev->dev.platform_data; | ||
252 | struct device *tps_dev = to_tps6586x_dev(&pdev->dev); | 282 | struct device *tps_dev = to_tps6586x_dev(&pdev->dev); |
253 | struct tps6586x_rtc *rtc; | 283 | struct tps6586x_rtc *rtc; |
254 | int ret; | 284 | int err; |
285 | struct tps6586x_epoch_start *epoch; | ||
286 | |||
287 | if (!pdata) { | ||
288 | dev_err(&pdev->dev, "no platform_data specified\n"); | ||
289 | return -EINVAL; | ||
290 | } | ||
291 | |||
292 | rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); | ||
255 | 293 | ||
256 | rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); | ||
257 | if (!rtc) | 294 | if (!rtc) |
258 | return -ENOMEM; | 295 | return -ENOMEM; |
259 | 296 | ||
260 | rtc->dev = &pdev->dev; | 297 | rtc->irq = -1; |
261 | rtc->irq = platform_get_irq(pdev, 0); | ||
262 | 298 | ||
263 | /* Set epoch start as 00:00:00:01:01:2009 */ | 299 | if (pdata->irq < 0) |
264 | rtc->epoch_start = mktime(2009, 1, 1, 0, 0, 0); | 300 | dev_warn(&pdev->dev, "no IRQ specified, wakeup is disabled\n"); |
265 | 301 | ||
266 | /* 1 kHz tick mode, enable tick counting */ | 302 | epoch = &pdata->start; |
267 | ret = tps6586x_update(tps_dev, RTC_CTRL, | 303 | rtc->epoch_start = mktime(epoch->year, epoch->month, epoch->day, |
268 | RTC_ENABLE | OSC_SRC_SEL | | 304 | epoch->hour, epoch->min, epoch->sec); |
269 | ((TPS6586X_RTC_CL_SEL_1_5PF << CL_SEL_POS) & CL_SEL_MASK), | 305 | |
270 | RTC_ENABLE | OSC_SRC_SEL | PRE_BYPASS | CL_SEL_MASK); | 306 | dev_set_drvdata(&pdev->dev, rtc); |
271 | if (ret < 0) { | ||
272 | dev_err(&pdev->dev, "unable to start counter\n"); | ||
273 | return ret; | ||
274 | } | ||
275 | 307 | ||
276 | platform_set_drvdata(pdev, rtc); | 308 | device_init_wakeup(&pdev->dev, 1); |
277 | rtc->rtc = rtc_device_register(dev_name(&pdev->dev), &pdev->dev, | 309 | |
310 | rtc->rtc = rtc_device_register("tps6586x-rtc", &pdev->dev, | ||
278 | &tps6586x_rtc_ops, THIS_MODULE); | 311 | &tps6586x_rtc_ops, THIS_MODULE); |
279 | if (IS_ERR(rtc->rtc)) { | ||
280 | ret = PTR_ERR(rtc->rtc); | ||
281 | dev_err(&pdev->dev, "RTC device register: ret %d\n", ret); | ||
282 | goto fail_rtc_register; | ||
283 | } | ||
284 | 312 | ||
285 | ret = request_threaded_irq(rtc->irq, NULL, tps6586x_rtc_irq, | 313 | if (IS_ERR(rtc->rtc)) { |
286 | IRQF_ONESHOT | IRQF_EARLY_RESUME, | 314 | err = PTR_ERR(rtc->rtc); |
287 | dev_name(&pdev->dev), rtc); | 315 | goto fail; |
288 | if (ret < 0) { | ||
289 | dev_err(&pdev->dev, "request IRQ(%d) failed with ret %d\n", | ||
290 | rtc->irq, ret); | ||
291 | goto fail_req_irq; | ||
292 | } | 316 | } |
293 | disable_irq(rtc->irq); | ||
294 | device_set_wakeup_capable(&pdev->dev, 1); | ||
295 | return 0; | ||
296 | |||
297 | fail_req_irq: | ||
298 | rtc_device_unregister(rtc->rtc); | ||
299 | 317 | ||
300 | fail_rtc_register: | 318 | /* 1 kHz tick mode, enable tick counting */ |
301 | tps6586x_update(tps_dev, RTC_CTRL, 0, | 319 | err = tps6586x_update(tps_dev, RTC_CTRL, |
320 | RTC_ENABLE | OSC_SRC_SEL | ((pdata->cl_sel << CL_SEL_POS) & | ||
321 | CL_SEL_MASK), | ||
302 | RTC_ENABLE | OSC_SRC_SEL | PRE_BYPASS | CL_SEL_MASK); | 322 | RTC_ENABLE | OSC_SRC_SEL | PRE_BYPASS | CL_SEL_MASK); |
303 | return ret; | 323 | if (err < 0) { |
304 | }; | 324 | dev_err(&pdev->dev, "unable to start counter\n"); |
325 | goto fail; | ||
326 | } | ||
305 | 327 | ||
306 | static int tps6586x_rtc_remove(struct platform_device *pdev) | 328 | if (pdata && (pdata->irq >= 0)) { |
307 | { | 329 | rtc->irq = pdata->irq; |
308 | struct tps6586x_rtc *rtc = platform_get_drvdata(pdev); | 330 | err = request_threaded_irq(pdata->irq, NULL, tps6586x_rtc_irq, |
309 | struct device *tps_dev = to_tps6586x_dev(&pdev->dev); | 331 | IRQF_ONESHOT, "tps6586x-rtc", |
332 | &pdev->dev); | ||
333 | if (err) { | ||
334 | dev_warn(&pdev->dev, "unable to request IRQ(%d)\n", rtc->irq); | ||
335 | rtc->irq = -1; | ||
336 | } else { | ||
337 | enable_irq_wake(rtc->irq); | ||
338 | disable_irq(rtc->irq); | ||
339 | } | ||
340 | } | ||
310 | 341 | ||
311 | tps6586x_update(tps_dev, RTC_CTRL, 0, | ||
312 | RTC_ENABLE | OSC_SRC_SEL | PRE_BYPASS | CL_SEL_MASK); | ||
313 | rtc_device_unregister(rtc->rtc); | ||
314 | free_irq(rtc->irq, rtc); | ||
315 | return 0; | 342 | return 0; |
316 | } | ||
317 | 343 | ||
318 | #ifdef CONFIG_PM_SLEEP | 344 | fail: |
319 | static int tps6586x_rtc_suspend(struct device *dev) | 345 | if (!IS_ERR_OR_NULL(rtc->rtc)) |
320 | { | 346 | rtc_device_unregister(rtc->rtc); |
321 | struct tps6586x_rtc *rtc = dev_get_drvdata(dev); | 347 | device_init_wakeup(&pdev->dev, 0); |
322 | 348 | kfree(rtc); | |
323 | if (device_may_wakeup(dev)) | 349 | return err; |
324 | enable_irq_wake(rtc->irq); | ||
325 | return 0; | ||
326 | } | 350 | } |
327 | 351 | ||
328 | static int tps6586x_rtc_resume(struct device *dev) | 352 | static int __devexit tps6586x_rtc_remove(struct platform_device *pdev) |
329 | { | 353 | { |
330 | struct tps6586x_rtc *rtc = dev_get_drvdata(dev); | 354 | struct tps6586x_rtc *rtc = dev_get_drvdata(&pdev->dev); |
331 | 355 | ||
332 | if (device_may_wakeup(dev)) | 356 | if (rtc->irq != -1) |
333 | disable_irq_wake(rtc->irq); | 357 | free_irq(rtc->irq, rtc); |
358 | rtc_device_unregister(rtc->rtc); | ||
359 | kfree(rtc); | ||
334 | return 0; | 360 | return 0; |
335 | } | 361 | } |
336 | #endif | ||
337 | |||
338 | static const struct dev_pm_ops tps6586x_pm_ops = { | ||
339 | SET_SYSTEM_SLEEP_PM_OPS(tps6586x_rtc_suspend, tps6586x_rtc_resume) | ||
340 | }; | ||
341 | 362 | ||
342 | static struct platform_driver tps6586x_rtc_driver = { | 363 | static struct platform_driver tps6586x_rtc_driver = { |
343 | .driver = { | 364 | .driver = { |
344 | .name = "tps6586x-rtc", | 365 | .name = "tps6586x-rtc", |
345 | .owner = THIS_MODULE, | 366 | .owner = THIS_MODULE, |
346 | .pm = &tps6586x_pm_ops, | ||
347 | }, | 367 | }, |
348 | .probe = tps6586x_rtc_probe, | 368 | .probe = tps6586x_rtc_probe, |
349 | .remove = tps6586x_rtc_remove, | 369 | .remove = __devexit_p(tps6586x_rtc_remove), |
350 | }; | 370 | }; |
351 | module_platform_driver(tps6586x_rtc_driver); | ||
352 | 371 | ||
353 | MODULE_ALIAS("platform:rtc-tps6586x"); | 372 | static int __init tps6586x_rtc_init(void) |
373 | { | ||
374 | return platform_driver_register(&tps6586x_rtc_driver); | ||
375 | } | ||
376 | module_init(tps6586x_rtc_init); | ||
377 | |||
378 | static void __exit tps6586x_rtc_exit(void) | ||
379 | { | ||
380 | platform_driver_unregister(&tps6586x_rtc_driver); | ||
381 | } | ||
382 | module_exit(tps6586x_rtc_exit); | ||
383 | |||
354 | MODULE_DESCRIPTION("TI TPS6586x RTC driver"); | 384 | MODULE_DESCRIPTION("TI TPS6586x RTC driver"); |
355 | MODULE_AUTHOR("Laxman dewangan <ldewangan@nvidia.com>"); | 385 | MODULE_AUTHOR("NVIDIA Corporation"); |
356 | MODULE_LICENSE("GPL v2"); | 386 | MODULE_LICENSE("GPL"); |
387 | MODULE_ALIAS("platform:rtc-tps6586x"); | ||
diff --git a/drivers/rtc/rtc-tps65910.c b/drivers/rtc/rtc-tps65910.c deleted file mode 100644 index e5fef141a0e..00000000000 --- a/drivers/rtc/rtc-tps65910.c +++ /dev/null | |||
@@ -1,356 +0,0 @@ | |||
1 | /* | ||
2 | * rtc-tps65910.c -- TPS65910 Real Time Clock interface | ||
3 | * | ||
4 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
5 | * Author: Venu Byravarasu <vbyravarasu@nvidia.com> | ||
6 | * | ||
7 | * Based on original TI driver rtc-twl.c | ||
8 | * Copyright (C) 2007 MontaVista Software, Inc | ||
9 | * Author: Alexandre Rusev <source@mvista.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * as published by the Free Software Foundation; either version | ||
14 | * 2 of the License, or (at your option) any later version. | ||
15 | */ | ||
16 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/types.h> | ||
22 | #include <linux/rtc.h> | ||
23 | #include <linux/bcd.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/mfd/tps65910.h> | ||
27 | |||
28 | struct tps65910_rtc { | ||
29 | struct rtc_device *rtc; | ||
30 | /* To store the list of enabled interrupts */ | ||
31 | u32 irqstat; | ||
32 | }; | ||
33 | |||
34 | /* Total number of RTC registers needed to set time*/ | ||
35 | #define NUM_TIME_REGS (TPS65910_YEARS - TPS65910_SECONDS + 1) | ||
36 | |||
37 | static int tps65910_rtc_alarm_irq_enable(struct device *dev, unsigned enabled) | ||
38 | { | ||
39 | struct tps65910 *tps = dev_get_drvdata(dev->parent); | ||
40 | u8 val = 0; | ||
41 | |||
42 | if (enabled) | ||
43 | val = TPS65910_RTC_INTERRUPTS_IT_ALARM; | ||
44 | |||
45 | return regmap_write(tps->regmap, TPS65910_RTC_INTERRUPTS, val); | ||
46 | } | ||
47 | |||
48 | /* | ||
49 | * Gets current tps65910 RTC time and date parameters. | ||
50 | * | ||
51 | * The RTC's time/alarm representation is not what gmtime(3) requires | ||
52 | * Linux to use: | ||
53 | * | ||
54 | * - Months are 1..12 vs Linux 0-11 | ||
55 | * - Years are 0..99 vs Linux 1900..N (we assume 21st century) | ||
56 | */ | ||
57 | static int tps65910_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
58 | { | ||
59 | unsigned char rtc_data[NUM_TIME_REGS]; | ||
60 | struct tps65910 *tps = dev_get_drvdata(dev->parent); | ||
61 | int ret; | ||
62 | |||
63 | /* Copy RTC counting registers to static registers or latches */ | ||
64 | ret = regmap_update_bits(tps->regmap, TPS65910_RTC_CTRL, | ||
65 | TPS65910_RTC_CTRL_GET_TIME, TPS65910_RTC_CTRL_GET_TIME); | ||
66 | if (ret < 0) { | ||
67 | dev_err(dev, "RTC CTRL reg update failed with err:%d\n", ret); | ||
68 | return ret; | ||
69 | } | ||
70 | |||
71 | ret = regmap_bulk_read(tps->regmap, TPS65910_SECONDS, rtc_data, | ||
72 | NUM_TIME_REGS); | ||
73 | if (ret < 0) { | ||
74 | dev_err(dev, "reading from RTC failed with err:%d\n", ret); | ||
75 | return ret; | ||
76 | } | ||
77 | |||
78 | tm->tm_sec = bcd2bin(rtc_data[0]); | ||
79 | tm->tm_min = bcd2bin(rtc_data[1]); | ||
80 | tm->tm_hour = bcd2bin(rtc_data[2]); | ||
81 | tm->tm_mday = bcd2bin(rtc_data[3]); | ||
82 | tm->tm_mon = bcd2bin(rtc_data[4]) - 1; | ||
83 | tm->tm_year = bcd2bin(rtc_data[5]) + 100; | ||
84 | |||
85 | return ret; | ||
86 | } | ||
87 | |||
88 | static int tps65910_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
89 | { | ||
90 | unsigned char rtc_data[NUM_TIME_REGS]; | ||
91 | struct tps65910 *tps = dev_get_drvdata(dev->parent); | ||
92 | int ret; | ||
93 | |||
94 | rtc_data[0] = bin2bcd(tm->tm_sec); | ||
95 | rtc_data[1] = bin2bcd(tm->tm_min); | ||
96 | rtc_data[2] = bin2bcd(tm->tm_hour); | ||
97 | rtc_data[3] = bin2bcd(tm->tm_mday); | ||
98 | rtc_data[4] = bin2bcd(tm->tm_mon + 1); | ||
99 | rtc_data[5] = bin2bcd(tm->tm_year - 100); | ||
100 | |||
101 | /* Stop RTC while updating the RTC time registers */ | ||
102 | ret = regmap_update_bits(tps->regmap, TPS65910_RTC_CTRL, | ||
103 | TPS65910_RTC_CTRL_STOP_RTC, 0); | ||
104 | if (ret < 0) { | ||
105 | dev_err(dev, "RTC stop failed with err:%d\n", ret); | ||
106 | return ret; | ||
107 | } | ||
108 | |||
109 | /* update all the time registers in one shot */ | ||
110 | ret = regmap_bulk_write(tps->regmap, TPS65910_SECONDS, rtc_data, | ||
111 | NUM_TIME_REGS); | ||
112 | if (ret < 0) { | ||
113 | dev_err(dev, "rtc_set_time error %d\n", ret); | ||
114 | return ret; | ||
115 | } | ||
116 | |||
117 | /* Start back RTC */ | ||
118 | ret = regmap_update_bits(tps->regmap, TPS65910_RTC_CTRL, | ||
119 | TPS65910_RTC_CTRL_STOP_RTC, 1); | ||
120 | if (ret < 0) | ||
121 | dev_err(dev, "RTC start failed with err:%d\n", ret); | ||
122 | |||
123 | return ret; | ||
124 | } | ||
125 | |||
126 | /* | ||
127 | * Gets current tps65910 RTC alarm time. | ||
128 | */ | ||
129 | static int tps65910_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | ||
130 | { | ||
131 | unsigned char alarm_data[NUM_TIME_REGS]; | ||
132 | u32 int_val; | ||
133 | struct tps65910 *tps = dev_get_drvdata(dev->parent); | ||
134 | int ret; | ||
135 | |||
136 | ret = regmap_bulk_read(tps->regmap, TPS65910_SECONDS, alarm_data, | ||
137 | NUM_TIME_REGS); | ||
138 | if (ret < 0) { | ||
139 | dev_err(dev, "rtc_read_alarm error %d\n", ret); | ||
140 | return ret; | ||
141 | } | ||
142 | |||
143 | alm->time.tm_sec = bcd2bin(alarm_data[0]); | ||
144 | alm->time.tm_min = bcd2bin(alarm_data[1]); | ||
145 | alm->time.tm_hour = bcd2bin(alarm_data[2]); | ||
146 | alm->time.tm_mday = bcd2bin(alarm_data[3]); | ||
147 | alm->time.tm_mon = bcd2bin(alarm_data[4]) - 1; | ||
148 | alm->time.tm_year = bcd2bin(alarm_data[5]) + 100; | ||
149 | |||
150 | ret = regmap_read(tps->regmap, TPS65910_RTC_INTERRUPTS, &int_val); | ||
151 | if (ret < 0) | ||
152 | return ret; | ||
153 | |||
154 | if (int_val & TPS65910_RTC_INTERRUPTS_IT_ALARM) | ||
155 | alm->enabled = 1; | ||
156 | |||
157 | return ret; | ||
158 | } | ||
159 | |||
160 | static int tps65910_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | ||
161 | { | ||
162 | unsigned char alarm_data[NUM_TIME_REGS]; | ||
163 | struct tps65910 *tps = dev_get_drvdata(dev->parent); | ||
164 | int ret; | ||
165 | |||
166 | ret = tps65910_rtc_alarm_irq_enable(dev, 0); | ||
167 | if (ret) | ||
168 | return ret; | ||
169 | |||
170 | alarm_data[0] = bin2bcd(alm->time.tm_sec); | ||
171 | alarm_data[1] = bin2bcd(alm->time.tm_min); | ||
172 | alarm_data[2] = bin2bcd(alm->time.tm_hour); | ||
173 | alarm_data[3] = bin2bcd(alm->time.tm_mday); | ||
174 | alarm_data[4] = bin2bcd(alm->time.tm_mon + 1); | ||
175 | alarm_data[5] = bin2bcd(alm->time.tm_year - 100); | ||
176 | |||
177 | /* update all the alarm registers in one shot */ | ||
178 | ret = regmap_bulk_write(tps->regmap, TPS65910_ALARM_SECONDS, | ||
179 | alarm_data, NUM_TIME_REGS); | ||
180 | if (ret) { | ||
181 | dev_err(dev, "rtc_set_alarm error %d\n", ret); | ||
182 | return ret; | ||
183 | } | ||
184 | |||
185 | if (alm->enabled) | ||
186 | ret = tps65910_rtc_alarm_irq_enable(dev, 1); | ||
187 | |||
188 | return ret; | ||
189 | } | ||
190 | |||
191 | static irqreturn_t tps65910_rtc_interrupt(int irq, void *rtc) | ||
192 | { | ||
193 | struct device *dev = rtc; | ||
194 | unsigned long events = 0; | ||
195 | struct tps65910 *tps = dev_get_drvdata(dev->parent); | ||
196 | struct tps65910_rtc *tps_rtc = dev_get_drvdata(dev); | ||
197 | int ret; | ||
198 | u32 rtc_reg; | ||
199 | |||
200 | ret = regmap_read(tps->regmap, TPS65910_RTC_STATUS, &rtc_reg); | ||
201 | if (ret) | ||
202 | return IRQ_NONE; | ||
203 | |||
204 | if (rtc_reg & TPS65910_RTC_STATUS_ALARM) | ||
205 | events = RTC_IRQF | RTC_AF; | ||
206 | |||
207 | ret = regmap_write(tps->regmap, TPS65910_RTC_STATUS, rtc_reg); | ||
208 | if (ret) | ||
209 | return IRQ_NONE; | ||
210 | |||
211 | /* Notify RTC core on event */ | ||
212 | rtc_update_irq(tps_rtc->rtc, 1, events); | ||
213 | |||
214 | return IRQ_HANDLED; | ||
215 | } | ||
216 | |||
217 | static const struct rtc_class_ops tps65910_rtc_ops = { | ||
218 | .read_time = tps65910_rtc_read_time, | ||
219 | .set_time = tps65910_rtc_set_time, | ||
220 | .read_alarm = tps65910_rtc_read_alarm, | ||
221 | .set_alarm = tps65910_rtc_set_alarm, | ||
222 | .alarm_irq_enable = tps65910_rtc_alarm_irq_enable, | ||
223 | }; | ||
224 | |||
225 | static int tps65910_rtc_probe(struct platform_device *pdev) | ||
226 | { | ||
227 | struct tps65910 *tps65910 = NULL; | ||
228 | struct tps65910_rtc *tps_rtc = NULL; | ||
229 | int ret; | ||
230 | int irq; | ||
231 | u32 rtc_reg; | ||
232 | |||
233 | tps65910 = dev_get_drvdata(pdev->dev.parent); | ||
234 | |||
235 | tps_rtc = devm_kzalloc(&pdev->dev, sizeof(struct tps65910_rtc), | ||
236 | GFP_KERNEL); | ||
237 | if (!tps_rtc) | ||
238 | return -ENOMEM; | ||
239 | |||
240 | /* Clear pending interrupts */ | ||
241 | ret = regmap_read(tps65910->regmap, TPS65910_RTC_STATUS, &rtc_reg); | ||
242 | if (ret < 0) | ||
243 | return ret; | ||
244 | |||
245 | ret = regmap_write(tps65910->regmap, TPS65910_RTC_STATUS, rtc_reg); | ||
246 | if (ret < 0) | ||
247 | return ret; | ||
248 | |||
249 | dev_dbg(&pdev->dev, "Enabling rtc-tps65910.\n"); | ||
250 | |||
251 | /* Enable RTC digital power domain */ | ||
252 | ret = regmap_update_bits(tps65910->regmap, TPS65910_DEVCTRL, | ||
253 | DEVCTRL_RTC_PWDN_MASK, 0 << DEVCTRL_RTC_PWDN_SHIFT); | ||
254 | if (ret < 0) | ||
255 | return ret; | ||
256 | |||
257 | rtc_reg = TPS65910_RTC_CTRL_STOP_RTC; | ||
258 | ret = regmap_write(tps65910->regmap, TPS65910_RTC_CTRL, rtc_reg); | ||
259 | if (ret < 0) | ||
260 | return ret; | ||
261 | |||
262 | irq = platform_get_irq(pdev, 0); | ||
263 | if (irq <= 0) { | ||
264 | dev_warn(&pdev->dev, "Wake up is not possible as irq = %d\n", | ||
265 | irq); | ||
266 | return ret; | ||
267 | } | ||
268 | |||
269 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, | ||
270 | tps65910_rtc_interrupt, IRQF_TRIGGER_LOW, | ||
271 | dev_name(&pdev->dev), &pdev->dev); | ||
272 | if (ret < 0) { | ||
273 | dev_err(&pdev->dev, "IRQ is not free.\n"); | ||
274 | return ret; | ||
275 | } | ||
276 | device_init_wakeup(&pdev->dev, 1); | ||
277 | |||
278 | tps_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, | ||
279 | &tps65910_rtc_ops, THIS_MODULE); | ||
280 | if (IS_ERR(tps_rtc->rtc)) { | ||
281 | ret = PTR_ERR(tps_rtc->rtc); | ||
282 | dev_err(&pdev->dev, "RTC device register: err %d\n", ret); | ||
283 | return ret; | ||
284 | } | ||
285 | |||
286 | platform_set_drvdata(pdev, tps_rtc); | ||
287 | |||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * Disable tps65910 RTC interrupts. | ||
293 | * Sets status flag to free. | ||
294 | */ | ||
295 | static int tps65910_rtc_remove(struct platform_device *pdev) | ||
296 | { | ||
297 | /* leave rtc running, but disable irqs */ | ||
298 | struct tps65910_rtc *tps_rtc = platform_get_drvdata(pdev); | ||
299 | |||
300 | tps65910_rtc_alarm_irq_enable(&pdev->dev, 0); | ||
301 | |||
302 | rtc_device_unregister(tps_rtc->rtc); | ||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | #ifdef CONFIG_PM_SLEEP | ||
307 | |||
308 | static int tps65910_rtc_suspend(struct device *dev) | ||
309 | { | ||
310 | struct tps65910 *tps = dev_get_drvdata(dev->parent); | ||
311 | u8 alarm = TPS65910_RTC_INTERRUPTS_IT_ALARM; | ||
312 | int ret; | ||
313 | |||
314 | /* Store current list of enabled interrupts*/ | ||
315 | ret = regmap_read(tps->regmap, TPS65910_RTC_INTERRUPTS, | ||
316 | &tps->rtc->irqstat); | ||
317 | if (ret < 0) | ||
318 | return ret; | ||
319 | |||
320 | /* Enable RTC ALARM interrupt only */ | ||
321 | return regmap_write(tps->regmap, TPS65910_RTC_INTERRUPTS, alarm); | ||
322 | } | ||
323 | |||
324 | static int tps65910_rtc_resume(struct device *dev) | ||
325 | { | ||
326 | struct tps65910 *tps = dev_get_drvdata(dev->parent); | ||
327 | |||
328 | /* Restore list of enabled interrupts before suspend */ | ||
329 | return regmap_write(tps->regmap, TPS65910_RTC_INTERRUPTS, | ||
330 | tps->rtc->irqstat); | ||
331 | } | ||
332 | |||
333 | static const struct dev_pm_ops tps65910_rtc_pm_ops = { | ||
334 | .suspend = tps65910_rtc_suspend, | ||
335 | .resume = tps65910_rtc_resume, | ||
336 | }; | ||
337 | |||
338 | #define DEV_PM_OPS (&tps65910_rtc_pm_ops) | ||
339 | #else | ||
340 | #define DEV_PM_OPS NULL | ||
341 | #endif | ||
342 | |||
343 | static struct platform_driver tps65910_rtc_driver = { | ||
344 | .probe = tps65910_rtc_probe, | ||
345 | .remove = tps65910_rtc_remove, | ||
346 | .driver = { | ||
347 | .owner = THIS_MODULE, | ||
348 | .name = "tps65910-rtc", | ||
349 | .pm = DEV_PM_OPS, | ||
350 | }, | ||
351 | }; | ||
352 | |||
353 | module_platform_driver(tps65910_rtc_driver); | ||
354 | MODULE_ALIAS("platform:rtc-tps65910"); | ||
355 | MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>"); | ||
356 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index ccd4ad370b3..20687d55e7a 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c | |||
@@ -112,7 +112,6 @@ static const u8 twl6030_rtc_reg_map[] = { | |||
112 | #define BIT_RTC_CTRL_REG_TEST_MODE_M 0x10 | 112 | #define BIT_RTC_CTRL_REG_TEST_MODE_M 0x10 |
113 | #define BIT_RTC_CTRL_REG_SET_32_COUNTER_M 0x20 | 113 | #define BIT_RTC_CTRL_REG_SET_32_COUNTER_M 0x20 |
114 | #define BIT_RTC_CTRL_REG_GET_TIME_M 0x40 | 114 | #define BIT_RTC_CTRL_REG_GET_TIME_M 0x40 |
115 | #define BIT_RTC_CTRL_REG_RTC_V_OPT 0x80 | ||
116 | 115 | ||
117 | /* RTC_STATUS_REG bitfields */ | 116 | /* RTC_STATUS_REG bitfields */ |
118 | #define BIT_RTC_STATUS_REG_RUN_M 0x02 | 117 | #define BIT_RTC_STATUS_REG_RUN_M 0x02 |
@@ -177,10 +176,6 @@ static int set_rtc_irq_bit(unsigned char bit) | |||
177 | unsigned char val; | 176 | unsigned char val; |
178 | int ret; | 177 | int ret; |
179 | 178 | ||
180 | /* if the bit is set, return from here */ | ||
181 | if (rtc_irq_bits & bit) | ||
182 | return 0; | ||
183 | |||
184 | val = rtc_irq_bits | bit; | 179 | val = rtc_irq_bits | bit; |
185 | val &= ~BIT_RTC_INTERRUPTS_REG_EVERY_M; | 180 | val &= ~BIT_RTC_INTERRUPTS_REG_EVERY_M; |
186 | ret = twl_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG); | 181 | ret = twl_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG); |
@@ -198,10 +193,6 @@ static int mask_rtc_irq_bit(unsigned char bit) | |||
198 | unsigned char val; | 193 | unsigned char val; |
199 | int ret; | 194 | int ret; |
200 | 195 | ||
201 | /* if the bit is clear, return from here */ | ||
202 | if (!(rtc_irq_bits & bit)) | ||
203 | return 0; | ||
204 | |||
205 | val = rtc_irq_bits & ~bit; | 196 | val = rtc_irq_bits & ~bit; |
206 | ret = twl_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG); | 197 | ret = twl_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG); |
207 | if (ret == 0) | 198 | if (ret == 0) |
@@ -233,60 +224,28 @@ static int twl_rtc_alarm_irq_enable(struct device *dev, unsigned enabled) | |||
233 | */ | 224 | */ |
234 | static int twl_rtc_read_time(struct device *dev, struct rtc_time *tm) | 225 | static int twl_rtc_read_time(struct device *dev, struct rtc_time *tm) |
235 | { | 226 | { |
236 | unsigned char rtc_data[ALL_TIME_REGS]; | 227 | unsigned char rtc_data[ALL_TIME_REGS + 1]; |
237 | int ret; | 228 | int ret; |
238 | u8 save_control; | 229 | u8 save_control; |
239 | u8 rtc_control; | ||
240 | 230 | ||
241 | ret = twl_rtc_read_u8(&save_control, REG_RTC_CTRL_REG); | 231 | ret = twl_rtc_read_u8(&save_control, REG_RTC_CTRL_REG); |
242 | if (ret < 0) { | 232 | if (ret < 0) |
243 | dev_err(dev, "%s: reading CTRL_REG, error %d\n", __func__, ret); | ||
244 | return ret; | 233 | return ret; |
245 | } | ||
246 | /* for twl6030/32 make sure BIT_RTC_CTRL_REG_GET_TIME_M is clear */ | ||
247 | if (twl_class_is_6030()) { | ||
248 | if (save_control & BIT_RTC_CTRL_REG_GET_TIME_M) { | ||
249 | save_control &= ~BIT_RTC_CTRL_REG_GET_TIME_M; | ||
250 | ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG); | ||
251 | if (ret < 0) { | ||
252 | dev_err(dev, "%s clr GET_TIME, error %d\n", | ||
253 | __func__, ret); | ||
254 | return ret; | ||
255 | } | ||
256 | } | ||
257 | } | ||
258 | 234 | ||
259 | /* Copy RTC counting registers to static registers or latches */ | 235 | save_control |= BIT_RTC_CTRL_REG_GET_TIME_M; |
260 | rtc_control = save_control | BIT_RTC_CTRL_REG_GET_TIME_M; | ||
261 | 236 | ||
262 | /* for twl6030/32 enable read access to static shadowed registers */ | 237 | ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG); |
263 | if (twl_class_is_6030()) | 238 | if (ret < 0) |
264 | rtc_control |= BIT_RTC_CTRL_REG_RTC_V_OPT; | ||
265 | |||
266 | ret = twl_rtc_write_u8(rtc_control, REG_RTC_CTRL_REG); | ||
267 | if (ret < 0) { | ||
268 | dev_err(dev, "%s: writing CTRL_REG, error %d\n", __func__, ret); | ||
269 | return ret; | 239 | return ret; |
270 | } | ||
271 | 240 | ||
272 | ret = twl_i2c_read(TWL_MODULE_RTC, rtc_data, | 241 | ret = twl_i2c_read(TWL_MODULE_RTC, rtc_data, |
273 | (rtc_reg_map[REG_SECONDS_REG]), ALL_TIME_REGS); | 242 | (rtc_reg_map[REG_SECONDS_REG]), ALL_TIME_REGS); |
274 | 243 | ||
275 | if (ret < 0) { | 244 | if (ret < 0) { |
276 | dev_err(dev, "%s: reading data, error %d\n", __func__, ret); | 245 | dev_err(dev, "rtc_read_time error %d\n", ret); |
277 | return ret; | 246 | return ret; |
278 | } | 247 | } |
279 | 248 | ||
280 | /* for twl6030 restore original state of rtc control register */ | ||
281 | if (twl_class_is_6030()) { | ||
282 | ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG); | ||
283 | if (ret < 0) { | ||
284 | dev_err(dev, "%s: restore CTRL_REG, error %d\n", | ||
285 | __func__, ret); | ||
286 | return ret; | ||
287 | } | ||
288 | } | ||
289 | |||
290 | tm->tm_sec = bcd2bin(rtc_data[0]); | 249 | tm->tm_sec = bcd2bin(rtc_data[0]); |
291 | tm->tm_min = bcd2bin(rtc_data[1]); | 250 | tm->tm_min = bcd2bin(rtc_data[1]); |
292 | tm->tm_hour = bcd2bin(rtc_data[2]); | 251 | tm->tm_hour = bcd2bin(rtc_data[2]); |
@@ -300,15 +259,15 @@ static int twl_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
300 | static int twl_rtc_set_time(struct device *dev, struct rtc_time *tm) | 259 | static int twl_rtc_set_time(struct device *dev, struct rtc_time *tm) |
301 | { | 260 | { |
302 | unsigned char save_control; | 261 | unsigned char save_control; |
303 | unsigned char rtc_data[ALL_TIME_REGS]; | 262 | unsigned char rtc_data[ALL_TIME_REGS + 1]; |
304 | int ret; | 263 | int ret; |
305 | 264 | ||
306 | rtc_data[0] = bin2bcd(tm->tm_sec); | 265 | rtc_data[1] = bin2bcd(tm->tm_sec); |
307 | rtc_data[1] = bin2bcd(tm->tm_min); | 266 | rtc_data[2] = bin2bcd(tm->tm_min); |
308 | rtc_data[2] = bin2bcd(tm->tm_hour); | 267 | rtc_data[3] = bin2bcd(tm->tm_hour); |
309 | rtc_data[3] = bin2bcd(tm->tm_mday); | 268 | rtc_data[4] = bin2bcd(tm->tm_mday); |
310 | rtc_data[4] = bin2bcd(tm->tm_mon + 1); | 269 | rtc_data[5] = bin2bcd(tm->tm_mon + 1); |
311 | rtc_data[5] = bin2bcd(tm->tm_year - 100); | 270 | rtc_data[6] = bin2bcd(tm->tm_year - 100); |
312 | 271 | ||
313 | /* Stop RTC while updating the TC registers */ | 272 | /* Stop RTC while updating the TC registers */ |
314 | ret = twl_rtc_read_u8(&save_control, REG_RTC_CTRL_REG); | 273 | ret = twl_rtc_read_u8(&save_control, REG_RTC_CTRL_REG); |
@@ -341,7 +300,7 @@ out: | |||
341 | */ | 300 | */ |
342 | static int twl_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | 301 | static int twl_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) |
343 | { | 302 | { |
344 | unsigned char rtc_data[ALL_TIME_REGS]; | 303 | unsigned char rtc_data[ALL_TIME_REGS + 1]; |
345 | int ret; | 304 | int ret; |
346 | 305 | ||
347 | ret = twl_i2c_read(TWL_MODULE_RTC, rtc_data, | 306 | ret = twl_i2c_read(TWL_MODULE_RTC, rtc_data, |
@@ -368,19 +327,19 @@ static int twl_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
368 | 327 | ||
369 | static int twl_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | 328 | static int twl_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) |
370 | { | 329 | { |
371 | unsigned char alarm_data[ALL_TIME_REGS]; | 330 | unsigned char alarm_data[ALL_TIME_REGS + 1]; |
372 | int ret; | 331 | int ret; |
373 | 332 | ||
374 | ret = twl_rtc_alarm_irq_enable(dev, 0); | 333 | ret = twl_rtc_alarm_irq_enable(dev, 0); |
375 | if (ret) | 334 | if (ret) |
376 | goto out; | 335 | goto out; |
377 | 336 | ||
378 | alarm_data[0] = bin2bcd(alm->time.tm_sec); | 337 | alarm_data[1] = bin2bcd(alm->time.tm_sec); |
379 | alarm_data[1] = bin2bcd(alm->time.tm_min); | 338 | alarm_data[2] = bin2bcd(alm->time.tm_min); |
380 | alarm_data[2] = bin2bcd(alm->time.tm_hour); | 339 | alarm_data[3] = bin2bcd(alm->time.tm_hour); |
381 | alarm_data[3] = bin2bcd(alm->time.tm_mday); | 340 | alarm_data[4] = bin2bcd(alm->time.tm_mday); |
382 | alarm_data[4] = bin2bcd(alm->time.tm_mon + 1); | 341 | alarm_data[5] = bin2bcd(alm->time.tm_mon + 1); |
383 | alarm_data[5] = bin2bcd(alm->time.tm_year - 100); | 342 | alarm_data[6] = bin2bcd(alm->time.tm_year - 100); |
384 | 343 | ||
385 | /* update all the alarm registers in one shot */ | 344 | /* update all the alarm registers in one shot */ |
386 | ret = twl_i2c_write(TWL_MODULE_RTC, alarm_data, | 345 | ret = twl_i2c_write(TWL_MODULE_RTC, alarm_data, |
@@ -398,7 +357,7 @@ out: | |||
398 | 357 | ||
399 | static irqreturn_t twl_rtc_interrupt(int irq, void *rtc) | 358 | static irqreturn_t twl_rtc_interrupt(int irq, void *rtc) |
400 | { | 359 | { |
401 | unsigned long events; | 360 | unsigned long events = 0; |
402 | int ret = IRQ_NONE; | 361 | int ret = IRQ_NONE; |
403 | int res; | 362 | int res; |
404 | u8 rd_reg; | 363 | u8 rd_reg; |
@@ -413,11 +372,11 @@ static irqreturn_t twl_rtc_interrupt(int irq, void *rtc) | |||
413 | * by reading RTS_INTERRUPTS_REGISTER[IT_TIMER,IT_ALARM] | 372 | * by reading RTS_INTERRUPTS_REGISTER[IT_TIMER,IT_ALARM] |
414 | */ | 373 | */ |
415 | if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M) | 374 | if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M) |
416 | events = RTC_IRQF | RTC_AF; | 375 | events |= RTC_IRQF | RTC_AF; |
417 | else | 376 | else |
418 | events = RTC_IRQF | RTC_PF; | 377 | events |= RTC_IRQF | RTC_UF; |
419 | 378 | ||
420 | res = twl_rtc_write_u8(BIT_RTC_STATUS_REG_ALARM_M, | 379 | res = twl_rtc_write_u8(rd_reg | BIT_RTC_STATUS_REG_ALARM_M, |
421 | REG_RTC_STATUS_REG); | 380 | REG_RTC_STATUS_REG); |
422 | if (res) | 381 | if (res) |
423 | goto out; | 382 | goto out; |
@@ -458,7 +417,7 @@ static struct rtc_class_ops twl_rtc_ops = { | |||
458 | 417 | ||
459 | /*----------------------------------------------------------------------*/ | 418 | /*----------------------------------------------------------------------*/ |
460 | 419 | ||
461 | static int twl_rtc_probe(struct platform_device *pdev) | 420 | static int __devinit twl_rtc_probe(struct platform_device *pdev) |
462 | { | 421 | { |
463 | struct rtc_device *rtc; | 422 | struct rtc_device *rtc; |
464 | int ret = -EINVAL; | 423 | int ret = -EINVAL; |
@@ -490,15 +449,18 @@ static int twl_rtc_probe(struct platform_device *pdev) | |||
490 | REG_INT_MSK_STS_A); | 449 | REG_INT_MSK_STS_A); |
491 | } | 450 | } |
492 | 451 | ||
493 | dev_info(&pdev->dev, "Enabling TWL-RTC\n"); | 452 | /* Check RTC module status, Enable if it is off */ |
494 | ret = twl_rtc_write_u8(BIT_RTC_CTRL_REG_STOP_RTC_M, REG_RTC_CTRL_REG); | 453 | ret = twl_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG); |
495 | if (ret < 0) | 454 | if (ret < 0) |
496 | goto out1; | 455 | goto out1; |
497 | 456 | ||
498 | /* ensure interrupts are disabled, bootloaders can be strange */ | 457 | if (!(rd_reg & BIT_RTC_CTRL_REG_STOP_RTC_M)) { |
499 | ret = twl_rtc_write_u8(0, REG_RTC_INTERRUPTS_REG); | 458 | dev_info(&pdev->dev, "Enabling TWL-RTC.\n"); |
500 | if (ret < 0) | 459 | rd_reg = BIT_RTC_CTRL_REG_STOP_RTC_M; |
501 | dev_warn(&pdev->dev, "unable to disable interrupt\n"); | 460 | ret = twl_rtc_write_u8(rd_reg, REG_RTC_CTRL_REG); |
461 | if (ret < 0) | ||
462 | goto out1; | ||
463 | } | ||
502 | 464 | ||
503 | /* init cached IRQ enable bits */ | 465 | /* init cached IRQ enable bits */ |
504 | ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG); | 466 | ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG); |
@@ -515,7 +477,7 @@ static int twl_rtc_probe(struct platform_device *pdev) | |||
515 | } | 477 | } |
516 | 478 | ||
517 | ret = request_threaded_irq(irq, NULL, twl_rtc_interrupt, | 479 | ret = request_threaded_irq(irq, NULL, twl_rtc_interrupt, |
518 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, | 480 | IRQF_TRIGGER_RISING, |
519 | dev_name(&rtc->dev), rtc); | 481 | dev_name(&rtc->dev), rtc); |
520 | if (ret < 0) { | 482 | if (ret < 0) { |
521 | dev_err(&pdev->dev, "IRQ is not free.\n"); | 483 | dev_err(&pdev->dev, "IRQ is not free.\n"); |
@@ -535,7 +497,7 @@ out1: | |||
535 | * Disable all TWL RTC module interrupts. | 497 | * Disable all TWL RTC module interrupts. |
536 | * Sets status flag to free. | 498 | * Sets status flag to free. |
537 | */ | 499 | */ |
538 | static int twl_rtc_remove(struct platform_device *pdev) | 500 | static int __devexit twl_rtc_remove(struct platform_device *pdev) |
539 | { | 501 | { |
540 | /* leave rtc running, but disable irqs */ | 502 | /* leave rtc running, but disable irqs */ |
541 | struct rtc_device *rtc = platform_get_drvdata(pdev); | 503 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
@@ -588,23 +550,17 @@ static int twl_rtc_resume(struct platform_device *pdev) | |||
588 | #define twl_rtc_resume NULL | 550 | #define twl_rtc_resume NULL |
589 | #endif | 551 | #endif |
590 | 552 | ||
591 | static const struct of_device_id twl_rtc_of_match[] = { | ||
592 | {.compatible = "ti,twl4030-rtc", }, | ||
593 | { }, | ||
594 | }; | ||
595 | MODULE_DEVICE_TABLE(of, twl_rtc_of_match); | ||
596 | MODULE_ALIAS("platform:twl_rtc"); | 553 | MODULE_ALIAS("platform:twl_rtc"); |
597 | 554 | ||
598 | static struct platform_driver twl4030rtc_driver = { | 555 | static struct platform_driver twl4030rtc_driver = { |
599 | .probe = twl_rtc_probe, | 556 | .probe = twl_rtc_probe, |
600 | .remove = twl_rtc_remove, | 557 | .remove = __devexit_p(twl_rtc_remove), |
601 | .shutdown = twl_rtc_shutdown, | 558 | .shutdown = twl_rtc_shutdown, |
602 | .suspend = twl_rtc_suspend, | 559 | .suspend = twl_rtc_suspend, |
603 | .resume = twl_rtc_resume, | 560 | .resume = twl_rtc_resume, |
604 | .driver = { | 561 | .driver = { |
605 | .owner = THIS_MODULE, | 562 | .owner = THIS_MODULE, |
606 | .name = "twl_rtc", | 563 | .name = "twl_rtc", |
607 | .of_match_table = twl_rtc_of_match, | ||
608 | }, | 564 | }, |
609 | }; | 565 | }; |
610 | 566 | ||
diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c index a12bfac49d3..ec6313d1535 100644 --- a/drivers/rtc/rtc-tx4939.c +++ b/drivers/rtc/rtc-tx4939.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <linux/rtc.h> | 11 | #include <linux/rtc.h> |
12 | #include <linux/platform_device.h> | 12 | #include <linux/platform_device.h> |
13 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
14 | #include <linux/module.h> | ||
15 | #include <linux/io.h> | 14 | #include <linux/io.h> |
16 | #include <linux/gfp.h> | 15 | #include <linux/gfp.h> |
17 | #include <asm/txx9/tx4939.h> | 16 | #include <asm/txx9/tx4939.h> |
@@ -266,7 +265,7 @@ static int __init tx4939_rtc_probe(struct platform_device *pdev) | |||
266 | spin_lock_init(&pdata->lock); | 265 | spin_lock_init(&pdata->lock); |
267 | tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP); | 266 | tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP); |
268 | if (devm_request_irq(&pdev->dev, irq, tx4939_rtc_interrupt, | 267 | if (devm_request_irq(&pdev->dev, irq, tx4939_rtc_interrupt, |
269 | 0, pdev->name, &pdev->dev) < 0) | 268 | IRQF_DISABLED, pdev->name, &pdev->dev) < 0) |
270 | return -EBUSY; | 269 | return -EBUSY; |
271 | rtc = rtc_device_register(pdev->name, &pdev->dev, | 270 | rtc = rtc_device_register(pdev->name, &pdev->dev, |
272 | &tx4939_rtc_ops, THIS_MODULE); | 271 | &tx4939_rtc_ops, THIS_MODULE); |
diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c index bca5d677bc8..f71c3ce1803 100644 --- a/drivers/rtc/rtc-v3020.c +++ b/drivers/rtc/rtc-v3020.c | |||
@@ -393,7 +393,18 @@ static struct platform_driver rtc_device_driver = { | |||
393 | }, | 393 | }, |
394 | }; | 394 | }; |
395 | 395 | ||
396 | module_platform_driver(rtc_device_driver); | 396 | static __init int v3020_init(void) |
397 | { | ||
398 | return platform_driver_register(&rtc_device_driver); | ||
399 | } | ||
400 | |||
401 | static __exit void v3020_exit(void) | ||
402 | { | ||
403 | platform_driver_unregister(&rtc_device_driver); | ||
404 | } | ||
405 | |||
406 | module_init(v3020_init); | ||
407 | module_exit(v3020_exit); | ||
397 | 408 | ||
398 | MODULE_DESCRIPTION("V3020 RTC"); | 409 | MODULE_DESCRIPTION("V3020 RTC"); |
399 | MODULE_AUTHOR("Raphael Assenat"); | 410 | MODULE_AUTHOR("Raphael Assenat"); |
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index 6c3774cf5a2..c5698cda366 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c | |||
@@ -280,7 +280,7 @@ static const struct rtc_class_ops vr41xx_rtc_ops = { | |||
280 | .set_alarm = vr41xx_rtc_set_alarm, | 280 | .set_alarm = vr41xx_rtc_set_alarm, |
281 | }; | 281 | }; |
282 | 282 | ||
283 | static int rtc_probe(struct platform_device *pdev) | 283 | static int __devinit rtc_probe(struct platform_device *pdev) |
284 | { | 284 | { |
285 | struct resource *res; | 285 | struct resource *res; |
286 | struct rtc_device *rtc; | 286 | struct rtc_device *rtc; |
@@ -333,7 +333,7 @@ static int rtc_probe(struct platform_device *pdev) | |||
333 | goto err_device_unregister; | 333 | goto err_device_unregister; |
334 | } | 334 | } |
335 | 335 | ||
336 | retval = request_irq(aie_irq, elapsedtime_interrupt, 0, | 336 | retval = request_irq(aie_irq, elapsedtime_interrupt, IRQF_DISABLED, |
337 | "elapsed_time", pdev); | 337 | "elapsed_time", pdev); |
338 | if (retval < 0) | 338 | if (retval < 0) |
339 | goto err_device_unregister; | 339 | goto err_device_unregister; |
@@ -342,7 +342,7 @@ static int rtc_probe(struct platform_device *pdev) | |||
342 | if (pie_irq <= 0) | 342 | if (pie_irq <= 0) |
343 | goto err_free_irq; | 343 | goto err_free_irq; |
344 | 344 | ||
345 | retval = request_irq(pie_irq, rtclong1_interrupt, 0, | 345 | retval = request_irq(pie_irq, rtclong1_interrupt, IRQF_DISABLED, |
346 | "rtclong1", pdev); | 346 | "rtclong1", pdev); |
347 | if (retval < 0) | 347 | if (retval < 0) |
348 | goto err_free_irq; | 348 | goto err_free_irq; |
@@ -373,7 +373,7 @@ err_rtc1_iounmap: | |||
373 | return retval; | 373 | return retval; |
374 | } | 374 | } |
375 | 375 | ||
376 | static int rtc_remove(struct platform_device *pdev) | 376 | static int __devexit rtc_remove(struct platform_device *pdev) |
377 | { | 377 | { |
378 | struct rtc_device *rtc; | 378 | struct rtc_device *rtc; |
379 | 379 | ||
@@ -398,11 +398,22 @@ MODULE_ALIAS("platform:RTC"); | |||
398 | 398 | ||
399 | static struct platform_driver rtc_platform_driver = { | 399 | static struct platform_driver rtc_platform_driver = { |
400 | .probe = rtc_probe, | 400 | .probe = rtc_probe, |
401 | .remove = rtc_remove, | 401 | .remove = __devexit_p(rtc_remove), |
402 | .driver = { | 402 | .driver = { |
403 | .name = rtc_name, | 403 | .name = rtc_name, |
404 | .owner = THIS_MODULE, | 404 | .owner = THIS_MODULE, |
405 | }, | 405 | }, |
406 | }; | 406 | }; |
407 | 407 | ||
408 | module_platform_driver(rtc_platform_driver); | 408 | static int __init vr41xx_rtc_init(void) |
409 | { | ||
410 | return platform_driver_register(&rtc_platform_driver); | ||
411 | } | ||
412 | |||
413 | static void __exit vr41xx_rtc_exit(void) | ||
414 | { | ||
415 | platform_driver_unregister(&rtc_platform_driver); | ||
416 | } | ||
417 | |||
418 | module_init(vr41xx_rtc_init); | ||
419 | module_exit(vr41xx_rtc_exit); | ||
diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c index 00c930f4b6f..f93f412423c 100644 --- a/drivers/rtc/rtc-vt8500.c +++ b/drivers/rtc/rtc-vt8500.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/bcd.h> | 23 | #include <linux/bcd.h> |
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/of.h> | ||
27 | 26 | ||
28 | /* | 27 | /* |
29 | * Register definitions | 28 | * Register definitions |
@@ -70,7 +69,7 @@ | |||
70 | | ALARM_SEC_BIT) | 69 | | ALARM_SEC_BIT) |
71 | 70 | ||
72 | #define VT8500_RTC_CR_ENABLE (1 << 0) /* Enable RTC */ | 71 | #define VT8500_RTC_CR_ENABLE (1 << 0) /* Enable RTC */ |
73 | #define VT8500_RTC_CR_12H (1 << 1) /* 12h time format */ | 72 | #define VT8500_RTC_CR_24H (1 << 1) /* 24h time format */ |
74 | #define VT8500_RTC_CR_SM_ENABLE (1 << 2) /* Enable periodic irqs */ | 73 | #define VT8500_RTC_CR_SM_ENABLE (1 << 2) /* Enable periodic irqs */ |
75 | #define VT8500_RTC_CR_SM_SEC (1 << 3) /* 0: 1Hz/60, 1: 1Hz */ | 74 | #define VT8500_RTC_CR_SM_SEC (1 << 3) /* 0: 1Hz/60, 1: 1Hz */ |
76 | #define VT8500_RTC_CR_CALIB (1 << 4) /* Enable calibration */ | 75 | #define VT8500_RTC_CR_CALIB (1 << 4) /* Enable calibration */ |
@@ -119,7 +118,7 @@ static int vt8500_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
119 | tm->tm_min = bcd2bin((time & TIME_MIN_MASK) >> TIME_MIN_S); | 118 | tm->tm_min = bcd2bin((time & TIME_MIN_MASK) >> TIME_MIN_S); |
120 | tm->tm_hour = bcd2bin((time & TIME_HOUR_MASK) >> TIME_HOUR_S); | 119 | tm->tm_hour = bcd2bin((time & TIME_HOUR_MASK) >> TIME_HOUR_S); |
121 | tm->tm_mday = bcd2bin(date & DATE_DAY_MASK); | 120 | tm->tm_mday = bcd2bin(date & DATE_DAY_MASK); |
122 | tm->tm_mon = bcd2bin((date & DATE_MONTH_MASK) >> DATE_MONTH_S) - 1; | 121 | tm->tm_mon = bcd2bin((date & DATE_MONTH_MASK) >> DATE_MONTH_S); |
123 | tm->tm_year = bcd2bin((date & DATE_YEAR_MASK) >> DATE_YEAR_S) | 122 | tm->tm_year = bcd2bin((date & DATE_YEAR_MASK) >> DATE_YEAR_S) |
124 | + ((date >> DATE_CENTURY_S) & 1 ? 200 : 100); | 123 | + ((date >> DATE_CENTURY_S) & 1 ? 200 : 100); |
125 | tm->tm_wday = (time & TIME_DOW_MASK) >> TIME_DOW_S; | 124 | tm->tm_wday = (time & TIME_DOW_MASK) >> TIME_DOW_S; |
@@ -138,9 +137,8 @@ static int vt8500_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
138 | } | 137 | } |
139 | 138 | ||
140 | writel((bin2bcd(tm->tm_year - 100) << DATE_YEAR_S) | 139 | writel((bin2bcd(tm->tm_year - 100) << DATE_YEAR_S) |
141 | | (bin2bcd(tm->tm_mon + 1) << DATE_MONTH_S) | 140 | | (bin2bcd(tm->tm_mon) << DATE_MONTH_S) |
142 | | (bin2bcd(tm->tm_mday)) | 141 | | (bin2bcd(tm->tm_mday)), |
143 | | ((tm->tm_year >= 200) << DATE_CENTURY_S), | ||
144 | vt8500_rtc->regbase + VT8500_RTC_DS); | 142 | vt8500_rtc->regbase + VT8500_RTC_DS); |
145 | writel((bin2bcd(tm->tm_wday) << TIME_DOW_S) | 143 | writel((bin2bcd(tm->tm_wday) << TIME_DOW_S) |
146 | | (bin2bcd(tm->tm_hour) << TIME_HOUR_S) | 144 | | (bin2bcd(tm->tm_hour) << TIME_HOUR_S) |
@@ -206,13 +204,12 @@ static const struct rtc_class_ops vt8500_rtc_ops = { | |||
206 | .alarm_irq_enable = vt8500_alarm_irq_enable, | 204 | .alarm_irq_enable = vt8500_alarm_irq_enable, |
207 | }; | 205 | }; |
208 | 206 | ||
209 | static int vt8500_rtc_probe(struct platform_device *pdev) | 207 | static int __devinit vt8500_rtc_probe(struct platform_device *pdev) |
210 | { | 208 | { |
211 | struct vt8500_rtc *vt8500_rtc; | 209 | struct vt8500_rtc *vt8500_rtc; |
212 | int ret; | 210 | int ret; |
213 | 211 | ||
214 | vt8500_rtc = devm_kzalloc(&pdev->dev, | 212 | vt8500_rtc = kzalloc(sizeof(struct vt8500_rtc), GFP_KERNEL); |
215 | sizeof(struct vt8500_rtc), GFP_KERNEL); | ||
216 | if (!vt8500_rtc) | 213 | if (!vt8500_rtc) |
217 | return -ENOMEM; | 214 | return -ENOMEM; |
218 | 215 | ||
@@ -222,13 +219,15 @@ static int vt8500_rtc_probe(struct platform_device *pdev) | |||
222 | vt8500_rtc->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 219 | vt8500_rtc->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
223 | if (!vt8500_rtc->res) { | 220 | if (!vt8500_rtc->res) { |
224 | dev_err(&pdev->dev, "No I/O memory resource defined\n"); | 221 | dev_err(&pdev->dev, "No I/O memory resource defined\n"); |
225 | return -ENXIO; | 222 | ret = -ENXIO; |
223 | goto err_free; | ||
226 | } | 224 | } |
227 | 225 | ||
228 | vt8500_rtc->irq_alarm = platform_get_irq(pdev, 0); | 226 | vt8500_rtc->irq_alarm = platform_get_irq(pdev, 0); |
229 | if (vt8500_rtc->irq_alarm < 0) { | 227 | if (vt8500_rtc->irq_alarm < 0) { |
230 | dev_err(&pdev->dev, "No alarm IRQ resource defined\n"); | 228 | dev_err(&pdev->dev, "No alarm IRQ resource defined\n"); |
231 | return -ENXIO; | 229 | ret = -ENXIO; |
230 | goto err_free; | ||
232 | } | 231 | } |
233 | 232 | ||
234 | vt8500_rtc->res = request_mem_region(vt8500_rtc->res->start, | 233 | vt8500_rtc->res = request_mem_region(vt8500_rtc->res->start, |
@@ -236,7 +235,8 @@ static int vt8500_rtc_probe(struct platform_device *pdev) | |||
236 | "vt8500-rtc"); | 235 | "vt8500-rtc"); |
237 | if (vt8500_rtc->res == NULL) { | 236 | if (vt8500_rtc->res == NULL) { |
238 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | 237 | dev_err(&pdev->dev, "failed to request I/O memory\n"); |
239 | return -EBUSY; | 238 | ret = -EBUSY; |
239 | goto err_free; | ||
240 | } | 240 | } |
241 | 241 | ||
242 | vt8500_rtc->regbase = ioremap(vt8500_rtc->res->start, | 242 | vt8500_rtc->regbase = ioremap(vt8500_rtc->res->start, |
@@ -248,7 +248,7 @@ static int vt8500_rtc_probe(struct platform_device *pdev) | |||
248 | } | 248 | } |
249 | 249 | ||
250 | /* Enable RTC and set it to 24-hour mode */ | 250 | /* Enable RTC and set it to 24-hour mode */ |
251 | writel(VT8500_RTC_CR_ENABLE, | 251 | writel(VT8500_RTC_CR_ENABLE | VT8500_RTC_CR_24H, |
252 | vt8500_rtc->regbase + VT8500_RTC_CR); | 252 | vt8500_rtc->regbase + VT8500_RTC_CR); |
253 | 253 | ||
254 | vt8500_rtc->rtc = rtc_device_register("vt8500-rtc", &pdev->dev, | 254 | vt8500_rtc->rtc = rtc_device_register("vt8500-rtc", &pdev->dev, |
@@ -277,10 +277,12 @@ err_unmap: | |||
277 | err_release: | 277 | err_release: |
278 | release_mem_region(vt8500_rtc->res->start, | 278 | release_mem_region(vt8500_rtc->res->start, |
279 | resource_size(vt8500_rtc->res)); | 279 | resource_size(vt8500_rtc->res)); |
280 | err_free: | ||
281 | kfree(vt8500_rtc); | ||
280 | return ret; | 282 | return ret; |
281 | } | 283 | } |
282 | 284 | ||
283 | static int vt8500_rtc_remove(struct platform_device *pdev) | 285 | static int __devexit vt8500_rtc_remove(struct platform_device *pdev) |
284 | { | 286 | { |
285 | struct vt8500_rtc *vt8500_rtc = platform_get_drvdata(pdev); | 287 | struct vt8500_rtc *vt8500_rtc = platform_get_drvdata(pdev); |
286 | 288 | ||
@@ -294,29 +296,34 @@ static int vt8500_rtc_remove(struct platform_device *pdev) | |||
294 | release_mem_region(vt8500_rtc->res->start, | 296 | release_mem_region(vt8500_rtc->res->start, |
295 | resource_size(vt8500_rtc->res)); | 297 | resource_size(vt8500_rtc->res)); |
296 | 298 | ||
299 | kfree(vt8500_rtc); | ||
297 | platform_set_drvdata(pdev, NULL); | 300 | platform_set_drvdata(pdev, NULL); |
298 | 301 | ||
299 | return 0; | 302 | return 0; |
300 | } | 303 | } |
301 | 304 | ||
302 | static const struct of_device_id wmt_dt_ids[] = { | ||
303 | { .compatible = "via,vt8500-rtc", }, | ||
304 | {} | ||
305 | }; | ||
306 | |||
307 | static struct platform_driver vt8500_rtc_driver = { | 305 | static struct platform_driver vt8500_rtc_driver = { |
308 | .probe = vt8500_rtc_probe, | 306 | .probe = vt8500_rtc_probe, |
309 | .remove = vt8500_rtc_remove, | 307 | .remove = __devexit_p(vt8500_rtc_remove), |
310 | .driver = { | 308 | .driver = { |
311 | .name = "vt8500-rtc", | 309 | .name = "vt8500-rtc", |
312 | .owner = THIS_MODULE, | 310 | .owner = THIS_MODULE, |
313 | .of_match_table = of_match_ptr(wmt_dt_ids), | ||
314 | }, | 311 | }, |
315 | }; | 312 | }; |
316 | 313 | ||
317 | module_platform_driver(vt8500_rtc_driver); | 314 | static int __init vt8500_rtc_init(void) |
315 | { | ||
316 | return platform_driver_register(&vt8500_rtc_driver); | ||
317 | } | ||
318 | module_init(vt8500_rtc_init); | ||
319 | |||
320 | static void __exit vt8500_rtc_exit(void) | ||
321 | { | ||
322 | platform_driver_unregister(&vt8500_rtc_driver); | ||
323 | } | ||
324 | module_exit(vt8500_rtc_exit); | ||
318 | 325 | ||
319 | MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>"); | 326 | MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>"); |
320 | MODULE_DESCRIPTION("VIA VT8500 SoC Realtime Clock Driver (RTC)"); | 327 | MODULE_DESCRIPTION("VIA VT8500 SoC Realtime Clock Driver (RTC)"); |
321 | MODULE_LICENSE("GPL v2"); | 328 | MODULE_LICENSE("GPL"); |
322 | MODULE_ALIAS("platform:vt8500-rtc"); | 329 | MODULE_ALIAS("platform:vt8500-rtc"); |
diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c index 1b0affbe265..bdc909bd56d 100644 --- a/drivers/rtc/rtc-wm831x.c +++ b/drivers/rtc/rtc-wm831x.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/mfd/wm831x/core.h> | 24 | #include <linux/mfd/wm831x/core.h> |
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/random.h> | 27 | |
28 | 28 | ||
29 | /* | 29 | /* |
30 | * R16416 (0x4020) - RTC Write Counter | 30 | * R16416 (0x4020) - RTC Write Counter |
@@ -96,26 +96,6 @@ struct wm831x_rtc { | |||
96 | unsigned int alarm_enabled:1; | 96 | unsigned int alarm_enabled:1; |
97 | }; | 97 | }; |
98 | 98 | ||
99 | static void wm831x_rtc_add_randomness(struct wm831x *wm831x) | ||
100 | { | ||
101 | int ret; | ||
102 | u16 reg; | ||
103 | |||
104 | /* | ||
105 | * The write counter contains a pseudo-random number which is | ||
106 | * regenerated every time we set the RTC so it should be a | ||
107 | * useful per-system source of entropy. | ||
108 | */ | ||
109 | ret = wm831x_reg_read(wm831x, WM831X_RTC_WRITE_COUNTER); | ||
110 | if (ret >= 0) { | ||
111 | reg = ret; | ||
112 | add_device_randomness(®, sizeof(reg)); | ||
113 | } else { | ||
114 | dev_warn(wm831x->dev, "Failed to read RTC write counter: %d\n", | ||
115 | ret); | ||
116 | } | ||
117 | } | ||
118 | |||
119 | /* | 99 | /* |
120 | * Read current time and date in RTC | 100 | * Read current time and date in RTC |
121 | */ | 101 | */ |
@@ -344,6 +324,15 @@ static irqreturn_t wm831x_alm_irq(int irq, void *data) | |||
344 | return IRQ_HANDLED; | 324 | return IRQ_HANDLED; |
345 | } | 325 | } |
346 | 326 | ||
327 | static irqreturn_t wm831x_per_irq(int irq, void *data) | ||
328 | { | ||
329 | struct wm831x_rtc *wm831x_rtc = data; | ||
330 | |||
331 | rtc_update_irq(wm831x_rtc->rtc, 1, RTC_IRQF | RTC_UF); | ||
332 | |||
333 | return IRQ_HANDLED; | ||
334 | } | ||
335 | |||
347 | static const struct rtc_class_ops wm831x_rtc_ops = { | 336 | static const struct rtc_class_ops wm831x_rtc_ops = { |
348 | .read_time = wm831x_rtc_readtime, | 337 | .read_time = wm831x_rtc_readtime, |
349 | .set_mmss = wm831x_rtc_set_mmss, | 338 | .set_mmss = wm831x_rtc_set_mmss, |
@@ -416,10 +405,11 @@ static int wm831x_rtc_probe(struct platform_device *pdev) | |||
416 | { | 405 | { |
417 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); | 406 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); |
418 | struct wm831x_rtc *wm831x_rtc; | 407 | struct wm831x_rtc *wm831x_rtc; |
419 | int alm_irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "ALM")); | 408 | int per_irq = platform_get_irq_byname(pdev, "PER"); |
409 | int alm_irq = platform_get_irq_byname(pdev, "ALM"); | ||
420 | int ret = 0; | 410 | int ret = 0; |
421 | 411 | ||
422 | wm831x_rtc = devm_kzalloc(&pdev->dev, sizeof(*wm831x_rtc), GFP_KERNEL); | 412 | wm831x_rtc = kzalloc(sizeof(*wm831x_rtc), GFP_KERNEL); |
423 | if (wm831x_rtc == NULL) | 413 | if (wm831x_rtc == NULL) |
424 | return -ENOMEM; | 414 | return -ENOMEM; |
425 | 415 | ||
@@ -443,6 +433,14 @@ static int wm831x_rtc_probe(struct platform_device *pdev) | |||
443 | goto err; | 433 | goto err; |
444 | } | 434 | } |
445 | 435 | ||
436 | ret = request_threaded_irq(per_irq, NULL, wm831x_per_irq, | ||
437 | IRQF_TRIGGER_RISING, "RTC period", | ||
438 | wm831x_rtc); | ||
439 | if (ret != 0) { | ||
440 | dev_err(&pdev->dev, "Failed to request periodic IRQ %d: %d\n", | ||
441 | per_irq, ret); | ||
442 | } | ||
443 | |||
446 | ret = request_threaded_irq(alm_irq, NULL, wm831x_alm_irq, | 444 | ret = request_threaded_irq(alm_irq, NULL, wm831x_alm_irq, |
447 | IRQF_TRIGGER_RISING, "RTC alarm", | 445 | IRQF_TRIGGER_RISING, "RTC alarm", |
448 | wm831x_rtc); | 446 | wm831x_rtc); |
@@ -451,21 +449,23 @@ static int wm831x_rtc_probe(struct platform_device *pdev) | |||
451 | alm_irq, ret); | 449 | alm_irq, ret); |
452 | } | 450 | } |
453 | 451 | ||
454 | wm831x_rtc_add_randomness(wm831x); | ||
455 | |||
456 | return 0; | 452 | return 0; |
457 | 453 | ||
458 | err: | 454 | err: |
455 | kfree(wm831x_rtc); | ||
459 | return ret; | 456 | return ret; |
460 | } | 457 | } |
461 | 458 | ||
462 | static int wm831x_rtc_remove(struct platform_device *pdev) | 459 | static int __devexit wm831x_rtc_remove(struct platform_device *pdev) |
463 | { | 460 | { |
464 | struct wm831x_rtc *wm831x_rtc = platform_get_drvdata(pdev); | 461 | struct wm831x_rtc *wm831x_rtc = platform_get_drvdata(pdev); |
462 | int per_irq = platform_get_irq_byname(pdev, "PER"); | ||
465 | int alm_irq = platform_get_irq_byname(pdev, "ALM"); | 463 | int alm_irq = platform_get_irq_byname(pdev, "ALM"); |
466 | 464 | ||
467 | free_irq(alm_irq, wm831x_rtc); | 465 | free_irq(alm_irq, wm831x_rtc); |
466 | free_irq(per_irq, wm831x_rtc); | ||
468 | rtc_device_unregister(wm831x_rtc->rtc); | 467 | rtc_device_unregister(wm831x_rtc->rtc); |
468 | kfree(wm831x_rtc); | ||
469 | 469 | ||
470 | return 0; | 470 | return 0; |
471 | } | 471 | } |
@@ -483,14 +483,24 @@ static const struct dev_pm_ops wm831x_rtc_pm_ops = { | |||
483 | 483 | ||
484 | static struct platform_driver wm831x_rtc_driver = { | 484 | static struct platform_driver wm831x_rtc_driver = { |
485 | .probe = wm831x_rtc_probe, | 485 | .probe = wm831x_rtc_probe, |
486 | .remove = wm831x_rtc_remove, | 486 | .remove = __devexit_p(wm831x_rtc_remove), |
487 | .driver = { | 487 | .driver = { |
488 | .name = "wm831x-rtc", | 488 | .name = "wm831x-rtc", |
489 | .pm = &wm831x_rtc_pm_ops, | 489 | .pm = &wm831x_rtc_pm_ops, |
490 | }, | 490 | }, |
491 | }; | 491 | }; |
492 | 492 | ||
493 | module_platform_driver(wm831x_rtc_driver); | 493 | static int __init wm831x_rtc_init(void) |
494 | { | ||
495 | return platform_driver_register(&wm831x_rtc_driver); | ||
496 | } | ||
497 | module_init(wm831x_rtc_init); | ||
498 | |||
499 | static void __exit wm831x_rtc_exit(void) | ||
500 | { | ||
501 | platform_driver_unregister(&wm831x_rtc_driver); | ||
502 | } | ||
503 | module_exit(wm831x_rtc_exit); | ||
494 | 504 | ||
495 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 505 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
496 | MODULE_DESCRIPTION("RTC driver for the WM831x series PMICs"); | 506 | MODULE_DESCRIPTION("RTC driver for the WM831x series PMICs"); |
diff --git a/drivers/rtc/rtc-wm8350.c b/drivers/rtc/rtc-wm8350.c index 8ad86ae0d30..66421426e40 100644 --- a/drivers/rtc/rtc-wm8350.c +++ b/drivers/rtc/rtc-wm8350.c | |||
@@ -459,7 +459,7 @@ static int wm8350_rtc_probe(struct platform_device *pdev) | |||
459 | return 0; | 459 | return 0; |
460 | } | 460 | } |
461 | 461 | ||
462 | static int wm8350_rtc_remove(struct platform_device *pdev) | 462 | static int __devexit wm8350_rtc_remove(struct platform_device *pdev) |
463 | { | 463 | { |
464 | struct wm8350 *wm8350 = platform_get_drvdata(pdev); | 464 | struct wm8350 *wm8350 = platform_get_drvdata(pdev); |
465 | struct wm8350_rtc *wm_rtc = &wm8350->rtc; | 465 | struct wm8350_rtc *wm_rtc = &wm8350->rtc; |
@@ -479,14 +479,24 @@ static struct dev_pm_ops wm8350_rtc_pm_ops = { | |||
479 | 479 | ||
480 | static struct platform_driver wm8350_rtc_driver = { | 480 | static struct platform_driver wm8350_rtc_driver = { |
481 | .probe = wm8350_rtc_probe, | 481 | .probe = wm8350_rtc_probe, |
482 | .remove = wm8350_rtc_remove, | 482 | .remove = __devexit_p(wm8350_rtc_remove), |
483 | .driver = { | 483 | .driver = { |
484 | .name = "wm8350-rtc", | 484 | .name = "wm8350-rtc", |
485 | .pm = &wm8350_rtc_pm_ops, | 485 | .pm = &wm8350_rtc_pm_ops, |
486 | }, | 486 | }, |
487 | }; | 487 | }; |
488 | 488 | ||
489 | module_platform_driver(wm8350_rtc_driver); | 489 | static int __init wm8350_rtc_init(void) |
490 | { | ||
491 | return platform_driver_register(&wm8350_rtc_driver); | ||
492 | } | ||
493 | module_init(wm8350_rtc_init); | ||
494 | |||
495 | static void __exit wm8350_rtc_exit(void) | ||
496 | { | ||
497 | platform_driver_unregister(&wm8350_rtc_driver); | ||
498 | } | ||
499 | module_exit(wm8350_rtc_exit); | ||
490 | 500 | ||
491 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 501 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
492 | MODULE_DESCRIPTION("RTC driver for the WM8350"); | 502 | MODULE_DESCRIPTION("RTC driver for the WM8350"); |
diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index f36e59c6bc0..b00aad2620d 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/bcd.h> | 21 | #include <linux/bcd.h> |
22 | #include <linux/rtc.h> | 22 | #include <linux/rtc.h> |
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
24 | #include <linux/module.h> | ||
25 | 24 | ||
26 | #define DRV_VERSION "1.0.8" | 25 | #define DRV_VERSION "1.0.8" |
27 | 26 | ||
@@ -97,17 +96,8 @@ static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm, | |||
97 | int i; | 96 | int i; |
98 | 97 | ||
99 | struct i2c_msg msgs[] = { | 98 | struct i2c_msg msgs[] = { |
100 | {/* setup read ptr */ | 99 | { client->addr, 0, 2, dt_addr }, /* setup read ptr */ |
101 | .addr = client->addr, | 100 | { client->addr, I2C_M_RD, 8, buf }, /* read date */ |
102 | .len = 2, | ||
103 | .buf = dt_addr | ||
104 | }, | ||
105 | {/* read date */ | ||
106 | .addr = client->addr, | ||
107 | .flags = I2C_M_RD, | ||
108 | .len = 8, | ||
109 | .buf = buf | ||
110 | }, | ||
111 | }; | 101 | }; |
112 | 102 | ||
113 | /* read date registers */ | 103 | /* read date registers */ |
@@ -151,17 +141,8 @@ static int x1205_get_status(struct i2c_client *client, unsigned char *sr) | |||
151 | static unsigned char sr_addr[2] = { 0, X1205_REG_SR }; | 141 | static unsigned char sr_addr[2] = { 0, X1205_REG_SR }; |
152 | 142 | ||
153 | struct i2c_msg msgs[] = { | 143 | struct i2c_msg msgs[] = { |
154 | { /* setup read ptr */ | 144 | { client->addr, 0, 2, sr_addr }, /* setup read ptr */ |
155 | .addr = client->addr, | 145 | { client->addr, I2C_M_RD, 1, sr }, /* read status */ |
156 | .len = 2, | ||
157 | .buf = sr_addr | ||
158 | }, | ||
159 | { /* read status */ | ||
160 | .addr = client->addr, | ||
161 | .flags = I2C_M_RD, | ||
162 | .len = 1, | ||
163 | .buf = sr | ||
164 | }, | ||
165 | }; | 146 | }; |
166 | 147 | ||
167 | /* read status register */ | 148 | /* read status register */ |
@@ -297,17 +278,8 @@ static int x1205_get_dtrim(struct i2c_client *client, int *trim) | |||
297 | static unsigned char dtr_addr[2] = { 0, X1205_REG_DTR }; | 278 | static unsigned char dtr_addr[2] = { 0, X1205_REG_DTR }; |
298 | 279 | ||
299 | struct i2c_msg msgs[] = { | 280 | struct i2c_msg msgs[] = { |
300 | { /* setup read ptr */ | 281 | { client->addr, 0, 2, dtr_addr }, /* setup read ptr */ |
301 | .addr = client->addr, | 282 | { client->addr, I2C_M_RD, 1, &dtr }, /* read dtr */ |
302 | .len = 2, | ||
303 | .buf = dtr_addr | ||
304 | }, | ||
305 | { /* read dtr */ | ||
306 | .addr = client->addr, | ||
307 | .flags = I2C_M_RD, | ||
308 | .len = 1, | ||
309 | .buf = &dtr | ||
310 | }, | ||
311 | }; | 283 | }; |
312 | 284 | ||
313 | /* read dtr register */ | 285 | /* read dtr register */ |
@@ -338,17 +310,8 @@ static int x1205_get_atrim(struct i2c_client *client, int *trim) | |||
338 | static unsigned char atr_addr[2] = { 0, X1205_REG_ATR }; | 310 | static unsigned char atr_addr[2] = { 0, X1205_REG_ATR }; |
339 | 311 | ||
340 | struct i2c_msg msgs[] = { | 312 | struct i2c_msg msgs[] = { |
341 | {/* setup read ptr */ | 313 | { client->addr, 0, 2, atr_addr }, /* setup read ptr */ |
342 | .addr = client->addr, | 314 | { client->addr, I2C_M_RD, 1, &atr }, /* read atr */ |
343 | .len = 2, | ||
344 | .buf = atr_addr | ||
345 | }, | ||
346 | {/* read atr */ | ||
347 | .addr = client->addr, | ||
348 | .flags = I2C_M_RD, | ||
349 | .len = 1, | ||
350 | .buf = &atr | ||
351 | }, | ||
352 | }; | 315 | }; |
353 | 316 | ||
354 | /* read atr register */ | 317 | /* read atr register */ |
@@ -417,17 +380,8 @@ static int x1205_validate_client(struct i2c_client *client) | |||
417 | unsigned char addr[2] = { 0, probe_zero_pattern[i] }; | 380 | unsigned char addr[2] = { 0, probe_zero_pattern[i] }; |
418 | 381 | ||
419 | struct i2c_msg msgs[2] = { | 382 | struct i2c_msg msgs[2] = { |
420 | { | 383 | { client->addr, 0, 2, addr }, |
421 | .addr = client->addr, | 384 | { client->addr, I2C_M_RD, 1, &buf }, |
422 | .len = 2, | ||
423 | .buf = addr | ||
424 | }, | ||
425 | { | ||
426 | .addr = client->addr, | ||
427 | .flags = I2C_M_RD, | ||
428 | .len = 1, | ||
429 | .buf = &buf | ||
430 | }, | ||
431 | }; | 385 | }; |
432 | 386 | ||
433 | if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) { | 387 | if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) { |
@@ -454,17 +408,8 @@ static int x1205_validate_client(struct i2c_client *client) | |||
454 | unsigned char addr[2] = { 0, probe_limits_pattern[i].reg }; | 408 | unsigned char addr[2] = { 0, probe_limits_pattern[i].reg }; |
455 | 409 | ||
456 | struct i2c_msg msgs[2] = { | 410 | struct i2c_msg msgs[2] = { |
457 | { | 411 | { client->addr, 0, 2, addr }, |
458 | .addr = client->addr, | 412 | { client->addr, I2C_M_RD, 1, ® }, |
459 | .len = 2, | ||
460 | .buf = addr | ||
461 | }, | ||
462 | { | ||
463 | .addr = client->addr, | ||
464 | .flags = I2C_M_RD, | ||
465 | .len = 1, | ||
466 | .buf = ® | ||
467 | }, | ||
468 | }; | 413 | }; |
469 | 414 | ||
470 | if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) { | 415 | if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) { |
@@ -498,18 +443,8 @@ static int x1205_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
498 | static unsigned char int_addr[2] = { 0, X1205_REG_INT }; | 443 | static unsigned char int_addr[2] = { 0, X1205_REG_INT }; |
499 | struct i2c_client *client = to_i2c_client(dev); | 444 | struct i2c_client *client = to_i2c_client(dev); |
500 | struct i2c_msg msgs[] = { | 445 | struct i2c_msg msgs[] = { |
501 | { /* setup read ptr */ | 446 | { client->addr, 0, 2, int_addr }, /* setup read ptr */ |
502 | .addr = client->addr, | 447 | { client->addr, I2C_M_RD, 1, &intreg }, /* read INT register */ |
503 | .len = 2, | ||
504 | .buf = int_addr | ||
505 | }, | ||
506 | {/* read INT register */ | ||
507 | |||
508 | .addr = client->addr, | ||
509 | .flags = I2C_M_RD, | ||
510 | .len = 1, | ||
511 | .buf = &intreg | ||
512 | }, | ||
513 | }; | 448 | }; |
514 | 449 | ||
515 | /* read interrupt register and status register */ | 450 | /* read interrupt register and status register */ |
@@ -687,7 +622,15 @@ static struct i2c_driver x1205_driver = { | |||
687 | .id_table = x1205_id, | 622 | .id_table = x1205_id, |
688 | }; | 623 | }; |
689 | 624 | ||
690 | module_i2c_driver(x1205_driver); | 625 | static int __init x1205_init(void) |
626 | { | ||
627 | return i2c_add_driver(&x1205_driver); | ||
628 | } | ||
629 | |||
630 | static void __exit x1205_exit(void) | ||
631 | { | ||
632 | i2c_del_driver(&x1205_driver); | ||
633 | } | ||
691 | 634 | ||
692 | MODULE_AUTHOR( | 635 | MODULE_AUTHOR( |
693 | "Karen Spearel <kas111 at gmail dot com>, " | 636 | "Karen Spearel <kas111 at gmail dot com>, " |
@@ -695,3 +638,6 @@ MODULE_AUTHOR( | |||
695 | MODULE_DESCRIPTION("Xicor/Intersil X1205 RTC driver"); | 638 | MODULE_DESCRIPTION("Xicor/Intersil X1205 RTC driver"); |
696 | MODULE_LICENSE("GPL"); | 639 | MODULE_LICENSE("GPL"); |
697 | MODULE_VERSION(DRV_VERSION); | 640 | MODULE_VERSION(DRV_VERSION); |
641 | |||
642 | module_init(x1205_init); | ||
643 | module_exit(x1205_exit); | ||