diff options
Diffstat (limited to 'drivers/rtc')
47 files changed, 2829 insertions, 253 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index f11f746f7a35..79fbe3832dfc 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -20,14 +20,24 @@ if RTC_CLASS | |||
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 | default y | 22 | default y |
23 | depends on !ALWAYS_USE_PERSISTENT_CLOCK | ||
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 |
25 | the value read from a specified RTC device. This is useful to avoid | 26 | the value read from a specified RTC device. This is useful to avoid |
26 | unnecessary fsck runs at boot time, and to network better. | 27 | unnecessary fsck runs at boot time, and to network better. |
27 | 28 | ||
29 | config RTC_SYSTOHC | ||
30 | bool "Set the RTC time based on NTP synchronization" | ||
31 | default y | ||
32 | depends on !ALWAYS_USE_PERSISTENT_CLOCK | ||
33 | help | ||
34 | If you say yes here, the system time (wall clock) will be stored | ||
35 | in the RTC specified by RTC_HCTOSYS_DEVICE approximately every 11 | ||
36 | minutes if userspace reports synchronized NTP status. | ||
37 | |||
28 | config RTC_HCTOSYS_DEVICE | 38 | config RTC_HCTOSYS_DEVICE |
29 | string "RTC used to set the system time" | 39 | string "RTC used to set the system time" |
30 | depends on RTC_HCTOSYS = y | 40 | depends on RTC_HCTOSYS = y || RTC_SYSTOHC = y |
31 | default "rtc0" | 41 | default "rtc0" |
32 | help | 42 | help |
33 | The RTC device that will be used to (re)initialize the system | 43 | The RTC device that will be used to (re)initialize the system |
@@ -194,6 +204,12 @@ config RTC_DRV_DS3232 | |||
194 | This driver can also be built as a module. If so, the module | 204 | This driver can also be built as a module. If so, the module |
195 | will be called rtc-ds3232. | 205 | will be called rtc-ds3232. |
196 | 206 | ||
207 | config RTC_DRV_LP8788 | ||
208 | tristate "TI LP8788 RTC driver" | ||
209 | depends on MFD_LP8788 | ||
210 | help | ||
211 | Say Y to enable support for the LP8788 RTC/ALARM driver. | ||
212 | |||
197 | config RTC_DRV_MAX6900 | 213 | config RTC_DRV_MAX6900 |
198 | tristate "Maxim MAX6900" | 214 | tristate "Maxim MAX6900" |
199 | help | 215 | help |
@@ -233,6 +249,26 @@ config RTC_DRV_MAX8998 | |||
233 | This driver can also be built as a module. If so, the module | 249 | This driver can also be built as a module. If so, the module |
234 | will be called rtc-max8998. | 250 | will be called rtc-max8998. |
235 | 251 | ||
252 | config RTC_DRV_MAX8997 | ||
253 | tristate "Maxim MAX8997" | ||
254 | depends on MFD_MAX8997 | ||
255 | help | ||
256 | If you say yes here you will get support for the | ||
257 | RTC of Maxim MAX8997 PMIC. | ||
258 | |||
259 | This driver can also be built as a module. If so, the module | ||
260 | will be called rtc-max8997. | ||
261 | |||
262 | config RTC_DRV_MAX77686 | ||
263 | tristate "Maxim MAX77686" | ||
264 | depends on MFD_MAX77686 | ||
265 | help | ||
266 | If you say yes here you will get support for the | ||
267 | RTC of Maxim MAX77686 PMIC. | ||
268 | |||
269 | This driver can also be built as a module. If so, the module | ||
270 | will be called rtc-max77686. | ||
271 | |||
236 | config RTC_DRV_RS5C372 | 272 | config RTC_DRV_RS5C372 |
237 | tristate "Ricoh R2025S/D, RS5C372A/B, RV5C386, RV5C387A" | 273 | tristate "Ricoh R2025S/D, RS5C372A/B, RV5C386, RV5C387A" |
238 | help | 274 | help |
@@ -380,6 +416,14 @@ config RTC_DRV_TPS65910 | |||
380 | This driver can also be built as a module. If so, the module | 416 | This driver can also be built as a module. If so, the module |
381 | will be called rtc-tps65910. | 417 | will be called rtc-tps65910. |
382 | 418 | ||
419 | config RTC_DRV_TPS80031 | ||
420 | tristate "TI TPS80031/TPS80032 RTC driver" | ||
421 | depends on MFD_TPS80031 | ||
422 | help | ||
423 | TI Power Managment IC TPS80031 supports RTC functionality | ||
424 | along with alarm. This driver supports the RTC driver for | ||
425 | the TPS80031 RTC module. | ||
426 | |||
383 | config RTC_DRV_RC5T583 | 427 | config RTC_DRV_RC5T583 |
384 | tristate "RICOH 5T583 RTC driver" | 428 | tristate "RICOH 5T583 RTC driver" |
385 | depends on MFD_RC5T583 | 429 | depends on MFD_RC5T583 |
@@ -537,6 +581,14 @@ config RTC_DRV_PCF2123 | |||
537 | This driver can also be built as a module. If so, the module | 581 | This driver can also be built as a module. If so, the module |
538 | will be called rtc-pcf2123. | 582 | will be called rtc-pcf2123. |
539 | 583 | ||
584 | config RTC_DRV_RX4581 | ||
585 | tristate "Epson RX-4581" | ||
586 | help | ||
587 | If you say yes here you will get support for the Epson RX-4581. | ||
588 | |||
589 | This driver can also be built as a module. If so the module | ||
590 | will be called rtc-rx4581. | ||
591 | |||
540 | endif # SPI_MASTER | 592 | endif # SPI_MASTER |
541 | 593 | ||
542 | comment "Platform RTC drivers" | 594 | comment "Platform RTC drivers" |
@@ -1033,7 +1085,7 @@ config RTC_DRV_TX4939 | |||
1033 | 1085 | ||
1034 | config RTC_DRV_MV | 1086 | config RTC_DRV_MV |
1035 | tristate "Marvell SoC RTC" | 1087 | tristate "Marvell SoC RTC" |
1036 | depends on ARCH_KIRKWOOD || ARCH_DOVE | 1088 | depends on ARCH_KIRKWOOD || ARCH_DOVE || ARCH_MVEBU |
1037 | help | 1089 | help |
1038 | If you say yes here you will get support for the in-chip RTC | 1090 | If you say yes here you will get support for the in-chip RTC |
1039 | that can be found in some of Marvell's SoC devices, such as | 1091 | that can be found in some of Marvell's SoC devices, such as |
@@ -1183,4 +1235,20 @@ config RTC_DRV_SNVS | |||
1183 | This driver can also be built as a module, if so, the module | 1235 | This driver can also be built as a module, if so, the module |
1184 | will be called "rtc-snvs". | 1236 | will be called "rtc-snvs". |
1185 | 1237 | ||
1238 | comment "HID Sensor RTC drivers" | ||
1239 | |||
1240 | config RTC_DRV_HID_SENSOR_TIME | ||
1241 | tristate "HID Sensor Time" | ||
1242 | depends on USB_HID | ||
1243 | select IIO | ||
1244 | select HID_SENSOR_HUB | ||
1245 | select HID_SENSOR_IIO_COMMON | ||
1246 | help | ||
1247 | Say yes here to build support for the HID Sensors of type Time. | ||
1248 | This drivers makes such sensors available as RTCs. | ||
1249 | |||
1250 | If this driver is compiled as a module, it will be named | ||
1251 | rtc-hid-sensor-time. | ||
1252 | |||
1253 | |||
1186 | endif # RTC_CLASS | 1254 | endif # RTC_CLASS |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 3b66c75f6c76..c33f86f1a69b 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -6,6 +6,7 @@ ccflags-$(CONFIG_RTC_DEBUG) := -DDEBUG | |||
6 | 6 | ||
7 | obj-$(CONFIG_RTC_LIB) += rtc-lib.o | 7 | obj-$(CONFIG_RTC_LIB) += rtc-lib.o |
8 | obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o | 8 | obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o |
9 | obj-$(CONFIG_RTC_SYSTOHC) += systohc.o | ||
9 | obj-$(CONFIG_RTC_CLASS) += rtc-core.o | 10 | obj-$(CONFIG_RTC_CLASS) += rtc-core.o |
10 | rtc-core-y := class.o interface.o | 11 | rtc-core-y := class.o interface.o |
11 | 12 | ||
@@ -52,10 +53,12 @@ obj-$(CONFIG_RTC_DRV_EM3027) += rtc-em3027.o | |||
52 | obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o | 53 | obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o |
53 | obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o | 54 | obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o |
54 | obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o | 55 | obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o |
56 | obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o | ||
55 | obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.o | 57 | obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.o |
56 | obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o | 58 | obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o |
57 | obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o | 59 | obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o |
58 | obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o | 60 | obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o |
61 | obj-$(CONFIG_RTC_DRV_LP8788) += rtc-lp8788.o | ||
59 | obj-$(CONFIG_RTC_DRV_LPC32XX) += rtc-lpc32xx.o | 62 | obj-$(CONFIG_RTC_DRV_LPC32XX) += rtc-lpc32xx.o |
60 | obj-$(CONFIG_RTC_DRV_LOONGSON1) += rtc-ls1x.o | 63 | obj-$(CONFIG_RTC_DRV_LOONGSON1) += rtc-ls1x.o |
61 | obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o | 64 | obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o |
@@ -69,7 +72,9 @@ obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o | |||
69 | obj-$(CONFIG_RTC_DRV_MAX8907) += rtc-max8907.o | 72 | obj-$(CONFIG_RTC_DRV_MAX8907) += rtc-max8907.o |
70 | obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o | 73 | obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o |
71 | obj-$(CONFIG_RTC_DRV_MAX8998) += rtc-max8998.o | 74 | obj-$(CONFIG_RTC_DRV_MAX8998) += rtc-max8998.o |
75 | obj-$(CONFIG_RTC_DRV_MAX8997) += rtc-max8997.o | ||
72 | obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o | 76 | obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o |
77 | obj-$(CONFIG_RTC_DRV_MAX77686) += rtc-max77686.o | ||
73 | obj-$(CONFIG_RTC_DRV_MC13XXX) += rtc-mc13xxx.o | 78 | obj-$(CONFIG_RTC_DRV_MC13XXX) += rtc-mc13xxx.o |
74 | obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o | 79 | obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o |
75 | obj-$(CONFIG_RTC_DRV_MPC5121) += rtc-mpc5121.o | 80 | obj-$(CONFIG_RTC_DRV_MPC5121) += rtc-mpc5121.o |
@@ -96,6 +101,7 @@ obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o | |||
96 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o | 101 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o |
97 | obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o | 102 | obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o |
98 | obj-$(CONFIG_RTC_DRV_RV3029C2) += rtc-rv3029c2.o | 103 | obj-$(CONFIG_RTC_DRV_RV3029C2) += rtc-rv3029c2.o |
104 | obj-$(CONFIG_RTC_DRV_RX4581) += rtc-rx4581.o | ||
99 | obj-$(CONFIG_RTC_DRV_RX8025) += rtc-rx8025.o | 105 | obj-$(CONFIG_RTC_DRV_RX8025) += rtc-rx8025.o |
100 | obj-$(CONFIG_RTC_DRV_RX8581) += rtc-rx8581.o | 106 | obj-$(CONFIG_RTC_DRV_RX8581) += rtc-rx8581.o |
101 | obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o | 107 | obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o |
@@ -114,6 +120,7 @@ obj-$(CONFIG_RTC_DRV_TILE) += rtc-tile.o | |||
114 | obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o | 120 | obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o |
115 | obj-$(CONFIG_RTC_DRV_TPS6586X) += rtc-tps6586x.o | 121 | obj-$(CONFIG_RTC_DRV_TPS6586X) += rtc-tps6586x.o |
116 | obj-$(CONFIG_RTC_DRV_TPS65910) += rtc-tps65910.o | 122 | obj-$(CONFIG_RTC_DRV_TPS65910) += rtc-tps65910.o |
123 | obj-$(CONFIG_RTC_DRV_TPS80031) += rtc-tps80031.o | ||
117 | obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o | 124 | obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o |
118 | obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o | 125 | obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o |
119 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o | 126 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o |
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 5143629dedbd..9b742d3ffb94 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c | |||
@@ -11,6 +11,8 @@ | |||
11 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
15 | |||
14 | #include <linux/module.h> | 16 | #include <linux/module.h> |
15 | #include <linux/rtc.h> | 17 | #include <linux/rtc.h> |
16 | #include <linux/kdev_t.h> | 18 | #include <linux/kdev_t.h> |
@@ -50,6 +52,10 @@ static int rtc_suspend(struct device *dev, pm_message_t mesg) | |||
50 | struct rtc_device *rtc = to_rtc_device(dev); | 52 | struct rtc_device *rtc = to_rtc_device(dev); |
51 | struct rtc_time tm; | 53 | struct rtc_time tm; |
52 | struct timespec delta, delta_delta; | 54 | struct timespec delta, delta_delta; |
55 | |||
56 | if (has_persistent_clock()) | ||
57 | return 0; | ||
58 | |||
53 | if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) | 59 | if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) |
54 | return 0; | 60 | return 0; |
55 | 61 | ||
@@ -88,6 +94,9 @@ static int rtc_resume(struct device *dev) | |||
88 | struct timespec new_system, new_rtc; | 94 | struct timespec new_system, new_rtc; |
89 | struct timespec sleep_time; | 95 | struct timespec sleep_time; |
90 | 96 | ||
97 | if (has_persistent_clock()) | ||
98 | return 0; | ||
99 | |||
91 | rtc_hctosys_ret = -ENODEV; | 100 | rtc_hctosys_ret = -ENODEV; |
92 | if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) | 101 | if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) |
93 | return 0; | 102 | return 0; |
@@ -254,7 +263,7 @@ static int __init rtc_init(void) | |||
254 | { | 263 | { |
255 | rtc_class = class_create(THIS_MODULE, "rtc"); | 264 | rtc_class = class_create(THIS_MODULE, "rtc"); |
256 | if (IS_ERR(rtc_class)) { | 265 | if (IS_ERR(rtc_class)) { |
257 | printk(KERN_ERR "%s: couldn't create class\n", __FILE__); | 266 | pr_err("couldn't create class\n"); |
258 | return PTR_ERR(rtc_class); | 267 | return PTR_ERR(rtc_class); |
259 | } | 268 | } |
260 | rtc_class->suspend = rtc_suspend; | 269 | rtc_class->suspend = rtc_suspend; |
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 9592b936b71b..42bd57da239d 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
@@ -587,16 +587,16 @@ void rtc_update_irq(struct rtc_device *rtc, | |||
587 | } | 587 | } |
588 | EXPORT_SYMBOL_GPL(rtc_update_irq); | 588 | EXPORT_SYMBOL_GPL(rtc_update_irq); |
589 | 589 | ||
590 | static int __rtc_match(struct device *dev, void *data) | 590 | static int __rtc_match(struct device *dev, const void *data) |
591 | { | 591 | { |
592 | char *name = (char *)data; | 592 | const char *name = data; |
593 | 593 | ||
594 | if (strcmp(dev_name(dev), name) == 0) | 594 | if (strcmp(dev_name(dev), name) == 0) |
595 | return 1; | 595 | return 1; |
596 | return 0; | 596 | return 0; |
597 | } | 597 | } |
598 | 598 | ||
599 | struct rtc_device *rtc_class_open(char *name) | 599 | struct rtc_device *rtc_class_open(const char *name) |
600 | { | 600 | { |
601 | struct device *dev; | 601 | struct device *dev; |
602 | struct rtc_device *rtc = NULL; | 602 | struct rtc_device *rtc = NULL; |
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index b6469e2cae89..434ebc3a99dc 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c | |||
@@ -86,7 +86,7 @@ static int at91_rtc_readtime(struct device *dev, struct rtc_time *tm) | |||
86 | tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); | 86 | tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); |
87 | tm->tm_year = tm->tm_year - 1900; | 87 | tm->tm_year = tm->tm_year - 1900; |
88 | 88 | ||
89 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, | 89 | dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, |
90 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | 90 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, |
91 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 91 | tm->tm_hour, tm->tm_min, tm->tm_sec); |
92 | 92 | ||
@@ -100,7 +100,7 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) | |||
100 | { | 100 | { |
101 | unsigned long cr; | 101 | unsigned long cr; |
102 | 102 | ||
103 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, | 103 | dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, |
104 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | 104 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, |
105 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 105 | tm->tm_hour, tm->tm_min, tm->tm_sec); |
106 | 106 | ||
@@ -145,7 +145,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
145 | alrm->enabled = (at91_rtc_read(AT91_RTC_IMR) & AT91_RTC_ALARM) | 145 | alrm->enabled = (at91_rtc_read(AT91_RTC_IMR) & AT91_RTC_ALARM) |
146 | ? 1 : 0; | 146 | ? 1 : 0; |
147 | 147 | ||
148 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, | 148 | dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, |
149 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | 149 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, |
150 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 150 | tm->tm_hour, tm->tm_min, tm->tm_sec); |
151 | 151 | ||
@@ -183,7 +183,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
183 | at91_rtc_write(AT91_RTC_IER, AT91_RTC_ALARM); | 183 | at91_rtc_write(AT91_RTC_IER, AT91_RTC_ALARM); |
184 | } | 184 | } |
185 | 185 | ||
186 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, | 186 | dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, |
187 | at91_alarm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, | 187 | at91_alarm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, |
188 | tm.tm_min, tm.tm_sec); | 188 | tm.tm_min, tm.tm_sec); |
189 | 189 | ||
@@ -192,7 +192,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
192 | 192 | ||
193 | static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | 193 | static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) |
194 | { | 194 | { |
195 | pr_debug("%s(): cmd=%08x\n", __func__, enabled); | 195 | dev_dbg(dev, "%s(): cmd=%08x\n", __func__, enabled); |
196 | 196 | ||
197 | if (enabled) { | 197 | if (enabled) { |
198 | at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM); | 198 | at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM); |
@@ -240,7 +240,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) | |||
240 | 240 | ||
241 | rtc_update_irq(rtc, 1, events); | 241 | rtc_update_irq(rtc, 1, events); |
242 | 242 | ||
243 | pr_debug("%s(): num=%ld, events=0x%02lx\n", __func__, | 243 | dev_dbg(&pdev->dev, "%s(): num=%ld, events=0x%02lx\n", __func__, |
244 | events >> 8, events & 0x000000FF); | 244 | events >> 8, events & 0x000000FF); |
245 | 245 | ||
246 | return IRQ_HANDLED; | 246 | return IRQ_HANDLED; |
@@ -296,8 +296,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev) | |||
296 | IRQF_SHARED, | 296 | IRQF_SHARED, |
297 | "at91_rtc", pdev); | 297 | "at91_rtc", pdev); |
298 | if (ret) { | 298 | if (ret) { |
299 | printk(KERN_ERR "at91_rtc: IRQ %d already in use.\n", | 299 | dev_err(&pdev->dev, "IRQ %d already in use.\n", irq); |
300 | irq); | ||
301 | return ret; | 300 | return ret; |
302 | } | 301 | } |
303 | 302 | ||
@@ -315,7 +314,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev) | |||
315 | } | 314 | } |
316 | platform_set_drvdata(pdev, rtc); | 315 | platform_set_drvdata(pdev, rtc); |
317 | 316 | ||
318 | printk(KERN_INFO "AT91 Real Time Clock driver.\n"); | 317 | dev_info(&pdev->dev, "AT91 Real Time Clock driver.\n"); |
319 | return 0; | 318 | return 0; |
320 | } | 319 | } |
321 | 320 | ||
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 16630aa87f45..af97c94e8a3a 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -706,7 +706,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
706 | rtc_cmos_int_handler = hpet_rtc_interrupt; | 706 | rtc_cmos_int_handler = hpet_rtc_interrupt; |
707 | err = hpet_register_irq_handler(cmos_interrupt); | 707 | err = hpet_register_irq_handler(cmos_interrupt); |
708 | if (err != 0) { | 708 | if (err != 0) { |
709 | printk(KERN_WARNING "hpet_register_irq_handler " | 709 | dev_warn(dev, "hpet_register_irq_handler " |
710 | " failed in rtc_init()."); | 710 | " failed in rtc_init()."); |
711 | goto cleanup1; | 711 | goto cleanup1; |
712 | } | 712 | } |
@@ -731,8 +731,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
731 | goto cleanup2; | 731 | goto cleanup2; |
732 | } | 732 | } |
733 | 733 | ||
734 | pr_info("%s: %s%s, %zd bytes nvram%s\n", | 734 | dev_info(dev, "%s%s, %zd bytes nvram%s\n", |
735 | dev_name(&cmos_rtc.rtc->dev), | ||
736 | !is_valid_irq(rtc_irq) ? "no alarms" : | 735 | !is_valid_irq(rtc_irq) ? "no alarms" : |
737 | cmos_rtc.mon_alrm ? "alarms up to one year" : | 736 | cmos_rtc.mon_alrm ? "alarms up to one year" : |
738 | cmos_rtc.day_alrm ? "alarms up to one month" : | 737 | cmos_rtc.day_alrm ? "alarms up to one month" : |
@@ -820,8 +819,7 @@ static int cmos_suspend(struct device *dev) | |||
820 | enable_irq_wake(cmos->irq); | 819 | enable_irq_wake(cmos->irq); |
821 | } | 820 | } |
822 | 821 | ||
823 | pr_debug("%s: suspend%s, ctrl %02x\n", | 822 | dev_dbg(dev, "suspend%s, ctrl %02x\n", |
824 | dev_name(&cmos_rtc.rtc->dev), | ||
825 | (tmp & RTC_AIE) ? ", alarm may wake" : "", | 823 | (tmp & RTC_AIE) ? ", alarm may wake" : "", |
826 | tmp); | 824 | tmp); |
827 | 825 | ||
@@ -876,9 +874,7 @@ static int cmos_resume(struct device *dev) | |||
876 | spin_unlock_irq(&rtc_lock); | 874 | spin_unlock_irq(&rtc_lock); |
877 | } | 875 | } |
878 | 876 | ||
879 | pr_debug("%s: resume, ctrl %02x\n", | 877 | dev_dbg(dev, "resume, ctrl %02x\n", tmp); |
880 | dev_name(&cmos_rtc.rtc->dev), | ||
881 | tmp); | ||
882 | 878 | ||
883 | return 0; | 879 | return 0; |
884 | } | 880 | } |
@@ -1098,7 +1094,6 @@ static __init void cmos_of_init(struct platform_device *pdev) | |||
1098 | } | 1094 | } |
1099 | #else | 1095 | #else |
1100 | static inline void cmos_of_init(struct platform_device *pdev) {} | 1096 | static inline void cmos_of_init(struct platform_device *pdev) {} |
1101 | #define of_cmos_match NULL | ||
1102 | #endif | 1097 | #endif |
1103 | /*----------------------------------------------------------------*/ | 1098 | /*----------------------------------------------------------------*/ |
1104 | 1099 | ||
@@ -1140,7 +1135,7 @@ static struct platform_driver cmos_platform_driver = { | |||
1140 | #ifdef CONFIG_PM | 1135 | #ifdef CONFIG_PM |
1141 | .pm = &cmos_pm_ops, | 1136 | .pm = &cmos_pm_ops, |
1142 | #endif | 1137 | #endif |
1143 | .of_match_table = of_cmos_match, | 1138 | .of_match_table = of_match_ptr(of_cmos_match), |
1144 | } | 1139 | } |
1145 | }; | 1140 | }; |
1146 | 1141 | ||
diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c index c8115b83e5ab..2d28ec1aa1cd 100644 --- a/drivers/rtc/rtc-coh901331.c +++ b/drivers/rtc/rtc-coh901331.c | |||
@@ -157,7 +157,6 @@ static int __exit coh901331_remove(struct platform_device *pdev) | |||
157 | if (rtap) { | 157 | if (rtap) { |
158 | rtc_device_unregister(rtap->rtc); | 158 | rtc_device_unregister(rtap->rtc); |
159 | clk_unprepare(rtap->clk); | 159 | clk_unprepare(rtap->clk); |
160 | clk_put(rtap->clk); | ||
161 | platform_set_drvdata(pdev, NULL); | 160 | platform_set_drvdata(pdev, NULL); |
162 | } | 161 | } |
163 | 162 | ||
@@ -196,7 +195,7 @@ static int __init coh901331_probe(struct platform_device *pdev) | |||
196 | "RTC COH 901 331 Alarm", rtap)) | 195 | "RTC COH 901 331 Alarm", rtap)) |
197 | return -EIO; | 196 | return -EIO; |
198 | 197 | ||
199 | rtap->clk = clk_get(&pdev->dev, NULL); | 198 | rtap->clk = devm_clk_get(&pdev->dev, NULL); |
200 | if (IS_ERR(rtap->clk)) { | 199 | if (IS_ERR(rtap->clk)) { |
201 | ret = PTR_ERR(rtap->clk); | 200 | ret = PTR_ERR(rtap->clk); |
202 | dev_err(&pdev->dev, "could not get clock\n"); | 201 | dev_err(&pdev->dev, "could not get clock\n"); |
@@ -207,7 +206,7 @@ static int __init coh901331_probe(struct platform_device *pdev) | |||
207 | ret = clk_prepare_enable(rtap->clk); | 206 | ret = clk_prepare_enable(rtap->clk); |
208 | if (ret) { | 207 | if (ret) { |
209 | dev_err(&pdev->dev, "could not enable clock\n"); | 208 | dev_err(&pdev->dev, "could not enable clock\n"); |
210 | goto out_no_clk_prepenable; | 209 | return ret; |
211 | } | 210 | } |
212 | clk_disable(rtap->clk); | 211 | clk_disable(rtap->clk); |
213 | 212 | ||
@@ -224,8 +223,6 @@ static int __init coh901331_probe(struct platform_device *pdev) | |||
224 | out_no_rtc: | 223 | out_no_rtc: |
225 | platform_set_drvdata(pdev, NULL); | 224 | platform_set_drvdata(pdev, NULL); |
226 | clk_unprepare(rtap->clk); | 225 | clk_unprepare(rtap->clk); |
227 | out_no_clk_prepenable: | ||
228 | clk_put(rtap->clk); | ||
229 | return ret; | 226 | return ret; |
230 | } | 227 | } |
231 | 228 | ||
diff --git a/drivers/rtc/rtc-da9052.c b/drivers/rtc/rtc-da9052.c index 60b826e520e2..0dde688ca09b 100644 --- a/drivers/rtc/rtc-da9052.c +++ b/drivers/rtc/rtc-da9052.c | |||
@@ -240,9 +240,10 @@ static int da9052_rtc_probe(struct platform_device *pdev) | |||
240 | rtc->da9052 = dev_get_drvdata(pdev->dev.parent); | 240 | rtc->da9052 = dev_get_drvdata(pdev->dev.parent); |
241 | platform_set_drvdata(pdev, rtc); | 241 | platform_set_drvdata(pdev, rtc); |
242 | rtc->irq = platform_get_irq_byname(pdev, "ALM"); | 242 | rtc->irq = platform_get_irq_byname(pdev, "ALM"); |
243 | ret = request_threaded_irq(rtc->irq, NULL, da9052_rtc_irq, | 243 | ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL, |
244 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | 244 | da9052_rtc_irq, |
245 | "ALM", rtc); | 245 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, |
246 | "ALM", rtc); | ||
246 | if (ret != 0) { | 247 | if (ret != 0) { |
247 | rtc_err(rtc->da9052, "irq registration failed: %d\n", ret); | 248 | rtc_err(rtc->da9052, "irq registration failed: %d\n", ret); |
248 | return ret; | 249 | return ret; |
@@ -250,16 +251,10 @@ static int da9052_rtc_probe(struct platform_device *pdev) | |||
250 | 251 | ||
251 | rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, | 252 | rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, |
252 | &da9052_rtc_ops, THIS_MODULE); | 253 | &da9052_rtc_ops, THIS_MODULE); |
253 | if (IS_ERR(rtc->rtc)) { | 254 | if (IS_ERR(rtc->rtc)) |
254 | ret = PTR_ERR(rtc->rtc); | 255 | return PTR_ERR(rtc->rtc); |
255 | goto err_free_irq; | ||
256 | } | ||
257 | 256 | ||
258 | return 0; | 257 | return 0; |
259 | |||
260 | err_free_irq: | ||
261 | free_irq(rtc->irq, rtc); | ||
262 | return ret; | ||
263 | } | 258 | } |
264 | 259 | ||
265 | static int da9052_rtc_remove(struct platform_device *pdev) | 260 | static int da9052_rtc_remove(struct platform_device *pdev) |
@@ -267,7 +262,6 @@ static int da9052_rtc_remove(struct platform_device *pdev) | |||
267 | struct da9052_rtc *rtc = pdev->dev.platform_data; | 262 | struct da9052_rtc *rtc = pdev->dev.platform_data; |
268 | 263 | ||
269 | rtc_device_unregister(rtc->rtc); | 264 | rtc_device_unregister(rtc->rtc); |
270 | free_irq(rtc->irq, rtc); | ||
271 | platform_set_drvdata(pdev, NULL); | 265 | platform_set_drvdata(pdev, NULL); |
272 | 266 | ||
273 | return 0; | 267 | return 0; |
diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c index 5f7982f7c1b5..56b73089bb29 100644 --- a/drivers/rtc/rtc-davinci.c +++ b/drivers/rtc/rtc-davinci.c | |||
@@ -506,19 +506,19 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) | |||
506 | davinci_rtc->pbase = res->start; | 506 | davinci_rtc->pbase = res->start; |
507 | davinci_rtc->base_size = resource_size(res); | 507 | davinci_rtc->base_size = resource_size(res); |
508 | 508 | ||
509 | mem = request_mem_region(davinci_rtc->pbase, davinci_rtc->base_size, | 509 | mem = devm_request_mem_region(dev, davinci_rtc->pbase, |
510 | pdev->name); | 510 | davinci_rtc->base_size, pdev->name); |
511 | if (!mem) { | 511 | if (!mem) { |
512 | dev_err(dev, "RTC registers at %08x are not free\n", | 512 | dev_err(dev, "RTC registers at %08x are not free\n", |
513 | davinci_rtc->pbase); | 513 | davinci_rtc->pbase); |
514 | return -EBUSY; | 514 | return -EBUSY; |
515 | } | 515 | } |
516 | 516 | ||
517 | davinci_rtc->base = ioremap(davinci_rtc->pbase, davinci_rtc->base_size); | 517 | davinci_rtc->base = devm_ioremap(dev, davinci_rtc->pbase, |
518 | davinci_rtc->base_size); | ||
518 | if (!davinci_rtc->base) { | 519 | if (!davinci_rtc->base) { |
519 | dev_err(dev, "unable to ioremap MEM resource\n"); | 520 | dev_err(dev, "unable to ioremap MEM resource\n"); |
520 | ret = -ENOMEM; | 521 | return -ENOMEM; |
521 | goto fail2; | ||
522 | } | 522 | } |
523 | 523 | ||
524 | platform_set_drvdata(pdev, davinci_rtc); | 524 | platform_set_drvdata(pdev, davinci_rtc); |
@@ -529,7 +529,7 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) | |||
529 | ret = PTR_ERR(davinci_rtc->rtc); | 529 | ret = PTR_ERR(davinci_rtc->rtc); |
530 | dev_err(dev, "unable to register RTC device, err %d\n", | 530 | dev_err(dev, "unable to register RTC device, err %d\n", |
531 | ret); | 531 | ret); |
532 | goto fail3; | 532 | goto fail1; |
533 | } | 533 | } |
534 | 534 | ||
535 | rtcif_write(davinci_rtc, PRTCIF_INTFLG_RTCSS, PRTCIF_INTFLG); | 535 | rtcif_write(davinci_rtc, PRTCIF_INTFLG_RTCSS, PRTCIF_INTFLG); |
@@ -539,11 +539,11 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) | |||
539 | rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CTRL); | 539 | rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CTRL); |
540 | rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CCTRL); | 540 | rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CCTRL); |
541 | 541 | ||
542 | ret = request_irq(davinci_rtc->irq, davinci_rtc_interrupt, | 542 | ret = devm_request_irq(dev, davinci_rtc->irq, davinci_rtc_interrupt, |
543 | 0, "davinci_rtc", davinci_rtc); | 543 | 0, "davinci_rtc", davinci_rtc); |
544 | if (ret < 0) { | 544 | if (ret < 0) { |
545 | dev_err(dev, "unable to register davinci RTC interrupt\n"); | 545 | dev_err(dev, "unable to register davinci RTC interrupt\n"); |
546 | goto fail4; | 546 | goto fail2; |
547 | } | 547 | } |
548 | 548 | ||
549 | /* Enable interrupts */ | 549 | /* Enable interrupts */ |
@@ -557,13 +557,10 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) | |||
557 | 557 | ||
558 | return 0; | 558 | return 0; |
559 | 559 | ||
560 | fail4: | 560 | fail2: |
561 | rtc_device_unregister(davinci_rtc->rtc); | 561 | rtc_device_unregister(davinci_rtc->rtc); |
562 | fail3: | 562 | fail1: |
563 | platform_set_drvdata(pdev, NULL); | 563 | platform_set_drvdata(pdev, NULL); |
564 | iounmap(davinci_rtc->base); | ||
565 | fail2: | ||
566 | release_mem_region(davinci_rtc->pbase, davinci_rtc->base_size); | ||
567 | return ret; | 564 | return ret; |
568 | } | 565 | } |
569 | 566 | ||
@@ -575,13 +572,8 @@ static int davinci_rtc_remove(struct platform_device *pdev) | |||
575 | 572 | ||
576 | rtcif_write(davinci_rtc, 0, PRTCIF_INTEN); | 573 | rtcif_write(davinci_rtc, 0, PRTCIF_INTEN); |
577 | 574 | ||
578 | free_irq(davinci_rtc->irq, davinci_rtc); | ||
579 | |||
580 | rtc_device_unregister(davinci_rtc->rtc); | 575 | rtc_device_unregister(davinci_rtc->rtc); |
581 | 576 | ||
582 | iounmap(davinci_rtc->base); | ||
583 | release_mem_region(davinci_rtc->pbase, davinci_rtc->base_size); | ||
584 | |||
585 | platform_set_drvdata(pdev, NULL); | 577 | platform_set_drvdata(pdev, NULL); |
586 | 578 | ||
587 | return 0; | 579 | return 0; |
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 9a86b4bd8699..d04939369251 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c | |||
@@ -11,6 +11,8 @@ | |||
11 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
15 | |||
14 | #include <linux/module.h> | 16 | #include <linux/module.h> |
15 | #include <linux/rtc.h> | 17 | #include <linux/rtc.h> |
16 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
@@ -462,7 +464,7 @@ void rtc_dev_prepare(struct rtc_device *rtc) | |||
462 | return; | 464 | return; |
463 | 465 | ||
464 | if (rtc->id >= RTC_DEV_MAX) { | 466 | if (rtc->id >= RTC_DEV_MAX) { |
465 | pr_debug("%s: too many RTC devices\n", rtc->name); | 467 | dev_dbg(&rtc->dev, "%s: too many RTC devices\n", rtc->name); |
466 | return; | 468 | return; |
467 | } | 469 | } |
468 | 470 | ||
@@ -480,10 +482,10 @@ void rtc_dev_prepare(struct rtc_device *rtc) | |||
480 | void rtc_dev_add_device(struct rtc_device *rtc) | 482 | void rtc_dev_add_device(struct rtc_device *rtc) |
481 | { | 483 | { |
482 | if (cdev_add(&rtc->char_dev, rtc->dev.devt, 1)) | 484 | if (cdev_add(&rtc->char_dev, rtc->dev.devt, 1)) |
483 | printk(KERN_WARNING "%s: failed to add char device %d:%d\n", | 485 | dev_warn(&rtc->dev, "%s: failed to add char device %d:%d\n", |
484 | rtc->name, MAJOR(rtc_devt), rtc->id); | 486 | rtc->name, MAJOR(rtc_devt), rtc->id); |
485 | else | 487 | else |
486 | pr_debug("%s: dev (%d:%d)\n", rtc->name, | 488 | dev_dbg(&rtc->dev, "%s: dev (%d:%d)\n", rtc->name, |
487 | MAJOR(rtc_devt), rtc->id); | 489 | MAJOR(rtc_devt), rtc->id); |
488 | } | 490 | } |
489 | 491 | ||
@@ -499,8 +501,7 @@ void __init rtc_dev_init(void) | |||
499 | 501 | ||
500 | err = alloc_chrdev_region(&rtc_devt, 0, RTC_DEV_MAX, "rtc"); | 502 | err = alloc_chrdev_region(&rtc_devt, 0, RTC_DEV_MAX, "rtc"); |
501 | if (err < 0) | 503 | if (err < 0) |
502 | printk(KERN_ERR "%s: failed to allocate char dev region\n", | 504 | pr_err("failed to allocate char dev region\n"); |
503 | __FILE__); | ||
504 | } | 505 | } |
505 | 506 | ||
506 | void __exit rtc_dev_exit(void) | 507 | void __exit rtc_dev_exit(void) |
diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index d578773f5ce2..b05a6dc96405 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c | |||
@@ -635,9 +635,7 @@ static int ds1305_probe(struct spi_device *spi) | |||
635 | goto fail0; | 635 | goto fail0; |
636 | } | 636 | } |
637 | 637 | ||
638 | dev_dbg(&spi->dev, "ctrl %s: %02x %02x %02x\n", | 638 | dev_dbg(&spi->dev, "ctrl %s: %3ph\n", "read", ds1305->ctrl); |
639 | "read", ds1305->ctrl[0], | ||
640 | ds1305->ctrl[1], ds1305->ctrl[2]); | ||
641 | 639 | ||
642 | /* Sanity check register values ... partially compensating for the | 640 | /* Sanity check register values ... partially compensating for the |
643 | * fact that SPI has no device handshake. A pullup on MISO would | 641 | * fact that SPI has no device handshake. A pullup on MISO would |
@@ -723,9 +721,7 @@ static int ds1305_probe(struct spi_device *spi) | |||
723 | goto fail0; | 721 | goto fail0; |
724 | } | 722 | } |
725 | 723 | ||
726 | dev_dbg(&spi->dev, "ctrl %s: %02x %02x %02x\n", | 724 | dev_dbg(&spi->dev, "ctrl %s: %3ph\n", "write", ds1305->ctrl); |
727 | "write", ds1305->ctrl[0], | ||
728 | ds1305->ctrl[1], ds1305->ctrl[2]); | ||
729 | } | 725 | } |
730 | 726 | ||
731 | /* see if non-Linux software set up AM/PM mode */ | 727 | /* see if non-Linux software set up AM/PM mode */ |
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index e0d0ba4de03f..970a236b147a 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c | |||
@@ -322,12 +322,7 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t) | |||
322 | return -EIO; | 322 | return -EIO; |
323 | } | 323 | } |
324 | 324 | ||
325 | dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x\n", | 325 | dev_dbg(dev, "%s: %7ph\n", "read", ds1307->regs); |
326 | "read", | ||
327 | ds1307->regs[0], ds1307->regs[1], | ||
328 | ds1307->regs[2], ds1307->regs[3], | ||
329 | ds1307->regs[4], ds1307->regs[5], | ||
330 | ds1307->regs[6]); | ||
331 | 326 | ||
332 | t->tm_sec = bcd2bin(ds1307->regs[DS1307_REG_SECS] & 0x7f); | 327 | t->tm_sec = bcd2bin(ds1307->regs[DS1307_REG_SECS] & 0x7f); |
333 | t->tm_min = bcd2bin(ds1307->regs[DS1307_REG_MIN] & 0x7f); | 328 | t->tm_min = bcd2bin(ds1307->regs[DS1307_REG_MIN] & 0x7f); |
@@ -398,9 +393,7 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) | |||
398 | break; | 393 | break; |
399 | } | 394 | } |
400 | 395 | ||
401 | dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x\n", | 396 | dev_dbg(dev, "%s: %7ph\n", "write", buf); |
402 | "write", buf[0], buf[1], buf[2], buf[3], | ||
403 | buf[4], buf[5], buf[6]); | ||
404 | 397 | ||
405 | result = ds1307->write_block_data(ds1307->client, | 398 | result = ds1307->write_block_data(ds1307->client, |
406 | ds1307->offset, 7, buf); | 399 | ds1307->offset, 7, buf); |
diff --git a/drivers/rtc/rtc-ds2404.c b/drivers/rtc/rtc-ds2404.c index 5ea9df7c8c31..b04fc4272fb3 100644 --- a/drivers/rtc/rtc-ds2404.c +++ b/drivers/rtc/rtc-ds2404.c | |||
@@ -70,7 +70,7 @@ static int ds2404_gpio_map(struct ds2404 *chip, struct platform_device *pdev, | |||
70 | for (i = 0; i < ARRAY_SIZE(ds2404_gpio); i++) { | 70 | for (i = 0; i < ARRAY_SIZE(ds2404_gpio); i++) { |
71 | err = gpio_request(ds2404_gpio[i].gpio, ds2404_gpio[i].name); | 71 | err = gpio_request(ds2404_gpio[i].gpio, ds2404_gpio[i].name); |
72 | if (err) { | 72 | if (err) { |
73 | printk(KERN_ERR "error mapping gpio %s: %d\n", | 73 | dev_err(&pdev->dev, "error mapping gpio %s: %d\n", |
74 | ds2404_gpio[i].name, err); | 74 | ds2404_gpio[i].name, err); |
75 | goto err_request; | 75 | goto err_request; |
76 | } | 76 | } |
@@ -177,7 +177,7 @@ static void ds2404_write_memory(struct device *dev, u16 offset, | |||
177 | 177 | ||
178 | for (i = 0; i < length; i++) { | 178 | for (i = 0; i < length; i++) { |
179 | if (out[i] != ds2404_read_byte(dev)) { | 179 | if (out[i] != ds2404_read_byte(dev)) { |
180 | printk(KERN_ERR "read invalid data\n"); | 180 | dev_err(dev, "read invalid data\n"); |
181 | return; | 181 | return; |
182 | } | 182 | } |
183 | } | 183 | } |
@@ -283,19 +283,7 @@ static struct platform_driver rtc_device_driver = { | |||
283 | .owner = THIS_MODULE, | 283 | .owner = THIS_MODULE, |
284 | }, | 284 | }, |
285 | }; | 285 | }; |
286 | 286 | module_platform_driver(rtc_device_driver); | |
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 | 287 | ||
300 | MODULE_DESCRIPTION("DS2404 RTC"); | 288 | MODULE_DESCRIPTION("DS2404 RTC"); |
301 | MODULE_AUTHOR("Sven Schnelle"); | 289 | MODULE_AUTHOR("Sven Schnelle"); |
diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c index c9f890b088da..1a0c37c9152b 100644 --- a/drivers/rtc/rtc-efi.c +++ b/drivers/rtc/rtc-efi.c | |||
@@ -13,6 +13,8 @@ | |||
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
17 | |||
16 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
17 | #include <linux/module.h> | 19 | #include <linux/module.h> |
18 | #include <linux/time.h> | 20 | #include <linux/time.h> |
@@ -47,7 +49,7 @@ compute_wday(efi_time_t *eft) | |||
47 | int ndays = 0; | 49 | int ndays = 0; |
48 | 50 | ||
49 | if (eft->year < 1998) { | 51 | if (eft->year < 1998) { |
50 | printk(KERN_ERR "efirtc: EFI year < 1998, invalid date\n"); | 52 | pr_err("EFI year < 1998, invalid date\n"); |
51 | return -1; | 53 | return -1; |
52 | } | 54 | } |
53 | 55 | ||
@@ -70,7 +72,7 @@ convert_to_efi_time(struct rtc_time *wtime, efi_time_t *eft) | |||
70 | eft->day = wtime->tm_mday; | 72 | eft->day = wtime->tm_mday; |
71 | eft->hour = wtime->tm_hour; | 73 | eft->hour = wtime->tm_hour; |
72 | eft->minute = wtime->tm_min; | 74 | eft->minute = wtime->tm_min; |
73 | eft->second = wtime->tm_sec; | 75 | eft->second = wtime->tm_sec; |
74 | eft->nanosecond = 0; | 76 | eft->nanosecond = 0; |
75 | eft->daylight = wtime->tm_isdst ? EFI_ISDST : 0; | 77 | eft->daylight = wtime->tm_isdst ? EFI_ISDST : 0; |
76 | eft->timezone = EFI_UNSPECIFIED_TIMEZONE; | 78 | eft->timezone = EFI_UNSPECIFIED_TIMEZONE; |
@@ -142,7 +144,7 @@ static int efi_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | |||
142 | */ | 144 | */ |
143 | status = efi.set_wakeup_time((efi_bool_t)wkalrm->enabled, &eft); | 145 | status = efi.set_wakeup_time((efi_bool_t)wkalrm->enabled, &eft); |
144 | 146 | ||
145 | printk(KERN_WARNING "write status is %d\n", (int)status); | 147 | dev_warn(dev, "write status is %d\n", (int)status); |
146 | 148 | ||
147 | return status == EFI_SUCCESS ? 0 : -EINVAL; | 149 | return status == EFI_SUCCESS ? 0 : -EINVAL; |
148 | } | 150 | } |
@@ -157,7 +159,7 @@ static int efi_read_time(struct device *dev, struct rtc_time *tm) | |||
157 | 159 | ||
158 | if (status != EFI_SUCCESS) { | 160 | if (status != EFI_SUCCESS) { |
159 | /* should never happen */ | 161 | /* should never happen */ |
160 | printk(KERN_ERR "efitime: can't read time\n"); | 162 | dev_err(dev, "can't read time\n"); |
161 | return -EINVAL; | 163 | return -EINVAL; |
162 | } | 164 | } |
163 | 165 | ||
diff --git a/drivers/rtc/rtc-fm3130.c b/drivers/rtc/rtc-fm3130.c index 04e93c6597f8..bff3cdc5140e 100644 --- a/drivers/rtc/rtc-fm3130.c +++ b/drivers/rtc/rtc-fm3130.c | |||
@@ -116,17 +116,7 @@ static int fm3130_get_time(struct device *dev, struct rtc_time *t) | |||
116 | 116 | ||
117 | fm3130_rtc_mode(dev, FM3130_MODE_NORMAL); | 117 | fm3130_rtc_mode(dev, FM3130_MODE_NORMAL); |
118 | 118 | ||
119 | dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x %02x" | 119 | dev_dbg(dev, "%s: %15ph\n", "read", fm3130->regs); |
120 | "%02x %02x %02x %02x %02x %02x %02x\n", | ||
121 | "read", | ||
122 | fm3130->regs[0], fm3130->regs[1], | ||
123 | fm3130->regs[2], fm3130->regs[3], | ||
124 | fm3130->regs[4], fm3130->regs[5], | ||
125 | fm3130->regs[6], fm3130->regs[7], | ||
126 | fm3130->regs[8], fm3130->regs[9], | ||
127 | fm3130->regs[0xa], fm3130->regs[0xb], | ||
128 | fm3130->regs[0xc], fm3130->regs[0xd], | ||
129 | fm3130->regs[0xe]); | ||
130 | 120 | ||
131 | t->tm_sec = bcd2bin(fm3130->regs[FM3130_RTC_SECONDS] & 0x7f); | 121 | t->tm_sec = bcd2bin(fm3130->regs[FM3130_RTC_SECONDS] & 0x7f); |
132 | t->tm_min = bcd2bin(fm3130->regs[FM3130_RTC_MINUTES] & 0x7f); | 122 | t->tm_min = bcd2bin(fm3130->regs[FM3130_RTC_MINUTES] & 0x7f); |
@@ -175,12 +165,7 @@ static int fm3130_set_time(struct device *dev, struct rtc_time *t) | |||
175 | tmp = t->tm_year - 100; | 165 | tmp = t->tm_year - 100; |
176 | buf[FM3130_RTC_YEARS] = bin2bcd(tmp); | 166 | buf[FM3130_RTC_YEARS] = bin2bcd(tmp); |
177 | 167 | ||
178 | dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x" | 168 | dev_dbg(dev, "%s: %15ph\n", "write", buf); |
179 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", | ||
180 | "write", buf[0], buf[1], buf[2], buf[3], | ||
181 | buf[4], buf[5], buf[6], buf[7], | ||
182 | buf[8], buf[9], buf[0xa], buf[0xb], | ||
183 | buf[0xc], buf[0xd], buf[0xe]); | ||
184 | 169 | ||
185 | fm3130_rtc_mode(dev, FM3130_MODE_WRITE); | 170 | fm3130_rtc_mode(dev, FM3130_MODE_WRITE); |
186 | 171 | ||
@@ -517,18 +502,8 @@ bad_alarm: | |||
517 | bad_clock: | 502 | bad_clock: |
518 | 503 | ||
519 | if (!fm3130->data_valid || !fm3130->alarm_valid) | 504 | if (!fm3130->data_valid || !fm3130->alarm_valid) |
520 | dev_dbg(&client->dev, | 505 | dev_dbg(&client->dev, "%s: %15ph\n", "bogus registers", |
521 | "%s: %02x %02x %02x %02x %02x %02x %02x %02x" | 506 | fm3130->regs); |
522 | "%02x %02x %02x %02x %02x %02x %02x\n", | ||
523 | "bogus registers", | ||
524 | fm3130->regs[0], fm3130->regs[1], | ||
525 | fm3130->regs[2], fm3130->regs[3], | ||
526 | fm3130->regs[4], fm3130->regs[5], | ||
527 | fm3130->regs[6], fm3130->regs[7], | ||
528 | fm3130->regs[8], fm3130->regs[9], | ||
529 | fm3130->regs[0xa], fm3130->regs[0xb], | ||
530 | fm3130->regs[0xc], fm3130->regs[0xd], | ||
531 | fm3130->regs[0xe]); | ||
532 | 507 | ||
533 | /* We won't bail out here because we just got invalid data. | 508 | /* We won't bail out here because we just got invalid data. |
534 | Time setting from u-boot doesn't work anyway */ | 509 | Time setting from u-boot doesn't work anyway */ |
diff --git a/drivers/rtc/rtc-hid-sensor-time.c b/drivers/rtc/rtc-hid-sensor-time.c new file mode 100644 index 000000000000..31c5728ef629 --- /dev/null +++ b/drivers/rtc/rtc-hid-sensor-time.c | |||
@@ -0,0 +1,292 @@ | |||
1 | /* | ||
2 | * HID Sensor Time Driver | ||
3 | * Copyright (c) 2012, Alexander Holler. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
17 | * | ||
18 | */ | ||
19 | #include <linux/device.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/hid-sensor-hub.h> | ||
23 | #include <linux/iio/iio.h> | ||
24 | #include <linux/rtc.h> | ||
25 | |||
26 | /* Format: HID-SENSOR-usage_id_in_hex */ | ||
27 | /* Usage ID from spec for Time: 0x2000A0 */ | ||
28 | #define DRIVER_NAME "HID-SENSOR-2000a0" /* must be lowercase */ | ||
29 | |||
30 | enum hid_time_channel { | ||
31 | CHANNEL_SCAN_INDEX_YEAR, | ||
32 | CHANNEL_SCAN_INDEX_MONTH, | ||
33 | CHANNEL_SCAN_INDEX_DAY, | ||
34 | CHANNEL_SCAN_INDEX_HOUR, | ||
35 | CHANNEL_SCAN_INDEX_MINUTE, | ||
36 | CHANNEL_SCAN_INDEX_SECOND, | ||
37 | TIME_RTC_CHANNEL_MAX, | ||
38 | }; | ||
39 | |||
40 | struct hid_time_state { | ||
41 | struct hid_sensor_hub_callbacks callbacks; | ||
42 | struct hid_sensor_common common_attributes; | ||
43 | struct hid_sensor_hub_attribute_info info[TIME_RTC_CHANNEL_MAX]; | ||
44 | struct rtc_time last_time; | ||
45 | spinlock_t lock_last_time; | ||
46 | struct completion comp_last_time; | ||
47 | struct rtc_time time_buf; | ||
48 | struct rtc_device *rtc; | ||
49 | }; | ||
50 | |||
51 | static const u32 hid_time_addresses[TIME_RTC_CHANNEL_MAX] = { | ||
52 | HID_USAGE_SENSOR_TIME_YEAR, | ||
53 | HID_USAGE_SENSOR_TIME_MONTH, | ||
54 | HID_USAGE_SENSOR_TIME_DAY, | ||
55 | HID_USAGE_SENSOR_TIME_HOUR, | ||
56 | HID_USAGE_SENSOR_TIME_MINUTE, | ||
57 | HID_USAGE_SENSOR_TIME_SECOND, | ||
58 | }; | ||
59 | |||
60 | /* Channel names for verbose error messages */ | ||
61 | static const char * const hid_time_channel_names[TIME_RTC_CHANNEL_MAX] = { | ||
62 | "year", "month", "day", "hour", "minute", "second", | ||
63 | }; | ||
64 | |||
65 | /* Callback handler to send event after all samples are received and captured */ | ||
66 | static int hid_time_proc_event(struct hid_sensor_hub_device *hsdev, | ||
67 | unsigned usage_id, void *priv) | ||
68 | { | ||
69 | unsigned long flags; | ||
70 | struct hid_time_state *time_state = platform_get_drvdata(priv); | ||
71 | |||
72 | spin_lock_irqsave(&time_state->lock_last_time, flags); | ||
73 | time_state->last_time = time_state->time_buf; | ||
74 | spin_unlock_irqrestore(&time_state->lock_last_time, flags); | ||
75 | complete(&time_state->comp_last_time); | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | static int hid_time_capture_sample(struct hid_sensor_hub_device *hsdev, | ||
80 | unsigned usage_id, size_t raw_len, | ||
81 | char *raw_data, void *priv) | ||
82 | { | ||
83 | struct hid_time_state *time_state = platform_get_drvdata(priv); | ||
84 | struct rtc_time *time_buf = &time_state->time_buf; | ||
85 | |||
86 | switch (usage_id) { | ||
87 | case HID_USAGE_SENSOR_TIME_YEAR: | ||
88 | time_buf->tm_year = *(u8 *)raw_data; | ||
89 | if (time_buf->tm_year < 70) | ||
90 | /* assume we are in 1970...2069 */ | ||
91 | time_buf->tm_year += 100; | ||
92 | break; | ||
93 | case HID_USAGE_SENSOR_TIME_MONTH: | ||
94 | /* sensor sending the month as 1-12, we need 0-11 */ | ||
95 | time_buf->tm_mon = *(u8 *)raw_data-1; | ||
96 | break; | ||
97 | case HID_USAGE_SENSOR_TIME_DAY: | ||
98 | time_buf->tm_mday = *(u8 *)raw_data; | ||
99 | break; | ||
100 | case HID_USAGE_SENSOR_TIME_HOUR: | ||
101 | time_buf->tm_hour = *(u8 *)raw_data; | ||
102 | break; | ||
103 | case HID_USAGE_SENSOR_TIME_MINUTE: | ||
104 | time_buf->tm_min = *(u8 *)raw_data; | ||
105 | break; | ||
106 | case HID_USAGE_SENSOR_TIME_SECOND: | ||
107 | time_buf->tm_sec = *(u8 *)raw_data; | ||
108 | break; | ||
109 | default: | ||
110 | return -EINVAL; | ||
111 | } | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | /* small helper, haven't found any other way */ | ||
116 | static const char *hid_time_attrib_name(u32 attrib_id) | ||
117 | { | ||
118 | static const char unknown[] = "unknown"; | ||
119 | unsigned i; | ||
120 | |||
121 | for (i = 0; i < TIME_RTC_CHANNEL_MAX; ++i) { | ||
122 | if (hid_time_addresses[i] == attrib_id) | ||
123 | return hid_time_channel_names[i]; | ||
124 | } | ||
125 | return unknown; /* should never happen */ | ||
126 | } | ||
127 | |||
128 | static int hid_time_parse_report(struct platform_device *pdev, | ||
129 | struct hid_sensor_hub_device *hsdev, | ||
130 | unsigned usage_id, | ||
131 | struct hid_time_state *time_state) | ||
132 | { | ||
133 | int report_id, i; | ||
134 | |||
135 | for (i = 0; i < TIME_RTC_CHANNEL_MAX; ++i) | ||
136 | if (sensor_hub_input_get_attribute_info(hsdev, | ||
137 | HID_INPUT_REPORT, usage_id, | ||
138 | hid_time_addresses[i], | ||
139 | &time_state->info[i]) < 0) | ||
140 | return -EINVAL; | ||
141 | /* Check the (needed) attributes for sanity */ | ||
142 | report_id = time_state->info[0].report_id; | ||
143 | if (report_id < 0) { | ||
144 | dev_err(&pdev->dev, "bad report ID!\n"); | ||
145 | return -EINVAL; | ||
146 | } | ||
147 | for (i = 0; i < TIME_RTC_CHANNEL_MAX; ++i) { | ||
148 | if (time_state->info[i].report_id != report_id) { | ||
149 | dev_err(&pdev->dev, | ||
150 | "not all needed attributes inside the same report!\n"); | ||
151 | return -EINVAL; | ||
152 | } | ||
153 | if (time_state->info[i].size != 1) { | ||
154 | dev_err(&pdev->dev, | ||
155 | "attribute '%s' not 8 bits wide!\n", | ||
156 | hid_time_attrib_name( | ||
157 | time_state->info[i].attrib_id)); | ||
158 | return -EINVAL; | ||
159 | } | ||
160 | if (time_state->info[i].units != | ||
161 | HID_USAGE_SENSOR_UNITS_NOT_SPECIFIED && | ||
162 | /* allow attribute seconds with unit seconds */ | ||
163 | !(time_state->info[i].attrib_id == | ||
164 | HID_USAGE_SENSOR_TIME_SECOND && | ||
165 | time_state->info[i].units == | ||
166 | HID_USAGE_SENSOR_UNITS_SECOND)) { | ||
167 | dev_err(&pdev->dev, | ||
168 | "attribute '%s' hasn't a unit of type 'none'!\n", | ||
169 | hid_time_attrib_name( | ||
170 | time_state->info[i].attrib_id)); | ||
171 | return -EINVAL; | ||
172 | } | ||
173 | if (time_state->info[i].unit_expo) { | ||
174 | dev_err(&pdev->dev, | ||
175 | "attribute '%s' hasn't a unit exponent of 1!\n", | ||
176 | hid_time_attrib_name( | ||
177 | time_state->info[i].attrib_id)); | ||
178 | return -EINVAL; | ||
179 | } | ||
180 | } | ||
181 | |||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | static int hid_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
186 | { | ||
187 | unsigned long flags; | ||
188 | struct hid_time_state *time_state = | ||
189 | platform_get_drvdata(to_platform_device(dev)); | ||
190 | int ret; | ||
191 | |||
192 | INIT_COMPLETION(time_state->comp_last_time); | ||
193 | /* get a report with all values through requesting one value */ | ||
194 | sensor_hub_input_attr_get_raw_value(time_state->common_attributes.hsdev, | ||
195 | HID_USAGE_SENSOR_TIME, hid_time_addresses[0], | ||
196 | time_state->info[0].report_id); | ||
197 | /* wait for all values (event) */ | ||
198 | ret = wait_for_completion_killable_timeout( | ||
199 | &time_state->comp_last_time, HZ*6); | ||
200 | if (ret > 0) { | ||
201 | /* no error */ | ||
202 | spin_lock_irqsave(&time_state->lock_last_time, flags); | ||
203 | *tm = time_state->last_time; | ||
204 | spin_unlock_irqrestore(&time_state->lock_last_time, flags); | ||
205 | return 0; | ||
206 | } | ||
207 | if (!ret) | ||
208 | return -EIO; /* timeouted */ | ||
209 | return ret; /* killed (-ERESTARTSYS) */ | ||
210 | } | ||
211 | |||
212 | static const struct rtc_class_ops hid_time_rtc_ops = { | ||
213 | .read_time = hid_rtc_read_time, | ||
214 | }; | ||
215 | |||
216 | static int hid_time_probe(struct platform_device *pdev) | ||
217 | { | ||
218 | int ret = 0; | ||
219 | struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; | ||
220 | struct hid_time_state *time_state = devm_kzalloc(&pdev->dev, | ||
221 | sizeof(struct hid_time_state), GFP_KERNEL); | ||
222 | |||
223 | if (time_state == NULL) | ||
224 | return -ENOMEM; | ||
225 | |||
226 | platform_set_drvdata(pdev, time_state); | ||
227 | |||
228 | spin_lock_init(&time_state->lock_last_time); | ||
229 | init_completion(&time_state->comp_last_time); | ||
230 | time_state->common_attributes.hsdev = hsdev; | ||
231 | time_state->common_attributes.pdev = pdev; | ||
232 | |||
233 | ret = hid_sensor_parse_common_attributes(hsdev, | ||
234 | HID_USAGE_SENSOR_TIME, | ||
235 | &time_state->common_attributes); | ||
236 | if (ret) { | ||
237 | dev_err(&pdev->dev, "failed to setup common attributes!\n"); | ||
238 | return ret; | ||
239 | } | ||
240 | |||
241 | ret = hid_time_parse_report(pdev, hsdev, HID_USAGE_SENSOR_TIME, | ||
242 | time_state); | ||
243 | if (ret) { | ||
244 | dev_err(&pdev->dev, "failed to setup attributes!\n"); | ||
245 | return ret; | ||
246 | } | ||
247 | |||
248 | time_state->callbacks.send_event = hid_time_proc_event; | ||
249 | time_state->callbacks.capture_sample = hid_time_capture_sample; | ||
250 | time_state->callbacks.pdev = pdev; | ||
251 | ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_TIME, | ||
252 | &time_state->callbacks); | ||
253 | if (ret < 0) { | ||
254 | dev_err(&pdev->dev, "register callback failed!\n"); | ||
255 | return ret; | ||
256 | } | ||
257 | |||
258 | time_state->rtc = rtc_device_register("hid-sensor-time", | ||
259 | &pdev->dev, &hid_time_rtc_ops, THIS_MODULE); | ||
260 | |||
261 | if (IS_ERR(time_state->rtc)) { | ||
262 | dev_err(&pdev->dev, "rtc device register failed!\n"); | ||
263 | return PTR_ERR(time_state->rtc); | ||
264 | } | ||
265 | |||
266 | return ret; | ||
267 | } | ||
268 | |||
269 | static int hid_time_remove(struct platform_device *pdev) | ||
270 | { | ||
271 | struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; | ||
272 | struct hid_time_state *time_state = platform_get_drvdata(pdev); | ||
273 | |||
274 | rtc_device_unregister(time_state->rtc); | ||
275 | sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TIME); | ||
276 | |||
277 | return 0; | ||
278 | } | ||
279 | |||
280 | static struct platform_driver hid_time_platform_driver = { | ||
281 | .driver = { | ||
282 | .name = DRIVER_NAME, | ||
283 | .owner = THIS_MODULE, | ||
284 | }, | ||
285 | .probe = hid_time_probe, | ||
286 | .remove = hid_time_remove, | ||
287 | }; | ||
288 | module_platform_driver(hid_time_platform_driver); | ||
289 | |||
290 | MODULE_DESCRIPTION("HID Sensor Time"); | ||
291 | MODULE_AUTHOR("Alexander Holler <holler@ahsoftware.de>"); | ||
292 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c index 75d307ab37f4..82aad695979e 100644 --- a/drivers/rtc/rtc-imxdi.c +++ b/drivers/rtc/rtc-imxdi.c | |||
@@ -406,7 +406,7 @@ static int dryice_rtc_probe(struct platform_device *pdev) | |||
406 | 406 | ||
407 | mutex_init(&imxdi->write_mutex); | 407 | mutex_init(&imxdi->write_mutex); |
408 | 408 | ||
409 | imxdi->clk = clk_get(&pdev->dev, NULL); | 409 | imxdi->clk = devm_clk_get(&pdev->dev, NULL); |
410 | if (IS_ERR(imxdi->clk)) | 410 | if (IS_ERR(imxdi->clk)) |
411 | return PTR_ERR(imxdi->clk); | 411 | return PTR_ERR(imxdi->clk); |
412 | clk_prepare_enable(imxdi->clk); | 412 | clk_prepare_enable(imxdi->clk); |
@@ -475,7 +475,6 @@ static int dryice_rtc_probe(struct platform_device *pdev) | |||
475 | 475 | ||
476 | err: | 476 | err: |
477 | clk_disable_unprepare(imxdi->clk); | 477 | clk_disable_unprepare(imxdi->clk); |
478 | clk_put(imxdi->clk); | ||
479 | 478 | ||
480 | return rc; | 479 | return rc; |
481 | } | 480 | } |
@@ -492,7 +491,6 @@ static int dryice_rtc_remove(struct platform_device *pdev) | |||
492 | rtc_device_unregister(imxdi->rtc); | 491 | rtc_device_unregister(imxdi->rtc); |
493 | 492 | ||
494 | clk_disable_unprepare(imxdi->clk); | 493 | clk_disable_unprepare(imxdi->clk); |
495 | clk_put(imxdi->clk); | ||
496 | 494 | ||
497 | return 0; | 495 | return 0; |
498 | } | 496 | } |
diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c index 1850104705c0..6b4298ea683d 100644 --- a/drivers/rtc/rtc-isl12022.c +++ b/drivers/rtc/rtc-isl12022.c | |||
@@ -227,7 +227,7 @@ static int isl12022_set_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
227 | buf[ISL12022_REG_SC + i]); | 227 | buf[ISL12022_REG_SC + i]); |
228 | if (ret) | 228 | if (ret) |
229 | return -EIO; | 229 | return -EIO; |
230 | }; | 230 | } |
231 | 231 | ||
232 | return 0; | 232 | return 0; |
233 | } | 233 | } |
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index afb7cfa85ccc..c016ad81767a 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c | |||
@@ -506,6 +506,7 @@ isl1208_rtc_interrupt(int irq, void *data) | |||
506 | { | 506 | { |
507 | unsigned long timeout = jiffies + msecs_to_jiffies(1000); | 507 | unsigned long timeout = jiffies + msecs_to_jiffies(1000); |
508 | struct i2c_client *client = data; | 508 | struct i2c_client *client = data; |
509 | struct rtc_device *rtc = i2c_get_clientdata(client); | ||
509 | int handled = 0, sr, err; | 510 | int handled = 0, sr, err; |
510 | 511 | ||
511 | /* | 512 | /* |
@@ -528,6 +529,8 @@ isl1208_rtc_interrupt(int irq, void *data) | |||
528 | if (sr & ISL1208_REG_SR_ALM) { | 529 | if (sr & ISL1208_REG_SR_ALM) { |
529 | dev_dbg(&client->dev, "alarm!\n"); | 530 | dev_dbg(&client->dev, "alarm!\n"); |
530 | 531 | ||
532 | rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF); | ||
533 | |||
531 | /* Clear the alarm */ | 534 | /* Clear the alarm */ |
532 | sr &= ~ISL1208_REG_SR_ALM; | 535 | sr &= ~ISL1208_REG_SR_ALM; |
533 | sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, sr); | 536 | sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, sr); |
diff --git a/drivers/rtc/rtc-lp8788.c b/drivers/rtc/rtc-lp8788.c new file mode 100644 index 000000000000..9a4631218f41 --- /dev/null +++ b/drivers/rtc/rtc-lp8788.c | |||
@@ -0,0 +1,338 @@ | |||
1 | /* | ||
2 | * TI LP8788 MFD - rtc driver | ||
3 | * | ||
4 | * Copyright 2012 Texas Instruments | ||
5 | * | ||
6 | * Author: Milo(Woogyom) Kim <milo.kim@ti.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 version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/err.h> | ||
15 | #include <linux/irqdomain.h> | ||
16 | #include <linux/mfd/lp8788.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/rtc.h> | ||
20 | #include <linux/slab.h> | ||
21 | |||
22 | /* register address */ | ||
23 | #define LP8788_INTEN_3 0x05 | ||
24 | #define LP8788_RTC_UNLOCK 0x64 | ||
25 | #define LP8788_RTC_SEC 0x70 | ||
26 | #define LP8788_ALM1_SEC 0x77 | ||
27 | #define LP8788_ALM1_EN 0x7D | ||
28 | #define LP8788_ALM2_SEC 0x7E | ||
29 | #define LP8788_ALM2_EN 0x84 | ||
30 | |||
31 | /* mask/shift bits */ | ||
32 | #define LP8788_INT_RTC_ALM1_M BIT(1) /* Addr 05h */ | ||
33 | #define LP8788_INT_RTC_ALM1_S 1 | ||
34 | #define LP8788_INT_RTC_ALM2_M BIT(2) /* Addr 05h */ | ||
35 | #define LP8788_INT_RTC_ALM2_S 2 | ||
36 | #define LP8788_ALM_EN_M BIT(7) /* Addr 7Dh or 84h */ | ||
37 | #define LP8788_ALM_EN_S 7 | ||
38 | |||
39 | #define DEFAULT_ALARM_SEL LP8788_ALARM_1 | ||
40 | #define LP8788_MONTH_OFFSET 1 | ||
41 | #define LP8788_BASE_YEAR 2000 | ||
42 | #define MAX_WDAY_BITS 7 | ||
43 | #define LP8788_WDAY_SET 1 | ||
44 | #define RTC_UNLOCK 0x1 | ||
45 | #define RTC_LATCH 0x2 | ||
46 | #define ALARM_IRQ_FLAG (RTC_IRQF | RTC_AF) | ||
47 | |||
48 | enum lp8788_time { | ||
49 | LPTIME_SEC, | ||
50 | LPTIME_MIN, | ||
51 | LPTIME_HOUR, | ||
52 | LPTIME_MDAY, | ||
53 | LPTIME_MON, | ||
54 | LPTIME_YEAR, | ||
55 | LPTIME_WDAY, | ||
56 | LPTIME_MAX, | ||
57 | }; | ||
58 | |||
59 | struct lp8788_rtc { | ||
60 | struct lp8788 *lp; | ||
61 | struct rtc_device *rdev; | ||
62 | enum lp8788_alarm_sel alarm; | ||
63 | int irq; | ||
64 | }; | ||
65 | |||
66 | static const u8 addr_alarm_sec[LP8788_ALARM_MAX] = { | ||
67 | LP8788_ALM1_SEC, | ||
68 | LP8788_ALM2_SEC, | ||
69 | }; | ||
70 | |||
71 | static const u8 addr_alarm_en[LP8788_ALARM_MAX] = { | ||
72 | LP8788_ALM1_EN, | ||
73 | LP8788_ALM2_EN, | ||
74 | }; | ||
75 | |||
76 | static const u8 mask_alarm_en[LP8788_ALARM_MAX] = { | ||
77 | LP8788_INT_RTC_ALM1_M, | ||
78 | LP8788_INT_RTC_ALM2_M, | ||
79 | }; | ||
80 | |||
81 | static const u8 shift_alarm_en[LP8788_ALARM_MAX] = { | ||
82 | LP8788_INT_RTC_ALM1_S, | ||
83 | LP8788_INT_RTC_ALM2_S, | ||
84 | }; | ||
85 | |||
86 | static int _to_tm_wday(u8 lp8788_wday) | ||
87 | { | ||
88 | int i; | ||
89 | |||
90 | if (lp8788_wday == 0) | ||
91 | return 0; | ||
92 | |||
93 | /* lookup defined weekday from read register value */ | ||
94 | for (i = 0; i < MAX_WDAY_BITS; i++) { | ||
95 | if ((lp8788_wday >> i) == LP8788_WDAY_SET) | ||
96 | break; | ||
97 | } | ||
98 | |||
99 | return i + 1; | ||
100 | } | ||
101 | |||
102 | static inline int _to_lp8788_wday(int tm_wday) | ||
103 | { | ||
104 | return LP8788_WDAY_SET << (tm_wday - 1); | ||
105 | } | ||
106 | |||
107 | static void lp8788_rtc_unlock(struct lp8788 *lp) | ||
108 | { | ||
109 | lp8788_write_byte(lp, LP8788_RTC_UNLOCK, RTC_UNLOCK); | ||
110 | lp8788_write_byte(lp, LP8788_RTC_UNLOCK, RTC_LATCH); | ||
111 | } | ||
112 | |||
113 | static int lp8788_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
114 | { | ||
115 | struct lp8788_rtc *rtc = dev_get_drvdata(dev); | ||
116 | struct lp8788 *lp = rtc->lp; | ||
117 | u8 data[LPTIME_MAX]; | ||
118 | int ret; | ||
119 | |||
120 | lp8788_rtc_unlock(lp); | ||
121 | |||
122 | ret = lp8788_read_multi_bytes(lp, LP8788_RTC_SEC, data, LPTIME_MAX); | ||
123 | if (ret) | ||
124 | return ret; | ||
125 | |||
126 | tm->tm_sec = data[LPTIME_SEC]; | ||
127 | tm->tm_min = data[LPTIME_MIN]; | ||
128 | tm->tm_hour = data[LPTIME_HOUR]; | ||
129 | tm->tm_mday = data[LPTIME_MDAY]; | ||
130 | tm->tm_mon = data[LPTIME_MON] - LP8788_MONTH_OFFSET; | ||
131 | tm->tm_year = data[LPTIME_YEAR] + LP8788_BASE_YEAR - 1900; | ||
132 | tm->tm_wday = _to_tm_wday(data[LPTIME_WDAY]); | ||
133 | |||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | static int lp8788_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
138 | { | ||
139 | struct lp8788_rtc *rtc = dev_get_drvdata(dev); | ||
140 | struct lp8788 *lp = rtc->lp; | ||
141 | u8 data[LPTIME_MAX - 1]; | ||
142 | int ret, i, year; | ||
143 | |||
144 | year = tm->tm_year + 1900 - LP8788_BASE_YEAR; | ||
145 | if (year < 0) { | ||
146 | dev_err(lp->dev, "invalid year: %d\n", year); | ||
147 | return -EINVAL; | ||
148 | } | ||
149 | |||
150 | /* because rtc weekday is a readonly register, do not update */ | ||
151 | data[LPTIME_SEC] = tm->tm_sec; | ||
152 | data[LPTIME_MIN] = tm->tm_min; | ||
153 | data[LPTIME_HOUR] = tm->tm_hour; | ||
154 | data[LPTIME_MDAY] = tm->tm_mday; | ||
155 | data[LPTIME_MON] = tm->tm_mon + LP8788_MONTH_OFFSET; | ||
156 | data[LPTIME_YEAR] = year; | ||
157 | |||
158 | for (i = 0; i < ARRAY_SIZE(data); i++) { | ||
159 | ret = lp8788_write_byte(lp, LP8788_RTC_SEC + i, data[i]); | ||
160 | if (ret) | ||
161 | return ret; | ||
162 | } | ||
163 | |||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | static int lp8788_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | ||
168 | { | ||
169 | struct lp8788_rtc *rtc = dev_get_drvdata(dev); | ||
170 | struct lp8788 *lp = rtc->lp; | ||
171 | struct rtc_time *tm = &alarm->time; | ||
172 | u8 addr, data[LPTIME_MAX]; | ||
173 | int ret; | ||
174 | |||
175 | addr = addr_alarm_sec[rtc->alarm]; | ||
176 | ret = lp8788_read_multi_bytes(lp, addr, data, LPTIME_MAX); | ||
177 | if (ret) | ||
178 | return ret; | ||
179 | |||
180 | tm->tm_sec = data[LPTIME_SEC]; | ||
181 | tm->tm_min = data[LPTIME_MIN]; | ||
182 | tm->tm_hour = data[LPTIME_HOUR]; | ||
183 | tm->tm_mday = data[LPTIME_MDAY]; | ||
184 | tm->tm_mon = data[LPTIME_MON] - LP8788_MONTH_OFFSET; | ||
185 | tm->tm_year = data[LPTIME_YEAR] + LP8788_BASE_YEAR - 1900; | ||
186 | tm->tm_wday = _to_tm_wday(data[LPTIME_WDAY]); | ||
187 | alarm->enabled = data[LPTIME_WDAY] & LP8788_ALM_EN_M; | ||
188 | |||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | static int lp8788_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) | ||
193 | { | ||
194 | struct lp8788_rtc *rtc = dev_get_drvdata(dev); | ||
195 | struct lp8788 *lp = rtc->lp; | ||
196 | struct rtc_time *tm = &alarm->time; | ||
197 | u8 addr, data[LPTIME_MAX]; | ||
198 | int ret, i, year; | ||
199 | |||
200 | year = tm->tm_year + 1900 - LP8788_BASE_YEAR; | ||
201 | if (year < 0) { | ||
202 | dev_err(lp->dev, "invalid year: %d\n", year); | ||
203 | return -EINVAL; | ||
204 | } | ||
205 | |||
206 | data[LPTIME_SEC] = tm->tm_sec; | ||
207 | data[LPTIME_MIN] = tm->tm_min; | ||
208 | data[LPTIME_HOUR] = tm->tm_hour; | ||
209 | data[LPTIME_MDAY] = tm->tm_mday; | ||
210 | data[LPTIME_MON] = tm->tm_mon + LP8788_MONTH_OFFSET; | ||
211 | data[LPTIME_YEAR] = year; | ||
212 | data[LPTIME_WDAY] = _to_lp8788_wday(tm->tm_wday); | ||
213 | |||
214 | for (i = 0; i < ARRAY_SIZE(data); i++) { | ||
215 | addr = addr_alarm_sec[rtc->alarm] + i; | ||
216 | ret = lp8788_write_byte(lp, addr, data[i]); | ||
217 | if (ret) | ||
218 | return ret; | ||
219 | } | ||
220 | |||
221 | alarm->enabled = 1; | ||
222 | addr = addr_alarm_en[rtc->alarm]; | ||
223 | |||
224 | return lp8788_update_bits(lp, addr, LP8788_ALM_EN_M, | ||
225 | alarm->enabled << LP8788_ALM_EN_S); | ||
226 | } | ||
227 | |||
228 | static int lp8788_alarm_irq_enable(struct device *dev, unsigned int enable) | ||
229 | { | ||
230 | struct lp8788_rtc *rtc = dev_get_drvdata(dev); | ||
231 | struct lp8788 *lp = rtc->lp; | ||
232 | u8 mask, shift; | ||
233 | |||
234 | if (!rtc->irq) | ||
235 | return -EIO; | ||
236 | |||
237 | mask = mask_alarm_en[rtc->alarm]; | ||
238 | shift = shift_alarm_en[rtc->alarm]; | ||
239 | |||
240 | return lp8788_update_bits(lp, LP8788_INTEN_3, mask, enable << shift); | ||
241 | } | ||
242 | |||
243 | static const struct rtc_class_ops lp8788_rtc_ops = { | ||
244 | .read_time = lp8788_rtc_read_time, | ||
245 | .set_time = lp8788_rtc_set_time, | ||
246 | .read_alarm = lp8788_read_alarm, | ||
247 | .set_alarm = lp8788_set_alarm, | ||
248 | .alarm_irq_enable = lp8788_alarm_irq_enable, | ||
249 | }; | ||
250 | |||
251 | static irqreturn_t lp8788_alarm_irq_handler(int irq, void *ptr) | ||
252 | { | ||
253 | struct lp8788_rtc *rtc = ptr; | ||
254 | |||
255 | rtc_update_irq(rtc->rdev, 1, ALARM_IRQ_FLAG); | ||
256 | return IRQ_HANDLED; | ||
257 | } | ||
258 | |||
259 | static int lp8788_alarm_irq_register(struct platform_device *pdev, | ||
260 | struct lp8788_rtc *rtc) | ||
261 | { | ||
262 | struct resource *r; | ||
263 | struct lp8788 *lp = rtc->lp; | ||
264 | struct irq_domain *irqdm = lp->irqdm; | ||
265 | int irq; | ||
266 | |||
267 | rtc->irq = 0; | ||
268 | |||
269 | /* even the alarm IRQ number is not specified, rtc time should work */ | ||
270 | r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, LP8788_ALM_IRQ); | ||
271 | if (!r) | ||
272 | return 0; | ||
273 | |||
274 | if (rtc->alarm == LP8788_ALARM_1) | ||
275 | irq = r->start; | ||
276 | else | ||
277 | irq = r->end; | ||
278 | |||
279 | rtc->irq = irq_create_mapping(irqdm, irq); | ||
280 | |||
281 | return devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL, | ||
282 | lp8788_alarm_irq_handler, | ||
283 | 0, LP8788_ALM_IRQ, rtc); | ||
284 | } | ||
285 | |||
286 | static int lp8788_rtc_probe(struct platform_device *pdev) | ||
287 | { | ||
288 | struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent); | ||
289 | struct lp8788_rtc *rtc; | ||
290 | struct device *dev = &pdev->dev; | ||
291 | |||
292 | rtc = devm_kzalloc(dev, sizeof(struct lp8788_rtc), GFP_KERNEL); | ||
293 | if (!rtc) | ||
294 | return -ENOMEM; | ||
295 | |||
296 | rtc->lp = lp; | ||
297 | rtc->alarm = lp->pdata ? lp->pdata->alarm_sel : DEFAULT_ALARM_SEL; | ||
298 | platform_set_drvdata(pdev, rtc); | ||
299 | |||
300 | device_init_wakeup(dev, 1); | ||
301 | |||
302 | rtc->rdev = rtc_device_register("lp8788_rtc", dev, | ||
303 | &lp8788_rtc_ops, THIS_MODULE); | ||
304 | if (IS_ERR(rtc->rdev)) { | ||
305 | dev_err(dev, "can not register rtc device\n"); | ||
306 | return PTR_ERR(rtc->rdev); | ||
307 | } | ||
308 | |||
309 | if (lp8788_alarm_irq_register(pdev, rtc)) | ||
310 | dev_warn(lp->dev, "no rtc irq handler\n"); | ||
311 | |||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | static int lp8788_rtc_remove(struct platform_device *pdev) | ||
316 | { | ||
317 | struct lp8788_rtc *rtc = platform_get_drvdata(pdev); | ||
318 | |||
319 | rtc_device_unregister(rtc->rdev); | ||
320 | platform_set_drvdata(pdev, NULL); | ||
321 | |||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | static struct platform_driver lp8788_rtc_driver = { | ||
326 | .probe = lp8788_rtc_probe, | ||
327 | .remove = lp8788_rtc_remove, | ||
328 | .driver = { | ||
329 | .name = LP8788_DEV_RTC, | ||
330 | .owner = THIS_MODULE, | ||
331 | }, | ||
332 | }; | ||
333 | module_platform_driver(lp8788_rtc_driver); | ||
334 | |||
335 | MODULE_DESCRIPTION("Texas Instruments LP8788 RTC Driver"); | ||
336 | MODULE_AUTHOR("Milo Kim"); | ||
337 | MODULE_LICENSE("GPL"); | ||
338 | MODULE_ALIAS("platform:lp8788-rtc"); | ||
diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c new file mode 100644 index 000000000000..6b1337f9baf4 --- /dev/null +++ b/drivers/rtc/rtc-max77686.c | |||
@@ -0,0 +1,641 @@ | |||
1 | /* | ||
2 | * RTC driver for Maxim MAX77686 | ||
3 | * | ||
4 | * Copyright (C) 2012 Samsung Electronics Co.Ltd | ||
5 | * | ||
6 | * based on rtc-max8997.c | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/slab.h> | ||
16 | #include <linux/rtc.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/mutex.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/mfd/max77686-private.h> | ||
22 | #include <linux/irqdomain.h> | ||
23 | #include <linux/regmap.h> | ||
24 | |||
25 | /* RTC Control Register */ | ||
26 | #define BCD_EN_SHIFT 0 | ||
27 | #define BCD_EN_MASK (1 << BCD_EN_SHIFT) | ||
28 | #define MODEL24_SHIFT 1 | ||
29 | #define MODEL24_MASK (1 << MODEL24_SHIFT) | ||
30 | /* RTC Update Register1 */ | ||
31 | #define RTC_UDR_SHIFT 0 | ||
32 | #define RTC_UDR_MASK (1 << RTC_UDR_SHIFT) | ||
33 | #define RTC_RBUDR_SHIFT 4 | ||
34 | #define RTC_RBUDR_MASK (1 << RTC_RBUDR_SHIFT) | ||
35 | /* WTSR and SMPL Register */ | ||
36 | #define WTSRT_SHIFT 0 | ||
37 | #define SMPLT_SHIFT 2 | ||
38 | #define WTSR_EN_SHIFT 6 | ||
39 | #define SMPL_EN_SHIFT 7 | ||
40 | #define WTSRT_MASK (3 << WTSRT_SHIFT) | ||
41 | #define SMPLT_MASK (3 << SMPLT_SHIFT) | ||
42 | #define WTSR_EN_MASK (1 << WTSR_EN_SHIFT) | ||
43 | #define SMPL_EN_MASK (1 << SMPL_EN_SHIFT) | ||
44 | /* RTC Hour register */ | ||
45 | #define HOUR_PM_SHIFT 6 | ||
46 | #define HOUR_PM_MASK (1 << HOUR_PM_SHIFT) | ||
47 | /* RTC Alarm Enable */ | ||
48 | #define ALARM_ENABLE_SHIFT 7 | ||
49 | #define ALARM_ENABLE_MASK (1 << ALARM_ENABLE_SHIFT) | ||
50 | |||
51 | #define MAX77686_RTC_UPDATE_DELAY 16 | ||
52 | #undef MAX77686_RTC_WTSR_SMPL | ||
53 | |||
54 | enum { | ||
55 | RTC_SEC = 0, | ||
56 | RTC_MIN, | ||
57 | RTC_HOUR, | ||
58 | RTC_WEEKDAY, | ||
59 | RTC_MONTH, | ||
60 | RTC_YEAR, | ||
61 | RTC_DATE, | ||
62 | RTC_NR_TIME | ||
63 | }; | ||
64 | |||
65 | struct max77686_rtc_info { | ||
66 | struct device *dev; | ||
67 | struct max77686_dev *max77686; | ||
68 | struct i2c_client *rtc; | ||
69 | struct rtc_device *rtc_dev; | ||
70 | struct mutex lock; | ||
71 | |||
72 | struct regmap *regmap; | ||
73 | |||
74 | int virq; | ||
75 | int rtc_24hr_mode; | ||
76 | }; | ||
77 | |||
78 | enum MAX77686_RTC_OP { | ||
79 | MAX77686_RTC_WRITE, | ||
80 | MAX77686_RTC_READ, | ||
81 | }; | ||
82 | |||
83 | static inline int max77686_rtc_calculate_wday(u8 shifted) | ||
84 | { | ||
85 | int counter = -1; | ||
86 | while (shifted) { | ||
87 | shifted >>= 1; | ||
88 | counter++; | ||
89 | } | ||
90 | return counter; | ||
91 | } | ||
92 | |||
93 | static void max77686_rtc_data_to_tm(u8 *data, struct rtc_time *tm, | ||
94 | int rtc_24hr_mode) | ||
95 | { | ||
96 | tm->tm_sec = data[RTC_SEC] & 0x7f; | ||
97 | tm->tm_min = data[RTC_MIN] & 0x7f; | ||
98 | if (rtc_24hr_mode) | ||
99 | tm->tm_hour = data[RTC_HOUR] & 0x1f; | ||
100 | else { | ||
101 | tm->tm_hour = data[RTC_HOUR] & 0x0f; | ||
102 | if (data[RTC_HOUR] & HOUR_PM_MASK) | ||
103 | tm->tm_hour += 12; | ||
104 | } | ||
105 | |||
106 | tm->tm_wday = max77686_rtc_calculate_wday(data[RTC_WEEKDAY] & 0x7f); | ||
107 | tm->tm_mday = data[RTC_DATE] & 0x1f; | ||
108 | tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1; | ||
109 | tm->tm_year = (data[RTC_YEAR] & 0x7f) + 100; | ||
110 | tm->tm_yday = 0; | ||
111 | tm->tm_isdst = 0; | ||
112 | } | ||
113 | |||
114 | static int max77686_rtc_tm_to_data(struct rtc_time *tm, u8 *data) | ||
115 | { | ||
116 | data[RTC_SEC] = tm->tm_sec; | ||
117 | data[RTC_MIN] = tm->tm_min; | ||
118 | data[RTC_HOUR] = tm->tm_hour; | ||
119 | data[RTC_WEEKDAY] = 1 << tm->tm_wday; | ||
120 | data[RTC_DATE] = tm->tm_mday; | ||
121 | data[RTC_MONTH] = tm->tm_mon + 1; | ||
122 | data[RTC_YEAR] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0 ; | ||
123 | |||
124 | if (tm->tm_year < 100) { | ||
125 | pr_warn("%s: MAX77686 RTC cannot handle the year %d." | ||
126 | "Assume it's 2000.\n", __func__, 1900 + tm->tm_year); | ||
127 | return -EINVAL; | ||
128 | } | ||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | static int max77686_rtc_update(struct max77686_rtc_info *info, | ||
133 | enum MAX77686_RTC_OP op) | ||
134 | { | ||
135 | int ret; | ||
136 | unsigned int data; | ||
137 | |||
138 | if (op == MAX77686_RTC_WRITE) | ||
139 | data = 1 << RTC_UDR_SHIFT; | ||
140 | else | ||
141 | data = 1 << RTC_RBUDR_SHIFT; | ||
142 | |||
143 | ret = regmap_update_bits(info->max77686->rtc_regmap, | ||
144 | MAX77686_RTC_UPDATE0, data, data); | ||
145 | if (ret < 0) | ||
146 | dev_err(info->dev, "%s: fail to write update reg(ret=%d, data=0x%x)\n", | ||
147 | __func__, ret, data); | ||
148 | else { | ||
149 | /* Minimum 16ms delay required before RTC update. */ | ||
150 | msleep(MAX77686_RTC_UPDATE_DELAY); | ||
151 | } | ||
152 | |||
153 | return ret; | ||
154 | } | ||
155 | |||
156 | static int max77686_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
157 | { | ||
158 | struct max77686_rtc_info *info = dev_get_drvdata(dev); | ||
159 | u8 data[RTC_NR_TIME]; | ||
160 | int ret; | ||
161 | |||
162 | mutex_lock(&info->lock); | ||
163 | |||
164 | ret = max77686_rtc_update(info, MAX77686_RTC_READ); | ||
165 | if (ret < 0) | ||
166 | goto out; | ||
167 | |||
168 | ret = regmap_bulk_read(info->max77686->rtc_regmap, | ||
169 | MAX77686_RTC_SEC, data, RTC_NR_TIME); | ||
170 | if (ret < 0) { | ||
171 | dev_err(info->dev, "%s: fail to read time reg(%d)\n", __func__, ret); | ||
172 | goto out; | ||
173 | } | ||
174 | |||
175 | max77686_rtc_data_to_tm(data, tm, info->rtc_24hr_mode); | ||
176 | |||
177 | ret = rtc_valid_tm(tm); | ||
178 | |||
179 | out: | ||
180 | mutex_unlock(&info->lock); | ||
181 | return ret; | ||
182 | } | ||
183 | |||
184 | static int max77686_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
185 | { | ||
186 | struct max77686_rtc_info *info = dev_get_drvdata(dev); | ||
187 | u8 data[RTC_NR_TIME]; | ||
188 | int ret; | ||
189 | |||
190 | ret = max77686_rtc_tm_to_data(tm, data); | ||
191 | if (ret < 0) | ||
192 | return ret; | ||
193 | |||
194 | mutex_lock(&info->lock); | ||
195 | |||
196 | ret = regmap_bulk_write(info->max77686->rtc_regmap, | ||
197 | MAX77686_RTC_SEC, data, RTC_NR_TIME); | ||
198 | if (ret < 0) { | ||
199 | dev_err(info->dev, "%s: fail to write time reg(%d)\n", __func__, | ||
200 | ret); | ||
201 | goto out; | ||
202 | } | ||
203 | |||
204 | ret = max77686_rtc_update(info, MAX77686_RTC_WRITE); | ||
205 | |||
206 | out: | ||
207 | mutex_unlock(&info->lock); | ||
208 | return ret; | ||
209 | } | ||
210 | |||
211 | static int max77686_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
212 | { | ||
213 | struct max77686_rtc_info *info = dev_get_drvdata(dev); | ||
214 | u8 data[RTC_NR_TIME]; | ||
215 | unsigned int val; | ||
216 | int i, ret; | ||
217 | |||
218 | mutex_lock(&info->lock); | ||
219 | |||
220 | ret = max77686_rtc_update(info, MAX77686_RTC_READ); | ||
221 | if (ret < 0) | ||
222 | goto out; | ||
223 | |||
224 | ret = regmap_bulk_read(info->max77686->rtc_regmap, | ||
225 | MAX77686_ALARM1_SEC, data, RTC_NR_TIME); | ||
226 | if (ret < 0) { | ||
227 | dev_err(info->dev, "%s:%d fail to read alarm reg(%d)\n", | ||
228 | __func__, __LINE__, ret); | ||
229 | goto out; | ||
230 | } | ||
231 | |||
232 | max77686_rtc_data_to_tm(data, &alrm->time, info->rtc_24hr_mode); | ||
233 | |||
234 | alrm->enabled = 0; | ||
235 | for (i = 0; i < RTC_NR_TIME; i++) { | ||
236 | if (data[i] & ALARM_ENABLE_MASK) { | ||
237 | alrm->enabled = 1; | ||
238 | break; | ||
239 | } | ||
240 | } | ||
241 | |||
242 | alrm->pending = 0; | ||
243 | ret = regmap_read(info->max77686->regmap, MAX77686_REG_STATUS1, &val); | ||
244 | if (ret < 0) { | ||
245 | dev_err(info->dev, "%s:%d fail to read status1 reg(%d)\n", | ||
246 | __func__, __LINE__, ret); | ||
247 | goto out; | ||
248 | } | ||
249 | |||
250 | if (val & (1 << 4)) /* RTCA1 */ | ||
251 | alrm->pending = 1; | ||
252 | |||
253 | out: | ||
254 | mutex_unlock(&info->lock); | ||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | static int max77686_rtc_stop_alarm(struct max77686_rtc_info *info) | ||
259 | { | ||
260 | u8 data[RTC_NR_TIME]; | ||
261 | int ret, i; | ||
262 | struct rtc_time tm; | ||
263 | |||
264 | if (!mutex_is_locked(&info->lock)) | ||
265 | dev_warn(info->dev, "%s: should have mutex locked\n", __func__); | ||
266 | |||
267 | ret = max77686_rtc_update(info, MAX77686_RTC_READ); | ||
268 | if (ret < 0) | ||
269 | goto out; | ||
270 | |||
271 | ret = regmap_bulk_read(info->max77686->rtc_regmap, | ||
272 | MAX77686_ALARM1_SEC, data, RTC_NR_TIME); | ||
273 | if (ret < 0) { | ||
274 | dev_err(info->dev, "%s: fail to read alarm reg(%d)\n", | ||
275 | __func__, ret); | ||
276 | goto out; | ||
277 | } | ||
278 | |||
279 | max77686_rtc_data_to_tm(data, &tm, info->rtc_24hr_mode); | ||
280 | |||
281 | for (i = 0; i < RTC_NR_TIME; i++) | ||
282 | data[i] &= ~ALARM_ENABLE_MASK; | ||
283 | |||
284 | ret = regmap_bulk_write(info->max77686->rtc_regmap, | ||
285 | MAX77686_ALARM1_SEC, data, RTC_NR_TIME); | ||
286 | if (ret < 0) { | ||
287 | dev_err(info->dev, "%s: fail to write alarm reg(%d)\n", | ||
288 | __func__, ret); | ||
289 | goto out; | ||
290 | } | ||
291 | |||
292 | ret = max77686_rtc_update(info, MAX77686_RTC_WRITE); | ||
293 | out: | ||
294 | return ret; | ||
295 | } | ||
296 | |||
297 | static int max77686_rtc_start_alarm(struct max77686_rtc_info *info) | ||
298 | { | ||
299 | u8 data[RTC_NR_TIME]; | ||
300 | int ret; | ||
301 | struct rtc_time tm; | ||
302 | |||
303 | if (!mutex_is_locked(&info->lock)) | ||
304 | dev_warn(info->dev, "%s: should have mutex locked\n", __func__); | ||
305 | |||
306 | ret = max77686_rtc_update(info, MAX77686_RTC_READ); | ||
307 | if (ret < 0) | ||
308 | goto out; | ||
309 | |||
310 | ret = regmap_bulk_read(info->max77686->rtc_regmap, | ||
311 | MAX77686_ALARM1_SEC, data, RTC_NR_TIME); | ||
312 | if (ret < 0) { | ||
313 | dev_err(info->dev, "%s: fail to read alarm reg(%d)\n", | ||
314 | __func__, ret); | ||
315 | goto out; | ||
316 | } | ||
317 | |||
318 | max77686_rtc_data_to_tm(data, &tm, info->rtc_24hr_mode); | ||
319 | |||
320 | data[RTC_SEC] |= (1 << ALARM_ENABLE_SHIFT); | ||
321 | data[RTC_MIN] |= (1 << ALARM_ENABLE_SHIFT); | ||
322 | data[RTC_HOUR] |= (1 << ALARM_ENABLE_SHIFT); | ||
323 | data[RTC_WEEKDAY] &= ~ALARM_ENABLE_MASK; | ||
324 | if (data[RTC_MONTH] & 0xf) | ||
325 | data[RTC_MONTH] |= (1 << ALARM_ENABLE_SHIFT); | ||
326 | if (data[RTC_YEAR] & 0x7f) | ||
327 | data[RTC_YEAR] |= (1 << ALARM_ENABLE_SHIFT); | ||
328 | if (data[RTC_DATE] & 0x1f) | ||
329 | data[RTC_DATE] |= (1 << ALARM_ENABLE_SHIFT); | ||
330 | |||
331 | ret = regmap_bulk_write(info->max77686->rtc_regmap, | ||
332 | MAX77686_ALARM1_SEC, data, RTC_NR_TIME); | ||
333 | if (ret < 0) { | ||
334 | dev_err(info->dev, "%s: fail to write alarm reg(%d)\n", | ||
335 | __func__, ret); | ||
336 | goto out; | ||
337 | } | ||
338 | |||
339 | ret = max77686_rtc_update(info, MAX77686_RTC_WRITE); | ||
340 | out: | ||
341 | return ret; | ||
342 | } | ||
343 | |||
344 | static int max77686_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
345 | { | ||
346 | struct max77686_rtc_info *info = dev_get_drvdata(dev); | ||
347 | u8 data[RTC_NR_TIME]; | ||
348 | int ret; | ||
349 | |||
350 | ret = max77686_rtc_tm_to_data(&alrm->time, data); | ||
351 | if (ret < 0) | ||
352 | return ret; | ||
353 | |||
354 | mutex_lock(&info->lock); | ||
355 | |||
356 | ret = max77686_rtc_stop_alarm(info); | ||
357 | if (ret < 0) | ||
358 | goto out; | ||
359 | |||
360 | ret = regmap_bulk_write(info->max77686->rtc_regmap, | ||
361 | MAX77686_ALARM1_SEC, data, RTC_NR_TIME); | ||
362 | |||
363 | if (ret < 0) { | ||
364 | dev_err(info->dev, "%s: fail to write alarm reg(%d)\n", | ||
365 | __func__, ret); | ||
366 | goto out; | ||
367 | } | ||
368 | |||
369 | ret = max77686_rtc_update(info, MAX77686_RTC_WRITE); | ||
370 | if (ret < 0) | ||
371 | goto out; | ||
372 | |||
373 | if (alrm->enabled) | ||
374 | ret = max77686_rtc_start_alarm(info); | ||
375 | out: | ||
376 | mutex_unlock(&info->lock); | ||
377 | return ret; | ||
378 | } | ||
379 | |||
380 | static int max77686_rtc_alarm_irq_enable(struct device *dev, | ||
381 | unsigned int enabled) | ||
382 | { | ||
383 | struct max77686_rtc_info *info = dev_get_drvdata(dev); | ||
384 | int ret; | ||
385 | |||
386 | mutex_lock(&info->lock); | ||
387 | if (enabled) | ||
388 | ret = max77686_rtc_start_alarm(info); | ||
389 | else | ||
390 | ret = max77686_rtc_stop_alarm(info); | ||
391 | mutex_unlock(&info->lock); | ||
392 | |||
393 | return ret; | ||
394 | } | ||
395 | |||
396 | static irqreturn_t max77686_rtc_alarm_irq(int irq, void *data) | ||
397 | { | ||
398 | struct max77686_rtc_info *info = data; | ||
399 | |||
400 | dev_info(info->dev, "%s:irq(%d)\n", __func__, irq); | ||
401 | |||
402 | rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF); | ||
403 | |||
404 | return IRQ_HANDLED; | ||
405 | } | ||
406 | |||
407 | static const struct rtc_class_ops max77686_rtc_ops = { | ||
408 | .read_time = max77686_rtc_read_time, | ||
409 | .set_time = max77686_rtc_set_time, | ||
410 | .read_alarm = max77686_rtc_read_alarm, | ||
411 | .set_alarm = max77686_rtc_set_alarm, | ||
412 | .alarm_irq_enable = max77686_rtc_alarm_irq_enable, | ||
413 | }; | ||
414 | |||
415 | #ifdef MAX77686_RTC_WTSR_SMPL | ||
416 | static void max77686_rtc_enable_wtsr(struct max77686_rtc_info *info, bool enable) | ||
417 | { | ||
418 | int ret; | ||
419 | unsigned int val, mask; | ||
420 | |||
421 | if (enable) | ||
422 | val = (1 << WTSR_EN_SHIFT) | (3 << WTSRT_SHIFT); | ||
423 | else | ||
424 | val = 0; | ||
425 | |||
426 | mask = WTSR_EN_MASK | WTSRT_MASK; | ||
427 | |||
428 | dev_info(info->dev, "%s: %s WTSR\n", __func__, | ||
429 | enable ? "enable" : "disable"); | ||
430 | |||
431 | ret = regmap_update_bits(info->max77686->rtc_regmap, | ||
432 | MAX77686_WTSR_SMPL_CNTL, mask, val); | ||
433 | if (ret < 0) { | ||
434 | dev_err(info->dev, "%s: fail to update WTSR reg(%d)\n", | ||
435 | __func__, ret); | ||
436 | return; | ||
437 | } | ||
438 | |||
439 | max77686_rtc_update(info, MAX77686_RTC_WRITE); | ||
440 | } | ||
441 | |||
442 | static void max77686_rtc_enable_smpl(struct max77686_rtc_info *info, bool enable) | ||
443 | { | ||
444 | int ret; | ||
445 | unsigned int val, mask; | ||
446 | |||
447 | if (enable) | ||
448 | val = (1 << SMPL_EN_SHIFT) | (0 << SMPLT_SHIFT); | ||
449 | else | ||
450 | val = 0; | ||
451 | |||
452 | mask = SMPL_EN_MASK | SMPLT_MASK; | ||
453 | |||
454 | dev_info(info->dev, "%s: %s SMPL\n", __func__, | ||
455 | enable ? "enable" : "disable"); | ||
456 | |||
457 | ret = regmap_update_bits(info->max77686->rtc_regmap, | ||
458 | MAX77686_WTSR_SMPL_CNTL, mask, val); | ||
459 | if (ret < 0) { | ||
460 | dev_err(info->dev, "%s: fail to update SMPL reg(%d)\n", | ||
461 | __func__, ret); | ||
462 | return; | ||
463 | } | ||
464 | |||
465 | max77686_rtc_update(info, MAX77686_RTC_WRITE); | ||
466 | |||
467 | val = 0; | ||
468 | regmap_read(info->max77686->rtc_regmap, MAX77686_WTSR_SMPL_CNTL, &val); | ||
469 | pr_info("%s: WTSR_SMPL(0x%02x)\n", __func__, val); | ||
470 | } | ||
471 | #endif /* MAX77686_RTC_WTSR_SMPL */ | ||
472 | |||
473 | static int max77686_rtc_init_reg(struct max77686_rtc_info *info) | ||
474 | { | ||
475 | u8 data[2]; | ||
476 | int ret; | ||
477 | |||
478 | /* Set RTC control register : Binary mode, 24hour mdoe */ | ||
479 | data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); | ||
480 | data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); | ||
481 | |||
482 | info->rtc_24hr_mode = 1; | ||
483 | |||
484 | ret = regmap_bulk_write(info->max77686->rtc_regmap, MAX77686_RTC_CONTROLM, data, 2); | ||
485 | if (ret < 0) { | ||
486 | dev_err(info->dev, "%s: fail to write controlm reg(%d)\n", | ||
487 | __func__, ret); | ||
488 | return ret; | ||
489 | } | ||
490 | |||
491 | ret = max77686_rtc_update(info, MAX77686_RTC_WRITE); | ||
492 | return ret; | ||
493 | } | ||
494 | |||
495 | static struct regmap_config max77686_rtc_regmap_config = { | ||
496 | .reg_bits = 8, | ||
497 | .val_bits = 8, | ||
498 | }; | ||
499 | |||
500 | static int max77686_rtc_probe(struct platform_device *pdev) | ||
501 | { | ||
502 | struct max77686_dev *max77686 = dev_get_drvdata(pdev->dev.parent); | ||
503 | struct max77686_rtc_info *info; | ||
504 | int ret, virq; | ||
505 | |||
506 | dev_info(&pdev->dev, "%s\n", __func__); | ||
507 | |||
508 | info = kzalloc(sizeof(struct max77686_rtc_info), GFP_KERNEL); | ||
509 | if (!info) | ||
510 | return -ENOMEM; | ||
511 | |||
512 | mutex_init(&info->lock); | ||
513 | info->dev = &pdev->dev; | ||
514 | info->max77686 = max77686; | ||
515 | info->rtc = max77686->rtc; | ||
516 | info->max77686->rtc_regmap = regmap_init_i2c(info->max77686->rtc, | ||
517 | &max77686_rtc_regmap_config); | ||
518 | if (IS_ERR(info->max77686->rtc_regmap)) { | ||
519 | ret = PTR_ERR(info->max77686->rtc_regmap); | ||
520 | dev_err(info->max77686->dev, "Failed to allocate register map: %d\n", | ||
521 | ret); | ||
522 | kfree(info); | ||
523 | return ret; | ||
524 | } | ||
525 | platform_set_drvdata(pdev, info); | ||
526 | |||
527 | ret = max77686_rtc_init_reg(info); | ||
528 | |||
529 | if (ret < 0) { | ||
530 | dev_err(&pdev->dev, "Failed to initialize RTC reg:%d\n", ret); | ||
531 | goto err_rtc; | ||
532 | } | ||
533 | |||
534 | #ifdef MAX77686_RTC_WTSR_SMPL | ||
535 | max77686_rtc_enable_wtsr(info, true); | ||
536 | max77686_rtc_enable_smpl(info, true); | ||
537 | #endif | ||
538 | |||
539 | device_init_wakeup(&pdev->dev, 1); | ||
540 | |||
541 | info->rtc_dev = rtc_device_register("max77686-rtc", &pdev->dev, | ||
542 | &max77686_rtc_ops, THIS_MODULE); | ||
543 | |||
544 | if (IS_ERR(info->rtc_dev)) { | ||
545 | dev_info(&pdev->dev, "%s: fail\n", __func__); | ||
546 | |||
547 | ret = PTR_ERR(info->rtc_dev); | ||
548 | dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); | ||
549 | if (ret == 0) | ||
550 | ret = -EINVAL; | ||
551 | goto err_rtc; | ||
552 | } | ||
553 | virq = irq_create_mapping(max77686->irq_domain, MAX77686_RTCIRQ_RTCA1); | ||
554 | if (!virq) | ||
555 | goto err_rtc; | ||
556 | info->virq = virq; | ||
557 | |||
558 | ret = request_threaded_irq(virq, NULL, max77686_rtc_alarm_irq, 0, | ||
559 | "rtc-alarm0", info); | ||
560 | if (ret < 0) { | ||
561 | dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", | ||
562 | info->virq, ret); | ||
563 | goto err_rtc; | ||
564 | } | ||
565 | |||
566 | goto out; | ||
567 | err_rtc: | ||
568 | kfree(info); | ||
569 | return ret; | ||
570 | out: | ||
571 | return ret; | ||
572 | } | ||
573 | |||
574 | static int max77686_rtc_remove(struct platform_device *pdev) | ||
575 | { | ||
576 | struct max77686_rtc_info *info = platform_get_drvdata(pdev); | ||
577 | |||
578 | if (info) { | ||
579 | free_irq(info->virq, info); | ||
580 | rtc_device_unregister(info->rtc_dev); | ||
581 | kfree(info); | ||
582 | } | ||
583 | |||
584 | return 0; | ||
585 | } | ||
586 | |||
587 | static void max77686_rtc_shutdown(struct platform_device *pdev) | ||
588 | { | ||
589 | #ifdef MAX77686_RTC_WTSR_SMPL | ||
590 | struct max77686_rtc_info *info = platform_get_drvdata(pdev); | ||
591 | int i; | ||
592 | u8 val = 0; | ||
593 | |||
594 | for (i = 0; i < 3; i++) { | ||
595 | max77686_rtc_enable_wtsr(info, false); | ||
596 | regmap_read(info->max77686->rtc_regmap, MAX77686_WTSR_SMPL_CNTL, &val); | ||
597 | pr_info("%s: WTSR_SMPL reg(0x%02x)\n", __func__, val); | ||
598 | if (val & WTSR_EN_MASK) | ||
599 | pr_emerg("%s: fail to disable WTSR\n", __func__); | ||
600 | else { | ||
601 | pr_info("%s: success to disable WTSR\n", __func__); | ||
602 | break; | ||
603 | } | ||
604 | } | ||
605 | |||
606 | /* Disable SMPL when power off */ | ||
607 | max77686_rtc_enable_smpl(info, false); | ||
608 | #endif /* MAX77686_RTC_WTSR_SMPL */ | ||
609 | } | ||
610 | |||
611 | static const struct platform_device_id rtc_id[] = { | ||
612 | { "max77686-rtc", 0 }, | ||
613 | {}, | ||
614 | }; | ||
615 | |||
616 | static struct platform_driver max77686_rtc_driver = { | ||
617 | .driver = { | ||
618 | .name = "max77686-rtc", | ||
619 | .owner = THIS_MODULE, | ||
620 | }, | ||
621 | .probe = max77686_rtc_probe, | ||
622 | .remove = max77686_rtc_remove, | ||
623 | .shutdown = max77686_rtc_shutdown, | ||
624 | .id_table = rtc_id, | ||
625 | }; | ||
626 | |||
627 | static int __init max77686_rtc_init(void) | ||
628 | { | ||
629 | return platform_driver_register(&max77686_rtc_driver); | ||
630 | } | ||
631 | module_init(max77686_rtc_init); | ||
632 | |||
633 | static void __exit max77686_rtc_exit(void) | ||
634 | { | ||
635 | platform_driver_unregister(&max77686_rtc_driver); | ||
636 | } | ||
637 | module_exit(max77686_rtc_exit); | ||
638 | |||
639 | MODULE_DESCRIPTION("Maxim MAX77686 RTC driver"); | ||
640 | MODULE_AUTHOR("<woong.byun@samsung.com>"); | ||
641 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-max8907.c b/drivers/rtc/rtc-max8907.c index 1d049da16c85..31ca8faf9f05 100644 --- a/drivers/rtc/rtc-max8907.c +++ b/drivers/rtc/rtc-max8907.c | |||
@@ -205,8 +205,9 @@ static int max8907_rtc_probe(struct platform_device *pdev) | |||
205 | goto err_unregister; | 205 | goto err_unregister; |
206 | } | 206 | } |
207 | 207 | ||
208 | ret = request_threaded_irq(rtc->irq, NULL, max8907_irq_handler, | 208 | ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL, |
209 | IRQF_ONESHOT, "max8907-alarm0", rtc); | 209 | max8907_irq_handler, |
210 | IRQF_ONESHOT, "max8907-alarm0", rtc); | ||
210 | if (ret < 0) { | 211 | if (ret < 0) { |
211 | dev_err(&pdev->dev, "Failed to request IRQ%d: %d\n", | 212 | dev_err(&pdev->dev, "Failed to request IRQ%d: %d\n", |
212 | rtc->irq, ret); | 213 | rtc->irq, ret); |
@@ -224,7 +225,6 @@ static int max8907_rtc_remove(struct platform_device *pdev) | |||
224 | { | 225 | { |
225 | struct max8907_rtc *rtc = platform_get_drvdata(pdev); | 226 | struct max8907_rtc *rtc = platform_get_drvdata(pdev); |
226 | 227 | ||
227 | free_irq(rtc->irq, rtc); | ||
228 | rtc_device_unregister(rtc->rtc_dev); | 228 | rtc_device_unregister(rtc->rtc_dev); |
229 | 229 | ||
230 | return 0; | 230 | return 0; |
diff --git a/drivers/rtc/rtc-max8997.c b/drivers/rtc/rtc-max8997.c new file mode 100644 index 000000000000..00e505b6bee3 --- /dev/null +++ b/drivers/rtc/rtc-max8997.c | |||
@@ -0,0 +1,552 @@ | |||
1 | /* | ||
2 | * RTC driver for Maxim MAX8997 | ||
3 | * | ||
4 | * Copyright (C) 2013 Samsung Electronics Co.Ltd | ||
5 | * | ||
6 | * based on rtc-max8998.c | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/slab.h> | ||
16 | #include <linux/rtc.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/mutex.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/mfd/max8997-private.h> | ||
22 | #include <linux/irqdomain.h> | ||
23 | |||
24 | /* Module parameter for WTSR function control */ | ||
25 | static int wtsr_en = 1; | ||
26 | module_param(wtsr_en, int, 0444); | ||
27 | MODULE_PARM_DESC(wtsr_en, "Wachdog Timeout & Sofware Reset (default=on)"); | ||
28 | /* Module parameter for SMPL function control */ | ||
29 | static int smpl_en = 1; | ||
30 | module_param(smpl_en, int, 0444); | ||
31 | MODULE_PARM_DESC(smpl_en, "Sudden Momentary Power Loss (default=on)"); | ||
32 | |||
33 | /* RTC Control Register */ | ||
34 | #define BCD_EN_SHIFT 0 | ||
35 | #define BCD_EN_MASK (1 << BCD_EN_SHIFT) | ||
36 | #define MODEL24_SHIFT 1 | ||
37 | #define MODEL24_MASK (1 << MODEL24_SHIFT) | ||
38 | /* RTC Update Register1 */ | ||
39 | #define RTC_UDR_SHIFT 0 | ||
40 | #define RTC_UDR_MASK (1 << RTC_UDR_SHIFT) | ||
41 | /* WTSR and SMPL Register */ | ||
42 | #define WTSRT_SHIFT 0 | ||
43 | #define SMPLT_SHIFT 2 | ||
44 | #define WTSR_EN_SHIFT 6 | ||
45 | #define SMPL_EN_SHIFT 7 | ||
46 | #define WTSRT_MASK (3 << WTSRT_SHIFT) | ||
47 | #define SMPLT_MASK (3 << SMPLT_SHIFT) | ||
48 | #define WTSR_EN_MASK (1 << WTSR_EN_SHIFT) | ||
49 | #define SMPL_EN_MASK (1 << SMPL_EN_SHIFT) | ||
50 | /* RTC Hour register */ | ||
51 | #define HOUR_PM_SHIFT 6 | ||
52 | #define HOUR_PM_MASK (1 << HOUR_PM_SHIFT) | ||
53 | /* RTC Alarm Enable */ | ||
54 | #define ALARM_ENABLE_SHIFT 7 | ||
55 | #define ALARM_ENABLE_MASK (1 << ALARM_ENABLE_SHIFT) | ||
56 | |||
57 | enum { | ||
58 | RTC_SEC = 0, | ||
59 | RTC_MIN, | ||
60 | RTC_HOUR, | ||
61 | RTC_WEEKDAY, | ||
62 | RTC_MONTH, | ||
63 | RTC_YEAR, | ||
64 | RTC_DATE, | ||
65 | RTC_NR_TIME | ||
66 | }; | ||
67 | |||
68 | struct max8997_rtc_info { | ||
69 | struct device *dev; | ||
70 | struct max8997_dev *max8997; | ||
71 | struct i2c_client *rtc; | ||
72 | struct rtc_device *rtc_dev; | ||
73 | struct mutex lock; | ||
74 | int virq; | ||
75 | int rtc_24hr_mode; | ||
76 | }; | ||
77 | |||
78 | static void max8997_rtc_data_to_tm(u8 *data, struct rtc_time *tm, | ||
79 | int rtc_24hr_mode) | ||
80 | { | ||
81 | tm->tm_sec = data[RTC_SEC] & 0x7f; | ||
82 | tm->tm_min = data[RTC_MIN] & 0x7f; | ||
83 | if (rtc_24hr_mode) | ||
84 | tm->tm_hour = data[RTC_HOUR] & 0x1f; | ||
85 | else { | ||
86 | tm->tm_hour = data[RTC_HOUR] & 0x0f; | ||
87 | if (data[RTC_HOUR] & HOUR_PM_MASK) | ||
88 | tm->tm_hour += 12; | ||
89 | } | ||
90 | |||
91 | tm->tm_wday = fls(data[RTC_WEEKDAY] & 0x7f) - 1; | ||
92 | tm->tm_mday = data[RTC_DATE] & 0x1f; | ||
93 | tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1; | ||
94 | tm->tm_year = (data[RTC_YEAR] & 0x7f) + 100; | ||
95 | tm->tm_yday = 0; | ||
96 | tm->tm_isdst = 0; | ||
97 | } | ||
98 | |||
99 | static int max8997_rtc_tm_to_data(struct rtc_time *tm, u8 *data) | ||
100 | { | ||
101 | data[RTC_SEC] = tm->tm_sec; | ||
102 | data[RTC_MIN] = tm->tm_min; | ||
103 | data[RTC_HOUR] = tm->tm_hour; | ||
104 | data[RTC_WEEKDAY] = 1 << tm->tm_wday; | ||
105 | data[RTC_DATE] = tm->tm_mday; | ||
106 | data[RTC_MONTH] = tm->tm_mon + 1; | ||
107 | data[RTC_YEAR] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0 ; | ||
108 | |||
109 | if (tm->tm_year < 100) { | ||
110 | pr_warn("%s: MAX8997 RTC cannot handle the year %d." | ||
111 | "Assume it's 2000.\n", __func__, 1900 + tm->tm_year); | ||
112 | return -EINVAL; | ||
113 | } | ||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | static inline int max8997_rtc_set_update_reg(struct max8997_rtc_info *info) | ||
118 | { | ||
119 | int ret; | ||
120 | |||
121 | ret = max8997_write_reg(info->rtc, MAX8997_RTC_UPDATE1, | ||
122 | RTC_UDR_MASK); | ||
123 | if (ret < 0) | ||
124 | dev_err(info->dev, "%s: fail to write update reg(%d)\n", | ||
125 | __func__, ret); | ||
126 | else { | ||
127 | /* Minimum 16ms delay required before RTC update. | ||
128 | * Otherwise, we may read and update based on out-of-date | ||
129 | * value */ | ||
130 | msleep(20); | ||
131 | } | ||
132 | |||
133 | return ret; | ||
134 | } | ||
135 | |||
136 | static int max8997_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
137 | { | ||
138 | struct max8997_rtc_info *info = dev_get_drvdata(dev); | ||
139 | u8 data[RTC_NR_TIME]; | ||
140 | int ret; | ||
141 | |||
142 | mutex_lock(&info->lock); | ||
143 | ret = max8997_bulk_read(info->rtc, MAX8997_RTC_SEC, RTC_NR_TIME, data); | ||
144 | mutex_unlock(&info->lock); | ||
145 | |||
146 | if (ret < 0) { | ||
147 | dev_err(info->dev, "%s: fail to read time reg(%d)\n", __func__, | ||
148 | ret); | ||
149 | return ret; | ||
150 | } | ||
151 | |||
152 | max8997_rtc_data_to_tm(data, tm, info->rtc_24hr_mode); | ||
153 | |||
154 | return rtc_valid_tm(tm); | ||
155 | } | ||
156 | |||
157 | static int max8997_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
158 | { | ||
159 | struct max8997_rtc_info *info = dev_get_drvdata(dev); | ||
160 | u8 data[RTC_NR_TIME]; | ||
161 | int ret; | ||
162 | |||
163 | ret = max8997_rtc_tm_to_data(tm, data); | ||
164 | if (ret < 0) | ||
165 | return ret; | ||
166 | |||
167 | mutex_lock(&info->lock); | ||
168 | |||
169 | ret = max8997_bulk_write(info->rtc, MAX8997_RTC_SEC, RTC_NR_TIME, data); | ||
170 | if (ret < 0) { | ||
171 | dev_err(info->dev, "%s: fail to write time reg(%d)\n", __func__, | ||
172 | ret); | ||
173 | goto out; | ||
174 | } | ||
175 | |||
176 | ret = max8997_rtc_set_update_reg(info); | ||
177 | out: | ||
178 | mutex_unlock(&info->lock); | ||
179 | return ret; | ||
180 | } | ||
181 | |||
182 | static int max8997_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
183 | { | ||
184 | struct max8997_rtc_info *info = dev_get_drvdata(dev); | ||
185 | u8 data[RTC_NR_TIME]; | ||
186 | u8 val; | ||
187 | int i, ret; | ||
188 | |||
189 | mutex_lock(&info->lock); | ||
190 | |||
191 | ret = max8997_bulk_read(info->rtc, MAX8997_RTC_ALARM1_SEC, RTC_NR_TIME, | ||
192 | data); | ||
193 | if (ret < 0) { | ||
194 | dev_err(info->dev, "%s:%d fail to read alarm reg(%d)\n", | ||
195 | __func__, __LINE__, ret); | ||
196 | goto out; | ||
197 | } | ||
198 | |||
199 | max8997_rtc_data_to_tm(data, &alrm->time, info->rtc_24hr_mode); | ||
200 | |||
201 | alrm->enabled = 0; | ||
202 | for (i = 0; i < RTC_NR_TIME; i++) { | ||
203 | if (data[i] & ALARM_ENABLE_MASK) { | ||
204 | alrm->enabled = 1; | ||
205 | break; | ||
206 | } | ||
207 | } | ||
208 | |||
209 | alrm->pending = 0; | ||
210 | ret = max8997_read_reg(info->max8997->i2c, MAX8997_REG_STATUS1, &val); | ||
211 | if (ret < 0) { | ||
212 | dev_err(info->dev, "%s:%d fail to read status1 reg(%d)\n", | ||
213 | __func__, __LINE__, ret); | ||
214 | goto out; | ||
215 | } | ||
216 | |||
217 | if (val & (1 << 4)) /* RTCA1 */ | ||
218 | alrm->pending = 1; | ||
219 | |||
220 | out: | ||
221 | mutex_unlock(&info->lock); | ||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | static int max8997_rtc_stop_alarm(struct max8997_rtc_info *info) | ||
226 | { | ||
227 | u8 data[RTC_NR_TIME]; | ||
228 | int ret, i; | ||
229 | |||
230 | if (!mutex_is_locked(&info->lock)) | ||
231 | dev_warn(info->dev, "%s: should have mutex locked\n", __func__); | ||
232 | |||
233 | ret = max8997_bulk_read(info->rtc, MAX8997_RTC_ALARM1_SEC, RTC_NR_TIME, | ||
234 | data); | ||
235 | if (ret < 0) { | ||
236 | dev_err(info->dev, "%s: fail to read alarm reg(%d)\n", | ||
237 | __func__, ret); | ||
238 | goto out; | ||
239 | } | ||
240 | |||
241 | for (i = 0; i < RTC_NR_TIME; i++) | ||
242 | data[i] &= ~ALARM_ENABLE_MASK; | ||
243 | |||
244 | ret = max8997_bulk_write(info->rtc, MAX8997_RTC_ALARM1_SEC, RTC_NR_TIME, | ||
245 | data); | ||
246 | if (ret < 0) { | ||
247 | dev_err(info->dev, "%s: fail to write alarm reg(%d)\n", | ||
248 | __func__, ret); | ||
249 | goto out; | ||
250 | } | ||
251 | |||
252 | ret = max8997_rtc_set_update_reg(info); | ||
253 | out: | ||
254 | return ret; | ||
255 | } | ||
256 | |||
257 | static int max8997_rtc_start_alarm(struct max8997_rtc_info *info) | ||
258 | { | ||
259 | u8 data[RTC_NR_TIME]; | ||
260 | int ret; | ||
261 | |||
262 | if (!mutex_is_locked(&info->lock)) | ||
263 | dev_warn(info->dev, "%s: should have mutex locked\n", __func__); | ||
264 | |||
265 | ret = max8997_bulk_read(info->rtc, MAX8997_RTC_ALARM1_SEC, RTC_NR_TIME, | ||
266 | data); | ||
267 | if (ret < 0) { | ||
268 | dev_err(info->dev, "%s: fail to read alarm reg(%d)\n", | ||
269 | __func__, ret); | ||
270 | goto out; | ||
271 | } | ||
272 | |||
273 | data[RTC_SEC] |= (1 << ALARM_ENABLE_SHIFT); | ||
274 | data[RTC_MIN] |= (1 << ALARM_ENABLE_SHIFT); | ||
275 | data[RTC_HOUR] |= (1 << ALARM_ENABLE_SHIFT); | ||
276 | data[RTC_WEEKDAY] &= ~ALARM_ENABLE_MASK; | ||
277 | if (data[RTC_MONTH] & 0xf) | ||
278 | data[RTC_MONTH] |= (1 << ALARM_ENABLE_SHIFT); | ||
279 | if (data[RTC_YEAR] & 0x7f) | ||
280 | data[RTC_YEAR] |= (1 << ALARM_ENABLE_SHIFT); | ||
281 | if (data[RTC_DATE] & 0x1f) | ||
282 | data[RTC_DATE] |= (1 << ALARM_ENABLE_SHIFT); | ||
283 | |||
284 | ret = max8997_bulk_write(info->rtc, MAX8997_RTC_ALARM1_SEC, RTC_NR_TIME, | ||
285 | data); | ||
286 | if (ret < 0) { | ||
287 | dev_err(info->dev, "%s: fail to write alarm reg(%d)\n", | ||
288 | __func__, ret); | ||
289 | goto out; | ||
290 | } | ||
291 | |||
292 | ret = max8997_rtc_set_update_reg(info); | ||
293 | out: | ||
294 | return ret; | ||
295 | } | ||
296 | static int max8997_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
297 | { | ||
298 | struct max8997_rtc_info *info = dev_get_drvdata(dev); | ||
299 | u8 data[RTC_NR_TIME]; | ||
300 | int ret; | ||
301 | |||
302 | ret = max8997_rtc_tm_to_data(&alrm->time, data); | ||
303 | if (ret < 0) | ||
304 | return ret; | ||
305 | |||
306 | dev_info(info->dev, "%s: %d-%02d-%02d %02d:%02d:%02d\n", __func__, | ||
307 | data[RTC_YEAR] + 2000, data[RTC_MONTH], data[RTC_DATE], | ||
308 | data[RTC_HOUR], data[RTC_MIN], data[RTC_SEC]); | ||
309 | |||
310 | mutex_lock(&info->lock); | ||
311 | |||
312 | ret = max8997_rtc_stop_alarm(info); | ||
313 | if (ret < 0) | ||
314 | goto out; | ||
315 | |||
316 | ret = max8997_bulk_write(info->rtc, MAX8997_RTC_ALARM1_SEC, RTC_NR_TIME, | ||
317 | data); | ||
318 | if (ret < 0) { | ||
319 | dev_err(info->dev, "%s: fail to write alarm reg(%d)\n", | ||
320 | __func__, ret); | ||
321 | goto out; | ||
322 | } | ||
323 | |||
324 | ret = max8997_rtc_set_update_reg(info); | ||
325 | if (ret < 0) | ||
326 | goto out; | ||
327 | |||
328 | if (alrm->enabled) | ||
329 | ret = max8997_rtc_start_alarm(info); | ||
330 | out: | ||
331 | mutex_unlock(&info->lock); | ||
332 | return ret; | ||
333 | } | ||
334 | |||
335 | static int max8997_rtc_alarm_irq_enable(struct device *dev, | ||
336 | unsigned int enabled) | ||
337 | { | ||
338 | struct max8997_rtc_info *info = dev_get_drvdata(dev); | ||
339 | int ret; | ||
340 | |||
341 | mutex_lock(&info->lock); | ||
342 | if (enabled) | ||
343 | ret = max8997_rtc_start_alarm(info); | ||
344 | else | ||
345 | ret = max8997_rtc_stop_alarm(info); | ||
346 | mutex_unlock(&info->lock); | ||
347 | |||
348 | return ret; | ||
349 | } | ||
350 | |||
351 | static irqreturn_t max8997_rtc_alarm_irq(int irq, void *data) | ||
352 | { | ||
353 | struct max8997_rtc_info *info = data; | ||
354 | |||
355 | dev_info(info->dev, "%s:irq(%d)\n", __func__, irq); | ||
356 | |||
357 | rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF); | ||
358 | |||
359 | return IRQ_HANDLED; | ||
360 | } | ||
361 | |||
362 | static const struct rtc_class_ops max8997_rtc_ops = { | ||
363 | .read_time = max8997_rtc_read_time, | ||
364 | .set_time = max8997_rtc_set_time, | ||
365 | .read_alarm = max8997_rtc_read_alarm, | ||
366 | .set_alarm = max8997_rtc_set_alarm, | ||
367 | .alarm_irq_enable = max8997_rtc_alarm_irq_enable, | ||
368 | }; | ||
369 | |||
370 | static void max8997_rtc_enable_wtsr(struct max8997_rtc_info *info, bool enable) | ||
371 | { | ||
372 | int ret; | ||
373 | u8 val, mask; | ||
374 | |||
375 | if (!wtsr_en) | ||
376 | return; | ||
377 | |||
378 | if (enable) | ||
379 | val = (1 << WTSR_EN_SHIFT) | (3 << WTSRT_SHIFT); | ||
380 | else | ||
381 | val = 0; | ||
382 | |||
383 | mask = WTSR_EN_MASK | WTSRT_MASK; | ||
384 | |||
385 | dev_info(info->dev, "%s: %s WTSR\n", __func__, | ||
386 | enable ? "enable" : "disable"); | ||
387 | |||
388 | ret = max8997_update_reg(info->rtc, MAX8997_RTC_WTSR_SMPL, val, mask); | ||
389 | if (ret < 0) { | ||
390 | dev_err(info->dev, "%s: fail to update WTSR reg(%d)\n", | ||
391 | __func__, ret); | ||
392 | return; | ||
393 | } | ||
394 | |||
395 | max8997_rtc_set_update_reg(info); | ||
396 | } | ||
397 | |||
398 | static void max8997_rtc_enable_smpl(struct max8997_rtc_info *info, bool enable) | ||
399 | { | ||
400 | int ret; | ||
401 | u8 val, mask; | ||
402 | |||
403 | if (!smpl_en) | ||
404 | return; | ||
405 | |||
406 | if (enable) | ||
407 | val = (1 << SMPL_EN_SHIFT) | (0 << SMPLT_SHIFT); | ||
408 | else | ||
409 | val = 0; | ||
410 | |||
411 | mask = SMPL_EN_MASK | SMPLT_MASK; | ||
412 | |||
413 | dev_info(info->dev, "%s: %s SMPL\n", __func__, | ||
414 | enable ? "enable" : "disable"); | ||
415 | |||
416 | ret = max8997_update_reg(info->rtc, MAX8997_RTC_WTSR_SMPL, val, mask); | ||
417 | if (ret < 0) { | ||
418 | dev_err(info->dev, "%s: fail to update SMPL reg(%d)\n", | ||
419 | __func__, ret); | ||
420 | return; | ||
421 | } | ||
422 | |||
423 | max8997_rtc_set_update_reg(info); | ||
424 | |||
425 | val = 0; | ||
426 | max8997_read_reg(info->rtc, MAX8997_RTC_WTSR_SMPL, &val); | ||
427 | pr_info("%s: WTSR_SMPL(0x%02x)\n", __func__, val); | ||
428 | } | ||
429 | |||
430 | static int max8997_rtc_init_reg(struct max8997_rtc_info *info) | ||
431 | { | ||
432 | u8 data[2]; | ||
433 | int ret; | ||
434 | |||
435 | /* Set RTC control register : Binary mode, 24hour mdoe */ | ||
436 | data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); | ||
437 | data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); | ||
438 | |||
439 | info->rtc_24hr_mode = 1; | ||
440 | |||
441 | ret = max8997_bulk_write(info->rtc, MAX8997_RTC_CTRLMASK, 2, data); | ||
442 | if (ret < 0) { | ||
443 | dev_err(info->dev, "%s: fail to write controlm reg(%d)\n", | ||
444 | __func__, ret); | ||
445 | return ret; | ||
446 | } | ||
447 | |||
448 | ret = max8997_rtc_set_update_reg(info); | ||
449 | return ret; | ||
450 | } | ||
451 | |||
452 | static int max8997_rtc_probe(struct platform_device *pdev) | ||
453 | { | ||
454 | struct max8997_dev *max8997 = dev_get_drvdata(pdev->dev.parent); | ||
455 | struct max8997_rtc_info *info; | ||
456 | int ret, virq; | ||
457 | |||
458 | info = devm_kzalloc(&pdev->dev, sizeof(struct max8997_rtc_info), | ||
459 | GFP_KERNEL); | ||
460 | if (!info) | ||
461 | return -ENOMEM; | ||
462 | |||
463 | mutex_init(&info->lock); | ||
464 | info->dev = &pdev->dev; | ||
465 | info->max8997 = max8997; | ||
466 | info->rtc = max8997->rtc; | ||
467 | |||
468 | platform_set_drvdata(pdev, info); | ||
469 | |||
470 | ret = max8997_rtc_init_reg(info); | ||
471 | |||
472 | if (ret < 0) { | ||
473 | dev_err(&pdev->dev, "Failed to initialize RTC reg:%d\n", ret); | ||
474 | return ret; | ||
475 | } | ||
476 | |||
477 | max8997_rtc_enable_wtsr(info, true); | ||
478 | max8997_rtc_enable_smpl(info, true); | ||
479 | |||
480 | device_init_wakeup(&pdev->dev, 1); | ||
481 | |||
482 | info->rtc_dev = rtc_device_register("max8997-rtc", &pdev->dev, | ||
483 | &max8997_rtc_ops, THIS_MODULE); | ||
484 | |||
485 | if (IS_ERR(info->rtc_dev)) { | ||
486 | ret = PTR_ERR(info->rtc_dev); | ||
487 | dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); | ||
488 | return ret; | ||
489 | } | ||
490 | |||
491 | virq = irq_create_mapping(max8997->irq_domain, MAX8997_PMICIRQ_RTCA1); | ||
492 | if (!virq) { | ||
493 | dev_err(&pdev->dev, "Failed to create mapping alarm IRQ\n"); | ||
494 | goto err_out; | ||
495 | } | ||
496 | info->virq = virq; | ||
497 | |||
498 | ret = devm_request_threaded_irq(&pdev->dev, virq, NULL, | ||
499 | max8997_rtc_alarm_irq, 0, | ||
500 | "rtc-alarm0", info); | ||
501 | if (ret < 0) { | ||
502 | dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", | ||
503 | info->virq, ret); | ||
504 | goto err_out; | ||
505 | } | ||
506 | |||
507 | return ret; | ||
508 | |||
509 | err_out: | ||
510 | rtc_device_unregister(info->rtc_dev); | ||
511 | return ret; | ||
512 | } | ||
513 | |||
514 | static int max8997_rtc_remove(struct platform_device *pdev) | ||
515 | { | ||
516 | struct max8997_rtc_info *info = platform_get_drvdata(pdev); | ||
517 | |||
518 | if (info) | ||
519 | rtc_device_unregister(info->rtc_dev); | ||
520 | |||
521 | return 0; | ||
522 | } | ||
523 | |||
524 | static void max8997_rtc_shutdown(struct platform_device *pdev) | ||
525 | { | ||
526 | struct max8997_rtc_info *info = platform_get_drvdata(pdev); | ||
527 | |||
528 | max8997_rtc_enable_wtsr(info, false); | ||
529 | max8997_rtc_enable_smpl(info, false); | ||
530 | } | ||
531 | |||
532 | static const struct platform_device_id rtc_id[] = { | ||
533 | { "max8997-rtc", 0 }, | ||
534 | {}, | ||
535 | }; | ||
536 | |||
537 | static struct platform_driver max8997_rtc_driver = { | ||
538 | .driver = { | ||
539 | .name = "max8997-rtc", | ||
540 | .owner = THIS_MODULE, | ||
541 | }, | ||
542 | .probe = max8997_rtc_probe, | ||
543 | .remove = max8997_rtc_remove, | ||
544 | .shutdown = max8997_rtc_shutdown, | ||
545 | .id_table = rtc_id, | ||
546 | }; | ||
547 | |||
548 | module_platform_driver(max8997_rtc_driver); | ||
549 | |||
550 | MODULE_DESCRIPTION("Maxim MAX8997 RTC driver"); | ||
551 | MODULE_AUTHOR("<ms925.kim@samsung.com>"); | ||
552 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index bec10be96f84..bdcc60830aec 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/rtc.h> | 15 | #include <linux/rtc.h> |
16 | #include <linux/of.h> | ||
16 | #include <linux/of_device.h> | 17 | #include <linux/of_device.h> |
17 | #include <linux/of_platform.h> | 18 | #include <linux/of_platform.h> |
18 | #include <linux/io.h> | 19 | #include <linux/io.h> |
@@ -403,17 +404,19 @@ static int mpc5121_rtc_remove(struct platform_device *op) | |||
403 | return 0; | 404 | return 0; |
404 | } | 405 | } |
405 | 406 | ||
407 | #ifdef CONFIG_OF | ||
406 | static struct of_device_id mpc5121_rtc_match[] = { | 408 | static struct of_device_id mpc5121_rtc_match[] = { |
407 | { .compatible = "fsl,mpc5121-rtc", }, | 409 | { .compatible = "fsl,mpc5121-rtc", }, |
408 | { .compatible = "fsl,mpc5200-rtc", }, | 410 | { .compatible = "fsl,mpc5200-rtc", }, |
409 | {}, | 411 | {}, |
410 | }; | 412 | }; |
413 | #endif | ||
411 | 414 | ||
412 | static struct platform_driver mpc5121_rtc_driver = { | 415 | static struct platform_driver mpc5121_rtc_driver = { |
413 | .driver = { | 416 | .driver = { |
414 | .name = "mpc5121-rtc", | 417 | .name = "mpc5121-rtc", |
415 | .owner = THIS_MODULE, | 418 | .owner = THIS_MODULE, |
416 | .of_match_table = mpc5121_rtc_match, | 419 | .of_match_table = of_match_ptr(mpc5121_rtc_match), |
417 | }, | 420 | }, |
418 | .probe = mpc5121_rtc_probe, | 421 | .probe = mpc5121_rtc_probe, |
419 | .remove = mpc5121_rtc_remove, | 422 | .remove = mpc5121_rtc_remove, |
diff --git a/drivers/rtc/rtc-pcf8523.c b/drivers/rtc/rtc-pcf8523.c index be05a645f99e..889e3160e701 100644 --- a/drivers/rtc/rtc-pcf8523.c +++ b/drivers/rtc/rtc-pcf8523.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #define REG_CONTROL3_PM_VDD (1 << 6) /* switch-over disabled */ | 23 | #define REG_CONTROL3_PM_VDD (1 << 6) /* switch-over disabled */ |
24 | #define REG_CONTROL3_PM_DSM (1 << 5) /* direct switching mode */ | 24 | #define REG_CONTROL3_PM_DSM (1 << 5) /* direct switching mode */ |
25 | #define REG_CONTROL3_PM_MASK 0xe0 | 25 | #define REG_CONTROL3_PM_MASK 0xe0 |
26 | #define REG_CONTROL3_BLF (1 << 2) /* battery low bit, read-only */ | ||
26 | 27 | ||
27 | #define REG_SECONDS 0x03 | 28 | #define REG_SECONDS 0x03 |
28 | #define REG_SECONDS_OS (1 << 7) | 29 | #define REG_SECONDS_OS (1 << 7) |
@@ -250,9 +251,39 @@ static int pcf8523_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
250 | return pcf8523_start_rtc(client); | 251 | return pcf8523_start_rtc(client); |
251 | } | 252 | } |
252 | 253 | ||
254 | #ifdef CONFIG_RTC_INTF_DEV | ||
255 | static int pcf8523_rtc_ioctl(struct device *dev, unsigned int cmd, | ||
256 | unsigned long arg) | ||
257 | { | ||
258 | struct i2c_client *client = to_i2c_client(dev); | ||
259 | u8 value; | ||
260 | int ret = 0, err; | ||
261 | |||
262 | switch (cmd) { | ||
263 | case RTC_VL_READ: | ||
264 | err = pcf8523_read(client, REG_CONTROL3, &value); | ||
265 | if (err < 0) | ||
266 | return err; | ||
267 | |||
268 | if (value & REG_CONTROL3_BLF) | ||
269 | ret = 1; | ||
270 | |||
271 | if (copy_to_user((void __user *)arg, &ret, sizeof(int))) | ||
272 | return -EFAULT; | ||
273 | |||
274 | return 0; | ||
275 | default: | ||
276 | return -ENOIOCTLCMD; | ||
277 | } | ||
278 | } | ||
279 | #else | ||
280 | #define pcf8523_rtc_ioctl NULL | ||
281 | #endif | ||
282 | |||
253 | static const struct rtc_class_ops pcf8523_rtc_ops = { | 283 | static const struct rtc_class_ops pcf8523_rtc_ops = { |
254 | .read_time = pcf8523_rtc_read_time, | 284 | .read_time = pcf8523_rtc_read_time, |
255 | .set_time = pcf8523_rtc_set_time, | 285 | .set_time = pcf8523_rtc_set_time, |
286 | .ioctl = pcf8523_rtc_ioctl, | ||
256 | }; | 287 | }; |
257 | 288 | ||
258 | static int pcf8523_probe(struct i2c_client *client, | 289 | static int pcf8523_probe(struct i2c_client *client, |
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 7098ee89bd29..f7daf18a112e 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c | |||
@@ -181,7 +181,7 @@ static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
181 | __func__, err, data[0], data[1]); | 181 | __func__, err, data[0], data[1]); |
182 | return -EIO; | 182 | return -EIO; |
183 | } | 183 | } |
184 | }; | 184 | } |
185 | 185 | ||
186 | return 0; | 186 | return 0; |
187 | } | 187 | } |
diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c index 3415b8f18555..5f97c61247d5 100644 --- a/drivers/rtc/rtc-pcf8583.c +++ b/drivers/rtc/rtc-pcf8583.c | |||
@@ -185,8 +185,8 @@ static int pcf8583_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
185 | if (ctrl & (CTRL_STOP | CTRL_HOLD)) { | 185 | if (ctrl & (CTRL_STOP | CTRL_HOLD)) { |
186 | unsigned char new_ctrl = ctrl & ~(CTRL_STOP | CTRL_HOLD); | 186 | unsigned char new_ctrl = ctrl & ~(CTRL_STOP | CTRL_HOLD); |
187 | 187 | ||
188 | printk(KERN_WARNING "RTC: resetting control %02x -> %02x\n", | 188 | dev_warn(dev, "resetting control %02x -> %02x\n", |
189 | ctrl, new_ctrl); | 189 | ctrl, new_ctrl); |
190 | 190 | ||
191 | if ((err = pcf8583_set_ctrl(client, &new_ctrl)) < 0) | 191 | if ((err = pcf8583_set_ctrl(client, &new_ctrl)) < 0) |
192 | return err; | 192 | return err; |
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 08378e3cc21c..8900ea784817 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #define RTC_YMR 0x34 /* Year match register */ | 44 | #define RTC_YMR 0x34 /* Year match register */ |
45 | #define RTC_YLR 0x38 /* Year data load register */ | 45 | #define RTC_YLR 0x38 /* Year data load register */ |
46 | 46 | ||
47 | #define RTC_CR_EN (1 << 0) /* counter enable bit */ | ||
47 | #define RTC_CR_CWEN (1 << 26) /* Clockwatch enable bit */ | 48 | #define RTC_CR_CWEN (1 << 26) /* Clockwatch enable bit */ |
48 | 49 | ||
49 | #define RTC_TCR_EN (1 << 1) /* Periodic timer enable bit */ | 50 | #define RTC_TCR_EN (1 << 1) /* Periodic timer enable bit */ |
@@ -320,7 +321,7 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) | |||
320 | struct pl031_local *ldata; | 321 | struct pl031_local *ldata; |
321 | struct pl031_vendor_data *vendor = id->data; | 322 | struct pl031_vendor_data *vendor = id->data; |
322 | struct rtc_class_ops *ops = &vendor->ops; | 323 | struct rtc_class_ops *ops = &vendor->ops; |
323 | unsigned long time; | 324 | unsigned long time, data; |
324 | 325 | ||
325 | ret = amba_request_regions(adev, NULL); | 326 | ret = amba_request_regions(adev, NULL); |
326 | if (ret) | 327 | if (ret) |
@@ -345,10 +346,13 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) | |||
345 | dev_dbg(&adev->dev, "designer ID = 0x%02x\n", amba_manf(adev)); | 346 | dev_dbg(&adev->dev, "designer ID = 0x%02x\n", amba_manf(adev)); |
346 | dev_dbg(&adev->dev, "revision = 0x%01x\n", amba_rev(adev)); | 347 | dev_dbg(&adev->dev, "revision = 0x%01x\n", amba_rev(adev)); |
347 | 348 | ||
349 | data = readl(ldata->base + RTC_CR); | ||
348 | /* Enable the clockwatch on ST Variants */ | 350 | /* Enable the clockwatch on ST Variants */ |
349 | if (vendor->clockwatch) | 351 | if (vendor->clockwatch) |
350 | writel(readl(ldata->base + RTC_CR) | RTC_CR_CWEN, | 352 | data |= RTC_CR_CWEN; |
351 | ldata->base + RTC_CR); | 353 | else |
354 | data |= RTC_CR_EN; | ||
355 | writel(data, ldata->base + RTC_CR); | ||
352 | 356 | ||
353 | /* | 357 | /* |
354 | * On ST PL031 variants, the RTC reset value does not provide correct | 358 | * On ST PL031 variants, the RTC reset value does not provide correct |
@@ -380,6 +384,8 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) | |||
380 | goto out_no_irq; | 384 | goto out_no_irq; |
381 | } | 385 | } |
382 | 386 | ||
387 | device_init_wakeup(&adev->dev, 1); | ||
388 | |||
383 | return 0; | 389 | return 0; |
384 | 390 | ||
385 | out_no_irq: | 391 | out_no_irq: |
diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c index f771b2ee4b18..03c85ee719a7 100644 --- a/drivers/rtc/rtc-pxa.c +++ b/drivers/rtc/rtc-pxa.c | |||
@@ -62,6 +62,10 @@ | |||
62 | #define RYxR_MONTH_S 5 | 62 | #define RYxR_MONTH_S 5 |
63 | #define RYxR_MONTH_MASK (0xf << RYxR_MONTH_S) | 63 | #define RYxR_MONTH_MASK (0xf << RYxR_MONTH_S) |
64 | #define RYxR_DAY_MASK 0x1f | 64 | #define RYxR_DAY_MASK 0x1f |
65 | #define RDxR_WOM_S 20 | ||
66 | #define RDxR_WOM_MASK (0x7 << RDxR_WOM_S) | ||
67 | #define RDxR_DOW_S 17 | ||
68 | #define RDxR_DOW_MASK (0x7 << RDxR_DOW_S) | ||
65 | #define RDxR_HOUR_S 12 | 69 | #define RDxR_HOUR_S 12 |
66 | #define RDxR_HOUR_MASK (0x1f << RDxR_HOUR_S) | 70 | #define RDxR_HOUR_MASK (0x1f << RDxR_HOUR_S) |
67 | #define RDxR_MIN_S 6 | 71 | #define RDxR_MIN_S 6 |
@@ -91,6 +95,7 @@ struct pxa_rtc { | |||
91 | spinlock_t lock; /* Protects this structure */ | 95 | spinlock_t lock; /* Protects this structure */ |
92 | }; | 96 | }; |
93 | 97 | ||
98 | |||
94 | static u32 ryxr_calc(struct rtc_time *tm) | 99 | static u32 ryxr_calc(struct rtc_time *tm) |
95 | { | 100 | { |
96 | return ((tm->tm_year + 1900) << RYxR_YEAR_S) | 101 | return ((tm->tm_year + 1900) << RYxR_YEAR_S) |
@@ -100,7 +105,10 @@ static u32 ryxr_calc(struct rtc_time *tm) | |||
100 | 105 | ||
101 | static u32 rdxr_calc(struct rtc_time *tm) | 106 | static u32 rdxr_calc(struct rtc_time *tm) |
102 | { | 107 | { |
103 | return (tm->tm_hour << RDxR_HOUR_S) | (tm->tm_min << RDxR_MIN_S) | 108 | return ((((tm->tm_mday + 6) / 7) << RDxR_WOM_S) & RDxR_WOM_MASK) |
109 | | (((tm->tm_wday + 1) << RDxR_DOW_S) & RDxR_DOW_MASK) | ||
110 | | (tm->tm_hour << RDxR_HOUR_S) | ||
111 | | (tm->tm_min << RDxR_MIN_S) | ||
104 | | tm->tm_sec; | 112 | | tm->tm_sec; |
105 | } | 113 | } |
106 | 114 | ||
@@ -109,6 +117,7 @@ static void tm_calc(u32 rycr, u32 rdcr, struct rtc_time *tm) | |||
109 | tm->tm_year = ((rycr & RYxR_YEAR_MASK) >> RYxR_YEAR_S) - 1900; | 117 | tm->tm_year = ((rycr & RYxR_YEAR_MASK) >> RYxR_YEAR_S) - 1900; |
110 | tm->tm_mon = (((rycr & RYxR_MONTH_MASK) >> RYxR_MONTH_S)) - 1; | 118 | tm->tm_mon = (((rycr & RYxR_MONTH_MASK) >> RYxR_MONTH_S)) - 1; |
111 | tm->tm_mday = (rycr & RYxR_DAY_MASK); | 119 | tm->tm_mday = (rycr & RYxR_DAY_MASK); |
120 | tm->tm_wday = ((rycr & RDxR_DOW_MASK) >> RDxR_DOW_S) - 1; | ||
112 | tm->tm_hour = (rdcr & RDxR_HOUR_MASK) >> RDxR_HOUR_S; | 121 | tm->tm_hour = (rdcr & RDxR_HOUR_MASK) >> RDxR_HOUR_S; |
113 | tm->tm_min = (rdcr & RDxR_MIN_MASK) >> RDxR_MIN_S; | 122 | tm->tm_min = (rdcr & RDxR_MIN_MASK) >> RDxR_MIN_S; |
114 | tm->tm_sec = rdcr & RDxR_SEC_MASK; | 123 | tm->tm_sec = rdcr & RDxR_SEC_MASK; |
@@ -300,8 +309,6 @@ static int pxa_rtc_proc(struct device *dev, struct seq_file *seq) | |||
300 | } | 309 | } |
301 | 310 | ||
302 | static const struct rtc_class_ops pxa_rtc_ops = { | 311 | static const struct rtc_class_ops pxa_rtc_ops = { |
303 | .open = pxa_rtc_open, | ||
304 | .release = pxa_rtc_release, | ||
305 | .read_time = pxa_rtc_read_time, | 312 | .read_time = pxa_rtc_read_time, |
306 | .set_time = pxa_rtc_set_time, | 313 | .set_time = pxa_rtc_set_time, |
307 | .read_alarm = pxa_rtc_read_alarm, | 314 | .read_alarm = pxa_rtc_read_alarm, |
@@ -341,7 +348,7 @@ static int __init pxa_rtc_probe(struct platform_device *pdev) | |||
341 | dev_err(dev, "No alarm IRQ resource defined\n"); | 348 | dev_err(dev, "No alarm IRQ resource defined\n"); |
342 | goto err_ress; | 349 | goto err_ress; |
343 | } | 350 | } |
344 | 351 | pxa_rtc_open(dev); | |
345 | ret = -ENOMEM; | 352 | ret = -ENOMEM; |
346 | pxa_rtc->base = ioremap(pxa_rtc->ress->start, | 353 | pxa_rtc->base = ioremap(pxa_rtc->ress->start, |
347 | resource_size(pxa_rtc->ress)); | 354 | resource_size(pxa_rtc->ress)); |
@@ -387,6 +394,9 @@ static int __exit pxa_rtc_remove(struct platform_device *pdev) | |||
387 | { | 394 | { |
388 | struct pxa_rtc *pxa_rtc = platform_get_drvdata(pdev); | 395 | struct pxa_rtc *pxa_rtc = platform_get_drvdata(pdev); |
389 | 396 | ||
397 | struct device *dev = &pdev->dev; | ||
398 | pxa_rtc_release(dev); | ||
399 | |||
390 | rtc_device_unregister(pxa_rtc->rtc); | 400 | rtc_device_unregister(pxa_rtc->rtc); |
391 | 401 | ||
392 | spin_lock_irq(&pxa_rtc->lock); | 402 | spin_lock_irq(&pxa_rtc->lock); |
@@ -444,10 +454,7 @@ static struct platform_driver pxa_rtc_driver = { | |||
444 | 454 | ||
445 | static int __init pxa_rtc_init(void) | 455 | static int __init pxa_rtc_init(void) |
446 | { | 456 | { |
447 | if (cpu_is_pxa27x() || cpu_is_pxa3xx()) | 457 | return platform_driver_probe(&pxa_rtc_driver, pxa_rtc_probe); |
448 | return platform_driver_probe(&pxa_rtc_driver, pxa_rtc_probe); | ||
449 | |||
450 | return -ENODEV; | ||
451 | } | 458 | } |
452 | 459 | ||
453 | static void __exit pxa_rtc_exit(void) | 460 | static void __exit pxa_rtc_exit(void) |
diff --git a/drivers/rtc/rtc-rs5c313.c b/drivers/rtc/rtc-rs5c313.c index d1aee793ecc8..d98ea5b759c8 100644 --- a/drivers/rtc/rtc-rs5c313.c +++ b/drivers/rtc/rtc-rs5c313.c | |||
@@ -39,6 +39,8 @@ | |||
39 | * 1.13 Nobuhiro Iwamatsu: Updata driver. | 39 | * 1.13 Nobuhiro Iwamatsu: Updata driver. |
40 | */ | 40 | */ |
41 | 41 | ||
42 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
43 | |||
42 | #include <linux/module.h> | 44 | #include <linux/module.h> |
43 | #include <linux/err.h> | 45 | #include <linux/err.h> |
44 | #include <linux/rtc.h> | 46 | #include <linux/rtc.h> |
@@ -352,8 +354,7 @@ static void rs5c313_check_xstp_bit(void) | |||
352 | tm.tm_year = 2000 - 1900; | 354 | tm.tm_year = 2000 - 1900; |
353 | 355 | ||
354 | rs5c313_rtc_set_time(NULL, &tm); | 356 | rs5c313_rtc_set_time(NULL, &tm); |
355 | printk(KERN_ERR "RICHO RS5C313: invalid value, resetting to " | 357 | pr_err("invalid value, resetting to 1 Jan 2000\n"); |
356 | "1 Jan 2000\n"); | ||
357 | } | 358 | } |
358 | RS5C313_CEDISABLE; | 359 | RS5C313_CEDISABLE; |
359 | ndelay(700); /* CE:L */ | 360 | ndelay(700); /* CE:L */ |
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index 76f565ae384d..581739f40097 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c | |||
@@ -311,8 +311,7 @@ static int rs5c_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | |||
311 | buf &= ~RS5C_CTRL1_AALE; | 311 | buf &= ~RS5C_CTRL1_AALE; |
312 | 312 | ||
313 | if (i2c_smbus_write_byte_data(client, addr, buf) < 0) { | 313 | if (i2c_smbus_write_byte_data(client, addr, buf) < 0) { |
314 | printk(KERN_WARNING "%s: can't update alarm\n", | 314 | dev_warn(dev, "can't update alarm\n"); |
315 | rs5c->rtc->name); | ||
316 | status = -EIO; | 315 | status = -EIO; |
317 | } else | 316 | } else |
318 | rs5c->regs[RS5C_REG_CTRL1] = buf; | 317 | rs5c->regs[RS5C_REG_CTRL1] = buf; |
@@ -381,7 +380,7 @@ static int rs5c_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
381 | addr = RS5C_ADDR(RS5C_REG_CTRL1); | 380 | addr = RS5C_ADDR(RS5C_REG_CTRL1); |
382 | buf[0] = rs5c->regs[RS5C_REG_CTRL1] & ~RS5C_CTRL1_AALE; | 381 | buf[0] = rs5c->regs[RS5C_REG_CTRL1] & ~RS5C_CTRL1_AALE; |
383 | if (i2c_smbus_write_byte_data(client, addr, buf[0]) < 0) { | 382 | if (i2c_smbus_write_byte_data(client, addr, buf[0]) < 0) { |
384 | pr_debug("%s: can't disable alarm\n", rs5c->rtc->name); | 383 | dev_dbg(dev, "can't disable alarm\n"); |
385 | return -EIO; | 384 | return -EIO; |
386 | } | 385 | } |
387 | rs5c->regs[RS5C_REG_CTRL1] = buf[0]; | 386 | rs5c->regs[RS5C_REG_CTRL1] = buf[0]; |
@@ -395,7 +394,7 @@ static int rs5c_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
395 | for (i = 0; i < sizeof(buf); i++) { | 394 | for (i = 0; i < sizeof(buf); i++) { |
396 | addr = RS5C_ADDR(RS5C_REG_ALARM_A_MIN + i); | 395 | addr = RS5C_ADDR(RS5C_REG_ALARM_A_MIN + i); |
397 | if (i2c_smbus_write_byte_data(client, addr, buf[i]) < 0) { | 396 | if (i2c_smbus_write_byte_data(client, addr, buf[i]) < 0) { |
398 | pr_debug("%s: can't set alarm time\n", rs5c->rtc->name); | 397 | dev_dbg(dev, "can't set alarm time\n"); |
399 | return -EIO; | 398 | return -EIO; |
400 | } | 399 | } |
401 | } | 400 | } |
@@ -405,8 +404,7 @@ static int rs5c_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
405 | addr = RS5C_ADDR(RS5C_REG_CTRL1); | 404 | addr = RS5C_ADDR(RS5C_REG_CTRL1); |
406 | buf[0] = rs5c->regs[RS5C_REG_CTRL1] | RS5C_CTRL1_AALE; | 405 | buf[0] = rs5c->regs[RS5C_REG_CTRL1] | RS5C_CTRL1_AALE; |
407 | if (i2c_smbus_write_byte_data(client, addr, buf[0]) < 0) | 406 | if (i2c_smbus_write_byte_data(client, addr, buf[0]) < 0) |
408 | printk(KERN_WARNING "%s: can't enable alarm\n", | 407 | dev_warn(dev, "can't enable alarm\n"); |
409 | rs5c->rtc->name); | ||
410 | rs5c->regs[RS5C_REG_CTRL1] = buf[0]; | 408 | rs5c->regs[RS5C_REG_CTRL1] = buf[0]; |
411 | } | 409 | } |
412 | 410 | ||
diff --git a/drivers/rtc/rtc-rx4581.c b/drivers/rtc/rtc-rx4581.c new file mode 100644 index 000000000000..599ec73ec886 --- /dev/null +++ b/drivers/rtc/rtc-rx4581.c | |||
@@ -0,0 +1,314 @@ | |||
1 | /* drivers/rtc/rtc-rx4581.c | ||
2 | * | ||
3 | * written by Torben Hohn <torbenh@linutronix.de> | ||
4 | * | ||
5 | * Based on: | ||
6 | * drivers/rtc/rtc-max6902.c | ||
7 | * | ||
8 | * Copyright (C) 2006 8D Technologies inc. | ||
9 | * Copyright (C) 2004 Compulab Ltd. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | * | ||
15 | * Driver for MAX6902 spi RTC | ||
16 | * | ||
17 | * and based on: | ||
18 | * drivers/rtc/rtc-rx8581.c | ||
19 | * | ||
20 | * An I2C driver for the Epson RX8581 RTC | ||
21 | * | ||
22 | * Author: Martyn Welch <martyn.welch@ge.com> | ||
23 | * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. | ||
24 | * | ||
25 | * This program is free software; you can redistribute it and/or modify | ||
26 | * it under the terms of the GNU General Public License version 2 as | ||
27 | * published by the Free Software Foundation. | ||
28 | * | ||
29 | * Based on: rtc-pcf8563.c (An I2C driver for the Philips PCF8563 RTC) | ||
30 | * Copyright 2005-06 Tower Technologies | ||
31 | * | ||
32 | */ | ||
33 | |||
34 | #include <linux/module.h> | ||
35 | #include <linux/kernel.h> | ||
36 | #include <linux/platform_device.h> | ||
37 | #include <linux/init.h> | ||
38 | #include <linux/rtc.h> | ||
39 | #include <linux/spi/spi.h> | ||
40 | #include <linux/bcd.h> | ||
41 | |||
42 | #define RX4581_REG_SC 0x00 /* Second in BCD */ | ||
43 | #define RX4581_REG_MN 0x01 /* Minute in BCD */ | ||
44 | #define RX4581_REG_HR 0x02 /* Hour in BCD */ | ||
45 | #define RX4581_REG_DW 0x03 /* Day of Week */ | ||
46 | #define RX4581_REG_DM 0x04 /* Day of Month in BCD */ | ||
47 | #define RX4581_REG_MO 0x05 /* Month in BCD */ | ||
48 | #define RX4581_REG_YR 0x06 /* Year in BCD */ | ||
49 | #define RX4581_REG_RAM 0x07 /* RAM */ | ||
50 | #define RX4581_REG_AMN 0x08 /* Alarm Min in BCD*/ | ||
51 | #define RX4581_REG_AHR 0x09 /* Alarm Hour in BCD */ | ||
52 | #define RX4581_REG_ADM 0x0A | ||
53 | #define RX4581_REG_ADW 0x0A | ||
54 | #define RX4581_REG_TMR0 0x0B | ||
55 | #define RX4581_REG_TMR1 0x0C | ||
56 | #define RX4581_REG_EXT 0x0D /* Extension Register */ | ||
57 | #define RX4581_REG_FLAG 0x0E /* Flag Register */ | ||
58 | #define RX4581_REG_CTRL 0x0F /* Control Register */ | ||
59 | |||
60 | |||
61 | /* Flag Register bit definitions */ | ||
62 | #define RX4581_FLAG_UF 0x20 /* Update */ | ||
63 | #define RX4581_FLAG_TF 0x10 /* Timer */ | ||
64 | #define RX4581_FLAG_AF 0x08 /* Alarm */ | ||
65 | #define RX4581_FLAG_VLF 0x02 /* Voltage Low */ | ||
66 | |||
67 | /* Control Register bit definitions */ | ||
68 | #define RX4581_CTRL_UIE 0x20 /* Update Interrupt Enable */ | ||
69 | #define RX4581_CTRL_TIE 0x10 /* Timer Interrupt Enable */ | ||
70 | #define RX4581_CTRL_AIE 0x08 /* Alarm Interrupt Enable */ | ||
71 | #define RX4581_CTRL_STOP 0x02 /* STOP bit */ | ||
72 | #define RX4581_CTRL_RESET 0x01 /* RESET bit */ | ||
73 | |||
74 | static int rx4581_set_reg(struct device *dev, unsigned char address, | ||
75 | unsigned char data) | ||
76 | { | ||
77 | struct spi_device *spi = to_spi_device(dev); | ||
78 | unsigned char buf[2]; | ||
79 | |||
80 | /* high nibble must be '0' to write */ | ||
81 | buf[0] = address & 0x0f; | ||
82 | buf[1] = data; | ||
83 | |||
84 | return spi_write_then_read(spi, buf, 2, NULL, 0); | ||
85 | } | ||
86 | |||
87 | static int rx4581_get_reg(struct device *dev, unsigned char address, | ||
88 | unsigned char *data) | ||
89 | { | ||
90 | struct spi_device *spi = to_spi_device(dev); | ||
91 | |||
92 | /* Set MSB to indicate read */ | ||
93 | *data = address | 0x80; | ||
94 | |||
95 | return spi_write_then_read(spi, data, 1, data, 1); | ||
96 | } | ||
97 | |||
98 | /* | ||
99 | * In the routines that deal directly with the rx8581 hardware, we use | ||
100 | * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch. | ||
101 | */ | ||
102 | static int rx4581_get_datetime(struct device *dev, struct rtc_time *tm) | ||
103 | { | ||
104 | struct spi_device *spi = to_spi_device(dev); | ||
105 | unsigned char date[7]; | ||
106 | unsigned char data; | ||
107 | int err; | ||
108 | |||
109 | /* First we ensure that the "update flag" is not set, we read the | ||
110 | * time and date then re-read the "update flag". If the update flag | ||
111 | * has been set, we know that the time has changed during the read so | ||
112 | * we repeat the whole process again. | ||
113 | */ | ||
114 | err = rx4581_get_reg(dev, RX4581_REG_FLAG, &data); | ||
115 | if (err != 0) { | ||
116 | dev_err(dev, "Unable to read device flags\n"); | ||
117 | return -EIO; | ||
118 | } | ||
119 | |||
120 | do { | ||
121 | /* If update flag set, clear it */ | ||
122 | if (data & RX4581_FLAG_UF) { | ||
123 | err = rx4581_set_reg(dev, | ||
124 | RX4581_REG_FLAG, (data & ~RX4581_FLAG_UF)); | ||
125 | if (err != 0) { | ||
126 | dev_err(dev, "Unable to write device " | ||
127 | "flags\n"); | ||
128 | return -EIO; | ||
129 | } | ||
130 | } | ||
131 | |||
132 | /* Now read time and date */ | ||
133 | date[0] = 0x80; | ||
134 | err = spi_write_then_read(spi, date, 1, date, 7); | ||
135 | if (err < 0) { | ||
136 | dev_err(dev, "Unable to read date\n"); | ||
137 | return -EIO; | ||
138 | } | ||
139 | |||
140 | /* Check flag register */ | ||
141 | err = rx4581_get_reg(dev, RX4581_REG_FLAG, &data); | ||
142 | if (err != 0) { | ||
143 | dev_err(dev, "Unable to read device flags\n"); | ||
144 | return -EIO; | ||
145 | } | ||
146 | } while (data & RX4581_FLAG_UF); | ||
147 | |||
148 | if (data & RX4581_FLAG_VLF) | ||
149 | dev_info(dev, | ||
150 | "low voltage detected, date/time is not reliable.\n"); | ||
151 | |||
152 | dev_dbg(dev, | ||
153 | "%s: raw data is sec=%02x, min=%02x, hr=%02x, " | ||
154 | "wday=%02x, mday=%02x, mon=%02x, year=%02x\n", | ||
155 | __func__, | ||
156 | date[0], date[1], date[2], date[3], date[4], date[5], date[6]); | ||
157 | |||
158 | tm->tm_sec = bcd2bin(date[RX4581_REG_SC] & 0x7F); | ||
159 | tm->tm_min = bcd2bin(date[RX4581_REG_MN] & 0x7F); | ||
160 | tm->tm_hour = bcd2bin(date[RX4581_REG_HR] & 0x3F); /* rtc hr 0-23 */ | ||
161 | tm->tm_wday = ilog2(date[RX4581_REG_DW] & 0x7F); | ||
162 | tm->tm_mday = bcd2bin(date[RX4581_REG_DM] & 0x3F); | ||
163 | tm->tm_mon = bcd2bin(date[RX4581_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */ | ||
164 | tm->tm_year = bcd2bin(date[RX4581_REG_YR]); | ||
165 | if (tm->tm_year < 70) | ||
166 | tm->tm_year += 100; /* assume we are in 1970...2069 */ | ||
167 | |||
168 | |||
169 | dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, " | ||
170 | "mday=%d, mon=%d, year=%d, wday=%d\n", | ||
171 | __func__, | ||
172 | tm->tm_sec, tm->tm_min, tm->tm_hour, | ||
173 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | ||
174 | |||
175 | err = rtc_valid_tm(tm); | ||
176 | if (err < 0) | ||
177 | dev_err(dev, "retrieved date/time is not valid.\n"); | ||
178 | |||
179 | return err; | ||
180 | } | ||
181 | |||
182 | static int rx4581_set_datetime(struct device *dev, struct rtc_time *tm) | ||
183 | { | ||
184 | struct spi_device *spi = to_spi_device(dev); | ||
185 | int err; | ||
186 | unsigned char buf[8], data; | ||
187 | |||
188 | dev_dbg(dev, "%s: secs=%d, mins=%d, hours=%d, " | ||
189 | "mday=%d, mon=%d, year=%d, wday=%d\n", | ||
190 | __func__, | ||
191 | tm->tm_sec, tm->tm_min, tm->tm_hour, | ||
192 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | ||
193 | |||
194 | buf[0] = 0x00; | ||
195 | /* hours, minutes and seconds */ | ||
196 | buf[RX4581_REG_SC+1] = bin2bcd(tm->tm_sec); | ||
197 | buf[RX4581_REG_MN+1] = bin2bcd(tm->tm_min); | ||
198 | buf[RX4581_REG_HR+1] = bin2bcd(tm->tm_hour); | ||
199 | |||
200 | buf[RX4581_REG_DM+1] = bin2bcd(tm->tm_mday); | ||
201 | |||
202 | /* month, 1 - 12 */ | ||
203 | buf[RX4581_REG_MO+1] = bin2bcd(tm->tm_mon + 1); | ||
204 | |||
205 | /* year and century */ | ||
206 | buf[RX4581_REG_YR+1] = bin2bcd(tm->tm_year % 100); | ||
207 | buf[RX4581_REG_DW+1] = (0x1 << tm->tm_wday); | ||
208 | |||
209 | /* Stop the clock */ | ||
210 | err = rx4581_get_reg(dev, RX4581_REG_CTRL, &data); | ||
211 | if (err != 0) { | ||
212 | dev_err(dev, "Unable to read control register\n"); | ||
213 | return -EIO; | ||
214 | } | ||
215 | |||
216 | err = rx4581_set_reg(dev, RX4581_REG_CTRL, | ||
217 | (data | RX4581_CTRL_STOP)); | ||
218 | if (err != 0) { | ||
219 | dev_err(dev, "Unable to write control register\n"); | ||
220 | return -EIO; | ||
221 | } | ||
222 | |||
223 | /* write register's data */ | ||
224 | err = spi_write_then_read(spi, buf, 8, NULL, 0); | ||
225 | if (err != 0) { | ||
226 | dev_err(dev, "Unable to write to date registers\n"); | ||
227 | return -EIO; | ||
228 | } | ||
229 | |||
230 | /* get VLF and clear it */ | ||
231 | err = rx4581_get_reg(dev, RX4581_REG_FLAG, &data); | ||
232 | if (err != 0) { | ||
233 | dev_err(dev, "Unable to read flag register\n"); | ||
234 | return -EIO; | ||
235 | } | ||
236 | |||
237 | err = rx4581_set_reg(dev, RX4581_REG_FLAG, | ||
238 | (data & ~(RX4581_FLAG_VLF))); | ||
239 | if (err != 0) { | ||
240 | dev_err(dev, "Unable to write flag register\n"); | ||
241 | return -EIO; | ||
242 | } | ||
243 | |||
244 | /* Restart the clock */ | ||
245 | err = rx4581_get_reg(dev, RX4581_REG_CTRL, &data); | ||
246 | if (err != 0) { | ||
247 | dev_err(dev, "Unable to read control register\n"); | ||
248 | return -EIO; | ||
249 | } | ||
250 | |||
251 | err = rx4581_set_reg(dev, RX4581_REG_CTRL, | ||
252 | (data & ~(RX4581_CTRL_STOP))); | ||
253 | if (err != 0) { | ||
254 | dev_err(dev, "Unable to write control register\n"); | ||
255 | return -EIO; | ||
256 | } | ||
257 | |||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | static const struct rtc_class_ops rx4581_rtc_ops = { | ||
262 | .read_time = rx4581_get_datetime, | ||
263 | .set_time = rx4581_set_datetime, | ||
264 | }; | ||
265 | |||
266 | static int rx4581_probe(struct spi_device *spi) | ||
267 | { | ||
268 | struct rtc_device *rtc; | ||
269 | unsigned char tmp; | ||
270 | int res; | ||
271 | |||
272 | res = rx4581_get_reg(&spi->dev, RX4581_REG_SC, &tmp); | ||
273 | if (res != 0) | ||
274 | return res; | ||
275 | |||
276 | rtc = rtc_device_register("rx4581", | ||
277 | &spi->dev, &rx4581_rtc_ops, THIS_MODULE); | ||
278 | if (IS_ERR(rtc)) | ||
279 | return PTR_ERR(rtc); | ||
280 | |||
281 | dev_set_drvdata(&spi->dev, rtc); | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static int rx4581_remove(struct spi_device *spi) | ||
286 | { | ||
287 | struct rtc_device *rtc = dev_get_drvdata(&spi->dev); | ||
288 | |||
289 | rtc_device_unregister(rtc); | ||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | static const struct spi_device_id rx4581_id[] = { | ||
294 | { "rx4581", 0 }, | ||
295 | { } | ||
296 | }; | ||
297 | MODULE_DEVICE_TABLE(spi, rx4581_id); | ||
298 | |||
299 | static struct spi_driver rx4581_driver = { | ||
300 | .driver = { | ||
301 | .name = "rtc-rx4581", | ||
302 | .owner = THIS_MODULE, | ||
303 | }, | ||
304 | .probe = rx4581_probe, | ||
305 | .remove = rx4581_remove, | ||
306 | .id_table = rx4581_id, | ||
307 | }; | ||
308 | |||
309 | module_spi_driver(rx4581_driver); | ||
310 | |||
311 | MODULE_DESCRIPTION("rx4581 spi RTC driver"); | ||
312 | MODULE_AUTHOR("Torben Hohn"); | ||
313 | MODULE_LICENSE("GPL"); | ||
314 | MODULE_ALIAS("spi:rtc-rx4581"); | ||
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 404651464d45..fb994e9ddc15 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -115,7 +115,7 @@ static int s3c_rtc_setaie(struct device *dev, unsigned int enabled) | |||
115 | { | 115 | { |
116 | unsigned int tmp; | 116 | unsigned int tmp; |
117 | 117 | ||
118 | pr_debug("%s: aie=%d\n", __func__, enabled); | 118 | dev_dbg(dev, "%s: aie=%d\n", __func__, enabled); |
119 | 119 | ||
120 | clk_enable(rtc_clk); | 120 | clk_enable(rtc_clk); |
121 | tmp = readb(s3c_rtc_base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; | 121 | tmp = readb(s3c_rtc_base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; |
@@ -203,7 +203,7 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) | |||
203 | 203 | ||
204 | rtc_tm->tm_year += 100; | 204 | rtc_tm->tm_year += 100; |
205 | 205 | ||
206 | pr_debug("read time %04d.%02d.%02d %02d:%02d:%02d\n", | 206 | dev_dbg(dev, "read time %04d.%02d.%02d %02d:%02d:%02d\n", |
207 | 1900 + rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday, | 207 | 1900 + rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday, |
208 | rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec); | 208 | rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec); |
209 | 209 | ||
@@ -218,7 +218,7 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) | |||
218 | void __iomem *base = s3c_rtc_base; | 218 | void __iomem *base = s3c_rtc_base; |
219 | int year = tm->tm_year - 100; | 219 | int year = tm->tm_year - 100; |
220 | 220 | ||
221 | pr_debug("set time %04d.%02d.%02d %02d:%02d:%02d\n", | 221 | dev_dbg(dev, "set time %04d.%02d.%02d %02d:%02d:%02d\n", |
222 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | 222 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, |
223 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 223 | tm->tm_hour, tm->tm_min, tm->tm_sec); |
224 | 224 | ||
@@ -259,7 +259,7 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
259 | 259 | ||
260 | alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0; | 260 | alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0; |
261 | 261 | ||
262 | pr_debug("read alarm %d, %04d.%02d.%02d %02d:%02d:%02d\n", | 262 | dev_dbg(dev, "read alarm %d, %04d.%02d.%02d %02d:%02d:%02d\n", |
263 | alm_en, | 263 | alm_en, |
264 | 1900 + alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday, | 264 | 1900 + alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday, |
265 | alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec); | 265 | alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec); |
@@ -310,7 +310,7 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
310 | unsigned int alrm_en; | 310 | unsigned int alrm_en; |
311 | 311 | ||
312 | clk_enable(rtc_clk); | 312 | clk_enable(rtc_clk); |
313 | pr_debug("s3c_rtc_setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n", | 313 | dev_dbg(dev, "s3c_rtc_setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n", |
314 | alrm->enabled, | 314 | alrm->enabled, |
315 | 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, | 315 | 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, |
316 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 316 | tm->tm_hour, tm->tm_min, tm->tm_sec); |
@@ -333,7 +333,7 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
333 | writeb(bin2bcd(tm->tm_hour), base + S3C2410_ALMHOUR); | 333 | writeb(bin2bcd(tm->tm_hour), base + S3C2410_ALMHOUR); |
334 | } | 334 | } |
335 | 335 | ||
336 | pr_debug("setting S3C2410_RTCALM to %08x\n", alrm_en); | 336 | dev_dbg(dev, "setting S3C2410_RTCALM to %08x\n", alrm_en); |
337 | 337 | ||
338 | writeb(alrm_en, base + S3C2410_RTCALM); | 338 | writeb(alrm_en, base + S3C2410_RTCALM); |
339 | 339 | ||
@@ -459,7 +459,7 @@ static int s3c_rtc_probe(struct platform_device *pdev) | |||
459 | int ret; | 459 | int ret; |
460 | int tmp; | 460 | int tmp; |
461 | 461 | ||
462 | pr_debug("%s: probe=%p\n", __func__, pdev); | 462 | dev_dbg(&pdev->dev, "%s: probe=%p\n", __func__, pdev); |
463 | 463 | ||
464 | /* find the IRQs */ | 464 | /* find the IRQs */ |
465 | 465 | ||
@@ -475,7 +475,7 @@ static int s3c_rtc_probe(struct platform_device *pdev) | |||
475 | return s3c_rtc_alarmno; | 475 | return s3c_rtc_alarmno; |
476 | } | 476 | } |
477 | 477 | ||
478 | pr_debug("s3c2410_rtc: tick irq %d, alarm irq %d\n", | 478 | dev_dbg(&pdev->dev, "s3c2410_rtc: tick irq %d, alarm irq %d\n", |
479 | s3c_rtc_tickno, s3c_rtc_alarmno); | 479 | s3c_rtc_tickno, s3c_rtc_alarmno); |
480 | 480 | ||
481 | /* get the memory region */ | 481 | /* get the memory region */ |
@@ -486,11 +486,9 @@ static int s3c_rtc_probe(struct platform_device *pdev) | |||
486 | return -ENOENT; | 486 | return -ENOENT; |
487 | } | 487 | } |
488 | 488 | ||
489 | s3c_rtc_base = devm_request_and_ioremap(&pdev->dev, res); | 489 | s3c_rtc_base = devm_ioremap_resource(&pdev->dev, res); |
490 | if (s3c_rtc_base == NULL) { | 490 | if (IS_ERR(s3c_rtc_base)) |
491 | dev_err(&pdev->dev, "failed to ioremap memory region\n"); | 491 | return PTR_ERR(s3c_rtc_base); |
492 | return -EINVAL; | ||
493 | } | ||
494 | 492 | ||
495 | rtc_clk = devm_clk_get(&pdev->dev, "rtc"); | 493 | rtc_clk = devm_clk_get(&pdev->dev, "rtc"); |
496 | if (IS_ERR(rtc_clk)) { | 494 | if (IS_ERR(rtc_clk)) { |
@@ -506,7 +504,7 @@ static int s3c_rtc_probe(struct platform_device *pdev) | |||
506 | 504 | ||
507 | s3c_rtc_enable(pdev, 1); | 505 | s3c_rtc_enable(pdev, 1); |
508 | 506 | ||
509 | pr_debug("s3c2410_rtc: RTCCON=%02x\n", | 507 | dev_dbg(&pdev->dev, "s3c2410_rtc: RTCCON=%02x\n", |
510 | readw(s3c_rtc_base + S3C2410_RTCCON)); | 508 | readw(s3c_rtc_base + S3C2410_RTCCON)); |
511 | 509 | ||
512 | device_init_wakeup(&pdev->dev, 1); | 510 | device_init_wakeup(&pdev->dev, 1); |
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index 50a5c4adee48..5ec5036df0bc 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c | |||
@@ -108,9 +108,6 @@ static int sa1100_rtc_open(struct device *dev) | |||
108 | struct rtc_device *rtc = info->rtc; | 108 | struct rtc_device *rtc = info->rtc; |
109 | int ret; | 109 | int ret; |
110 | 110 | ||
111 | ret = clk_prepare_enable(info->clk); | ||
112 | if (ret) | ||
113 | goto fail_clk; | ||
114 | ret = request_irq(info->irq_1hz, sa1100_rtc_interrupt, 0, "rtc 1Hz", dev); | 111 | ret = request_irq(info->irq_1hz, sa1100_rtc_interrupt, 0, "rtc 1Hz", dev); |
115 | if (ret) { | 112 | if (ret) { |
116 | dev_err(dev, "IRQ %d already in use.\n", info->irq_1hz); | 113 | dev_err(dev, "IRQ %d already in use.\n", info->irq_1hz); |
@@ -130,7 +127,6 @@ static int sa1100_rtc_open(struct device *dev) | |||
130 | free_irq(info->irq_1hz, dev); | 127 | free_irq(info->irq_1hz, dev); |
131 | fail_ui: | 128 | fail_ui: |
132 | clk_disable_unprepare(info->clk); | 129 | clk_disable_unprepare(info->clk); |
133 | fail_clk: | ||
134 | return ret; | 130 | return ret; |
135 | } | 131 | } |
136 | 132 | ||
@@ -144,7 +140,6 @@ static void sa1100_rtc_release(struct device *dev) | |||
144 | 140 | ||
145 | free_irq(info->irq_alarm, dev); | 141 | free_irq(info->irq_alarm, dev); |
146 | free_irq(info->irq_1hz, dev); | 142 | free_irq(info->irq_1hz, dev); |
147 | clk_disable_unprepare(info->clk); | ||
148 | } | 143 | } |
149 | 144 | ||
150 | static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | 145 | static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) |
@@ -253,6 +248,9 @@ static int sa1100_rtc_probe(struct platform_device *pdev) | |||
253 | spin_lock_init(&info->lock); | 248 | spin_lock_init(&info->lock); |
254 | platform_set_drvdata(pdev, info); | 249 | platform_set_drvdata(pdev, info); |
255 | 250 | ||
251 | ret = clk_prepare_enable(info->clk); | ||
252 | if (ret) | ||
253 | goto err_enable_clk; | ||
256 | /* | 254 | /* |
257 | * According to the manual we should be able to let RTTR be zero | 255 | * According to the manual we should be able to let RTTR be zero |
258 | * and then a default diviser for a 32.768KHz clock is used. | 256 | * and then a default diviser for a 32.768KHz clock is used. |
@@ -305,6 +303,8 @@ static int sa1100_rtc_probe(struct platform_device *pdev) | |||
305 | 303 | ||
306 | return 0; | 304 | return 0; |
307 | err_dev: | 305 | err_dev: |
306 | clk_disable_unprepare(info->clk); | ||
307 | err_enable_clk: | ||
308 | platform_set_drvdata(pdev, NULL); | 308 | platform_set_drvdata(pdev, NULL); |
309 | clk_put(info->clk); | 309 | clk_put(info->clk); |
310 | err_clk: | 310 | err_clk: |
@@ -318,6 +318,7 @@ static int sa1100_rtc_remove(struct platform_device *pdev) | |||
318 | 318 | ||
319 | if (info) { | 319 | if (info) { |
320 | rtc_device_unregister(info->rtc); | 320 | rtc_device_unregister(info->rtc); |
321 | clk_disable_unprepare(info->clk); | ||
321 | clk_put(info->clk); | 322 | clk_put(info->clk); |
322 | platform_set_drvdata(pdev, NULL); | 323 | platform_set_drvdata(pdev, NULL); |
323 | kfree(info); | 324 | kfree(info); |
@@ -349,12 +350,14 @@ static const struct dev_pm_ops sa1100_rtc_pm_ops = { | |||
349 | }; | 350 | }; |
350 | #endif | 351 | #endif |
351 | 352 | ||
353 | #ifdef CONFIG_OF | ||
352 | static struct of_device_id sa1100_rtc_dt_ids[] = { | 354 | static struct of_device_id sa1100_rtc_dt_ids[] = { |
353 | { .compatible = "mrvl,sa1100-rtc", }, | 355 | { .compatible = "mrvl,sa1100-rtc", }, |
354 | { .compatible = "mrvl,mmp-rtc", }, | 356 | { .compatible = "mrvl,mmp-rtc", }, |
355 | {} | 357 | {} |
356 | }; | 358 | }; |
357 | MODULE_DEVICE_TABLE(of, sa1100_rtc_dt_ids); | 359 | MODULE_DEVICE_TABLE(of, sa1100_rtc_dt_ids); |
360 | #endif | ||
358 | 361 | ||
359 | static struct platform_driver sa1100_rtc_driver = { | 362 | static struct platform_driver sa1100_rtc_driver = { |
360 | .probe = sa1100_rtc_probe, | 363 | .probe = sa1100_rtc_probe, |
@@ -364,7 +367,7 @@ static struct platform_driver sa1100_rtc_driver = { | |||
364 | #ifdef CONFIG_PM | 367 | #ifdef CONFIG_PM |
365 | .pm = &sa1100_rtc_pm_ops, | 368 | .pm = &sa1100_rtc_pm_ops, |
366 | #endif | 369 | #endif |
367 | .of_match_table = sa1100_rtc_dt_ids, | 370 | .of_match_table = of_match_ptr(sa1100_rtc_dt_ids), |
368 | }, | 371 | }, |
369 | }; | 372 | }; |
370 | 373 | ||
diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c index d5ec7854a651..f7d90703db5e 100644 --- a/drivers/rtc/rtc-snvs.c +++ b/drivers/rtc/rtc-snvs.c | |||
@@ -252,9 +252,9 @@ static int snvs_rtc_probe(struct platform_device *pdev) | |||
252 | return -ENOMEM; | 252 | return -ENOMEM; |
253 | 253 | ||
254 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 254 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
255 | data->ioaddr = devm_request_and_ioremap(&pdev->dev, res); | 255 | data->ioaddr = devm_ioremap_resource(&pdev->dev, res); |
256 | if (!data->ioaddr) | 256 | if (IS_ERR(data->ioaddr)) |
257 | return -EADDRNOTAVAIL; | 257 | return PTR_ERR(data->ioaddr); |
258 | 258 | ||
259 | data->irq = platform_get_irq(pdev, 0); | 259 | data->irq = platform_get_irq(pdev, 0); |
260 | if (data->irq < 0) | 260 | if (data->irq < 0) |
@@ -338,7 +338,7 @@ static struct platform_driver snvs_rtc_driver = { | |||
338 | .name = "snvs_rtc", | 338 | .name = "snvs_rtc", |
339 | .owner = THIS_MODULE, | 339 | .owner = THIS_MODULE, |
340 | .pm = &snvs_rtc_pm_ops, | 340 | .pm = &snvs_rtc_pm_ops, |
341 | .of_match_table = snvs_dt_ids, | 341 | .of_match_table = of_match_ptr(snvs_dt_ids), |
342 | }, | 342 | }, |
343 | .probe = snvs_rtc_probe, | 343 | .probe = snvs_rtc_probe, |
344 | .remove = snvs_rtc_remove, | 344 | .remove = snvs_rtc_remove, |
diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c index c2121b5a01f2..a18c3192ed40 100644 --- a/drivers/rtc/rtc-spear.c +++ b/drivers/rtc/rtc-spear.c | |||
@@ -385,11 +385,9 @@ static int spear_rtc_probe(struct platform_device *pdev) | |||
385 | return status; | 385 | return status; |
386 | } | 386 | } |
387 | 387 | ||
388 | config->ioaddr = devm_request_and_ioremap(&pdev->dev, res); | 388 | config->ioaddr = devm_ioremap_resource(&pdev->dev, res); |
389 | if (!config->ioaddr) { | 389 | if (IS_ERR(config->ioaddr)) |
390 | dev_err(&pdev->dev, "request-ioremap fail\n"); | 390 | return PTR_ERR(config->ioaddr); |
391 | return -ENOMEM; | ||
392 | } | ||
393 | 391 | ||
394 | config->clk = devm_clk_get(&pdev->dev, NULL); | 392 | config->clk = devm_clk_get(&pdev->dev, NULL); |
395 | if (IS_ERR(config->clk)) | 393 | if (IS_ERR(config->clk)) |
diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c index 739ef55694f4..b2a8ed99b2bf 100644 --- a/drivers/rtc/rtc-stmp3xxx.c +++ b/drivers/rtc/rtc-stmp3xxx.c | |||
@@ -26,6 +26,7 @@ | |||
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> | 28 | #include <linux/of_device.h> |
29 | #include <linux/of.h> | ||
29 | 30 | ||
30 | #include <mach/common.h> | 31 | #include <mach/common.h> |
31 | 32 | ||
@@ -280,7 +281,7 @@ static struct platform_driver stmp3xxx_rtcdrv = { | |||
280 | .driver = { | 281 | .driver = { |
281 | .name = "stmp3xxx-rtc", | 282 | .name = "stmp3xxx-rtc", |
282 | .owner = THIS_MODULE, | 283 | .owner = THIS_MODULE, |
283 | .of_match_table = rtc_dt_ids, | 284 | .of_match_table = of_match_ptr(rtc_dt_ids), |
284 | }, | 285 | }, |
285 | }; | 286 | }; |
286 | 287 | ||
diff --git a/drivers/rtc/rtc-sun4v.c b/drivers/rtc/rtc-sun4v.c index 5b2261052a65..59b5c2dcb58c 100644 --- a/drivers/rtc/rtc-sun4v.c +++ b/drivers/rtc/rtc-sun4v.c | |||
@@ -3,6 +3,8 @@ | |||
3 | * Copyright (C) 2008 David S. Miller <davem@davemloft.net> | 3 | * Copyright (C) 2008 David S. Miller <davem@davemloft.net> |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
7 | |||
6 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
7 | #include <linux/module.h> | 9 | #include <linux/module.h> |
8 | #include <linux/delay.h> | 10 | #include <linux/delay.h> |
@@ -26,10 +28,10 @@ retry: | |||
26 | udelay(100); | 28 | udelay(100); |
27 | goto retry; | 29 | goto retry; |
28 | } | 30 | } |
29 | printk(KERN_WARNING "SUN4V: tod_get() timed out.\n"); | 31 | pr_warn("tod_get() timed out.\n"); |
30 | return 0; | 32 | return 0; |
31 | } | 33 | } |
32 | printk(KERN_WARNING "SUN4V: tod_get() not supported.\n"); | 34 | pr_warn("tod_get() not supported.\n"); |
33 | return 0; | 35 | return 0; |
34 | } | 36 | } |
35 | 37 | ||
@@ -53,10 +55,10 @@ retry: | |||
53 | udelay(100); | 55 | udelay(100); |
54 | goto retry; | 56 | goto retry; |
55 | } | 57 | } |
56 | printk(KERN_WARNING "SUN4V: tod_set() timed out.\n"); | 58 | pr_warn("tod_set() timed out.\n"); |
57 | return -EAGAIN; | 59 | return -EAGAIN; |
58 | } | 60 | } |
59 | printk(KERN_WARNING "SUN4V: tod_set() not supported.\n"); | 61 | pr_warn("tod_set() not supported.\n"); |
60 | return -EOPNOTSUPP; | 62 | return -EOPNOTSUPP; |
61 | } | 63 | } |
62 | 64 | ||
diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c index c84ea6659f49..7c033756d6b5 100644 --- a/drivers/rtc/rtc-tegra.c +++ b/drivers/rtc/rtc-tegra.c | |||
@@ -327,11 +327,9 @@ static int tegra_rtc_probe(struct platform_device *pdev) | |||
327 | return -EBUSY; | 327 | return -EBUSY; |
328 | } | 328 | } |
329 | 329 | ||
330 | info->rtc_base = devm_request_and_ioremap(&pdev->dev, res); | 330 | info->rtc_base = devm_ioremap_resource(&pdev->dev, res); |
331 | if (!info->rtc_base) { | 331 | if (IS_ERR(info->rtc_base)) |
332 | dev_err(&pdev->dev, "Unable to request mem region and grab IOs for device.\n"); | 332 | return PTR_ERR(info->rtc_base); |
333 | return -EBUSY; | ||
334 | } | ||
335 | 333 | ||
336 | info->tegra_rtc_irq = platform_get_irq(pdev, 0); | 334 | info->tegra_rtc_irq = platform_get_irq(pdev, 0); |
337 | if (info->tegra_rtc_irq <= 0) | 335 | if (info->tegra_rtc_irq <= 0) |
diff --git a/drivers/rtc/rtc-tps6586x.c b/drivers/rtc/rtc-tps6586x.c index 70f61b8e9e6f..aab4e8c93622 100644 --- a/drivers/rtc/rtc-tps6586x.c +++ b/drivers/rtc/rtc-tps6586x.c | |||
@@ -282,7 +282,8 @@ static int tps6586x_rtc_probe(struct platform_device *pdev) | |||
282 | goto fail_rtc_register; | 282 | goto fail_rtc_register; |
283 | } | 283 | } |
284 | 284 | ||
285 | ret = request_threaded_irq(rtc->irq, NULL, tps6586x_rtc_irq, | 285 | ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL, |
286 | tps6586x_rtc_irq, | ||
286 | IRQF_ONESHOT | IRQF_EARLY_RESUME, | 287 | IRQF_ONESHOT | IRQF_EARLY_RESUME, |
287 | dev_name(&pdev->dev), rtc); | 288 | dev_name(&pdev->dev), rtc); |
288 | if (ret < 0) { | 289 | if (ret < 0) { |
@@ -311,7 +312,6 @@ static int tps6586x_rtc_remove(struct platform_device *pdev) | |||
311 | tps6586x_update(tps_dev, RTC_CTRL, 0, | 312 | tps6586x_update(tps_dev, RTC_CTRL, 0, |
312 | RTC_ENABLE | OSC_SRC_SEL | PRE_BYPASS | CL_SEL_MASK); | 313 | RTC_ENABLE | OSC_SRC_SEL | PRE_BYPASS | CL_SEL_MASK); |
313 | rtc_device_unregister(rtc->rtc); | 314 | rtc_device_unregister(rtc->rtc); |
314 | free_irq(rtc->irq, rtc); | ||
315 | return 0; | 315 | return 0; |
316 | } | 316 | } |
317 | 317 | ||
diff --git a/drivers/rtc/rtc-tps65910.c b/drivers/rtc/rtc-tps65910.c index e5fef141a0e2..8bd8115329b5 100644 --- a/drivers/rtc/rtc-tps65910.c +++ b/drivers/rtc/rtc-tps65910.c | |||
@@ -22,13 +22,13 @@ | |||
22 | #include <linux/rtc.h> | 22 | #include <linux/rtc.h> |
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/pm_runtime.h> | ||
25 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
26 | #include <linux/mfd/tps65910.h> | 27 | #include <linux/mfd/tps65910.h> |
27 | 28 | ||
28 | struct tps65910_rtc { | 29 | struct tps65910_rtc { |
29 | struct rtc_device *rtc; | 30 | struct rtc_device *rtc; |
30 | /* To store the list of enabled interrupts */ | 31 | int irq; |
31 | u32 irqstat; | ||
32 | }; | 32 | }; |
33 | 33 | ||
34 | /* Total number of RTC registers needed to set time*/ | 34 | /* Total number of RTC registers needed to set time*/ |
@@ -267,13 +267,14 @@ static int tps65910_rtc_probe(struct platform_device *pdev) | |||
267 | } | 267 | } |
268 | 268 | ||
269 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, | 269 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, |
270 | tps65910_rtc_interrupt, IRQF_TRIGGER_LOW, | 270 | tps65910_rtc_interrupt, IRQF_TRIGGER_LOW | IRQF_EARLY_RESUME, |
271 | dev_name(&pdev->dev), &pdev->dev); | 271 | dev_name(&pdev->dev), &pdev->dev); |
272 | if (ret < 0) { | 272 | if (ret < 0) { |
273 | dev_err(&pdev->dev, "IRQ is not free.\n"); | 273 | dev_err(&pdev->dev, "IRQ is not free.\n"); |
274 | return ret; | 274 | return ret; |
275 | } | 275 | } |
276 | device_init_wakeup(&pdev->dev, 1); | 276 | tps_rtc->irq = irq; |
277 | device_set_wakeup_capable(&pdev->dev, 1); | ||
277 | 278 | ||
278 | tps_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, | 279 | tps_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, |
279 | &tps65910_rtc_ops, THIS_MODULE); | 280 | &tps65910_rtc_ops, THIS_MODULE); |
@@ -304,49 +305,36 @@ static int tps65910_rtc_remove(struct platform_device *pdev) | |||
304 | } | 305 | } |
305 | 306 | ||
306 | #ifdef CONFIG_PM_SLEEP | 307 | #ifdef CONFIG_PM_SLEEP |
307 | |||
308 | static int tps65910_rtc_suspend(struct device *dev) | 308 | static int tps65910_rtc_suspend(struct device *dev) |
309 | { | 309 | { |
310 | struct tps65910 *tps = dev_get_drvdata(dev->parent); | 310 | struct tps65910_rtc *tps_rtc = dev_get_drvdata(dev); |
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 | 311 | ||
320 | /* Enable RTC ALARM interrupt only */ | 312 | if (device_may_wakeup(dev)) |
321 | return regmap_write(tps->regmap, TPS65910_RTC_INTERRUPTS, alarm); | 313 | enable_irq_wake(tps_rtc->irq); |
314 | return 0; | ||
322 | } | 315 | } |
323 | 316 | ||
324 | static int tps65910_rtc_resume(struct device *dev) | 317 | static int tps65910_rtc_resume(struct device *dev) |
325 | { | 318 | { |
326 | struct tps65910 *tps = dev_get_drvdata(dev->parent); | 319 | struct tps65910_rtc *tps_rtc = dev_get_drvdata(dev); |
327 | 320 | ||
328 | /* Restore list of enabled interrupts before suspend */ | 321 | if (device_may_wakeup(dev)) |
329 | return regmap_write(tps->regmap, TPS65910_RTC_INTERRUPTS, | 322 | disable_irq_wake(tps_rtc->irq); |
330 | tps->rtc->irqstat); | 323 | return 0; |
331 | } | 324 | } |
325 | #endif | ||
332 | 326 | ||
333 | static const struct dev_pm_ops tps65910_rtc_pm_ops = { | 327 | static const struct dev_pm_ops tps65910_rtc_pm_ops = { |
334 | .suspend = tps65910_rtc_suspend, | 328 | SET_SYSTEM_SLEEP_PM_OPS(tps65910_rtc_suspend, tps65910_rtc_resume) |
335 | .resume = tps65910_rtc_resume, | ||
336 | }; | 329 | }; |
337 | 330 | ||
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 = { | 331 | static struct platform_driver tps65910_rtc_driver = { |
344 | .probe = tps65910_rtc_probe, | 332 | .probe = tps65910_rtc_probe, |
345 | .remove = tps65910_rtc_remove, | 333 | .remove = tps65910_rtc_remove, |
346 | .driver = { | 334 | .driver = { |
347 | .owner = THIS_MODULE, | 335 | .owner = THIS_MODULE, |
348 | .name = "tps65910-rtc", | 336 | .name = "tps65910-rtc", |
349 | .pm = DEV_PM_OPS, | 337 | .pm = &tps65910_rtc_pm_ops, |
350 | }, | 338 | }, |
351 | }; | 339 | }; |
352 | 340 | ||
diff --git a/drivers/rtc/rtc-tps80031.c b/drivers/rtc/rtc-tps80031.c new file mode 100644 index 000000000000..9aaf8aaebae9 --- /dev/null +++ b/drivers/rtc/rtc-tps80031.c | |||
@@ -0,0 +1,349 @@ | |||
1 | /* | ||
2 | * rtc-tps80031.c -- TI TPS80031/TPS80032 RTC driver | ||
3 | * | ||
4 | * RTC driver for TI TPS80031/TPS80032 Fully Integrated | ||
5 | * Power Management with Power Path and Battery Charger | ||
6 | * | ||
7 | * Copyright (c) 2012, NVIDIA Corporation. | ||
8 | * | ||
9 | * Author: Laxman Dewangan <ldewangan@nvidia.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 as | ||
13 | * published by the Free Software Foundation version 2. | ||
14 | * | ||
15 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, | ||
16 | * whether express or implied; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
18 | * General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
23 | * 02111-1307, USA | ||
24 | */ | ||
25 | |||
26 | #include <linux/bcd.h> | ||
27 | #include <linux/device.h> | ||
28 | #include <linux/err.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/kernel.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/mfd/tps80031.h> | ||
33 | #include <linux/platform_device.h> | ||
34 | #include <linux/pm.h> | ||
35 | #include <linux/rtc.h> | ||
36 | #include <linux/slab.h> | ||
37 | |||
38 | #define ENABLE_ALARM_INT 0x08 | ||
39 | #define ALARM_INT_STATUS 0x40 | ||
40 | |||
41 | /** | ||
42 | * Setting bit to 1 in STOP_RTC will run the RTC and | ||
43 | * setting this bit to 0 will freeze RTC. | ||
44 | */ | ||
45 | #define STOP_RTC 0x1 | ||
46 | |||
47 | /* Power on reset Values of RTC registers */ | ||
48 | #define TPS80031_RTC_POR_YEAR 0 | ||
49 | #define TPS80031_RTC_POR_MONTH 1 | ||
50 | #define TPS80031_RTC_POR_DAY 1 | ||
51 | |||
52 | /* Numbers of registers for time and alarms */ | ||
53 | #define TPS80031_RTC_TIME_NUM_REGS 7 | ||
54 | #define TPS80031_RTC_ALARM_NUM_REGS 6 | ||
55 | |||
56 | /** | ||
57 | * PMU RTC have only 2 nibbles to store year information, so using an | ||
58 | * offset of 100 to set the base year as 2000 for our driver. | ||
59 | */ | ||
60 | #define RTC_YEAR_OFFSET 100 | ||
61 | |||
62 | struct tps80031_rtc { | ||
63 | struct rtc_device *rtc; | ||
64 | int irq; | ||
65 | }; | ||
66 | |||
67 | static int tps80031_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
68 | { | ||
69 | u8 buff[TPS80031_RTC_TIME_NUM_REGS]; | ||
70 | int ret; | ||
71 | |||
72 | ret = tps80031_reads(dev->parent, TPS80031_SLAVE_ID1, | ||
73 | TPS80031_SECONDS_REG, TPS80031_RTC_TIME_NUM_REGS, buff); | ||
74 | if (ret < 0) { | ||
75 | dev_err(dev, "reading RTC_SECONDS_REG failed, err = %d\n", ret); | ||
76 | return ret; | ||
77 | } | ||
78 | |||
79 | tm->tm_sec = bcd2bin(buff[0]); | ||
80 | tm->tm_min = bcd2bin(buff[1]); | ||
81 | tm->tm_hour = bcd2bin(buff[2]); | ||
82 | tm->tm_mday = bcd2bin(buff[3]); | ||
83 | tm->tm_mon = bcd2bin(buff[4]) - 1; | ||
84 | tm->tm_year = bcd2bin(buff[5]) + RTC_YEAR_OFFSET; | ||
85 | tm->tm_wday = bcd2bin(buff[6]); | ||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | static int tps80031_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
90 | { | ||
91 | u8 buff[7]; | ||
92 | int ret; | ||
93 | |||
94 | buff[0] = bin2bcd(tm->tm_sec); | ||
95 | buff[1] = bin2bcd(tm->tm_min); | ||
96 | buff[2] = bin2bcd(tm->tm_hour); | ||
97 | buff[3] = bin2bcd(tm->tm_mday); | ||
98 | buff[4] = bin2bcd(tm->tm_mon + 1); | ||
99 | buff[5] = bin2bcd(tm->tm_year % RTC_YEAR_OFFSET); | ||
100 | buff[6] = bin2bcd(tm->tm_wday); | ||
101 | |||
102 | /* Stop RTC while updating the RTC time registers */ | ||
103 | ret = tps80031_clr_bits(dev->parent, TPS80031_SLAVE_ID1, | ||
104 | TPS80031_RTC_CTRL_REG, STOP_RTC); | ||
105 | if (ret < 0) { | ||
106 | dev_err(dev->parent, "Stop RTC failed, err = %d\n", ret); | ||
107 | return ret; | ||
108 | } | ||
109 | |||
110 | ret = tps80031_writes(dev->parent, TPS80031_SLAVE_ID1, | ||
111 | TPS80031_SECONDS_REG, | ||
112 | TPS80031_RTC_TIME_NUM_REGS, buff); | ||
113 | if (ret < 0) { | ||
114 | dev_err(dev, "writing RTC_SECONDS_REG failed, err %d\n", ret); | ||
115 | return ret; | ||
116 | } | ||
117 | |||
118 | ret = tps80031_set_bits(dev->parent, TPS80031_SLAVE_ID1, | ||
119 | TPS80031_RTC_CTRL_REG, STOP_RTC); | ||
120 | if (ret < 0) | ||
121 | dev_err(dev->parent, "Start RTC failed, err = %d\n", ret); | ||
122 | return ret; | ||
123 | } | ||
124 | |||
125 | static int tps80031_rtc_alarm_irq_enable(struct device *dev, | ||
126 | unsigned int enable) | ||
127 | { | ||
128 | int ret; | ||
129 | |||
130 | if (enable) | ||
131 | ret = tps80031_set_bits(dev->parent, TPS80031_SLAVE_ID1, | ||
132 | TPS80031_RTC_INTERRUPTS_REG, ENABLE_ALARM_INT); | ||
133 | else | ||
134 | ret = tps80031_clr_bits(dev->parent, TPS80031_SLAVE_ID1, | ||
135 | TPS80031_RTC_INTERRUPTS_REG, ENABLE_ALARM_INT); | ||
136 | if (ret < 0) { | ||
137 | dev_err(dev, "Update on RTC_INT failed, err = %d\n", ret); | ||
138 | return ret; | ||
139 | } | ||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | static int tps80031_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
144 | { | ||
145 | u8 buff[TPS80031_RTC_ALARM_NUM_REGS]; | ||
146 | int ret; | ||
147 | |||
148 | buff[0] = bin2bcd(alrm->time.tm_sec); | ||
149 | buff[1] = bin2bcd(alrm->time.tm_min); | ||
150 | buff[2] = bin2bcd(alrm->time.tm_hour); | ||
151 | buff[3] = bin2bcd(alrm->time.tm_mday); | ||
152 | buff[4] = bin2bcd(alrm->time.tm_mon + 1); | ||
153 | buff[5] = bin2bcd(alrm->time.tm_year % RTC_YEAR_OFFSET); | ||
154 | ret = tps80031_writes(dev->parent, TPS80031_SLAVE_ID1, | ||
155 | TPS80031_ALARM_SECONDS_REG, | ||
156 | TPS80031_RTC_ALARM_NUM_REGS, buff); | ||
157 | if (ret < 0) { | ||
158 | dev_err(dev, "Writing RTC_ALARM failed, err %d\n", ret); | ||
159 | return ret; | ||
160 | } | ||
161 | return tps80031_rtc_alarm_irq_enable(dev, alrm->enabled); | ||
162 | } | ||
163 | |||
164 | static int tps80031_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
165 | { | ||
166 | u8 buff[6]; | ||
167 | int ret; | ||
168 | |||
169 | ret = tps80031_reads(dev->parent, TPS80031_SLAVE_ID1, | ||
170 | TPS80031_ALARM_SECONDS_REG, | ||
171 | TPS80031_RTC_ALARM_NUM_REGS, buff); | ||
172 | if (ret < 0) { | ||
173 | dev_err(dev->parent, | ||
174 | "reading RTC_ALARM failed, err = %d\n", ret); | ||
175 | return ret; | ||
176 | } | ||
177 | |||
178 | alrm->time.tm_sec = bcd2bin(buff[0]); | ||
179 | alrm->time.tm_min = bcd2bin(buff[1]); | ||
180 | alrm->time.tm_hour = bcd2bin(buff[2]); | ||
181 | alrm->time.tm_mday = bcd2bin(buff[3]); | ||
182 | alrm->time.tm_mon = bcd2bin(buff[4]) - 1; | ||
183 | alrm->time.tm_year = bcd2bin(buff[5]) + RTC_YEAR_OFFSET; | ||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | static int clear_alarm_int_status(struct device *dev, struct tps80031_rtc *rtc) | ||
188 | { | ||
189 | int ret; | ||
190 | u8 buf; | ||
191 | |||
192 | /** | ||
193 | * As per datasheet, A dummy read of this RTC_STATUS_REG register | ||
194 | * is necessary before each I2C read in order to update the status | ||
195 | * register value. | ||
196 | */ | ||
197 | ret = tps80031_read(dev->parent, TPS80031_SLAVE_ID1, | ||
198 | TPS80031_RTC_STATUS_REG, &buf); | ||
199 | if (ret < 0) { | ||
200 | dev_err(dev, "reading RTC_STATUS failed. err = %d\n", ret); | ||
201 | return ret; | ||
202 | } | ||
203 | |||
204 | /* clear Alarm status bits.*/ | ||
205 | ret = tps80031_set_bits(dev->parent, TPS80031_SLAVE_ID1, | ||
206 | TPS80031_RTC_STATUS_REG, ALARM_INT_STATUS); | ||
207 | if (ret < 0) { | ||
208 | dev_err(dev, "clear Alarm INT failed, err = %d\n", ret); | ||
209 | return ret; | ||
210 | } | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | static irqreturn_t tps80031_rtc_irq(int irq, void *data) | ||
215 | { | ||
216 | struct device *dev = data; | ||
217 | struct tps80031_rtc *rtc = dev_get_drvdata(dev); | ||
218 | int ret; | ||
219 | |||
220 | ret = clear_alarm_int_status(dev, rtc); | ||
221 | if (ret < 0) | ||
222 | return ret; | ||
223 | |||
224 | rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); | ||
225 | return IRQ_HANDLED; | ||
226 | } | ||
227 | |||
228 | static const struct rtc_class_ops tps80031_rtc_ops = { | ||
229 | .read_time = tps80031_rtc_read_time, | ||
230 | .set_time = tps80031_rtc_set_time, | ||
231 | .set_alarm = tps80031_rtc_set_alarm, | ||
232 | .read_alarm = tps80031_rtc_read_alarm, | ||
233 | .alarm_irq_enable = tps80031_rtc_alarm_irq_enable, | ||
234 | }; | ||
235 | |||
236 | static int tps80031_rtc_probe(struct platform_device *pdev) | ||
237 | { | ||
238 | struct tps80031_rtc *rtc; | ||
239 | struct rtc_time tm; | ||
240 | int ret; | ||
241 | |||
242 | rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); | ||
243 | if (!rtc) | ||
244 | return -ENOMEM; | ||
245 | |||
246 | rtc->irq = platform_get_irq(pdev, 0); | ||
247 | platform_set_drvdata(pdev, rtc); | ||
248 | |||
249 | /* Start RTC */ | ||
250 | ret = tps80031_set_bits(pdev->dev.parent, TPS80031_SLAVE_ID1, | ||
251 | TPS80031_RTC_CTRL_REG, STOP_RTC); | ||
252 | if (ret < 0) { | ||
253 | dev_err(&pdev->dev, "failed to start RTC. err = %d\n", ret); | ||
254 | return ret; | ||
255 | } | ||
256 | |||
257 | /* If RTC have POR values, set time 01:01:2000 */ | ||
258 | tps80031_rtc_read_time(&pdev->dev, &tm); | ||
259 | if ((tm.tm_year == RTC_YEAR_OFFSET + TPS80031_RTC_POR_YEAR) && | ||
260 | (tm.tm_mon == (TPS80031_RTC_POR_MONTH - 1)) && | ||
261 | (tm.tm_mday == TPS80031_RTC_POR_DAY)) { | ||
262 | tm.tm_year = 2000; | ||
263 | tm.tm_mday = 1; | ||
264 | tm.tm_mon = 1; | ||
265 | ret = tps80031_rtc_set_time(&pdev->dev, &tm); | ||
266 | if (ret < 0) { | ||
267 | dev_err(&pdev->dev, | ||
268 | "RTC set time failed, err = %d\n", ret); | ||
269 | return ret; | ||
270 | } | ||
271 | } | ||
272 | |||
273 | /* Clear alarm intretupt status if it is there */ | ||
274 | ret = clear_alarm_int_status(&pdev->dev, rtc); | ||
275 | if (ret < 0) { | ||
276 | dev_err(&pdev->dev, "Clear alarm int failed, err = %d\n", ret); | ||
277 | return ret; | ||
278 | } | ||
279 | |||
280 | rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, | ||
281 | &tps80031_rtc_ops, THIS_MODULE); | ||
282 | if (IS_ERR(rtc->rtc)) { | ||
283 | ret = PTR_ERR(rtc->rtc); | ||
284 | dev_err(&pdev->dev, "RTC registration failed, err %d\n", ret); | ||
285 | return ret; | ||
286 | } | ||
287 | |||
288 | ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL, | ||
289 | tps80031_rtc_irq, | ||
290 | IRQF_ONESHOT | IRQF_EARLY_RESUME, | ||
291 | dev_name(&pdev->dev), rtc); | ||
292 | if (ret < 0) { | ||
293 | dev_err(&pdev->dev, "request IRQ:%d failed, err = %d\n", | ||
294 | rtc->irq, ret); | ||
295 | rtc_device_unregister(rtc->rtc); | ||
296 | return ret; | ||
297 | } | ||
298 | device_set_wakeup_capable(&pdev->dev, 1); | ||
299 | return 0; | ||
300 | } | ||
301 | |||
302 | static int tps80031_rtc_remove(struct platform_device *pdev) | ||
303 | { | ||
304 | struct tps80031_rtc *rtc = platform_get_drvdata(pdev); | ||
305 | |||
306 | rtc_device_unregister(rtc->rtc); | ||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | #ifdef CONFIG_PM_SLEEP | ||
311 | static int tps80031_rtc_suspend(struct device *dev) | ||
312 | { | ||
313 | struct tps80031_rtc *rtc = dev_get_drvdata(dev); | ||
314 | |||
315 | if (device_may_wakeup(dev)) | ||
316 | enable_irq_wake(rtc->irq); | ||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | static int tps80031_rtc_resume(struct device *dev) | ||
321 | { | ||
322 | struct tps80031_rtc *rtc = dev_get_drvdata(dev); | ||
323 | |||
324 | if (device_may_wakeup(dev)) | ||
325 | disable_irq_wake(rtc->irq); | ||
326 | return 0; | ||
327 | }; | ||
328 | #endif | ||
329 | |||
330 | static const struct dev_pm_ops tps80031_pm_ops = { | ||
331 | SET_SYSTEM_SLEEP_PM_OPS(tps80031_rtc_suspend, tps80031_rtc_resume) | ||
332 | }; | ||
333 | |||
334 | static struct platform_driver tps80031_rtc_driver = { | ||
335 | .driver = { | ||
336 | .name = "tps80031-rtc", | ||
337 | .owner = THIS_MODULE, | ||
338 | .pm = &tps80031_pm_ops, | ||
339 | }, | ||
340 | .probe = tps80031_rtc_probe, | ||
341 | .remove = tps80031_rtc_remove, | ||
342 | }; | ||
343 | |||
344 | module_platform_driver(tps80031_rtc_driver); | ||
345 | |||
346 | MODULE_ALIAS("platform:tps80031-rtc"); | ||
347 | MODULE_DESCRIPTION("TI TPS80031/TPS80032 RTC driver"); | ||
348 | MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); | ||
349 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index ccd4ad370b32..8bc6c80b184c 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/bcd.h> | 27 | #include <linux/bcd.h> |
28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
29 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
30 | #include <linux/of.h> | ||
30 | 31 | ||
31 | #include <linux/i2c/twl.h> | 32 | #include <linux/i2c/twl.h> |
32 | 33 | ||
@@ -588,11 +589,14 @@ static int twl_rtc_resume(struct platform_device *pdev) | |||
588 | #define twl_rtc_resume NULL | 589 | #define twl_rtc_resume NULL |
589 | #endif | 590 | #endif |
590 | 591 | ||
592 | #ifdef CONFIG_OF | ||
591 | static const struct of_device_id twl_rtc_of_match[] = { | 593 | static const struct of_device_id twl_rtc_of_match[] = { |
592 | {.compatible = "ti,twl4030-rtc", }, | 594 | {.compatible = "ti,twl4030-rtc", }, |
593 | { }, | 595 | { }, |
594 | }; | 596 | }; |
595 | MODULE_DEVICE_TABLE(of, twl_rtc_of_match); | 597 | MODULE_DEVICE_TABLE(of, twl_rtc_of_match); |
598 | #endif | ||
599 | |||
596 | MODULE_ALIAS("platform:twl_rtc"); | 600 | MODULE_ALIAS("platform:twl_rtc"); |
597 | 601 | ||
598 | static struct platform_driver twl4030rtc_driver = { | 602 | static struct platform_driver twl4030rtc_driver = { |
@@ -604,7 +608,7 @@ static struct platform_driver twl4030rtc_driver = { | |||
604 | .driver = { | 608 | .driver = { |
605 | .owner = THIS_MODULE, | 609 | .owner = THIS_MODULE, |
606 | .name = "twl_rtc", | 610 | .name = "twl_rtc", |
607 | .of_match_table = twl_rtc_of_match, | 611 | .of_match_table = of_match_ptr(twl_rtc_of_match), |
608 | }, | 612 | }, |
609 | }; | 613 | }; |
610 | 614 | ||
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index 6c3774cf5a24..f91be04b9050 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c | |||
@@ -352,7 +352,7 @@ static int rtc_probe(struct platform_device *pdev) | |||
352 | disable_irq(aie_irq); | 352 | disable_irq(aie_irq); |
353 | disable_irq(pie_irq); | 353 | disable_irq(pie_irq); |
354 | 354 | ||
355 | printk(KERN_INFO "rtc: Real Time Clock of NEC VR4100 series\n"); | 355 | dev_info(&pdev->dev, "Real Time Clock of NEC VR4100 series\n"); |
356 | 356 | ||
357 | return 0; | 357 | return 0; |
358 | 358 | ||
diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c index 00c930f4b6f3..a000bc0a8bff 100644 --- a/drivers/rtc/rtc-vt8500.c +++ b/drivers/rtc/rtc-vt8500.c | |||
@@ -137,7 +137,7 @@ static int vt8500_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
137 | return -EINVAL; | 137 | return -EINVAL; |
138 | } | 138 | } |
139 | 139 | ||
140 | writel((bin2bcd(tm->tm_year - 100) << DATE_YEAR_S) | 140 | writel((bin2bcd(tm->tm_year % 100) << DATE_YEAR_S) |
141 | | (bin2bcd(tm->tm_mon + 1) << DATE_MONTH_S) | 141 | | (bin2bcd(tm->tm_mon + 1) << DATE_MONTH_S) |
142 | | (bin2bcd(tm->tm_mday)) | 142 | | (bin2bcd(tm->tm_mday)) |
143 | | ((tm->tm_year >= 200) << DATE_CENTURY_S), | 143 | | ((tm->tm_year >= 200) << DATE_CENTURY_S), |
@@ -231,20 +231,21 @@ static int vt8500_rtc_probe(struct platform_device *pdev) | |||
231 | return -ENXIO; | 231 | return -ENXIO; |
232 | } | 232 | } |
233 | 233 | ||
234 | vt8500_rtc->res = request_mem_region(vt8500_rtc->res->start, | 234 | vt8500_rtc->res = devm_request_mem_region(&pdev->dev, |
235 | resource_size(vt8500_rtc->res), | 235 | vt8500_rtc->res->start, |
236 | "vt8500-rtc"); | 236 | resource_size(vt8500_rtc->res), |
237 | "vt8500-rtc"); | ||
237 | if (vt8500_rtc->res == NULL) { | 238 | if (vt8500_rtc->res == NULL) { |
238 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | 239 | dev_err(&pdev->dev, "failed to request I/O memory\n"); |
239 | return -EBUSY; | 240 | return -EBUSY; |
240 | } | 241 | } |
241 | 242 | ||
242 | vt8500_rtc->regbase = ioremap(vt8500_rtc->res->start, | 243 | vt8500_rtc->regbase = devm_ioremap(&pdev->dev, vt8500_rtc->res->start, |
243 | resource_size(vt8500_rtc->res)); | 244 | resource_size(vt8500_rtc->res)); |
244 | if (!vt8500_rtc->regbase) { | 245 | if (!vt8500_rtc->regbase) { |
245 | dev_err(&pdev->dev, "Unable to map RTC I/O memory\n"); | 246 | dev_err(&pdev->dev, "Unable to map RTC I/O memory\n"); |
246 | ret = -EBUSY; | 247 | ret = -EBUSY; |
247 | goto err_release; | 248 | goto err_return; |
248 | } | 249 | } |
249 | 250 | ||
250 | /* Enable RTC and set it to 24-hour mode */ | 251 | /* Enable RTC and set it to 24-hour mode */ |
@@ -257,11 +258,11 @@ static int vt8500_rtc_probe(struct platform_device *pdev) | |||
257 | ret = PTR_ERR(vt8500_rtc->rtc); | 258 | ret = PTR_ERR(vt8500_rtc->rtc); |
258 | dev_err(&pdev->dev, | 259 | dev_err(&pdev->dev, |
259 | "Failed to register RTC device -> %d\n", ret); | 260 | "Failed to register RTC device -> %d\n", ret); |
260 | goto err_unmap; | 261 | goto err_return; |
261 | } | 262 | } |
262 | 263 | ||
263 | ret = request_irq(vt8500_rtc->irq_alarm, vt8500_rtc_irq, 0, | 264 | ret = devm_request_irq(&pdev->dev, vt8500_rtc->irq_alarm, |
264 | "rtc alarm", vt8500_rtc); | 265 | vt8500_rtc_irq, 0, "rtc alarm", vt8500_rtc); |
265 | if (ret < 0) { | 266 | if (ret < 0) { |
266 | dev_err(&pdev->dev, "can't get irq %i, err %d\n", | 267 | dev_err(&pdev->dev, "can't get irq %i, err %d\n", |
267 | vt8500_rtc->irq_alarm, ret); | 268 | vt8500_rtc->irq_alarm, ret); |
@@ -272,11 +273,7 @@ static int vt8500_rtc_probe(struct platform_device *pdev) | |||
272 | 273 | ||
273 | err_unreg: | 274 | err_unreg: |
274 | rtc_device_unregister(vt8500_rtc->rtc); | 275 | rtc_device_unregister(vt8500_rtc->rtc); |
275 | err_unmap: | 276 | err_return: |
276 | iounmap(vt8500_rtc->regbase); | ||
277 | err_release: | ||
278 | release_mem_region(vt8500_rtc->res->start, | ||
279 | resource_size(vt8500_rtc->res)); | ||
280 | return ret; | 277 | return ret; |
281 | } | 278 | } |
282 | 279 | ||
@@ -284,15 +281,10 @@ static int vt8500_rtc_remove(struct platform_device *pdev) | |||
284 | { | 281 | { |
285 | struct vt8500_rtc *vt8500_rtc = platform_get_drvdata(pdev); | 282 | struct vt8500_rtc *vt8500_rtc = platform_get_drvdata(pdev); |
286 | 283 | ||
287 | free_irq(vt8500_rtc->irq_alarm, vt8500_rtc); | ||
288 | |||
289 | rtc_device_unregister(vt8500_rtc->rtc); | 284 | rtc_device_unregister(vt8500_rtc->rtc); |
290 | 285 | ||
291 | /* Disable alarm matching */ | 286 | /* Disable alarm matching */ |
292 | writel(0, vt8500_rtc->regbase + VT8500_RTC_IS); | 287 | writel(0, vt8500_rtc->regbase + VT8500_RTC_IS); |
293 | iounmap(vt8500_rtc->regbase); | ||
294 | release_mem_region(vt8500_rtc->res->start, | ||
295 | resource_size(vt8500_rtc->res)); | ||
296 | 288 | ||
297 | platform_set_drvdata(pdev, NULL); | 289 | platform_set_drvdata(pdev, NULL); |
298 | 290 | ||
diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c index 1b0affbe2659..2f0ac7b30a0c 100644 --- a/drivers/rtc/rtc-wm831x.c +++ b/drivers/rtc/rtc-wm831x.c | |||
@@ -443,9 +443,10 @@ static int wm831x_rtc_probe(struct platform_device *pdev) | |||
443 | goto err; | 443 | goto err; |
444 | } | 444 | } |
445 | 445 | ||
446 | ret = request_threaded_irq(alm_irq, NULL, wm831x_alm_irq, | 446 | ret = devm_request_threaded_irq(&pdev->dev, alm_irq, NULL, |
447 | IRQF_TRIGGER_RISING, "RTC alarm", | 447 | wm831x_alm_irq, |
448 | wm831x_rtc); | 448 | IRQF_TRIGGER_RISING, "RTC alarm", |
449 | wm831x_rtc); | ||
449 | if (ret != 0) { | 450 | if (ret != 0) { |
450 | dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n", | 451 | dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n", |
451 | alm_irq, ret); | 452 | alm_irq, ret); |
@@ -462,9 +463,7 @@ err: | |||
462 | static int wm831x_rtc_remove(struct platform_device *pdev) | 463 | static int wm831x_rtc_remove(struct platform_device *pdev) |
463 | { | 464 | { |
464 | struct wm831x_rtc *wm831x_rtc = platform_get_drvdata(pdev); | 465 | struct wm831x_rtc *wm831x_rtc = platform_get_drvdata(pdev); |
465 | int alm_irq = platform_get_irq_byname(pdev, "ALM"); | ||
466 | 466 | ||
467 | free_irq(alm_irq, wm831x_rtc); | ||
468 | rtc_device_unregister(wm831x_rtc->rtc); | 467 | rtc_device_unregister(wm831x_rtc->rtc); |
469 | 468 | ||
470 | return 0; | 469 | return 0; |
diff --git a/drivers/rtc/systohc.c b/drivers/rtc/systohc.c new file mode 100644 index 000000000000..bf3e242ccc5c --- /dev/null +++ b/drivers/rtc/systohc.c | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published by | ||
4 | * the Free Software Foundation. | ||
5 | * | ||
6 | */ | ||
7 | #include <linux/rtc.h> | ||
8 | #include <linux/time.h> | ||
9 | |||
10 | /** | ||
11 | * rtc_set_ntp_time - Save NTP synchronized time to the RTC | ||
12 | * @now: Current time of day | ||
13 | * | ||
14 | * Replacement for the NTP platform function update_persistent_clock | ||
15 | * that stores time for later retrieval by rtc_hctosys. | ||
16 | * | ||
17 | * Returns 0 on successful RTC update, -ENODEV if a RTC update is not | ||
18 | * possible at all, and various other -errno for specific temporary failure | ||
19 | * cases. | ||
20 | * | ||
21 | * If temporary failure is indicated the caller should try again 'soon' | ||
22 | */ | ||
23 | int rtc_set_ntp_time(struct timespec now) | ||
24 | { | ||
25 | struct rtc_device *rtc; | ||
26 | struct rtc_time tm; | ||
27 | int err = -ENODEV; | ||
28 | |||
29 | if (now.tv_nsec < (NSEC_PER_SEC >> 1)) | ||
30 | rtc_time_to_tm(now.tv_sec, &tm); | ||
31 | else | ||
32 | rtc_time_to_tm(now.tv_sec + 1, &tm); | ||
33 | |||
34 | rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); | ||
35 | if (rtc) { | ||
36 | /* rtc_hctosys exclusively uses UTC, so we call set_time here, | ||
37 | * not set_mmss. */ | ||
38 | if (rtc->ops && (rtc->ops->set_time || rtc->ops->set_mmss)) | ||
39 | err = rtc_set_time(rtc, &tm); | ||
40 | rtc_class_close(rtc); | ||
41 | } | ||
42 | |||
43 | return err; | ||
44 | } | ||