diff options
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/Kconfig | 19 | ||||
-rw-r--r-- | drivers/rtc/Makefile | 2 | ||||
-rw-r--r-- | drivers/rtc/rtc-at91rm9200.c | 16 | ||||
-rw-r--r-- | drivers/rtc/rtc-cmos.c | 294 | ||||
-rw-r--r-- | drivers/rtc/rtc-dev.c | 58 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1305.c | 847 | ||||
-rw-r--r-- | drivers/rtc/rtc-m41t80.c | 20 | ||||
-rw-r--r-- | drivers/rtc/rtc-m41t94.c | 173 | ||||
-rw-r--r-- | drivers/rtc/rtc-omap.c | 21 | ||||
-rw-r--r-- | drivers/rtc/rtc-pcf8583.c | 129 | ||||
-rw-r--r-- | drivers/rtc/rtc-s3c.c | 89 | ||||
-rw-r--r-- | drivers/rtc/rtc-vr41xx.c | 65 |
12 files changed, 1366 insertions, 367 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index fc85bf2e4a97..90ab73825401 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -273,6 +273,25 @@ comment "SPI RTC drivers" | |||
273 | 273 | ||
274 | if SPI_MASTER | 274 | if SPI_MASTER |
275 | 275 | ||
276 | config RTC_DRV_M41T94 | ||
277 | tristate "ST M41T94" | ||
278 | help | ||
279 | If you say yes here you will get support for the | ||
280 | ST M41T94 SPI RTC chip. | ||
281 | |||
282 | This driver can also be built as a module. If so, the module | ||
283 | will be called rtc-m41t94. | ||
284 | |||
285 | config RTC_DRV_DS1305 | ||
286 | tristate "Dallas/Maxim DS1305/DS1306" | ||
287 | help | ||
288 | Select this driver to get support for the Dallas/Maxim DS1305 | ||
289 | and DS1306 real time clock chips. These support a trickle | ||
290 | charger, alarms, and NVRAM in addition to the clock. | ||
291 | |||
292 | This driver can also be built as a module. If so, the module | ||
293 | will be called rtc-ds1305. | ||
294 | |||
276 | config RTC_DRV_MAX6902 | 295 | config RTC_DRV_MAX6902 |
277 | tristate "Maxim MAX6902" | 296 | tristate "Maxim MAX6902" |
278 | help | 297 | help |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index b5d9d67df887..18622ef84cab 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -24,6 +24,7 @@ obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o | |||
24 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o | 24 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o |
25 | obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o | 25 | obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o |
26 | obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o | 26 | obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o |
27 | obj-$(CONFIG_RTC_DRV_DS1305) += rtc-ds1305.o | ||
27 | obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o | 28 | obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o |
28 | obj-$(CONFIG_RTC_DRV_DS1374) += rtc-ds1374.o | 29 | obj-$(CONFIG_RTC_DRV_DS1374) += rtc-ds1374.o |
29 | obj-$(CONFIG_RTC_DRV_DS1511) += rtc-ds1511.o | 30 | obj-$(CONFIG_RTC_DRV_DS1511) += rtc-ds1511.o |
@@ -34,6 +35,7 @@ obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o | |||
34 | obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o | 35 | obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o |
35 | obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o | 36 | obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o |
36 | obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o | 37 | obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o |
38 | obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o | ||
37 | obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o | 39 | obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o |
38 | obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o | 40 | obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o |
39 | obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o | 41 | obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o |
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index 9c3db934cc24..cd32d05db773 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c | |||
@@ -171,8 +171,10 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
171 | | BIN2BCD(tm.tm_mday) << 24 | 171 | | BIN2BCD(tm.tm_mday) << 24 |
172 | | AT91_RTC_DATEEN | AT91_RTC_MTHEN); | 172 | | AT91_RTC_DATEEN | AT91_RTC_MTHEN); |
173 | 173 | ||
174 | if (alrm->enabled) | 174 | if (alrm->enabled) { |
175 | at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM); | ||
175 | at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); | 176 | at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); |
177 | } | ||
176 | 178 | ||
177 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, | 179 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, |
178 | at91_alarm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, | 180 | at91_alarm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, |
@@ -191,28 +193,22 @@ static int at91_rtc_ioctl(struct device *dev, unsigned int cmd, | |||
191 | 193 | ||
192 | pr_debug("%s(): cmd=%08x, arg=%08lx.\n", __func__, cmd, arg); | 194 | pr_debug("%s(): cmd=%08x, arg=%08lx.\n", __func__, cmd, arg); |
193 | 195 | ||
196 | /* important: scrub old status before enabling IRQs */ | ||
194 | switch (cmd) { | 197 | switch (cmd) { |
195 | case RTC_AIE_OFF: /* alarm off */ | 198 | case RTC_AIE_OFF: /* alarm off */ |
196 | at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM); | 199 | at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM); |
197 | break; | 200 | break; |
198 | case RTC_AIE_ON: /* alarm on */ | 201 | case RTC_AIE_ON: /* alarm on */ |
202 | at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM); | ||
199 | at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); | 203 | at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); |
200 | break; | 204 | break; |
201 | case RTC_UIE_OFF: /* update off */ | 205 | case RTC_UIE_OFF: /* update off */ |
202 | case RTC_PIE_OFF: /* periodic off */ | ||
203 | at91_sys_write(AT91_RTC_IDR, AT91_RTC_SECEV); | 206 | at91_sys_write(AT91_RTC_IDR, AT91_RTC_SECEV); |
204 | break; | 207 | break; |
205 | case RTC_UIE_ON: /* update on */ | 208 | case RTC_UIE_ON: /* update on */ |
206 | case RTC_PIE_ON: /* periodic on */ | 209 | at91_sys_write(AT91_RTC_SCCR, AT91_RTC_SECEV); |
207 | at91_sys_write(AT91_RTC_IER, AT91_RTC_SECEV); | 210 | at91_sys_write(AT91_RTC_IER, AT91_RTC_SECEV); |
208 | break; | 211 | break; |
209 | case RTC_IRQP_READ: /* read periodic alarm frequency */ | ||
210 | ret = put_user(AT91_RTC_FREQ, (unsigned long *) arg); | ||
211 | break; | ||
212 | case RTC_IRQP_SET: /* set periodic alarm frequency */ | ||
213 | if (arg != AT91_RTC_FREQ) | ||
214 | ret = -EINVAL; | ||
215 | break; | ||
216 | default: | 212 | default: |
217 | ret = -ENOIOCTLCMD; | 213 | ret = -ENOIOCTLCMD; |
218 | break; | 214 | break; |
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index d7bb9bac71df..6ea349aba3ba 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -36,25 +36,9 @@ | |||
36 | #include <linux/platform_device.h> | 36 | #include <linux/platform_device.h> |
37 | #include <linux/mod_devicetable.h> | 37 | #include <linux/mod_devicetable.h> |
38 | 38 | ||
39 | #ifdef CONFIG_HPET_EMULATE_RTC | ||
40 | #include <asm/hpet.h> | ||
41 | #endif | ||
42 | |||
43 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ | 39 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ |
44 | #include <asm-generic/rtc.h> | 40 | #include <asm-generic/rtc.h> |
45 | 41 | ||
46 | #ifndef CONFIG_HPET_EMULATE_RTC | ||
47 | #define is_hpet_enabled() 0 | ||
48 | #define hpet_set_alarm_time(hrs, min, sec) do { } while (0) | ||
49 | #define hpet_set_periodic_freq(arg) 0 | ||
50 | #define hpet_mask_rtc_irq_bit(arg) do { } while (0) | ||
51 | #define hpet_set_rtc_irq_bit(arg) do { } while (0) | ||
52 | #define hpet_rtc_timer_init() do { } while (0) | ||
53 | #define hpet_register_irq_handler(h) 0 | ||
54 | #define hpet_unregister_irq_handler(h) do { } while (0) | ||
55 | extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id); | ||
56 | #endif | ||
57 | |||
58 | struct cmos_rtc { | 42 | struct cmos_rtc { |
59 | struct rtc_device *rtc; | 43 | struct rtc_device *rtc; |
60 | struct device *dev; | 44 | struct device *dev; |
@@ -93,6 +77,72 @@ static inline int is_intr(u8 rtc_intr) | |||
93 | 77 | ||
94 | /*----------------------------------------------------------------*/ | 78 | /*----------------------------------------------------------------*/ |
95 | 79 | ||
80 | /* Much modern x86 hardware has HPETs (10+ MHz timers) which, because | ||
81 | * many BIOS programmers don't set up "sane mode" IRQ routing, are mostly | ||
82 | * used in a broken "legacy replacement" mode. The breakage includes | ||
83 | * HPET #1 hijacking the IRQ for this RTC, and being unavailable for | ||
84 | * other (better) use. | ||
85 | * | ||
86 | * When that broken mode is in use, platform glue provides a partial | ||
87 | * emulation of hardware RTC IRQ facilities using HPET #1. We don't | ||
88 | * want to use HPET for anything except those IRQs though... | ||
89 | */ | ||
90 | #ifdef CONFIG_HPET_EMULATE_RTC | ||
91 | #include <asm/hpet.h> | ||
92 | #else | ||
93 | |||
94 | static inline int is_hpet_enabled(void) | ||
95 | { | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | static inline int hpet_mask_rtc_irq_bit(unsigned long mask) | ||
100 | { | ||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static inline int hpet_set_rtc_irq_bit(unsigned long mask) | ||
105 | { | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static inline int | ||
110 | hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned char sec) | ||
111 | { | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static inline int hpet_set_periodic_freq(unsigned long freq) | ||
116 | { | ||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | static inline int hpet_rtc_dropped_irq(void) | ||
121 | { | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | static inline int hpet_rtc_timer_init(void) | ||
126 | { | ||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | extern irq_handler_t hpet_rtc_interrupt; | ||
131 | |||
132 | static inline int hpet_register_irq_handler(irq_handler_t handler) | ||
133 | { | ||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | static inline int hpet_unregister_irq_handler(irq_handler_t handler) | ||
138 | { | ||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | #endif | ||
143 | |||
144 | /*----------------------------------------------------------------*/ | ||
145 | |||
96 | static int cmos_read_time(struct device *dev, struct rtc_time *t) | 146 | static int cmos_read_time(struct device *dev, struct rtc_time *t) |
97 | { | 147 | { |
98 | /* REVISIT: if the clock has a "century" register, use | 148 | /* REVISIT: if the clock has a "century" register, use |
@@ -185,11 +235,56 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
185 | return 0; | 235 | return 0; |
186 | } | 236 | } |
187 | 237 | ||
238 | static void cmos_checkintr(struct cmos_rtc *cmos, unsigned char rtc_control) | ||
239 | { | ||
240 | unsigned char rtc_intr; | ||
241 | |||
242 | /* NOTE after changing RTC_xIE bits we always read INTR_FLAGS; | ||
243 | * allegedly some older rtcs need that to handle irqs properly | ||
244 | */ | ||
245 | rtc_intr = CMOS_READ(RTC_INTR_FLAGS); | ||
246 | |||
247 | if (is_hpet_enabled()) | ||
248 | return; | ||
249 | |||
250 | rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; | ||
251 | if (is_intr(rtc_intr)) | ||
252 | rtc_update_irq(cmos->rtc, 1, rtc_intr); | ||
253 | } | ||
254 | |||
255 | static void cmos_irq_enable(struct cmos_rtc *cmos, unsigned char mask) | ||
256 | { | ||
257 | unsigned char rtc_control; | ||
258 | |||
259 | /* flush any pending IRQ status, notably for update irqs, | ||
260 | * before we enable new IRQs | ||
261 | */ | ||
262 | rtc_control = CMOS_READ(RTC_CONTROL); | ||
263 | cmos_checkintr(cmos, rtc_control); | ||
264 | |||
265 | rtc_control |= mask; | ||
266 | CMOS_WRITE(rtc_control, RTC_CONTROL); | ||
267 | hpet_set_rtc_irq_bit(mask); | ||
268 | |||
269 | cmos_checkintr(cmos, rtc_control); | ||
270 | } | ||
271 | |||
272 | static void cmos_irq_disable(struct cmos_rtc *cmos, unsigned char mask) | ||
273 | { | ||
274 | unsigned char rtc_control; | ||
275 | |||
276 | rtc_control = CMOS_READ(RTC_CONTROL); | ||
277 | rtc_control &= ~mask; | ||
278 | CMOS_WRITE(rtc_control, RTC_CONTROL); | ||
279 | hpet_mask_rtc_irq_bit(mask); | ||
280 | |||
281 | cmos_checkintr(cmos, rtc_control); | ||
282 | } | ||
283 | |||
188 | static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) | 284 | static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) |
189 | { | 285 | { |
190 | struct cmos_rtc *cmos = dev_get_drvdata(dev); | 286 | struct cmos_rtc *cmos = dev_get_drvdata(dev); |
191 | unsigned char mon, mday, hrs, min, sec; | 287 | unsigned char mon, mday, hrs, min, sec; |
192 | unsigned char rtc_control, rtc_intr; | ||
193 | 288 | ||
194 | if (!is_valid_irq(cmos->irq)) | 289 | if (!is_valid_irq(cmos->irq)) |
195 | return -EIO; | 290 | return -EIO; |
@@ -213,17 +308,10 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
213 | sec = t->time.tm_sec; | 308 | sec = t->time.tm_sec; |
214 | sec = (sec < 60) ? BIN2BCD(sec) : 0xff; | 309 | sec = (sec < 60) ? BIN2BCD(sec) : 0xff; |
215 | 310 | ||
216 | hpet_set_alarm_time(t->time.tm_hour, t->time.tm_min, t->time.tm_sec); | ||
217 | spin_lock_irq(&rtc_lock); | 311 | spin_lock_irq(&rtc_lock); |
218 | 312 | ||
219 | /* next rtc irq must not be from previous alarm setting */ | 313 | /* next rtc irq must not be from previous alarm setting */ |
220 | rtc_control = CMOS_READ(RTC_CONTROL); | 314 | cmos_irq_disable(cmos, RTC_AIE); |
221 | rtc_control &= ~RTC_AIE; | ||
222 | CMOS_WRITE(rtc_control, RTC_CONTROL); | ||
223 | rtc_intr = CMOS_READ(RTC_INTR_FLAGS); | ||
224 | rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; | ||
225 | if (is_intr(rtc_intr)) | ||
226 | rtc_update_irq(cmos->rtc, 1, rtc_intr); | ||
227 | 315 | ||
228 | /* update alarm */ | 316 | /* update alarm */ |
229 | CMOS_WRITE(hrs, RTC_HOURS_ALARM); | 317 | CMOS_WRITE(hrs, RTC_HOURS_ALARM); |
@@ -237,14 +325,13 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
237 | CMOS_WRITE(mon, cmos->mon_alrm); | 325 | CMOS_WRITE(mon, cmos->mon_alrm); |
238 | } | 326 | } |
239 | 327 | ||
240 | if (t->enabled) { | 328 | /* FIXME the HPET alarm glue currently ignores day_alrm |
241 | rtc_control |= RTC_AIE; | 329 | * and mon_alrm ... |
242 | CMOS_WRITE(rtc_control, RTC_CONTROL); | 330 | */ |
243 | rtc_intr = CMOS_READ(RTC_INTR_FLAGS); | 331 | hpet_set_alarm_time(t->time.tm_hour, t->time.tm_min, t->time.tm_sec); |
244 | rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; | 332 | |
245 | if (is_intr(rtc_intr)) | 333 | if (t->enabled) |
246 | rtc_update_irq(cmos->rtc, 1, rtc_intr); | 334 | cmos_irq_enable(cmos, RTC_AIE); |
247 | } | ||
248 | 335 | ||
249 | spin_unlock_irq(&rtc_lock); | 336 | spin_unlock_irq(&rtc_lock); |
250 | 337 | ||
@@ -267,8 +354,8 @@ static int cmos_irq_set_freq(struct device *dev, int freq) | |||
267 | f = 16 - f; | 354 | f = 16 - f; |
268 | 355 | ||
269 | spin_lock_irqsave(&rtc_lock, flags); | 356 | spin_lock_irqsave(&rtc_lock, flags); |
270 | if (!hpet_set_periodic_freq(freq)) | 357 | hpet_set_periodic_freq(freq); |
271 | CMOS_WRITE(RTC_REF_CLCK_32KHZ | f, RTC_FREQ_SELECT); | 358 | CMOS_WRITE(RTC_REF_CLCK_32KHZ | f, RTC_FREQ_SELECT); |
272 | spin_unlock_irqrestore(&rtc_lock, flags); | 359 | spin_unlock_irqrestore(&rtc_lock, flags); |
273 | 360 | ||
274 | return 0; | 361 | return 0; |
@@ -277,26 +364,17 @@ static int cmos_irq_set_freq(struct device *dev, int freq) | |||
277 | static int cmos_irq_set_state(struct device *dev, int enabled) | 364 | static int cmos_irq_set_state(struct device *dev, int enabled) |
278 | { | 365 | { |
279 | struct cmos_rtc *cmos = dev_get_drvdata(dev); | 366 | struct cmos_rtc *cmos = dev_get_drvdata(dev); |
280 | unsigned char rtc_control, rtc_intr; | ||
281 | unsigned long flags; | 367 | unsigned long flags; |
282 | 368 | ||
283 | if (!is_valid_irq(cmos->irq)) | 369 | if (!is_valid_irq(cmos->irq)) |
284 | return -ENXIO; | 370 | return -ENXIO; |
285 | 371 | ||
286 | spin_lock_irqsave(&rtc_lock, flags); | 372 | spin_lock_irqsave(&rtc_lock, flags); |
287 | rtc_control = CMOS_READ(RTC_CONTROL); | ||
288 | 373 | ||
289 | if (enabled) | 374 | if (enabled) |
290 | rtc_control |= RTC_PIE; | 375 | cmos_irq_enable(cmos, RTC_PIE); |
291 | else | 376 | else |
292 | rtc_control &= ~RTC_PIE; | 377 | cmos_irq_disable(cmos, RTC_PIE); |
293 | |||
294 | CMOS_WRITE(rtc_control, RTC_CONTROL); | ||
295 | |||
296 | rtc_intr = CMOS_READ(RTC_INTR_FLAGS); | ||
297 | rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; | ||
298 | if (is_intr(rtc_intr)) | ||
299 | rtc_update_irq(cmos->rtc, 1, rtc_intr); | ||
300 | 378 | ||
301 | spin_unlock_irqrestore(&rtc_lock, flags); | 379 | spin_unlock_irqrestore(&rtc_lock, flags); |
302 | return 0; | 380 | return 0; |
@@ -308,7 +386,6 @@ static int | |||
308 | cmos_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | 386 | cmos_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) |
309 | { | 387 | { |
310 | struct cmos_rtc *cmos = dev_get_drvdata(dev); | 388 | struct cmos_rtc *cmos = dev_get_drvdata(dev); |
311 | unsigned char rtc_control, rtc_intr; | ||
312 | unsigned long flags; | 389 | unsigned long flags; |
313 | 390 | ||
314 | switch (cmd) { | 391 | switch (cmd) { |
@@ -316,51 +393,29 @@ cmos_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | |||
316 | case RTC_AIE_ON: | 393 | case RTC_AIE_ON: |
317 | case RTC_UIE_OFF: | 394 | case RTC_UIE_OFF: |
318 | case RTC_UIE_ON: | 395 | case RTC_UIE_ON: |
319 | case RTC_PIE_OFF: | ||
320 | case RTC_PIE_ON: | ||
321 | if (!is_valid_irq(cmos->irq)) | 396 | if (!is_valid_irq(cmos->irq)) |
322 | return -EINVAL; | 397 | return -EINVAL; |
323 | break; | 398 | break; |
399 | /* PIE ON/OFF is handled by cmos_irq_set_state() */ | ||
324 | default: | 400 | default: |
325 | return -ENOIOCTLCMD; | 401 | return -ENOIOCTLCMD; |
326 | } | 402 | } |
327 | 403 | ||
328 | spin_lock_irqsave(&rtc_lock, flags); | 404 | spin_lock_irqsave(&rtc_lock, flags); |
329 | rtc_control = CMOS_READ(RTC_CONTROL); | ||
330 | switch (cmd) { | 405 | switch (cmd) { |
331 | case RTC_AIE_OFF: /* alarm off */ | 406 | case RTC_AIE_OFF: /* alarm off */ |
332 | rtc_control &= ~RTC_AIE; | 407 | cmos_irq_disable(cmos, RTC_AIE); |
333 | hpet_mask_rtc_irq_bit(RTC_AIE); | ||
334 | break; | 408 | break; |
335 | case RTC_AIE_ON: /* alarm on */ | 409 | case RTC_AIE_ON: /* alarm on */ |
336 | rtc_control |= RTC_AIE; | 410 | cmos_irq_enable(cmos, RTC_AIE); |
337 | hpet_set_rtc_irq_bit(RTC_AIE); | ||
338 | break; | 411 | break; |
339 | case RTC_UIE_OFF: /* update off */ | 412 | case RTC_UIE_OFF: /* update off */ |
340 | rtc_control &= ~RTC_UIE; | 413 | cmos_irq_disable(cmos, RTC_UIE); |
341 | hpet_mask_rtc_irq_bit(RTC_UIE); | ||
342 | break; | 414 | break; |
343 | case RTC_UIE_ON: /* update on */ | 415 | case RTC_UIE_ON: /* update on */ |
344 | rtc_control |= RTC_UIE; | 416 | cmos_irq_enable(cmos, RTC_UIE); |
345 | hpet_set_rtc_irq_bit(RTC_UIE); | ||
346 | break; | ||
347 | case RTC_PIE_OFF: /* periodic off */ | ||
348 | rtc_control &= ~RTC_PIE; | ||
349 | hpet_mask_rtc_irq_bit(RTC_PIE); | ||
350 | break; | ||
351 | case RTC_PIE_ON: /* periodic on */ | ||
352 | rtc_control |= RTC_PIE; | ||
353 | hpet_set_rtc_irq_bit(RTC_PIE); | ||
354 | break; | 417 | break; |
355 | } | 418 | } |
356 | if (!is_hpet_enabled()) | ||
357 | CMOS_WRITE(rtc_control, RTC_CONTROL); | ||
358 | |||
359 | rtc_intr = CMOS_READ(RTC_INTR_FLAGS); | ||
360 | rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; | ||
361 | if (is_intr(rtc_intr)) | ||
362 | rtc_update_irq(cmos->rtc, 1, rtc_intr); | ||
363 | |||
364 | spin_unlock_irqrestore(&rtc_lock, flags); | 419 | spin_unlock_irqrestore(&rtc_lock, flags); |
365 | return 0; | 420 | return 0; |
366 | } | 421 | } |
@@ -502,27 +557,29 @@ static irqreturn_t cmos_interrupt(int irq, void *p) | |||
502 | u8 rtc_control; | 557 | u8 rtc_control; |
503 | 558 | ||
504 | spin_lock(&rtc_lock); | 559 | spin_lock(&rtc_lock); |
505 | /* | 560 | |
506 | * In this case it is HPET RTC interrupt handler | 561 | /* When the HPET interrupt handler calls us, the interrupt |
507 | * calling us, with the interrupt information | 562 | * status is passed as arg1 instead of the irq number. But |
508 | * passed as arg1, instead of irq. | 563 | * always clear irq status, even when HPET is in the way. |
564 | * | ||
565 | * Note that HPET and RTC are almost certainly out of phase, | ||
566 | * giving different IRQ status ... | ||
509 | */ | 567 | */ |
568 | irqstat = CMOS_READ(RTC_INTR_FLAGS); | ||
569 | rtc_control = CMOS_READ(RTC_CONTROL); | ||
510 | if (is_hpet_enabled()) | 570 | if (is_hpet_enabled()) |
511 | irqstat = (unsigned long)irq & 0xF0; | 571 | irqstat = (unsigned long)irq & 0xF0; |
512 | else { | 572 | irqstat &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; |
513 | irqstat = CMOS_READ(RTC_INTR_FLAGS); | ||
514 | rtc_control = CMOS_READ(RTC_CONTROL); | ||
515 | irqstat &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; | ||
516 | } | ||
517 | 573 | ||
518 | /* All Linux RTC alarms should be treated as if they were oneshot. | 574 | /* All Linux RTC alarms should be treated as if they were oneshot. |
519 | * Similar code may be needed in system wakeup paths, in case the | 575 | * Similar code may be needed in system wakeup paths, in case the |
520 | * alarm woke the system. | 576 | * alarm woke the system. |
521 | */ | 577 | */ |
522 | if (irqstat & RTC_AIE) { | 578 | if (irqstat & RTC_AIE) { |
523 | rtc_control = CMOS_READ(RTC_CONTROL); | ||
524 | rtc_control &= ~RTC_AIE; | 579 | rtc_control &= ~RTC_AIE; |
525 | CMOS_WRITE(rtc_control, RTC_CONTROL); | 580 | CMOS_WRITE(rtc_control, RTC_CONTROL); |
581 | hpet_mask_rtc_irq_bit(RTC_AIE); | ||
582 | |||
526 | CMOS_READ(RTC_INTR_FLAGS); | 583 | CMOS_READ(RTC_INTR_FLAGS); |
527 | } | 584 | } |
528 | spin_unlock(&rtc_lock); | 585 | spin_unlock(&rtc_lock); |
@@ -629,18 +686,13 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
629 | * do something about other clock frequencies. | 686 | * do something about other clock frequencies. |
630 | */ | 687 | */ |
631 | cmos_rtc.rtc->irq_freq = 1024; | 688 | cmos_rtc.rtc->irq_freq = 1024; |
632 | if (!hpet_set_periodic_freq(cmos_rtc.rtc->irq_freq)) | 689 | hpet_set_periodic_freq(cmos_rtc.rtc->irq_freq); |
633 | CMOS_WRITE(RTC_REF_CLCK_32KHZ | 0x06, RTC_FREQ_SELECT); | 690 | CMOS_WRITE(RTC_REF_CLCK_32KHZ | 0x06, RTC_FREQ_SELECT); |
691 | |||
692 | /* disable irqs */ | ||
693 | cmos_irq_disable(&cmos_rtc, RTC_PIE | RTC_AIE | RTC_UIE); | ||
634 | 694 | ||
635 | /* disable irqs. | ||
636 | * | ||
637 | * NOTE after changing RTC_xIE bits we always read INTR_FLAGS; | ||
638 | * allegedly some older rtcs need that to handle irqs properly | ||
639 | */ | ||
640 | rtc_control = CMOS_READ(RTC_CONTROL); | 695 | rtc_control = CMOS_READ(RTC_CONTROL); |
641 | rtc_control &= ~(RTC_PIE | RTC_AIE | RTC_UIE); | ||
642 | CMOS_WRITE(rtc_control, RTC_CONTROL); | ||
643 | CMOS_READ(RTC_INTR_FLAGS); | ||
644 | 696 | ||
645 | spin_unlock_irq(&rtc_lock); | 697 | spin_unlock_irq(&rtc_lock); |
646 | 698 | ||
@@ -687,7 +739,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
687 | goto cleanup2; | 739 | goto cleanup2; |
688 | } | 740 | } |
689 | 741 | ||
690 | pr_info("%s: alarms up to one %s%s\n", | 742 | pr_info("%s: alarms up to one %s%s%s\n", |
691 | cmos_rtc.rtc->dev.bus_id, | 743 | cmos_rtc.rtc->dev.bus_id, |
692 | is_valid_irq(rtc_irq) | 744 | is_valid_irq(rtc_irq) |
693 | ? (cmos_rtc.mon_alrm | 745 | ? (cmos_rtc.mon_alrm |
@@ -695,8 +747,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
695 | : (cmos_rtc.day_alrm | 747 | : (cmos_rtc.day_alrm |
696 | ? "month" : "day")) | 748 | ? "month" : "day")) |
697 | : "no", | 749 | : "no", |
698 | cmos_rtc.century ? ", y3k" : "" | 750 | cmos_rtc.century ? ", y3k" : "", |
699 | ); | 751 | is_hpet_enabled() ? ", hpet irqs" : ""); |
700 | 752 | ||
701 | return 0; | 753 | return 0; |
702 | 754 | ||
@@ -713,13 +765,8 @@ cleanup0: | |||
713 | 765 | ||
714 | static void cmos_do_shutdown(void) | 766 | static void cmos_do_shutdown(void) |
715 | { | 767 | { |
716 | unsigned char rtc_control; | ||
717 | |||
718 | spin_lock_irq(&rtc_lock); | 768 | spin_lock_irq(&rtc_lock); |
719 | rtc_control = CMOS_READ(RTC_CONTROL); | 769 | cmos_irq_disable(&cmos_rtc, RTC_IRQMASK); |
720 | rtc_control &= ~(RTC_PIE|RTC_AIE|RTC_UIE); | ||
721 | CMOS_WRITE(rtc_control, RTC_CONTROL); | ||
722 | CMOS_READ(RTC_INTR_FLAGS); | ||
723 | spin_unlock_irq(&rtc_lock); | 770 | spin_unlock_irq(&rtc_lock); |
724 | } | 771 | } |
725 | 772 | ||
@@ -760,17 +807,17 @@ static int cmos_suspend(struct device *dev, pm_message_t mesg) | |||
760 | spin_lock_irq(&rtc_lock); | 807 | spin_lock_irq(&rtc_lock); |
761 | cmos->suspend_ctrl = tmp = CMOS_READ(RTC_CONTROL); | 808 | cmos->suspend_ctrl = tmp = CMOS_READ(RTC_CONTROL); |
762 | if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) { | 809 | if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) { |
763 | unsigned char irqstat; | 810 | unsigned char mask; |
764 | 811 | ||
765 | if (do_wake) | 812 | if (do_wake) |
766 | tmp &= ~(RTC_PIE|RTC_UIE); | 813 | mask = RTC_IRQMASK & ~RTC_AIE; |
767 | else | 814 | else |
768 | tmp &= ~(RTC_PIE|RTC_AIE|RTC_UIE); | 815 | mask = RTC_IRQMASK; |
816 | tmp &= ~mask; | ||
769 | CMOS_WRITE(tmp, RTC_CONTROL); | 817 | CMOS_WRITE(tmp, RTC_CONTROL); |
770 | irqstat = CMOS_READ(RTC_INTR_FLAGS); | 818 | hpet_mask_rtc_irq_bit(mask); |
771 | irqstat &= (tmp & RTC_IRQMASK) | RTC_IRQF; | 819 | |
772 | if (is_intr(irqstat)) | 820 | cmos_checkintr(cmos, tmp); |
773 | rtc_update_irq(cmos->rtc, 1, irqstat); | ||
774 | } | 821 | } |
775 | spin_unlock_irq(&rtc_lock); | 822 | spin_unlock_irq(&rtc_lock); |
776 | 823 | ||
@@ -796,7 +843,8 @@ static int cmos_resume(struct device *dev) | |||
796 | unsigned char tmp = cmos->suspend_ctrl; | 843 | unsigned char tmp = cmos->suspend_ctrl; |
797 | 844 | ||
798 | /* re-enable any irqs previously active */ | 845 | /* re-enable any irqs previously active */ |
799 | if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) { | 846 | if (tmp & RTC_IRQMASK) { |
847 | unsigned char mask; | ||
800 | 848 | ||
801 | if (cmos->enabled_wake) { | 849 | if (cmos->enabled_wake) { |
802 | if (cmos->wake_off) | 850 | if (cmos->wake_off) |
@@ -807,18 +855,28 @@ static int cmos_resume(struct device *dev) | |||
807 | } | 855 | } |
808 | 856 | ||
809 | spin_lock_irq(&rtc_lock); | 857 | spin_lock_irq(&rtc_lock); |
810 | CMOS_WRITE(tmp, RTC_CONTROL); | 858 | do { |
811 | tmp = CMOS_READ(RTC_INTR_FLAGS); | 859 | CMOS_WRITE(tmp, RTC_CONTROL); |
812 | tmp &= (cmos->suspend_ctrl & RTC_IRQMASK) | RTC_IRQF; | 860 | hpet_set_rtc_irq_bit(tmp & RTC_IRQMASK); |
813 | if (is_intr(tmp)) | 861 | |
814 | rtc_update_irq(cmos->rtc, 1, tmp); | 862 | mask = CMOS_READ(RTC_INTR_FLAGS); |
863 | mask &= (tmp & RTC_IRQMASK) | RTC_IRQF; | ||
864 | if (!is_hpet_enabled() || !is_intr(mask)) | ||
865 | break; | ||
866 | |||
867 | /* force one-shot behavior if HPET blocked | ||
868 | * the wake alarm's irq | ||
869 | */ | ||
870 | rtc_update_irq(cmos->rtc, 1, mask); | ||
871 | tmp &= ~RTC_AIE; | ||
872 | hpet_mask_rtc_irq_bit(RTC_AIE); | ||
873 | } while (mask & RTC_AIE); | ||
815 | spin_unlock_irq(&rtc_lock); | 874 | spin_unlock_irq(&rtc_lock); |
816 | } | 875 | } |
817 | 876 | ||
818 | pr_debug("%s: resume, ctrl %02x\n", | 877 | pr_debug("%s: resume, ctrl %02x\n", |
819 | cmos_rtc.rtc->dev.bus_id, | 878 | cmos_rtc.rtc->dev.bus_id, |
820 | cmos->suspend_ctrl); | 879 | tmp); |
821 | |||
822 | 880 | ||
823 | return 0; | 881 | return 0; |
824 | } | 882 | } |
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 0114a78b7cbb..0a870b7e5c32 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c | |||
@@ -209,7 +209,7 @@ static unsigned int rtc_dev_poll(struct file *file, poll_table *wait) | |||
209 | return (data != 0) ? (POLLIN | POLLRDNORM) : 0; | 209 | return (data != 0) ? (POLLIN | POLLRDNORM) : 0; |
210 | } | 210 | } |
211 | 211 | ||
212 | static int rtc_dev_ioctl(struct inode *inode, struct file *file, | 212 | static long rtc_dev_ioctl(struct file *file, |
213 | unsigned int cmd, unsigned long arg) | 213 | unsigned int cmd, unsigned long arg) |
214 | { | 214 | { |
215 | int err = 0; | 215 | int err = 0; |
@@ -219,6 +219,10 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, | |||
219 | struct rtc_wkalrm alarm; | 219 | struct rtc_wkalrm alarm; |
220 | void __user *uarg = (void __user *) arg; | 220 | void __user *uarg = (void __user *) arg; |
221 | 221 | ||
222 | err = mutex_lock_interruptible(&rtc->ops_lock); | ||
223 | if (err) | ||
224 | return -EBUSY; | ||
225 | |||
222 | /* check that the calling task has appropriate permissions | 226 | /* check that the calling task has appropriate permissions |
223 | * for certain ioctls. doing this check here is useful | 227 | * for certain ioctls. doing this check here is useful |
224 | * to avoid duplicate code in each driver. | 228 | * to avoid duplicate code in each driver. |
@@ -227,26 +231,31 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, | |||
227 | case RTC_EPOCH_SET: | 231 | case RTC_EPOCH_SET: |
228 | case RTC_SET_TIME: | 232 | case RTC_SET_TIME: |
229 | if (!capable(CAP_SYS_TIME)) | 233 | if (!capable(CAP_SYS_TIME)) |
230 | return -EACCES; | 234 | err = -EACCES; |
231 | break; | 235 | break; |
232 | 236 | ||
233 | case RTC_IRQP_SET: | 237 | case RTC_IRQP_SET: |
234 | if (arg > rtc->max_user_freq && !capable(CAP_SYS_RESOURCE)) | 238 | if (arg > rtc->max_user_freq && !capable(CAP_SYS_RESOURCE)) |
235 | return -EACCES; | 239 | err = -EACCES; |
236 | break; | 240 | break; |
237 | 241 | ||
238 | case RTC_PIE_ON: | 242 | case RTC_PIE_ON: |
239 | if (rtc->irq_freq > rtc->max_user_freq && | 243 | if (rtc->irq_freq > rtc->max_user_freq && |
240 | !capable(CAP_SYS_RESOURCE)) | 244 | !capable(CAP_SYS_RESOURCE)) |
241 | return -EACCES; | 245 | err = -EACCES; |
242 | break; | 246 | break; |
243 | } | 247 | } |
244 | 248 | ||
249 | if (err) | ||
250 | goto done; | ||
251 | |||
245 | /* try the driver's ioctl interface */ | 252 | /* try the driver's ioctl interface */ |
246 | if (ops->ioctl) { | 253 | if (ops->ioctl) { |
247 | err = ops->ioctl(rtc->dev.parent, cmd, arg); | 254 | err = ops->ioctl(rtc->dev.parent, cmd, arg); |
248 | if (err != -ENOIOCTLCMD) | 255 | if (err != -ENOIOCTLCMD) { |
256 | mutex_unlock(&rtc->ops_lock); | ||
249 | return err; | 257 | return err; |
258 | } | ||
250 | } | 259 | } |
251 | 260 | ||
252 | /* if the driver does not provide the ioctl interface | 261 | /* if the driver does not provide the ioctl interface |
@@ -265,15 +274,19 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, | |||
265 | 274 | ||
266 | switch (cmd) { | 275 | switch (cmd) { |
267 | case RTC_ALM_READ: | 276 | case RTC_ALM_READ: |
277 | mutex_unlock(&rtc->ops_lock); | ||
278 | |||
268 | err = rtc_read_alarm(rtc, &alarm); | 279 | err = rtc_read_alarm(rtc, &alarm); |
269 | if (err < 0) | 280 | if (err < 0) |
270 | return err; | 281 | return err; |
271 | 282 | ||
272 | if (copy_to_user(uarg, &alarm.time, sizeof(tm))) | 283 | if (copy_to_user(uarg, &alarm.time, sizeof(tm))) |
273 | return -EFAULT; | 284 | err = -EFAULT; |
274 | break; | 285 | return err; |
275 | 286 | ||
276 | case RTC_ALM_SET: | 287 | case RTC_ALM_SET: |
288 | mutex_unlock(&rtc->ops_lock); | ||
289 | |||
277 | if (copy_from_user(&alarm.time, uarg, sizeof(tm))) | 290 | if (copy_from_user(&alarm.time, uarg, sizeof(tm))) |
278 | return -EFAULT; | 291 | return -EFAULT; |
279 | 292 | ||
@@ -321,24 +334,26 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, | |||
321 | } | 334 | } |
322 | } | 335 | } |
323 | 336 | ||
324 | err = rtc_set_alarm(rtc, &alarm); | 337 | return rtc_set_alarm(rtc, &alarm); |
325 | break; | ||
326 | 338 | ||
327 | case RTC_RD_TIME: | 339 | case RTC_RD_TIME: |
340 | mutex_unlock(&rtc->ops_lock); | ||
341 | |||
328 | err = rtc_read_time(rtc, &tm); | 342 | err = rtc_read_time(rtc, &tm); |
329 | if (err < 0) | 343 | if (err < 0) |
330 | return err; | 344 | return err; |
331 | 345 | ||
332 | if (copy_to_user(uarg, &tm, sizeof(tm))) | 346 | if (copy_to_user(uarg, &tm, sizeof(tm))) |
333 | return -EFAULT; | 347 | err = -EFAULT; |
334 | break; | 348 | return err; |
335 | 349 | ||
336 | case RTC_SET_TIME: | 350 | case RTC_SET_TIME: |
351 | mutex_unlock(&rtc->ops_lock); | ||
352 | |||
337 | if (copy_from_user(&tm, uarg, sizeof(tm))) | 353 | if (copy_from_user(&tm, uarg, sizeof(tm))) |
338 | return -EFAULT; | 354 | return -EFAULT; |
339 | 355 | ||
340 | err = rtc_set_time(rtc, &tm); | 356 | return rtc_set_time(rtc, &tm); |
341 | break; | ||
342 | 357 | ||
343 | case RTC_PIE_ON: | 358 | case RTC_PIE_ON: |
344 | err = rtc_irq_set_state(rtc, NULL, 1); | 359 | err = rtc_irq_set_state(rtc, NULL, 1); |
@@ -376,34 +391,37 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, | |||
376 | break; | 391 | break; |
377 | #endif | 392 | #endif |
378 | case RTC_WKALM_SET: | 393 | case RTC_WKALM_SET: |
394 | mutex_unlock(&rtc->ops_lock); | ||
379 | if (copy_from_user(&alarm, uarg, sizeof(alarm))) | 395 | if (copy_from_user(&alarm, uarg, sizeof(alarm))) |
380 | return -EFAULT; | 396 | return -EFAULT; |
381 | 397 | ||
382 | err = rtc_set_alarm(rtc, &alarm); | 398 | return rtc_set_alarm(rtc, &alarm); |
383 | break; | ||
384 | 399 | ||
385 | case RTC_WKALM_RD: | 400 | case RTC_WKALM_RD: |
401 | mutex_unlock(&rtc->ops_lock); | ||
386 | err = rtc_read_alarm(rtc, &alarm); | 402 | err = rtc_read_alarm(rtc, &alarm); |
387 | if (err < 0) | 403 | if (err < 0) |
388 | return err; | 404 | return err; |
389 | 405 | ||
390 | if (copy_to_user(uarg, &alarm, sizeof(alarm))) | 406 | if (copy_to_user(uarg, &alarm, sizeof(alarm))) |
391 | return -EFAULT; | 407 | err = -EFAULT; |
392 | break; | 408 | return err; |
393 | 409 | ||
394 | #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL | 410 | #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL |
395 | case RTC_UIE_OFF: | 411 | case RTC_UIE_OFF: |
396 | clear_uie(rtc); | 412 | clear_uie(rtc); |
397 | return 0; | 413 | break; |
398 | 414 | ||
399 | case RTC_UIE_ON: | 415 | case RTC_UIE_ON: |
400 | return set_uie(rtc); | 416 | err = set_uie(rtc); |
401 | #endif | 417 | #endif |
402 | default: | 418 | default: |
403 | err = -ENOTTY; | 419 | err = -ENOTTY; |
404 | break; | 420 | break; |
405 | } | 421 | } |
406 | 422 | ||
423 | done: | ||
424 | mutex_unlock(&rtc->ops_lock); | ||
407 | return err; | 425 | return err; |
408 | } | 426 | } |
409 | 427 | ||
@@ -432,7 +450,7 @@ static const struct file_operations rtc_dev_fops = { | |||
432 | .llseek = no_llseek, | 450 | .llseek = no_llseek, |
433 | .read = rtc_dev_read, | 451 | .read = rtc_dev_read, |
434 | .poll = rtc_dev_poll, | 452 | .poll = rtc_dev_poll, |
435 | .ioctl = rtc_dev_ioctl, | 453 | .unlocked_ioctl = rtc_dev_ioctl, |
436 | .open = rtc_dev_open, | 454 | .open = rtc_dev_open, |
437 | .release = rtc_dev_release, | 455 | .release = rtc_dev_release, |
438 | .fasync = rtc_dev_fasync, | 456 | .fasync = rtc_dev_fasync, |
diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c new file mode 100644 index 000000000000..b91d02a3ace9 --- /dev/null +++ b/drivers/rtc/rtc-ds1305.c | |||
@@ -0,0 +1,847 @@ | |||
1 | /* | ||
2 | * rtc-ds1305.c -- driver for DS1305 and DS1306 SPI RTC chips | ||
3 | * | ||
4 | * Copyright (C) 2008 David Brownell | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/bcd.h> | ||
14 | #include <linux/rtc.h> | ||
15 | #include <linux/workqueue.h> | ||
16 | |||
17 | #include <linux/spi/spi.h> | ||
18 | #include <linux/spi/ds1305.h> | ||
19 | |||
20 | |||
21 | /* | ||
22 | * Registers ... mask DS1305_WRITE into register address to write, | ||
23 | * otherwise you're reading it. All non-bitmask values are BCD. | ||
24 | */ | ||
25 | #define DS1305_WRITE 0x80 | ||
26 | |||
27 | |||
28 | /* RTC date/time ... the main special cases are that we: | ||
29 | * - Need fancy "hours" encoding in 12hour mode | ||
30 | * - Don't rely on the "day-of-week" field (or tm_wday) | ||
31 | * - Are a 21st-century clock (2000 <= year < 2100) | ||
32 | */ | ||
33 | #define DS1305_RTC_LEN 7 /* bytes for RTC regs */ | ||
34 | |||
35 | #define DS1305_SEC 0x00 /* register addresses */ | ||
36 | #define DS1305_MIN 0x01 | ||
37 | #define DS1305_HOUR 0x02 | ||
38 | # define DS1305_HR_12 0x40 /* set == 12 hr mode */ | ||
39 | # define DS1305_HR_PM 0x20 /* set == PM (12hr mode) */ | ||
40 | #define DS1305_WDAY 0x03 | ||
41 | #define DS1305_MDAY 0x04 | ||
42 | #define DS1305_MON 0x05 | ||
43 | #define DS1305_YEAR 0x06 | ||
44 | |||
45 | |||
46 | /* The two alarms have only sec/min/hour/wday fields (ALM_LEN). | ||
47 | * DS1305_ALM_DISABLE disables a match field (some combos are bad). | ||
48 | * | ||
49 | * NOTE that since we don't use WDAY, we limit ourselves to alarms | ||
50 | * only one day into the future (vs potentially up to a week). | ||
51 | * | ||
52 | * NOTE ALSO that while we could generate once-a-second IRQs (UIE), we | ||
53 | * don't currently support them. We'd either need to do it only when | ||
54 | * no alarm is pending (not the standard model), or to use the second | ||
55 | * alarm (implying that this is a DS1305 not DS1306, *and* that either | ||
56 | * it's wired up a second IRQ we know, or that INTCN is set) | ||
57 | */ | ||
58 | #define DS1305_ALM_LEN 4 /* bytes for ALM regs */ | ||
59 | #define DS1305_ALM_DISABLE 0x80 | ||
60 | |||
61 | #define DS1305_ALM0(r) (0x07 + (r)) /* register addresses */ | ||
62 | #define DS1305_ALM1(r) (0x0b + (r)) | ||
63 | |||
64 | |||
65 | /* three control registers */ | ||
66 | #define DS1305_CONTROL_LEN 3 /* bytes of control regs */ | ||
67 | |||
68 | #define DS1305_CONTROL 0x0f /* register addresses */ | ||
69 | # define DS1305_nEOSC 0x80 /* low enables oscillator */ | ||
70 | # define DS1305_WP 0x40 /* write protect */ | ||
71 | # define DS1305_INTCN 0x04 /* clear == only int0 used */ | ||
72 | # define DS1306_1HZ 0x04 /* enable 1Hz output */ | ||
73 | # define DS1305_AEI1 0x02 /* enable ALM1 IRQ */ | ||
74 | # define DS1305_AEI0 0x01 /* enable ALM0 IRQ */ | ||
75 | #define DS1305_STATUS 0x10 | ||
76 | /* status has just AEIx bits, mirrored as IRQFx */ | ||
77 | #define DS1305_TRICKLE 0x11 | ||
78 | /* trickle bits are defined in <linux/spi/ds1305.h> */ | ||
79 | |||
80 | /* a bunch of NVRAM */ | ||
81 | #define DS1305_NVRAM_LEN 96 /* bytes of NVRAM */ | ||
82 | |||
83 | #define DS1305_NVRAM 0x20 /* register addresses */ | ||
84 | |||
85 | |||
86 | struct ds1305 { | ||
87 | struct spi_device *spi; | ||
88 | struct rtc_device *rtc; | ||
89 | |||
90 | struct work_struct work; | ||
91 | |||
92 | unsigned long flags; | ||
93 | #define FLAG_EXITING 0 | ||
94 | |||
95 | bool hr12; | ||
96 | u8 ctrl[DS1305_CONTROL_LEN]; | ||
97 | }; | ||
98 | |||
99 | |||
100 | /*----------------------------------------------------------------------*/ | ||
101 | |||
102 | /* | ||
103 | * Utilities ... tolerate 12-hour AM/PM notation in case of non-Linux | ||
104 | * software (like a bootloader) which may require it. | ||
105 | */ | ||
106 | |||
107 | static unsigned bcd2hour(u8 bcd) | ||
108 | { | ||
109 | if (bcd & DS1305_HR_12) { | ||
110 | unsigned hour = 0; | ||
111 | |||
112 | bcd &= ~DS1305_HR_12; | ||
113 | if (bcd & DS1305_HR_PM) { | ||
114 | hour = 12; | ||
115 | bcd &= ~DS1305_HR_PM; | ||
116 | } | ||
117 | hour += BCD2BIN(bcd); | ||
118 | return hour - 1; | ||
119 | } | ||
120 | return BCD2BIN(bcd); | ||
121 | } | ||
122 | |||
123 | static u8 hour2bcd(bool hr12, int hour) | ||
124 | { | ||
125 | if (hr12) { | ||
126 | hour++; | ||
127 | if (hour <= 12) | ||
128 | return DS1305_HR_12 | BIN2BCD(hour); | ||
129 | hour -= 12; | ||
130 | return DS1305_HR_12 | DS1305_HR_PM | BIN2BCD(hour); | ||
131 | } | ||
132 | return BIN2BCD(hour); | ||
133 | } | ||
134 | |||
135 | /*----------------------------------------------------------------------*/ | ||
136 | |||
137 | /* | ||
138 | * Interface to RTC framework | ||
139 | */ | ||
140 | |||
141 | #ifdef CONFIG_RTC_INTF_DEV | ||
142 | |||
143 | /* | ||
144 | * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl) | ||
145 | */ | ||
146 | static int ds1305_ioctl(struct device *dev, unsigned cmd, unsigned long arg) | ||
147 | { | ||
148 | struct ds1305 *ds1305 = dev_get_drvdata(dev); | ||
149 | u8 buf[2]; | ||
150 | int status = -ENOIOCTLCMD; | ||
151 | |||
152 | buf[0] = DS1305_WRITE | DS1305_CONTROL; | ||
153 | buf[1] = ds1305->ctrl[0]; | ||
154 | |||
155 | switch (cmd) { | ||
156 | case RTC_AIE_OFF: | ||
157 | status = 0; | ||
158 | if (!(buf[1] & DS1305_AEI0)) | ||
159 | goto done; | ||
160 | buf[1] &= ~DS1305_AEI0; | ||
161 | break; | ||
162 | |||
163 | case RTC_AIE_ON: | ||
164 | status = 0; | ||
165 | if (ds1305->ctrl[0] & DS1305_AEI0) | ||
166 | goto done; | ||
167 | buf[1] |= DS1305_AEI0; | ||
168 | break; | ||
169 | } | ||
170 | if (status == 0) { | ||
171 | status = spi_write_then_read(ds1305->spi, buf, sizeof buf, | ||
172 | NULL, 0); | ||
173 | if (status >= 0) | ||
174 | ds1305->ctrl[0] = buf[1]; | ||
175 | } | ||
176 | |||
177 | done: | ||
178 | return status; | ||
179 | } | ||
180 | |||
181 | #else | ||
182 | #define ds1305_ioctl NULL | ||
183 | #endif | ||
184 | |||
185 | /* | ||
186 | * Get/set of date and time is pretty normal. | ||
187 | */ | ||
188 | |||
189 | static int ds1305_get_time(struct device *dev, struct rtc_time *time) | ||
190 | { | ||
191 | struct ds1305 *ds1305 = dev_get_drvdata(dev); | ||
192 | u8 addr = DS1305_SEC; | ||
193 | u8 buf[DS1305_RTC_LEN]; | ||
194 | int status; | ||
195 | |||
196 | /* Use write-then-read to get all the date/time registers | ||
197 | * since dma from stack is nonportable | ||
198 | */ | ||
199 | status = spi_write_then_read(ds1305->spi, &addr, sizeof addr, | ||
200 | buf, sizeof buf); | ||
201 | if (status < 0) | ||
202 | return status; | ||
203 | |||
204 | dev_vdbg(dev, "%s: %02x %02x %02x, %02x %02x %02x %02x\n", | ||
205 | "read", buf[0], buf[1], buf[2], buf[3], | ||
206 | buf[4], buf[5], buf[6]); | ||
207 | |||
208 | /* Decode the registers */ | ||
209 | time->tm_sec = BCD2BIN(buf[DS1305_SEC]); | ||
210 | time->tm_min = BCD2BIN(buf[DS1305_MIN]); | ||
211 | time->tm_hour = bcd2hour(buf[DS1305_HOUR]); | ||
212 | time->tm_wday = buf[DS1305_WDAY] - 1; | ||
213 | time->tm_mday = BCD2BIN(buf[DS1305_MDAY]); | ||
214 | time->tm_mon = BCD2BIN(buf[DS1305_MON]) - 1; | ||
215 | time->tm_year = BCD2BIN(buf[DS1305_YEAR]) + 100; | ||
216 | |||
217 | dev_vdbg(dev, "%s secs=%d, mins=%d, " | ||
218 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", | ||
219 | "read", time->tm_sec, time->tm_min, | ||
220 | time->tm_hour, time->tm_mday, | ||
221 | time->tm_mon, time->tm_year, time->tm_wday); | ||
222 | |||
223 | /* Time may not be set */ | ||
224 | return rtc_valid_tm(time); | ||
225 | } | ||
226 | |||
227 | static int ds1305_set_time(struct device *dev, struct rtc_time *time) | ||
228 | { | ||
229 | struct ds1305 *ds1305 = dev_get_drvdata(dev); | ||
230 | u8 buf[1 + DS1305_RTC_LEN]; | ||
231 | u8 *bp = buf; | ||
232 | |||
233 | dev_vdbg(dev, "%s secs=%d, mins=%d, " | ||
234 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", | ||
235 | "write", time->tm_sec, time->tm_min, | ||
236 | time->tm_hour, time->tm_mday, | ||
237 | time->tm_mon, time->tm_year, time->tm_wday); | ||
238 | |||
239 | /* Write registers starting at the first time/date address. */ | ||
240 | *bp++ = DS1305_WRITE | DS1305_SEC; | ||
241 | |||
242 | *bp++ = BIN2BCD(time->tm_sec); | ||
243 | *bp++ = BIN2BCD(time->tm_min); | ||
244 | *bp++ = hour2bcd(ds1305->hr12, time->tm_hour); | ||
245 | *bp++ = (time->tm_wday < 7) ? (time->tm_wday + 1) : 1; | ||
246 | *bp++ = BIN2BCD(time->tm_mday); | ||
247 | *bp++ = BIN2BCD(time->tm_mon + 1); | ||
248 | *bp++ = BIN2BCD(time->tm_year - 100); | ||
249 | |||
250 | dev_dbg(dev, "%s: %02x %02x %02x, %02x %02x %02x %02x\n", | ||
251 | "write", buf[1], buf[2], buf[3], | ||
252 | buf[4], buf[5], buf[6], buf[7]); | ||
253 | |||
254 | /* use write-then-read since dma from stack is nonportable */ | ||
255 | return spi_write_then_read(ds1305->spi, buf, sizeof buf, | ||
256 | NULL, 0); | ||
257 | } | ||
258 | |||
259 | /* | ||
260 | * Get/set of alarm is a bit funky: | ||
261 | * | ||
262 | * - First there's the inherent raciness of getting the (partitioned) | ||
263 | * status of an alarm that could trigger while we're reading parts | ||
264 | * of that status. | ||
265 | * | ||
266 | * - Second there's its limited range (we could increase it a bit by | ||
267 | * relying on WDAY), which means it will easily roll over. | ||
268 | * | ||
269 | * - Third there's the choice of two alarms and alarm signals. | ||
270 | * Here we use ALM0 and expect that nINT0 (open drain) is used; | ||
271 | * that's the only real option for DS1306 runtime alarms, and is | ||
272 | * natural on DS1305. | ||
273 | * | ||
274 | * - Fourth, there's also ALM1, and a second interrupt signal: | ||
275 | * + On DS1305 ALM1 uses nINT1 (when INTCN=1) else nINT0; | ||
276 | * + On DS1306 ALM1 only uses INT1 (an active high pulse) | ||
277 | * and it won't work when VCC1 is active. | ||
278 | * | ||
279 | * So to be most general, we should probably set both alarms to the | ||
280 | * same value, letting ALM1 be the wakeup event source on DS1306 | ||
281 | * and handling several wiring options on DS1305. | ||
282 | * | ||
283 | * - Fifth, we support the polled mode (as well as possible; why not?) | ||
284 | * even when no interrupt line is wired to an IRQ. | ||
285 | */ | ||
286 | |||
287 | /* | ||
288 | * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl) | ||
289 | */ | ||
290 | static int ds1305_get_alarm(struct device *dev, struct rtc_wkalrm *alm) | ||
291 | { | ||
292 | struct ds1305 *ds1305 = dev_get_drvdata(dev); | ||
293 | struct spi_device *spi = ds1305->spi; | ||
294 | u8 addr; | ||
295 | int status; | ||
296 | u8 buf[DS1305_ALM_LEN]; | ||
297 | |||
298 | /* Refresh control register cache BEFORE reading ALM0 registers, | ||
299 | * since reading alarm registers acks any pending IRQ. That | ||
300 | * makes returning "pending" status a bit of a lie, but that bit | ||
301 | * of EFI status is at best fragile anyway (given IRQ handlers). | ||
302 | */ | ||
303 | addr = DS1305_CONTROL; | ||
304 | status = spi_write_then_read(spi, &addr, sizeof addr, | ||
305 | ds1305->ctrl, sizeof ds1305->ctrl); | ||
306 | if (status < 0) | ||
307 | return status; | ||
308 | |||
309 | alm->enabled = !!(ds1305->ctrl[0] & DS1305_AEI0); | ||
310 | alm->pending = !!(ds1305->ctrl[1] & DS1305_AEI0); | ||
311 | |||
312 | /* get and check ALM0 registers */ | ||
313 | addr = DS1305_ALM0(DS1305_SEC); | ||
314 | status = spi_write_then_read(spi, &addr, sizeof addr, | ||
315 | buf, sizeof buf); | ||
316 | if (status < 0) | ||
317 | return status; | ||
318 | |||
319 | dev_vdbg(dev, "%s: %02x %02x %02x %02x\n", | ||
320 | "alm0 read", buf[DS1305_SEC], buf[DS1305_MIN], | ||
321 | buf[DS1305_HOUR], buf[DS1305_WDAY]); | ||
322 | |||
323 | if ((DS1305_ALM_DISABLE & buf[DS1305_SEC]) | ||
324 | || (DS1305_ALM_DISABLE & buf[DS1305_MIN]) | ||
325 | || (DS1305_ALM_DISABLE & buf[DS1305_HOUR])) | ||
326 | return -EIO; | ||
327 | |||
328 | /* Stuff these values into alm->time and let RTC framework code | ||
329 | * fill in the rest ... and also handle rollover to tomorrow when | ||
330 | * that's needed. | ||
331 | */ | ||
332 | alm->time.tm_sec = BCD2BIN(buf[DS1305_SEC]); | ||
333 | alm->time.tm_min = BCD2BIN(buf[DS1305_MIN]); | ||
334 | alm->time.tm_hour = bcd2hour(buf[DS1305_HOUR]); | ||
335 | alm->time.tm_mday = -1; | ||
336 | alm->time.tm_mon = -1; | ||
337 | alm->time.tm_year = -1; | ||
338 | /* next three fields are unused by Linux */ | ||
339 | alm->time.tm_wday = -1; | ||
340 | alm->time.tm_mday = -1; | ||
341 | alm->time.tm_isdst = -1; | ||
342 | |||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | /* | ||
347 | * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl) | ||
348 | */ | ||
349 | static int ds1305_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | ||
350 | { | ||
351 | struct ds1305 *ds1305 = dev_get_drvdata(dev); | ||
352 | struct spi_device *spi = ds1305->spi; | ||
353 | unsigned long now, later; | ||
354 | struct rtc_time tm; | ||
355 | int status; | ||
356 | u8 buf[1 + DS1305_ALM_LEN]; | ||
357 | |||
358 | /* convert desired alarm to time_t */ | ||
359 | status = rtc_tm_to_time(&alm->time, &later); | ||
360 | if (status < 0) | ||
361 | return status; | ||
362 | |||
363 | /* Read current time as time_t */ | ||
364 | status = ds1305_get_time(dev, &tm); | ||
365 | if (status < 0) | ||
366 | return status; | ||
367 | status = rtc_tm_to_time(&tm, &now); | ||
368 | if (status < 0) | ||
369 | return status; | ||
370 | |||
371 | /* make sure alarm fires within the next 24 hours */ | ||
372 | if (later <= now) | ||
373 | return -EINVAL; | ||
374 | if ((later - now) > 24 * 60 * 60) | ||
375 | return -EDOM; | ||
376 | |||
377 | /* disable alarm if needed */ | ||
378 | if (ds1305->ctrl[0] & DS1305_AEI0) { | ||
379 | ds1305->ctrl[0] &= ~DS1305_AEI0; | ||
380 | |||
381 | buf[0] = DS1305_WRITE | DS1305_CONTROL; | ||
382 | buf[1] = ds1305->ctrl[0]; | ||
383 | status = spi_write_then_read(ds1305->spi, buf, 2, NULL, 0); | ||
384 | if (status < 0) | ||
385 | return status; | ||
386 | } | ||
387 | |||
388 | /* write alarm */ | ||
389 | buf[0] = DS1305_WRITE | DS1305_ALM0(DS1305_SEC); | ||
390 | buf[1 + DS1305_SEC] = BIN2BCD(alm->time.tm_sec); | ||
391 | buf[1 + DS1305_MIN] = BIN2BCD(alm->time.tm_min); | ||
392 | buf[1 + DS1305_HOUR] = hour2bcd(ds1305->hr12, alm->time.tm_hour); | ||
393 | buf[1 + DS1305_WDAY] = DS1305_ALM_DISABLE; | ||
394 | |||
395 | dev_dbg(dev, "%s: %02x %02x %02x %02x\n", | ||
396 | "alm0 write", buf[1 + DS1305_SEC], buf[1 + DS1305_MIN], | ||
397 | buf[1 + DS1305_HOUR], buf[1 + DS1305_WDAY]); | ||
398 | |||
399 | status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0); | ||
400 | if (status < 0) | ||
401 | return status; | ||
402 | |||
403 | /* enable alarm if requested */ | ||
404 | if (alm->enabled) { | ||
405 | ds1305->ctrl[0] |= DS1305_AEI0; | ||
406 | |||
407 | buf[0] = DS1305_WRITE | DS1305_CONTROL; | ||
408 | buf[1] = ds1305->ctrl[0]; | ||
409 | status = spi_write_then_read(ds1305->spi, buf, 2, NULL, 0); | ||
410 | } | ||
411 | |||
412 | return status; | ||
413 | } | ||
414 | |||
415 | #ifdef CONFIG_PROC_FS | ||
416 | |||
417 | static int ds1305_proc(struct device *dev, struct seq_file *seq) | ||
418 | { | ||
419 | struct ds1305 *ds1305 = dev_get_drvdata(dev); | ||
420 | char *diodes = "no"; | ||
421 | char *resistors = ""; | ||
422 | |||
423 | /* ctrl[2] is treated as read-only; no locking needed */ | ||
424 | if ((ds1305->ctrl[2] & 0xf0) == DS1305_TRICKLE_MAGIC) { | ||
425 | switch (ds1305->ctrl[2] & 0x0c) { | ||
426 | case DS1305_TRICKLE_DS2: | ||
427 | diodes = "2 diodes, "; | ||
428 | break; | ||
429 | case DS1305_TRICKLE_DS1: | ||
430 | diodes = "1 diode, "; | ||
431 | break; | ||
432 | default: | ||
433 | goto done; | ||
434 | } | ||
435 | switch (ds1305->ctrl[2] & 0x03) { | ||
436 | case DS1305_TRICKLE_2K: | ||
437 | resistors = "2k Ohm"; | ||
438 | break; | ||
439 | case DS1305_TRICKLE_4K: | ||
440 | resistors = "4k Ohm"; | ||
441 | break; | ||
442 | case DS1305_TRICKLE_8K: | ||
443 | resistors = "8k Ohm"; | ||
444 | break; | ||
445 | default: | ||
446 | diodes = "no"; | ||
447 | break; | ||
448 | } | ||
449 | } | ||
450 | |||
451 | done: | ||
452 | return seq_printf(seq, | ||
453 | "trickle_charge\t: %s%s\n", | ||
454 | diodes, resistors); | ||
455 | } | ||
456 | |||
457 | #else | ||
458 | #define ds1305_proc NULL | ||
459 | #endif | ||
460 | |||
461 | static const struct rtc_class_ops ds1305_ops = { | ||
462 | .ioctl = ds1305_ioctl, | ||
463 | .read_time = ds1305_get_time, | ||
464 | .set_time = ds1305_set_time, | ||
465 | .read_alarm = ds1305_get_alarm, | ||
466 | .set_alarm = ds1305_set_alarm, | ||
467 | .proc = ds1305_proc, | ||
468 | }; | ||
469 | |||
470 | static void ds1305_work(struct work_struct *work) | ||
471 | { | ||
472 | struct ds1305 *ds1305 = container_of(work, struct ds1305, work); | ||
473 | struct mutex *lock = &ds1305->rtc->ops_lock; | ||
474 | struct spi_device *spi = ds1305->spi; | ||
475 | u8 buf[3]; | ||
476 | int status; | ||
477 | |||
478 | /* lock to protect ds1305->ctrl */ | ||
479 | mutex_lock(lock); | ||
480 | |||
481 | /* Disable the IRQ, and clear its status ... for now, we "know" | ||
482 | * that if more than one alarm is active, they're in sync. | ||
483 | * Note that reading ALM data registers also clears IRQ status. | ||
484 | */ | ||
485 | ds1305->ctrl[0] &= ~(DS1305_AEI1 | DS1305_AEI0); | ||
486 | ds1305->ctrl[1] = 0; | ||
487 | |||
488 | buf[0] = DS1305_WRITE | DS1305_CONTROL; | ||
489 | buf[1] = ds1305->ctrl[0]; | ||
490 | buf[2] = 0; | ||
491 | |||
492 | status = spi_write_then_read(spi, buf, sizeof buf, | ||
493 | NULL, 0); | ||
494 | if (status < 0) | ||
495 | dev_dbg(&spi->dev, "clear irq --> %d\n", status); | ||
496 | |||
497 | mutex_unlock(lock); | ||
498 | |||
499 | if (!test_bit(FLAG_EXITING, &ds1305->flags)) | ||
500 | enable_irq(spi->irq); | ||
501 | |||
502 | /* rtc_update_irq() requires an IRQ-disabled context */ | ||
503 | local_irq_disable(); | ||
504 | rtc_update_irq(ds1305->rtc, 1, RTC_AF | RTC_IRQF); | ||
505 | local_irq_enable(); | ||
506 | } | ||
507 | |||
508 | /* | ||
509 | * This "real" IRQ handler hands off to a workqueue mostly to allow | ||
510 | * mutex locking for ds1305->ctrl ... unlike I2C, we could issue async | ||
511 | * I/O requests in IRQ context (to clear the IRQ status). | ||
512 | */ | ||
513 | static irqreturn_t ds1305_irq(int irq, void *p) | ||
514 | { | ||
515 | struct ds1305 *ds1305 = p; | ||
516 | |||
517 | disable_irq(irq); | ||
518 | schedule_work(&ds1305->work); | ||
519 | return IRQ_HANDLED; | ||
520 | } | ||
521 | |||
522 | /*----------------------------------------------------------------------*/ | ||
523 | |||
524 | /* | ||
525 | * Interface for NVRAM | ||
526 | */ | ||
527 | |||
528 | static void msg_init(struct spi_message *m, struct spi_transfer *x, | ||
529 | u8 *addr, size_t count, char *tx, char *rx) | ||
530 | { | ||
531 | spi_message_init(m); | ||
532 | memset(x, 0, 2 * sizeof(*x)); | ||
533 | |||
534 | x->tx_buf = addr; | ||
535 | x->len = 1; | ||
536 | spi_message_add_tail(x, m); | ||
537 | |||
538 | x++; | ||
539 | |||
540 | x->tx_buf = tx; | ||
541 | x->rx_buf = rx; | ||
542 | x->len = count; | ||
543 | spi_message_add_tail(x, m); | ||
544 | } | ||
545 | |||
546 | static ssize_t | ||
547 | ds1305_nvram_read(struct kobject *kobj, struct bin_attribute *attr, | ||
548 | char *buf, loff_t off, size_t count) | ||
549 | { | ||
550 | struct spi_device *spi; | ||
551 | u8 addr; | ||
552 | struct spi_message m; | ||
553 | struct spi_transfer x[2]; | ||
554 | int status; | ||
555 | |||
556 | spi = container_of(kobj, struct spi_device, dev.kobj); | ||
557 | |||
558 | if (unlikely(off >= DS1305_NVRAM_LEN)) | ||
559 | return 0; | ||
560 | if (count >= DS1305_NVRAM_LEN) | ||
561 | count = DS1305_NVRAM_LEN; | ||
562 | if ((off + count) > DS1305_NVRAM_LEN) | ||
563 | count = DS1305_NVRAM_LEN - off; | ||
564 | if (unlikely(!count)) | ||
565 | return count; | ||
566 | |||
567 | addr = DS1305_NVRAM + off; | ||
568 | msg_init(&m, x, &addr, count, NULL, buf); | ||
569 | |||
570 | status = spi_sync(spi, &m); | ||
571 | if (status < 0) | ||
572 | dev_err(&spi->dev, "nvram %s error %d\n", "read", status); | ||
573 | return (status < 0) ? status : count; | ||
574 | } | ||
575 | |||
576 | static ssize_t | ||
577 | ds1305_nvram_write(struct kobject *kobj, struct bin_attribute *attr, | ||
578 | char *buf, loff_t off, size_t count) | ||
579 | { | ||
580 | struct spi_device *spi; | ||
581 | u8 addr; | ||
582 | struct spi_message m; | ||
583 | struct spi_transfer x[2]; | ||
584 | int status; | ||
585 | |||
586 | spi = container_of(kobj, struct spi_device, dev.kobj); | ||
587 | |||
588 | if (unlikely(off >= DS1305_NVRAM_LEN)) | ||
589 | return -EFBIG; | ||
590 | if (count >= DS1305_NVRAM_LEN) | ||
591 | count = DS1305_NVRAM_LEN; | ||
592 | if ((off + count) > DS1305_NVRAM_LEN) | ||
593 | count = DS1305_NVRAM_LEN - off; | ||
594 | if (unlikely(!count)) | ||
595 | return count; | ||
596 | |||
597 | addr = (DS1305_WRITE | DS1305_NVRAM) + off; | ||
598 | msg_init(&m, x, &addr, count, buf, NULL); | ||
599 | |||
600 | status = spi_sync(spi, &m); | ||
601 | if (status < 0) | ||
602 | dev_err(&spi->dev, "nvram %s error %d\n", "write", status); | ||
603 | return (status < 0) ? status : count; | ||
604 | } | ||
605 | |||
606 | static struct bin_attribute nvram = { | ||
607 | .attr.name = "nvram", | ||
608 | .attr.mode = S_IRUGO | S_IWUSR, | ||
609 | .attr.owner = THIS_MODULE, | ||
610 | .read = ds1305_nvram_read, | ||
611 | .write = ds1305_nvram_write, | ||
612 | .size = DS1305_NVRAM_LEN, | ||
613 | }; | ||
614 | |||
615 | /*----------------------------------------------------------------------*/ | ||
616 | |||
617 | /* | ||
618 | * Interface to SPI stack | ||
619 | */ | ||
620 | |||
621 | static int __devinit ds1305_probe(struct spi_device *spi) | ||
622 | { | ||
623 | struct ds1305 *ds1305; | ||
624 | struct rtc_device *rtc; | ||
625 | int status; | ||
626 | u8 addr, value; | ||
627 | struct ds1305_platform_data *pdata = spi->dev.platform_data; | ||
628 | bool write_ctrl = false; | ||
629 | |||
630 | /* Sanity check board setup data. This may be hooked up | ||
631 | * in 3wire mode, but we don't care. Note that unless | ||
632 | * there's an inverter in place, this needs SPI_CS_HIGH! | ||
633 | */ | ||
634 | if ((spi->bits_per_word && spi->bits_per_word != 8) | ||
635 | || (spi->max_speed_hz > 2000000) | ||
636 | || !(spi->mode & SPI_CPHA)) | ||
637 | return -EINVAL; | ||
638 | |||
639 | /* set up driver data */ | ||
640 | ds1305 = kzalloc(sizeof *ds1305, GFP_KERNEL); | ||
641 | if (!ds1305) | ||
642 | return -ENOMEM; | ||
643 | ds1305->spi = spi; | ||
644 | spi_set_drvdata(spi, ds1305); | ||
645 | |||
646 | /* read and cache control registers */ | ||
647 | addr = DS1305_CONTROL; | ||
648 | status = spi_write_then_read(spi, &addr, sizeof addr, | ||
649 | ds1305->ctrl, sizeof ds1305->ctrl); | ||
650 | if (status < 0) { | ||
651 | dev_dbg(&spi->dev, "can't %s, %d\n", | ||
652 | "read", status); | ||
653 | goto fail0; | ||
654 | } | ||
655 | |||
656 | dev_dbg(&spi->dev, "ctrl %s: %02x %02x %02x\n", | ||
657 | "read", ds1305->ctrl[0], | ||
658 | ds1305->ctrl[1], ds1305->ctrl[2]); | ||
659 | |||
660 | /* Sanity check register values ... partially compensating for the | ||
661 | * fact that SPI has no device handshake. A pullup on MISO would | ||
662 | * make these tests fail; but not all systems will have one. If | ||
663 | * some register is neither 0x00 nor 0xff, a chip is likely there. | ||
664 | */ | ||
665 | if ((ds1305->ctrl[0] & 0x38) != 0 || (ds1305->ctrl[1] & 0xfc) != 0) { | ||
666 | dev_dbg(&spi->dev, "RTC chip is not present\n"); | ||
667 | status = -ENODEV; | ||
668 | goto fail0; | ||
669 | } | ||
670 | if (ds1305->ctrl[2] == 0) | ||
671 | dev_dbg(&spi->dev, "chip may not be present\n"); | ||
672 | |||
673 | /* enable writes if needed ... if we were paranoid it would | ||
674 | * make sense to enable them only when absolutely necessary. | ||
675 | */ | ||
676 | if (ds1305->ctrl[0] & DS1305_WP) { | ||
677 | u8 buf[2]; | ||
678 | |||
679 | ds1305->ctrl[0] &= ~DS1305_WP; | ||
680 | |||
681 | buf[0] = DS1305_WRITE | DS1305_CONTROL; | ||
682 | buf[1] = ds1305->ctrl[0]; | ||
683 | status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0); | ||
684 | |||
685 | dev_dbg(&spi->dev, "clear WP --> %d\n", status); | ||
686 | if (status < 0) | ||
687 | goto fail0; | ||
688 | } | ||
689 | |||
690 | /* on DS1305, maybe start oscillator; like most low power | ||
691 | * oscillators, it may take a second to stabilize | ||
692 | */ | ||
693 | if (ds1305->ctrl[0] & DS1305_nEOSC) { | ||
694 | ds1305->ctrl[0] &= ~DS1305_nEOSC; | ||
695 | write_ctrl = true; | ||
696 | dev_warn(&spi->dev, "SET TIME!\n"); | ||
697 | } | ||
698 | |||
699 | /* ack any pending IRQs */ | ||
700 | if (ds1305->ctrl[1]) { | ||
701 | ds1305->ctrl[1] = 0; | ||
702 | write_ctrl = true; | ||
703 | } | ||
704 | |||
705 | /* this may need one-time (re)init */ | ||
706 | if (pdata) { | ||
707 | /* maybe enable trickle charge */ | ||
708 | if (((ds1305->ctrl[2] & 0xf0) != DS1305_TRICKLE_MAGIC)) { | ||
709 | ds1305->ctrl[2] = DS1305_TRICKLE_MAGIC | ||
710 | | pdata->trickle; | ||
711 | write_ctrl = true; | ||
712 | } | ||
713 | |||
714 | /* on DS1306, configure 1 Hz signal */ | ||
715 | if (pdata->is_ds1306) { | ||
716 | if (pdata->en_1hz) { | ||
717 | if (!(ds1305->ctrl[0] & DS1306_1HZ)) { | ||
718 | ds1305->ctrl[0] |= DS1306_1HZ; | ||
719 | write_ctrl = true; | ||
720 | } | ||
721 | } else { | ||
722 | if (ds1305->ctrl[0] & DS1306_1HZ) { | ||
723 | ds1305->ctrl[0] &= ~DS1306_1HZ; | ||
724 | write_ctrl = true; | ||
725 | } | ||
726 | } | ||
727 | } | ||
728 | } | ||
729 | |||
730 | if (write_ctrl) { | ||
731 | u8 buf[4]; | ||
732 | |||
733 | buf[0] = DS1305_WRITE | DS1305_CONTROL; | ||
734 | buf[1] = ds1305->ctrl[0]; | ||
735 | buf[2] = ds1305->ctrl[1]; | ||
736 | buf[3] = ds1305->ctrl[2]; | ||
737 | status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0); | ||
738 | if (status < 0) { | ||
739 | dev_dbg(&spi->dev, "can't %s, %d\n", | ||
740 | "write", status); | ||
741 | goto fail0; | ||
742 | } | ||
743 | |||
744 | dev_dbg(&spi->dev, "ctrl %s: %02x %02x %02x\n", | ||
745 | "write", ds1305->ctrl[0], | ||
746 | ds1305->ctrl[1], ds1305->ctrl[2]); | ||
747 | } | ||
748 | |||
749 | /* see if non-Linux software set up AM/PM mode */ | ||
750 | addr = DS1305_HOUR; | ||
751 | status = spi_write_then_read(spi, &addr, sizeof addr, | ||
752 | &value, sizeof value); | ||
753 | if (status < 0) { | ||
754 | dev_dbg(&spi->dev, "read HOUR --> %d\n", status); | ||
755 | goto fail0; | ||
756 | } | ||
757 | |||
758 | ds1305->hr12 = (DS1305_HR_12 & value) != 0; | ||
759 | if (ds1305->hr12) | ||
760 | dev_dbg(&spi->dev, "AM/PM\n"); | ||
761 | |||
762 | /* register RTC ... from here on, ds1305->ctrl needs locking */ | ||
763 | rtc = rtc_device_register("ds1305", &spi->dev, | ||
764 | &ds1305_ops, THIS_MODULE); | ||
765 | if (IS_ERR(rtc)) { | ||
766 | status = PTR_ERR(rtc); | ||
767 | dev_dbg(&spi->dev, "register rtc --> %d\n", status); | ||
768 | goto fail0; | ||
769 | } | ||
770 | ds1305->rtc = rtc; | ||
771 | |||
772 | /* Maybe set up alarm IRQ; be ready to handle it triggering right | ||
773 | * away. NOTE that we don't share this. The signal is active low, | ||
774 | * and we can't ack it before a SPI message delay. We temporarily | ||
775 | * disable the IRQ until it's acked, which lets us work with more | ||
776 | * IRQ trigger modes (not all IRQ controllers can do falling edge). | ||
777 | */ | ||
778 | if (spi->irq) { | ||
779 | INIT_WORK(&ds1305->work, ds1305_work); | ||
780 | status = request_irq(spi->irq, ds1305_irq, | ||
781 | 0, dev_name(&rtc->dev), ds1305); | ||
782 | if (status < 0) { | ||
783 | dev_dbg(&spi->dev, "request_irq %d --> %d\n", | ||
784 | spi->irq, status); | ||
785 | goto fail1; | ||
786 | } | ||
787 | } | ||
788 | |||
789 | /* export NVRAM */ | ||
790 | status = sysfs_create_bin_file(&spi->dev.kobj, &nvram); | ||
791 | if (status < 0) { | ||
792 | dev_dbg(&spi->dev, "register nvram --> %d\n", status); | ||
793 | goto fail2; | ||
794 | } | ||
795 | |||
796 | return 0; | ||
797 | |||
798 | fail2: | ||
799 | free_irq(spi->irq, ds1305); | ||
800 | fail1: | ||
801 | rtc_device_unregister(rtc); | ||
802 | fail0: | ||
803 | kfree(ds1305); | ||
804 | return status; | ||
805 | } | ||
806 | |||
807 | static int __devexit ds1305_remove(struct spi_device *spi) | ||
808 | { | ||
809 | struct ds1305 *ds1305 = spi_get_drvdata(spi); | ||
810 | |||
811 | sysfs_remove_bin_file(&spi->dev.kobj, &nvram); | ||
812 | |||
813 | /* carefully shut down irq and workqueue, if present */ | ||
814 | if (spi->irq) { | ||
815 | set_bit(FLAG_EXITING, &ds1305->flags); | ||
816 | free_irq(spi->irq, ds1305); | ||
817 | flush_scheduled_work(); | ||
818 | } | ||
819 | |||
820 | rtc_device_unregister(ds1305->rtc); | ||
821 | spi_set_drvdata(spi, NULL); | ||
822 | kfree(ds1305); | ||
823 | return 0; | ||
824 | } | ||
825 | |||
826 | static struct spi_driver ds1305_driver = { | ||
827 | .driver.name = "rtc-ds1305", | ||
828 | .driver.owner = THIS_MODULE, | ||
829 | .probe = ds1305_probe, | ||
830 | .remove = __devexit_p(ds1305_remove), | ||
831 | /* REVISIT add suspend/resume */ | ||
832 | }; | ||
833 | |||
834 | static int __init ds1305_init(void) | ||
835 | { | ||
836 | return spi_register_driver(&ds1305_driver); | ||
837 | } | ||
838 | module_init(ds1305_init); | ||
839 | |||
840 | static void __exit ds1305_exit(void) | ||
841 | { | ||
842 | spi_unregister_driver(&ds1305_driver); | ||
843 | } | ||
844 | module_exit(ds1305_exit); | ||
845 | |||
846 | MODULE_DESCRIPTION("RTC driver for DS1305 and DS1306 chips"); | ||
847 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 0a19c06019be..24bc1689fc74 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c | |||
@@ -13,21 +13,21 @@ | |||
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/module.h> | 16 | #include <linux/bcd.h> |
17 | #include <linux/i2c.h> | ||
17 | #include <linux/init.h> | 18 | #include <linux/init.h> |
18 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/module.h> | ||
21 | #include <linux/rtc.h> | ||
19 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
20 | #include <linux/smp_lock.h> | 23 | #include <linux/smp_lock.h> |
21 | #include <linux/string.h> | 24 | #include <linux/string.h> |
22 | #include <linux/i2c.h> | ||
23 | #include <linux/rtc.h> | ||
24 | #include <linux/bcd.h> | ||
25 | #ifdef CONFIG_RTC_DRV_M41T80_WDT | 25 | #ifdef CONFIG_RTC_DRV_M41T80_WDT |
26 | #include <linux/miscdevice.h> | ||
27 | #include <linux/watchdog.h> | ||
28 | #include <linux/reboot.h> | ||
29 | #include <linux/fs.h> | 26 | #include <linux/fs.h> |
30 | #include <linux/ioctl.h> | 27 | #include <linux/ioctl.h> |
28 | #include <linux/miscdevice.h> | ||
29 | #include <linux/reboot.h> | ||
30 | #include <linux/watchdog.h> | ||
31 | #endif | 31 | #endif |
32 | 32 | ||
33 | #define M41T80_REG_SSEC 0 | 33 | #define M41T80_REG_SSEC 0 |
@@ -631,14 +631,12 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
631 | return -EFAULT; | 631 | return -EFAULT; |
632 | 632 | ||
633 | if (rv & WDIOS_DISABLECARD) { | 633 | if (rv & WDIOS_DISABLECARD) { |
634 | printk(KERN_INFO | 634 | pr_info("rtc-m41t80: disable watchdog\n"); |
635 | "rtc-m41t80: disable watchdog\n"); | ||
636 | wdt_disable(); | 635 | wdt_disable(); |
637 | } | 636 | } |
638 | 637 | ||
639 | if (rv & WDIOS_ENABLECARD) { | 638 | if (rv & WDIOS_ENABLECARD) { |
640 | printk(KERN_INFO | 639 | pr_info("rtc-m41t80: enable watchdog\n"); |
641 | "rtc-m41t80: enable watchdog\n"); | ||
642 | wdt_ping(); | 640 | wdt_ping(); |
643 | } | 641 | } |
644 | 642 | ||
diff --git a/drivers/rtc/rtc-m41t94.c b/drivers/rtc/rtc-m41t94.c new file mode 100644 index 000000000000..9b19499c829e --- /dev/null +++ b/drivers/rtc/rtc-m41t94.c | |||
@@ -0,0 +1,173 @@ | |||
1 | /* | ||
2 | * Driver for ST M41T94 SPI RTC | ||
3 | * | ||
4 | * Copyright (C) 2008 Kim B. Heino | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/rtc.h> | ||
15 | #include <linux/spi/spi.h> | ||
16 | #include <linux/bcd.h> | ||
17 | |||
18 | #define M41T94_REG_SECONDS 0x01 | ||
19 | #define M41T94_REG_MINUTES 0x02 | ||
20 | #define M41T94_REG_HOURS 0x03 | ||
21 | #define M41T94_REG_WDAY 0x04 | ||
22 | #define M41T94_REG_DAY 0x05 | ||
23 | #define M41T94_REG_MONTH 0x06 | ||
24 | #define M41T94_REG_YEAR 0x07 | ||
25 | #define M41T94_REG_HT 0x0c | ||
26 | |||
27 | #define M41T94_BIT_HALT 0x40 | ||
28 | #define M41T94_BIT_STOP 0x80 | ||
29 | #define M41T94_BIT_CB 0x40 | ||
30 | #define M41T94_BIT_CEB 0x80 | ||
31 | |||
32 | static int m41t94_set_time(struct device *dev, struct rtc_time *tm) | ||
33 | { | ||
34 | struct spi_device *spi = to_spi_device(dev); | ||
35 | u8 buf[8]; /* write cmd + 7 registers */ | ||
36 | |||
37 | dev_dbg(dev, "%s secs=%d, mins=%d, " | ||
38 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", | ||
39 | "write", tm->tm_sec, tm->tm_min, | ||
40 | tm->tm_hour, tm->tm_mday, | ||
41 | tm->tm_mon, tm->tm_year, tm->tm_wday); | ||
42 | |||
43 | buf[0] = 0x80 | M41T94_REG_SECONDS; /* write time + date */ | ||
44 | buf[M41T94_REG_SECONDS] = BIN2BCD(tm->tm_sec); | ||
45 | buf[M41T94_REG_MINUTES] = BIN2BCD(tm->tm_min); | ||
46 | buf[M41T94_REG_HOURS] = BIN2BCD(tm->tm_hour); | ||
47 | buf[M41T94_REG_WDAY] = BIN2BCD(tm->tm_wday + 1); | ||
48 | buf[M41T94_REG_DAY] = BIN2BCD(tm->tm_mday); | ||
49 | buf[M41T94_REG_MONTH] = BIN2BCD(tm->tm_mon + 1); | ||
50 | |||
51 | buf[M41T94_REG_HOURS] |= M41T94_BIT_CEB; | ||
52 | if (tm->tm_year >= 100) | ||
53 | buf[M41T94_REG_HOURS] |= M41T94_BIT_CB; | ||
54 | buf[M41T94_REG_YEAR] = BIN2BCD(tm->tm_year % 100); | ||
55 | |||
56 | return spi_write(spi, buf, 8); | ||
57 | } | ||
58 | |||
59 | static int m41t94_read_time(struct device *dev, struct rtc_time *tm) | ||
60 | { | ||
61 | struct spi_device *spi = to_spi_device(dev); | ||
62 | u8 buf[2]; | ||
63 | int ret, hour; | ||
64 | |||
65 | /* clear halt update bit */ | ||
66 | ret = spi_w8r8(spi, M41T94_REG_HT); | ||
67 | if (ret < 0) | ||
68 | return ret; | ||
69 | if (ret & M41T94_BIT_HALT) { | ||
70 | buf[0] = 0x80 | M41T94_REG_HT; | ||
71 | buf[1] = ret & ~M41T94_BIT_HALT; | ||
72 | spi_write(spi, buf, 2); | ||
73 | } | ||
74 | |||
75 | /* clear stop bit */ | ||
76 | ret = spi_w8r8(spi, M41T94_REG_SECONDS); | ||
77 | if (ret < 0) | ||
78 | return ret; | ||
79 | if (ret & M41T94_BIT_STOP) { | ||
80 | buf[0] = 0x80 | M41T94_REG_SECONDS; | ||
81 | buf[1] = ret & ~M41T94_BIT_STOP; | ||
82 | spi_write(spi, buf, 2); | ||
83 | } | ||
84 | |||
85 | tm->tm_sec = BCD2BIN(spi_w8r8(spi, M41T94_REG_SECONDS)); | ||
86 | tm->tm_min = BCD2BIN(spi_w8r8(spi, M41T94_REG_MINUTES)); | ||
87 | hour = spi_w8r8(spi, M41T94_REG_HOURS); | ||
88 | tm->tm_hour = BCD2BIN(hour & 0x3f); | ||
89 | tm->tm_wday = BCD2BIN(spi_w8r8(spi, M41T94_REG_WDAY)) - 1; | ||
90 | tm->tm_mday = BCD2BIN(spi_w8r8(spi, M41T94_REG_DAY)); | ||
91 | tm->tm_mon = BCD2BIN(spi_w8r8(spi, M41T94_REG_MONTH)) - 1; | ||
92 | tm->tm_year = BCD2BIN(spi_w8r8(spi, M41T94_REG_YEAR)); | ||
93 | if ((hour & M41T94_BIT_CB) || !(hour & M41T94_BIT_CEB)) | ||
94 | tm->tm_year += 100; | ||
95 | |||
96 | dev_dbg(dev, "%s secs=%d, mins=%d, " | ||
97 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", | ||
98 | "read", tm->tm_sec, tm->tm_min, | ||
99 | tm->tm_hour, tm->tm_mday, | ||
100 | tm->tm_mon, tm->tm_year, tm->tm_wday); | ||
101 | |||
102 | /* initial clock setting can be undefined */ | ||
103 | return rtc_valid_tm(tm); | ||
104 | } | ||
105 | |||
106 | static const struct rtc_class_ops m41t94_rtc_ops = { | ||
107 | .read_time = m41t94_read_time, | ||
108 | .set_time = m41t94_set_time, | ||
109 | }; | ||
110 | |||
111 | static struct spi_driver m41t94_driver; | ||
112 | |||
113 | static int __devinit m41t94_probe(struct spi_device *spi) | ||
114 | { | ||
115 | struct rtc_device *rtc; | ||
116 | int res; | ||
117 | |||
118 | spi->bits_per_word = 8; | ||
119 | spi_setup(spi); | ||
120 | |||
121 | res = spi_w8r8(spi, M41T94_REG_SECONDS); | ||
122 | if (res < 0) { | ||
123 | dev_err(&spi->dev, "not found.\n"); | ||
124 | return res; | ||
125 | } | ||
126 | |||
127 | rtc = rtc_device_register(m41t94_driver.driver.name, | ||
128 | &spi->dev, &m41t94_rtc_ops, THIS_MODULE); | ||
129 | if (IS_ERR(rtc)) | ||
130 | return PTR_ERR(rtc); | ||
131 | |||
132 | dev_set_drvdata(&spi->dev, rtc); | ||
133 | |||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | static int __devexit m41t94_remove(struct spi_device *spi) | ||
138 | { | ||
139 | struct rtc_device *rtc = platform_get_drvdata(spi); | ||
140 | |||
141 | if (rtc) | ||
142 | rtc_device_unregister(rtc); | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | static struct spi_driver m41t94_driver = { | ||
148 | .driver = { | ||
149 | .name = "rtc-m41t94", | ||
150 | .bus = &spi_bus_type, | ||
151 | .owner = THIS_MODULE, | ||
152 | }, | ||
153 | .probe = m41t94_probe, | ||
154 | .remove = __devexit_p(m41t94_remove), | ||
155 | }; | ||
156 | |||
157 | static __init int m41t94_init(void) | ||
158 | { | ||
159 | return spi_register_driver(&m41t94_driver); | ||
160 | } | ||
161 | |||
162 | module_init(m41t94_init); | ||
163 | |||
164 | static __exit void m41t94_exit(void) | ||
165 | { | ||
166 | spi_unregister_driver(&m41t94_driver); | ||
167 | } | ||
168 | |||
169 | module_exit(m41t94_exit); | ||
170 | |||
171 | MODULE_AUTHOR("Kim B. Heino <Kim.Heino@bluegiga.com>"); | ||
172 | MODULE_DESCRIPTION("Driver for ST M41T94 SPI RTC"); | ||
173 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index eb23d8423f42..8876605d4d4b 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c | |||
@@ -92,18 +92,6 @@ | |||
92 | #define rtc_write(val, addr) omap_writeb(val, OMAP_RTC_BASE + (addr)) | 92 | #define rtc_write(val, addr) omap_writeb(val, OMAP_RTC_BASE + (addr)) |
93 | 93 | ||
94 | 94 | ||
95 | /* platform_bus isn't hotpluggable, so for static linkage it'd be safe | ||
96 | * to get rid of probe() and remove() code ... too bad the driver struct | ||
97 | * remembers probe(), that's about 25% of the runtime footprint!! | ||
98 | */ | ||
99 | #ifndef MODULE | ||
100 | #undef __devexit | ||
101 | #undef __devexit_p | ||
102 | #define __devexit __exit | ||
103 | #define __devexit_p __exit_p | ||
104 | #endif | ||
105 | |||
106 | |||
107 | /* we rely on the rtc framework to handle locking (rtc->ops_lock), | 95 | /* we rely on the rtc framework to handle locking (rtc->ops_lock), |
108 | * so the only other requirement is that register accesses which | 96 | * so the only other requirement is that register accesses which |
109 | * require BUSY to be clear are made with IRQs locally disabled | 97 | * require BUSY to be clear are made with IRQs locally disabled |
@@ -324,7 +312,7 @@ static struct rtc_class_ops omap_rtc_ops = { | |||
324 | static int omap_rtc_alarm; | 312 | static int omap_rtc_alarm; |
325 | static int omap_rtc_timer; | 313 | static int omap_rtc_timer; |
326 | 314 | ||
327 | static int __devinit omap_rtc_probe(struct platform_device *pdev) | 315 | static int __init omap_rtc_probe(struct platform_device *pdev) |
328 | { | 316 | { |
329 | struct resource *res, *mem; | 317 | struct resource *res, *mem; |
330 | struct rtc_device *rtc; | 318 | struct rtc_device *rtc; |
@@ -440,7 +428,7 @@ fail: | |||
440 | return -EIO; | 428 | return -EIO; |
441 | } | 429 | } |
442 | 430 | ||
443 | static int __devexit omap_rtc_remove(struct platform_device *pdev) | 431 | static int __exit omap_rtc_remove(struct platform_device *pdev) |
444 | { | 432 | { |
445 | struct rtc_device *rtc = platform_get_drvdata(pdev);; | 433 | struct rtc_device *rtc = platform_get_drvdata(pdev);; |
446 | 434 | ||
@@ -498,8 +486,7 @@ static void omap_rtc_shutdown(struct platform_device *pdev) | |||
498 | 486 | ||
499 | MODULE_ALIAS("platform:omap_rtc"); | 487 | MODULE_ALIAS("platform:omap_rtc"); |
500 | static struct platform_driver omap_rtc_driver = { | 488 | static struct platform_driver omap_rtc_driver = { |
501 | .probe = omap_rtc_probe, | 489 | .remove = __exit_p(omap_rtc_remove), |
502 | .remove = __devexit_p(omap_rtc_remove), | ||
503 | .suspend = omap_rtc_suspend, | 490 | .suspend = omap_rtc_suspend, |
504 | .resume = omap_rtc_resume, | 491 | .resume = omap_rtc_resume, |
505 | .shutdown = omap_rtc_shutdown, | 492 | .shutdown = omap_rtc_shutdown, |
@@ -511,7 +498,7 @@ static struct platform_driver omap_rtc_driver = { | |||
511 | 498 | ||
512 | static int __init rtc_init(void) | 499 | static int __init rtc_init(void) |
513 | { | 500 | { |
514 | return platform_driver_register(&omap_rtc_driver); | 501 | return platform_driver_probe(&omap_rtc_driver, omap_rtc_probe); |
515 | } | 502 | } |
516 | module_init(rtc_init); | 503 | module_init(rtc_init); |
517 | 504 | ||
diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c index 3d09d8f0b1f0..d388c662bf4b 100644 --- a/drivers/rtc/rtc-pcf8583.c +++ b/drivers/rtc/rtc-pcf8583.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * drivers/rtc/rtc-pcf8583.c | 2 | * drivers/rtc/rtc-pcf8583.c |
3 | * | 3 | * |
4 | * Copyright (C) 2000 Russell King | 4 | * Copyright (C) 2000 Russell King |
5 | * Copyright (C) 2008 Wolfram Sang & Juergen Beisert, Pengutronix | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
@@ -14,7 +15,6 @@ | |||
14 | #include <linux/module.h> | 15 | #include <linux/module.h> |
15 | #include <linux/i2c.h> | 16 | #include <linux/i2c.h> |
16 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
17 | #include <linux/string.h> | ||
18 | #include <linux/rtc.h> | 18 | #include <linux/rtc.h> |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/errno.h> | 20 | #include <linux/errno.h> |
@@ -27,7 +27,6 @@ struct rtc_mem { | |||
27 | }; | 27 | }; |
28 | 28 | ||
29 | struct pcf8583 { | 29 | struct pcf8583 { |
30 | struct i2c_client client; | ||
31 | struct rtc_device *rtc; | 30 | struct rtc_device *rtc; |
32 | unsigned char ctrl; | 31 | unsigned char ctrl; |
33 | }; | 32 | }; |
@@ -40,10 +39,6 @@ struct pcf8583 { | |||
40 | #define CTRL_ALARM 0x02 | 39 | #define CTRL_ALARM 0x02 |
41 | #define CTRL_TIMER 0x01 | 40 | #define CTRL_TIMER 0x01 |
42 | 41 | ||
43 | static const unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END }; | ||
44 | |||
45 | /* Module parameters */ | ||
46 | I2C_CLIENT_INSMOD; | ||
47 | 42 | ||
48 | static struct i2c_driver pcf8583_driver; | 43 | static struct i2c_driver pcf8583_driver; |
49 | 44 | ||
@@ -269,106 +264,60 @@ static const struct rtc_class_ops pcf8583_rtc_ops = { | |||
269 | .set_time = pcf8583_rtc_set_time, | 264 | .set_time = pcf8583_rtc_set_time, |
270 | }; | 265 | }; |
271 | 266 | ||
272 | static int pcf8583_probe(struct i2c_adapter *adap, int addr, int kind); | 267 | static int pcf8583_probe(struct i2c_client *client, |
273 | 268 | const struct i2c_device_id *id) | |
274 | static int pcf8583_attach(struct i2c_adapter *adap) | ||
275 | { | ||
276 | return i2c_probe(adap, &addr_data, pcf8583_probe); | ||
277 | } | ||
278 | |||
279 | static int pcf8583_detach(struct i2c_client *client) | ||
280 | { | ||
281 | int err; | ||
282 | struct pcf8583 *pcf = i2c_get_clientdata(client); | ||
283 | struct rtc_device *rtc = pcf->rtc; | ||
284 | |||
285 | if (rtc) | ||
286 | rtc_device_unregister(rtc); | ||
287 | |||
288 | if ((err = i2c_detach_client(client))) | ||
289 | return err; | ||
290 | |||
291 | kfree(pcf); | ||
292 | return 0; | ||
293 | } | ||
294 | |||
295 | static struct i2c_driver pcf8583_driver = { | ||
296 | .driver = { | ||
297 | .name = "pcf8583", | ||
298 | }, | ||
299 | .id = I2C_DRIVERID_PCF8583, | ||
300 | .attach_adapter = pcf8583_attach, | ||
301 | .detach_client = pcf8583_detach, | ||
302 | }; | ||
303 | |||
304 | static int pcf8583_probe(struct i2c_adapter *adap, int addr, int kind) | ||
305 | { | 269 | { |
306 | struct pcf8583 *pcf; | 270 | struct pcf8583 *pcf8583; |
307 | struct i2c_client *client; | ||
308 | struct rtc_device *rtc; | ||
309 | unsigned char buf[1], ad[1] = { 0 }; | ||
310 | int err; | 271 | int err; |
311 | struct i2c_msg msgs[2] = { | ||
312 | { | ||
313 | .addr = addr, | ||
314 | .flags = 0, | ||
315 | .len = 1, | ||
316 | .buf = ad, | ||
317 | }, { | ||
318 | .addr = addr, | ||
319 | .flags = I2C_M_RD, | ||
320 | .len = 1, | ||
321 | .buf = buf, | ||
322 | } | ||
323 | }; | ||
324 | 272 | ||
325 | if (!i2c_check_functionality(adap, I2C_FUNC_I2C)) | 273 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) |
326 | return 0; | 274 | return -ENODEV; |
327 | 275 | ||
328 | pcf = kzalloc(sizeof(*pcf), GFP_KERNEL); | 276 | pcf8583 = kzalloc(sizeof(struct pcf8583), GFP_KERNEL); |
329 | if (!pcf) | 277 | if (!pcf8583) |
330 | return -ENOMEM; | 278 | return -ENOMEM; |
331 | 279 | ||
332 | client = &pcf->client; | 280 | pcf8583->rtc = rtc_device_register(pcf8583_driver.driver.name, |
281 | &client->dev, &pcf8583_rtc_ops, THIS_MODULE); | ||
333 | 282 | ||
334 | client->addr = addr; | 283 | if (IS_ERR(pcf8583->rtc)) { |
335 | client->adapter = adap; | 284 | err = PTR_ERR(pcf8583->rtc); |
336 | client->driver = &pcf8583_driver; | ||
337 | |||
338 | strlcpy(client->name, pcf8583_driver.driver.name, I2C_NAME_SIZE); | ||
339 | |||
340 | if (i2c_transfer(client->adapter, msgs, 2) != 2) { | ||
341 | err = -EIO; | ||
342 | goto exit_kfree; | 285 | goto exit_kfree; |
343 | } | 286 | } |
344 | 287 | ||
345 | err = i2c_attach_client(client); | 288 | i2c_set_clientdata(client, pcf8583); |
346 | 289 | return 0; | |
347 | if (err) | ||
348 | goto exit_kfree; | ||
349 | |||
350 | rtc = rtc_device_register(pcf8583_driver.driver.name, &client->dev, | ||
351 | &pcf8583_rtc_ops, THIS_MODULE); | ||
352 | 290 | ||
353 | if (IS_ERR(rtc)) { | 291 | exit_kfree: |
354 | err = PTR_ERR(rtc); | 292 | kfree(pcf8583); |
355 | goto exit_detach; | 293 | return err; |
356 | } | 294 | } |
357 | 295 | ||
358 | pcf->rtc = rtc; | 296 | static int __devexit pcf8583_remove(struct i2c_client *client) |
359 | i2c_set_clientdata(client, pcf); | 297 | { |
360 | set_ctrl(client, buf[0]); | 298 | struct pcf8583 *pcf8583 = i2c_get_clientdata(client); |
361 | 299 | ||
300 | if (pcf8583->rtc) | ||
301 | rtc_device_unregister(pcf8583->rtc); | ||
302 | kfree(pcf8583); | ||
362 | return 0; | 303 | return 0; |
304 | } | ||
363 | 305 | ||
364 | exit_detach: | 306 | static const struct i2c_device_id pcf8583_id[] = { |
365 | i2c_detach_client(client); | 307 | { "pcf8583", 0 }, |
366 | 308 | { } | |
367 | exit_kfree: | 309 | }; |
368 | kfree(pcf); | 310 | MODULE_DEVICE_TABLE(i2c, pcf8583_id); |
369 | 311 | ||
370 | return err; | 312 | static struct i2c_driver pcf8583_driver = { |
371 | } | 313 | .driver = { |
314 | .name = "pcf8583", | ||
315 | .owner = THIS_MODULE, | ||
316 | }, | ||
317 | .probe = pcf8583_probe, | ||
318 | .remove = __devexit_p(pcf8583_remove), | ||
319 | .id_table = pcf8583_id, | ||
320 | }; | ||
372 | 321 | ||
373 | static __init int pcf8583_init(void) | 322 | static __init int pcf8583_init(void) |
374 | { | 323 | { |
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index fed86e507fdf..54b1ebb01502 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -36,10 +36,8 @@ static struct resource *s3c_rtc_mem; | |||
36 | static void __iomem *s3c_rtc_base; | 36 | static void __iomem *s3c_rtc_base; |
37 | static int s3c_rtc_alarmno = NO_IRQ; | 37 | static int s3c_rtc_alarmno = NO_IRQ; |
38 | static int s3c_rtc_tickno = NO_IRQ; | 38 | static int s3c_rtc_tickno = NO_IRQ; |
39 | static int s3c_rtc_freq = 1; | ||
40 | 39 | ||
41 | static DEFINE_SPINLOCK(s3c_rtc_pie_lock); | 40 | static DEFINE_SPINLOCK(s3c_rtc_pie_lock); |
42 | static unsigned int tick_count; | ||
43 | 41 | ||
44 | /* IRQ Handlers */ | 42 | /* IRQ Handlers */ |
45 | 43 | ||
@@ -55,7 +53,7 @@ static irqreturn_t s3c_rtc_tickirq(int irq, void *id) | |||
55 | { | 53 | { |
56 | struct rtc_device *rdev = id; | 54 | struct rtc_device *rdev = id; |
57 | 55 | ||
58 | rtc_update_irq(rdev, tick_count++, RTC_PF | RTC_IRQF); | 56 | rtc_update_irq(rdev, 1, RTC_PF | RTC_IRQF); |
59 | return IRQ_HANDLED; | 57 | return IRQ_HANDLED; |
60 | } | 58 | } |
61 | 59 | ||
@@ -74,35 +72,37 @@ static void s3c_rtc_setaie(int to) | |||
74 | writeb(tmp, s3c_rtc_base + S3C2410_RTCALM); | 72 | writeb(tmp, s3c_rtc_base + S3C2410_RTCALM); |
75 | } | 73 | } |
76 | 74 | ||
77 | static void s3c_rtc_setpie(int to) | 75 | static int s3c_rtc_setpie(struct device *dev, int enabled) |
78 | { | 76 | { |
79 | unsigned int tmp; | 77 | unsigned int tmp; |
80 | 78 | ||
81 | pr_debug("%s: pie=%d\n", __func__, to); | 79 | pr_debug("%s: pie=%d\n", __func__, enabled); |
82 | 80 | ||
83 | spin_lock_irq(&s3c_rtc_pie_lock); | 81 | spin_lock_irq(&s3c_rtc_pie_lock); |
84 | tmp = readb(s3c_rtc_base + S3C2410_TICNT) & ~S3C2410_TICNT_ENABLE; | 82 | tmp = readb(s3c_rtc_base + S3C2410_TICNT) & ~S3C2410_TICNT_ENABLE; |
85 | 83 | ||
86 | if (to) | 84 | if (enabled) |
87 | tmp |= S3C2410_TICNT_ENABLE; | 85 | tmp |= S3C2410_TICNT_ENABLE; |
88 | 86 | ||
89 | writeb(tmp, s3c_rtc_base + S3C2410_TICNT); | 87 | writeb(tmp, s3c_rtc_base + S3C2410_TICNT); |
90 | spin_unlock_irq(&s3c_rtc_pie_lock); | 88 | spin_unlock_irq(&s3c_rtc_pie_lock); |
89 | |||
90 | return 0; | ||
91 | } | 91 | } |
92 | 92 | ||
93 | static void s3c_rtc_setfreq(int freq) | 93 | static int s3c_rtc_setfreq(struct device *dev, int freq) |
94 | { | 94 | { |
95 | unsigned int tmp; | 95 | unsigned int tmp; |
96 | 96 | ||
97 | spin_lock_irq(&s3c_rtc_pie_lock); | 97 | spin_lock_irq(&s3c_rtc_pie_lock); |
98 | tmp = readb(s3c_rtc_base + S3C2410_TICNT) & S3C2410_TICNT_ENABLE; | ||
99 | |||
100 | s3c_rtc_freq = freq; | ||
101 | 98 | ||
99 | tmp = readb(s3c_rtc_base + S3C2410_TICNT) & S3C2410_TICNT_ENABLE; | ||
102 | tmp |= (128 / freq)-1; | 100 | tmp |= (128 / freq)-1; |
103 | 101 | ||
104 | writeb(tmp, s3c_rtc_base + S3C2410_TICNT); | 102 | writeb(tmp, s3c_rtc_base + S3C2410_TICNT); |
105 | spin_unlock_irq(&s3c_rtc_pie_lock); | 103 | spin_unlock_irq(&s3c_rtc_pie_lock); |
104 | |||
105 | return 0; | ||
106 | } | 106 | } |
107 | 107 | ||
108 | /* Time read/write */ | 108 | /* Time read/write */ |
@@ -267,12 +267,7 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
267 | 267 | ||
268 | writeb(alrm_en, base + S3C2410_RTCALM); | 268 | writeb(alrm_en, base + S3C2410_RTCALM); |
269 | 269 | ||
270 | if (0) { | 270 | s3c_rtc_setaie(alrm->enabled); |
271 | alrm_en = readb(base + S3C2410_RTCALM); | ||
272 | alrm_en &= ~S3C2410_RTCALM_ALMEN; | ||
273 | writeb(alrm_en, base + S3C2410_RTCALM); | ||
274 | disable_irq_wake(s3c_rtc_alarmno); | ||
275 | } | ||
276 | 271 | ||
277 | if (alrm->enabled) | 272 | if (alrm->enabled) |
278 | enable_irq_wake(s3c_rtc_alarmno); | 273 | enable_irq_wake(s3c_rtc_alarmno); |
@@ -282,59 +277,12 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
282 | return 0; | 277 | return 0; |
283 | } | 278 | } |
284 | 279 | ||
285 | static int s3c_rtc_ioctl(struct device *dev, | ||
286 | unsigned int cmd, unsigned long arg) | ||
287 | { | ||
288 | unsigned int ret = -ENOIOCTLCMD; | ||
289 | |||
290 | switch (cmd) { | ||
291 | case RTC_AIE_OFF: | ||
292 | case RTC_AIE_ON: | ||
293 | s3c_rtc_setaie((cmd == RTC_AIE_ON) ? 1 : 0); | ||
294 | ret = 0; | ||
295 | break; | ||
296 | |||
297 | case RTC_PIE_OFF: | ||
298 | case RTC_PIE_ON: | ||
299 | tick_count = 0; | ||
300 | s3c_rtc_setpie((cmd == RTC_PIE_ON) ? 1 : 0); | ||
301 | ret = 0; | ||
302 | break; | ||
303 | |||
304 | case RTC_IRQP_READ: | ||
305 | ret = put_user(s3c_rtc_freq, (unsigned long __user *)arg); | ||
306 | break; | ||
307 | |||
308 | case RTC_IRQP_SET: | ||
309 | if (!is_power_of_2(arg)) { | ||
310 | ret = -EINVAL; | ||
311 | goto exit; | ||
312 | } | ||
313 | |||
314 | pr_debug("s3c2410_rtc: setting frequency %ld\n", arg); | ||
315 | |||
316 | s3c_rtc_setfreq(arg); | ||
317 | ret = 0; | ||
318 | break; | ||
319 | |||
320 | case RTC_UIE_ON: | ||
321 | case RTC_UIE_OFF: | ||
322 | ret = -EINVAL; | ||
323 | } | ||
324 | |||
325 | exit: | ||
326 | return ret; | ||
327 | } | ||
328 | |||
329 | static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) | 280 | static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) |
330 | { | 281 | { |
331 | unsigned int ticnt = readb(s3c_rtc_base + S3C2410_TICNT); | 282 | unsigned int ticnt = readb(s3c_rtc_base + S3C2410_TICNT); |
332 | 283 | ||
333 | seq_printf(seq, "periodic_IRQ\t: %s\n", | 284 | seq_printf(seq, "periodic_IRQ\t: %s\n", |
334 | (ticnt & S3C2410_TICNT_ENABLE) ? "yes" : "no" ); | 285 | (ticnt & S3C2410_TICNT_ENABLE) ? "yes" : "no" ); |
335 | |||
336 | seq_printf(seq, "periodic_freq\t: %d\n", s3c_rtc_freq); | ||
337 | |||
338 | return 0; | 286 | return 0; |
339 | } | 287 | } |
340 | 288 | ||
@@ -374,7 +322,7 @@ static void s3c_rtc_release(struct device *dev) | |||
374 | 322 | ||
375 | /* do not clear AIE here, it may be needed for wake */ | 323 | /* do not clear AIE here, it may be needed for wake */ |
376 | 324 | ||
377 | s3c_rtc_setpie(0); | 325 | s3c_rtc_setpie(dev, 0); |
378 | free_irq(s3c_rtc_alarmno, rtc_dev); | 326 | free_irq(s3c_rtc_alarmno, rtc_dev); |
379 | free_irq(s3c_rtc_tickno, rtc_dev); | 327 | free_irq(s3c_rtc_tickno, rtc_dev); |
380 | } | 328 | } |
@@ -382,11 +330,12 @@ static void s3c_rtc_release(struct device *dev) | |||
382 | static const struct rtc_class_ops s3c_rtcops = { | 330 | static const struct rtc_class_ops s3c_rtcops = { |
383 | .open = s3c_rtc_open, | 331 | .open = s3c_rtc_open, |
384 | .release = s3c_rtc_release, | 332 | .release = s3c_rtc_release, |
385 | .ioctl = s3c_rtc_ioctl, | ||
386 | .read_time = s3c_rtc_gettime, | 333 | .read_time = s3c_rtc_gettime, |
387 | .set_time = s3c_rtc_settime, | 334 | .set_time = s3c_rtc_settime, |
388 | .read_alarm = s3c_rtc_getalarm, | 335 | .read_alarm = s3c_rtc_getalarm, |
389 | .set_alarm = s3c_rtc_setalarm, | 336 | .set_alarm = s3c_rtc_setalarm, |
337 | .irq_set_freq = s3c_rtc_setfreq, | ||
338 | .irq_set_state = s3c_rtc_setpie, | ||
390 | .proc = s3c_rtc_proc, | 339 | .proc = s3c_rtc_proc, |
391 | }; | 340 | }; |
392 | 341 | ||
@@ -430,14 +379,14 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en) | |||
430 | } | 379 | } |
431 | } | 380 | } |
432 | 381 | ||
433 | static int s3c_rtc_remove(struct platform_device *dev) | 382 | static int __devexit s3c_rtc_remove(struct platform_device *dev) |
434 | { | 383 | { |
435 | struct rtc_device *rtc = platform_get_drvdata(dev); | 384 | struct rtc_device *rtc = platform_get_drvdata(dev); |
436 | 385 | ||
437 | platform_set_drvdata(dev, NULL); | 386 | platform_set_drvdata(dev, NULL); |
438 | rtc_device_unregister(rtc); | 387 | rtc_device_unregister(rtc); |
439 | 388 | ||
440 | s3c_rtc_setpie(0); | 389 | s3c_rtc_setpie(&dev->dev, 0); |
441 | s3c_rtc_setaie(0); | 390 | s3c_rtc_setaie(0); |
442 | 391 | ||
443 | iounmap(s3c_rtc_base); | 392 | iounmap(s3c_rtc_base); |
@@ -447,7 +396,7 @@ static int s3c_rtc_remove(struct platform_device *dev) | |||
447 | return 0; | 396 | return 0; |
448 | } | 397 | } |
449 | 398 | ||
450 | static int s3c_rtc_probe(struct platform_device *pdev) | 399 | static int __devinit s3c_rtc_probe(struct platform_device *pdev) |
451 | { | 400 | { |
452 | struct rtc_device *rtc; | 401 | struct rtc_device *rtc; |
453 | struct resource *res; | 402 | struct resource *res; |
@@ -504,7 +453,7 @@ static int s3c_rtc_probe(struct platform_device *pdev) | |||
504 | pr_debug("s3c2410_rtc: RTCCON=%02x\n", | 453 | pr_debug("s3c2410_rtc: RTCCON=%02x\n", |
505 | readb(s3c_rtc_base + S3C2410_RTCCON)); | 454 | readb(s3c_rtc_base + S3C2410_RTCCON)); |
506 | 455 | ||
507 | s3c_rtc_setfreq(s3c_rtc_freq); | 456 | s3c_rtc_setfreq(&pdev->dev, 1); |
508 | 457 | ||
509 | /* register RTC and exit */ | 458 | /* register RTC and exit */ |
510 | 459 | ||
@@ -560,7 +509,7 @@ static int s3c_rtc_resume(struct platform_device *pdev) | |||
560 | 509 | ||
561 | static struct platform_driver s3c2410_rtcdrv = { | 510 | static struct platform_driver s3c2410_rtcdrv = { |
562 | .probe = s3c_rtc_probe, | 511 | .probe = s3c_rtc_probe, |
563 | .remove = s3c_rtc_remove, | 512 | .remove = __devexit_p(s3c_rtc_remove), |
564 | .suspend = s3c_rtc_suspend, | 513 | .suspend = s3c_rtc_suspend, |
565 | .resume = s3c_rtc_resume, | 514 | .resume = s3c_rtc_resume, |
566 | .driver = { | 515 | .driver = { |
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index be9c70d0b193..884b635f028b 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for NEC VR4100 series Real Time Clock unit. | 2 | * Driver for NEC VR4100 series Real Time Clock unit. |
3 | * | 3 | * |
4 | * Copyright (C) 2003-2006 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | 4 | * Copyright (C) 2003-2008 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -34,7 +34,7 @@ | |||
34 | 34 | ||
35 | MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>"); | 35 | MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>"); |
36 | MODULE_DESCRIPTION("NEC VR4100 series RTC driver"); | 36 | MODULE_DESCRIPTION("NEC VR4100 series RTC driver"); |
37 | MODULE_LICENSE("GPL"); | 37 | MODULE_LICENSE("GPL v2"); |
38 | 38 | ||
39 | /* RTC 1 registers */ | 39 | /* RTC 1 registers */ |
40 | #define ETIMELREG 0x00 | 40 | #define ETIMELREG 0x00 |
@@ -82,7 +82,6 @@ static unsigned long epoch = 1970; /* Jan 1 1970 00:00:00 */ | |||
82 | 82 | ||
83 | static DEFINE_SPINLOCK(rtc_lock); | 83 | static DEFINE_SPINLOCK(rtc_lock); |
84 | static char rtc_name[] = "RTC"; | 84 | static char rtc_name[] = "RTC"; |
85 | static unsigned long periodic_frequency; | ||
86 | static unsigned long periodic_count; | 85 | static unsigned long periodic_count; |
87 | static unsigned int alarm_enabled; | 86 | static unsigned int alarm_enabled; |
88 | static int aie_irq = -1; | 87 | static int aie_irq = -1; |
@@ -207,10 +206,37 @@ static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | |||
207 | return 0; | 206 | return 0; |
208 | } | 207 | } |
209 | 208 | ||
210 | static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | 209 | static int vr41xx_rtc_irq_set_freq(struct device *dev, int freq) |
211 | { | 210 | { |
212 | unsigned long count; | 211 | unsigned long count; |
213 | 212 | ||
213 | count = RTC_FREQUENCY; | ||
214 | do_div(count, freq); | ||
215 | |||
216 | periodic_count = count; | ||
217 | |||
218 | spin_lock_irq(&rtc_lock); | ||
219 | |||
220 | rtc1_write(RTCL1LREG, count); | ||
221 | rtc1_write(RTCL1HREG, count >> 16); | ||
222 | |||
223 | spin_unlock_irq(&rtc_lock); | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | static int vr41xx_rtc_irq_set_state(struct device *dev, int enabled) | ||
229 | { | ||
230 | if (enabled) | ||
231 | enable_irq(pie_irq); | ||
232 | else | ||
233 | disable_irq(pie_irq); | ||
234 | |||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | ||
239 | { | ||
214 | switch (cmd) { | 240 | switch (cmd) { |
215 | case RTC_AIE_ON: | 241 | case RTC_AIE_ON: |
216 | spin_lock_irq(&rtc_lock); | 242 | spin_lock_irq(&rtc_lock); |
@@ -232,33 +258,6 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long | |||
232 | 258 | ||
233 | spin_unlock_irq(&rtc_lock); | 259 | spin_unlock_irq(&rtc_lock); |
234 | break; | 260 | break; |
235 | case RTC_PIE_ON: | ||
236 | enable_irq(pie_irq); | ||
237 | break; | ||
238 | case RTC_PIE_OFF: | ||
239 | disable_irq(pie_irq); | ||
240 | break; | ||
241 | case RTC_IRQP_READ: | ||
242 | return put_user(periodic_frequency, (unsigned long __user *)arg); | ||
243 | break; | ||
244 | case RTC_IRQP_SET: | ||
245 | if (arg > MAX_PERIODIC_RATE) | ||
246 | return -EINVAL; | ||
247 | |||
248 | periodic_frequency = arg; | ||
249 | |||
250 | count = RTC_FREQUENCY; | ||
251 | do_div(count, arg); | ||
252 | |||
253 | periodic_count = count; | ||
254 | |||
255 | spin_lock_irq(&rtc_lock); | ||
256 | |||
257 | rtc1_write(RTCL1LREG, count); | ||
258 | rtc1_write(RTCL1HREG, count >> 16); | ||
259 | |||
260 | spin_unlock_irq(&rtc_lock); | ||
261 | break; | ||
262 | case RTC_EPOCH_READ: | 261 | case RTC_EPOCH_READ: |
263 | return put_user(epoch, (unsigned long __user *)arg); | 262 | return put_user(epoch, (unsigned long __user *)arg); |
264 | case RTC_EPOCH_SET: | 263 | case RTC_EPOCH_SET: |
@@ -309,6 +308,8 @@ static const struct rtc_class_ops vr41xx_rtc_ops = { | |||
309 | .set_time = vr41xx_rtc_set_time, | 308 | .set_time = vr41xx_rtc_set_time, |
310 | .read_alarm = vr41xx_rtc_read_alarm, | 309 | .read_alarm = vr41xx_rtc_read_alarm, |
311 | .set_alarm = vr41xx_rtc_set_alarm, | 310 | .set_alarm = vr41xx_rtc_set_alarm, |
311 | .irq_set_freq = vr41xx_rtc_irq_set_freq, | ||
312 | .irq_set_state = vr41xx_rtc_irq_set_state, | ||
312 | }; | 313 | }; |
313 | 314 | ||
314 | static int __devinit rtc_probe(struct platform_device *pdev) | 315 | static int __devinit rtc_probe(struct platform_device *pdev) |
@@ -346,6 +347,8 @@ static int __devinit rtc_probe(struct platform_device *pdev) | |||
346 | goto err_iounmap_all; | 347 | goto err_iounmap_all; |
347 | } | 348 | } |
348 | 349 | ||
350 | rtc->max_user_freq = MAX_PERIODIC_RATE; | ||
351 | |||
349 | spin_lock_irq(&rtc_lock); | 352 | spin_lock_irq(&rtc_lock); |
350 | 353 | ||
351 | rtc1_write(ECMPLREG, 0); | 354 | rtc1_write(ECMPLREG, 0); |