diff options
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/Kconfig | 126 | ||||
-rw-r--r-- | drivers/rtc/Makefile | 4 | ||||
-rw-r--r-- | drivers/rtc/rtc-at91sam9.c | 520 | ||||
-rw-r--r-- | drivers/rtc/rtc-bfin.c | 351 | ||||
-rw-r--r-- | drivers/rtc/rtc-cmos.c | 221 | ||||
-rw-r--r-- | drivers/rtc/rtc-dev.c | 9 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1302.c | 262 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1307.c | 27 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1511.c | 656 | ||||
-rw-r--r-- | drivers/rtc/rtc-pcf8583.c | 24 | ||||
-rw-r--r-- | drivers/rtc/rtc-r9701.c | 178 | ||||
-rw-r--r-- | drivers/rtc/rtc-s3c.c | 5 | ||||
-rw-r--r-- | drivers/rtc/rtc-sa1100.c | 16 | ||||
-rw-r--r-- | drivers/rtc/rtc-sysfs.c | 19 |
14 files changed, 2157 insertions, 261 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 45e4b9648176..6402d699072b 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -20,6 +20,10 @@ menuconfig RTC_CLASS | |||
20 | 20 | ||
21 | if RTC_CLASS | 21 | if RTC_CLASS |
22 | 22 | ||
23 | if GEN_RTC || RTC | ||
24 | comment "Conflicting RTC option has been selected, check GEN_RTC and RTC" | ||
25 | endif | ||
26 | |||
23 | config RTC_HCTOSYS | 27 | config RTC_HCTOSYS |
24 | bool "Set system time from RTC on startup and resume" | 28 | bool "Set system time from RTC on startup and resume" |
25 | depends on RTC_CLASS = y | 29 | depends on RTC_CLASS = y |
@@ -49,7 +53,7 @@ config RTC_HCTOSYS_DEVICE | |||
49 | 53 | ||
50 | If the clock you specify here is not battery backed, it may still | 54 | If the clock you specify here is not battery backed, it may still |
51 | be useful to reinitialize system time when resuming from system | 55 | be useful to reinitialize system time when resuming from system |
52 | sleep states. Do not specify an RTC here unless it stays powered | 56 | sleep states. Do not specify an RTC here unless it stays powered |
53 | during all this system's supported sleep states. | 57 | during all this system's supported sleep states. |
54 | 58 | ||
55 | config RTC_DEBUG | 59 | config RTC_DEBUG |
@@ -142,7 +146,7 @@ config RTC_DRV_DS1307 | |||
142 | will be called rtc-ds1307. | 146 | will be called rtc-ds1307. |
143 | 147 | ||
144 | config RTC_DRV_DS1374 | 148 | config RTC_DRV_DS1374 |
145 | tristate "Maxim/Dallas Semiconductor DS1374 Real Time Clock" | 149 | tristate "Dallas/Maxim DS1374" |
146 | depends on RTC_CLASS && I2C | 150 | depends on RTC_CLASS && I2C |
147 | help | 151 | help |
148 | If you say yes here you get support for Dallas Semiconductor | 152 | If you say yes here you get support for Dallas Semiconductor |
@@ -162,7 +166,7 @@ config RTC_DRV_DS1672 | |||
162 | will be called rtc-ds1672. | 166 | will be called rtc-ds1672. |
163 | 167 | ||
164 | config RTC_DRV_MAX6900 | 168 | config RTC_DRV_MAX6900 |
165 | tristate "Maxim 6900" | 169 | tristate "Maxim MAX6900" |
166 | help | 170 | help |
167 | If you say yes here you will get support for the | 171 | If you say yes here you will get support for the |
168 | Maxim MAX6900 I2C RTC chip. | 172 | Maxim MAX6900 I2C RTC chip. |
@@ -180,10 +184,10 @@ config RTC_DRV_RS5C372 | |||
180 | will be called rtc-rs5c372. | 184 | will be called rtc-rs5c372. |
181 | 185 | ||
182 | config RTC_DRV_ISL1208 | 186 | config RTC_DRV_ISL1208 |
183 | tristate "Intersil 1208" | 187 | tristate "Intersil ISL1208" |
184 | help | 188 | help |
185 | If you say yes here you get support for the | 189 | If you say yes here you get support for the |
186 | Intersil 1208 RTC chip. | 190 | Intersil ISL1208 RTC chip. |
187 | 191 | ||
188 | This driver can also be built as a module. If so, the module | 192 | This driver can also be built as a module. If so, the module |
189 | will be called rtc-isl1208. | 193 | will be called rtc-isl1208. |
@@ -220,7 +224,7 @@ config RTC_DRV_PCF8583 | |||
220 | will be called rtc-pcf8583. | 224 | will be called rtc-pcf8583. |
221 | 225 | ||
222 | config RTC_DRV_M41T80 | 226 | config RTC_DRV_M41T80 |
223 | tristate "ST M41T80 series RTC" | 227 | tristate "ST M41T80/81/82/83/84/85/87" |
224 | help | 228 | help |
225 | If you say Y here you will get support for the | 229 | If you say Y here you will get support for the |
226 | ST M41T80 RTC chips series. Currently following chips are | 230 | ST M41T80 RTC chips series. Currently following chips are |
@@ -252,23 +256,32 @@ comment "SPI RTC drivers" | |||
252 | 256 | ||
253 | if SPI_MASTER | 257 | if SPI_MASTER |
254 | 258 | ||
255 | config RTC_DRV_RS5C348 | 259 | config RTC_DRV_MAX6902 |
256 | tristate "Ricoh RS5C348A/B" | 260 | tristate "Maxim MAX6902" |
257 | help | 261 | help |
258 | If you say yes here you get support for the | 262 | If you say yes here you will get support for the |
259 | Ricoh RS5C348A and RS5C348B RTC chips. | 263 | Maxim MAX6902 SPI RTC chip. |
260 | 264 | ||
261 | This driver can also be built as a module. If so, the module | 265 | This driver can also be built as a module. If so, the module |
262 | will be called rtc-rs5c348. | 266 | will be called rtc-max6902. |
263 | 267 | ||
264 | config RTC_DRV_MAX6902 | 268 | config RTC_DRV_R9701 |
265 | tristate "Maxim 6902" | 269 | tristate "Epson RTC-9701JE" |
266 | help | 270 | help |
267 | If you say yes here you will get support for the | 271 | If you say yes here you will get support for the |
268 | Maxim MAX6902 SPI RTC chip. | 272 | Epson RTC-9701JE SPI RTC chip. |
269 | 273 | ||
270 | This driver can also be built as a module. If so, the module | 274 | This driver can also be built as a module. If so, the module |
271 | will be called rtc-max6902. | 275 | will be called rtc-r9701. |
276 | |||
277 | config RTC_DRV_RS5C348 | ||
278 | tristate "Ricoh RS5C348A/B" | ||
279 | help | ||
280 | If you say yes here you get support for the | ||
281 | Ricoh RS5C348A and RS5C348B RTC chips. | ||
282 | |||
283 | This driver can also be built as a module. If so, the module | ||
284 | will be called rtc-rs5c348. | ||
272 | 285 | ||
273 | endif # SPI_MASTER | 286 | endif # SPI_MASTER |
274 | 287 | ||
@@ -302,34 +315,50 @@ config RTC_DRV_DS1216 | |||
302 | help | 315 | help |
303 | If you say yes here you get support for the Dallas DS1216 RTC chips. | 316 | If you say yes here you get support for the Dallas DS1216 RTC chips. |
304 | 317 | ||
305 | config RTC_DRV_DS1553 | 318 | config RTC_DRV_DS1302 |
306 | tristate "Dallas DS1553" | 319 | tristate "Dallas DS1302" |
320 | depends on SH_SECUREEDGE5410 | ||
321 | help | ||
322 | If you say yes here you get support for the Dallas DS1302 RTC chips. | ||
323 | |||
324 | config RTC_DRV_DS1511 | ||
325 | tristate "Dallas DS1511" | ||
326 | depends on RTC_CLASS | ||
307 | help | 327 | help |
308 | If you say yes here you get support for the | 328 | If you say yes here you get support for the |
309 | Dallas DS1553 timekeeping chip. | 329 | Dallas DS1511 timekeeping/watchdog chip. |
310 | 330 | ||
311 | This driver can also be built as a module. If so, the module | 331 | This driver can also be built as a module. If so, the module |
312 | will be called rtc-ds1553. | 332 | will be called rtc-ds1511. |
313 | 333 | ||
314 | config RTC_DRV_STK17TA8 | 334 | config RTC_DRV_DS1553 |
315 | tristate "Simtek STK17TA8" | 335 | tristate "Maxim/Dallas DS1553" |
316 | depends on RTC_CLASS | ||
317 | help | 336 | help |
318 | If you say yes here you get support for the | 337 | If you say yes here you get support for the |
319 | Simtek STK17TA8 timekeeping chip. | 338 | Maxim/Dallas DS1553 timekeeping chip. |
320 | 339 | ||
321 | This driver can also be built as a module. If so, the module | 340 | This driver can also be built as a module. If so, the module |
322 | will be called rtc-stk17ta8. | 341 | will be called rtc-ds1553. |
323 | 342 | ||
324 | config RTC_DRV_DS1742 | 343 | config RTC_DRV_DS1742 |
325 | tristate "Dallas DS1742/1743" | 344 | tristate "Maxim/Dallas DS1742/1743" |
326 | help | 345 | help |
327 | If you say yes here you get support for the | 346 | If you say yes here you get support for the |
328 | Dallas DS1742/1743 timekeeping chip. | 347 | Maxim/Dallas DS1742/1743 timekeeping chip. |
329 | 348 | ||
330 | This driver can also be built as a module. If so, the module | 349 | This driver can also be built as a module. If so, the module |
331 | will be called rtc-ds1742. | 350 | will be called rtc-ds1742. |
332 | 351 | ||
352 | config RTC_DRV_STK17TA8 | ||
353 | tristate "Simtek STK17TA8" | ||
354 | depends on RTC_CLASS | ||
355 | help | ||
356 | If you say yes here you get support for the | ||
357 | Simtek STK17TA8 timekeeping chip. | ||
358 | |||
359 | This driver can also be built as a module. If so, the module | ||
360 | will be called rtc-stk17ta8. | ||
361 | |||
333 | config RTC_DRV_M48T86 | 362 | config RTC_DRV_M48T86 |
334 | tristate "ST M48T86/Dallas DS12887" | 363 | tristate "ST M48T86/Dallas DS12887" |
335 | help | 364 | help |
@@ -440,10 +469,47 @@ config RTC_DRV_AT32AP700X | |||
440 | AT32AP700x family processors. | 469 | AT32AP700x family processors. |
441 | 470 | ||
442 | config RTC_DRV_AT91RM9200 | 471 | config RTC_DRV_AT91RM9200 |
443 | tristate "AT91RM9200" | 472 | tristate "AT91RM9200 or AT91SAM9RL" |
444 | depends on ARCH_AT91RM9200 | 473 | depends on ARCH_AT91RM9200 || ARCH_AT91SAM9RL |
445 | help | 474 | help |
446 | Driver for the Atmel AT91RM9200's internal RTC (Realtime Clock). | 475 | Driver for the internal RTC (Realtime Clock) module found on |
476 | Atmel AT91RM9200's and AT91SAM9RL chips. On SAM9RL chips | ||
477 | this is powered by the backup power supply. | ||
478 | |||
479 | config RTC_DRV_AT91SAM9 | ||
480 | tristate "AT91SAM9x" | ||
481 | depends on ARCH_AT91 && !(ARCH_AT91RM9200 || ARCH_AT91X40) | ||
482 | help | ||
483 | RTC driver for the Atmel AT91SAM9x internal RTT (Real Time Timer). | ||
484 | These timers are powered by the backup power supply (such as a | ||
485 | small coin cell battery), but do not need to be used as RTCs. | ||
486 | |||
487 | (On AT91SAM9rl chips you probably want to use the dedicated RTC | ||
488 | module and leave the RTT available for other uses.) | ||
489 | |||
490 | config RTC_DRV_AT91SAM9_RTT | ||
491 | int | ||
492 | range 0 1 | ||
493 | default 0 | ||
494 | prompt "RTT module Number" if ARCH_AT91SAM9263 | ||
495 | depends on RTC_DRV_AT91SAM9 | ||
496 | help | ||
497 | More than one RTT module is available. You can choose which | ||
498 | one will be used as an RTC. The default of zero is normally | ||
499 | OK to use, though some systems use that for non-RTC purposes. | ||
500 | |||
501 | config RTC_DRV_AT91SAM9_GPBR | ||
502 | int | ||
503 | range 0 3 if !ARCH_AT91SAM9263 | ||
504 | range 0 15 if ARCH_AT91SAM9263 | ||
505 | default 0 | ||
506 | prompt "Backup Register Number" | ||
507 | depends on RTC_DRV_AT91SAM9 | ||
508 | help | ||
509 | The RTC driver needs to use one of the General Purpose Backup | ||
510 | Registers (GPBRs) as well as the RTT. You can choose which one | ||
511 | will be used. The default of zero is normally OK to use, but | ||
512 | on some systems other software needs to use that register. | ||
447 | 513 | ||
448 | config RTC_DRV_BFIN | 514 | config RTC_DRV_BFIN |
449 | tristate "Blackfin On-Chip RTC" | 515 | tristate "Blackfin On-Chip RTC" |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 465db4dd50b2..ec703f34ab86 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -19,11 +19,14 @@ rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o | |||
19 | 19 | ||
20 | obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o | 20 | obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o |
21 | obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o | 21 | obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o |
22 | obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o | ||
22 | obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o | 23 | obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o |
23 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o | 24 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o |
24 | 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 | ||
25 | obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o | 27 | obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o |
26 | obj-$(CONFIG_RTC_DRV_DS1374) += rtc-ds1374.o | 28 | obj-$(CONFIG_RTC_DRV_DS1374) += rtc-ds1374.o |
29 | obj-$(CONFIG_RTC_DRV_DS1511) += rtc-ds1511.o | ||
27 | obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o | 30 | obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o |
28 | obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o | 31 | obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o |
29 | obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o | 32 | obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o |
@@ -38,6 +41,7 @@ obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o | |||
38 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o | 41 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o |
39 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o | 42 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o |
40 | obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o | 43 | obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o |
44 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o | ||
41 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o | 45 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o |
42 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o | 46 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o |
43 | obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o | 47 | obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o |
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c new file mode 100644 index 000000000000..bbf10ecf416c --- /dev/null +++ b/drivers/rtc/rtc-at91sam9.c | |||
@@ -0,0 +1,520 @@ | |||
1 | /* | ||
2 | * "RTT as Real Time Clock" driver for AT91SAM9 SoC family | ||
3 | * | ||
4 | * (C) 2007 Michel Benoit | ||
5 | * | ||
6 | * Based on rtc-at91rm9200.c by Rick Bronson | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; either version | ||
11 | * 2 of the License, or (at your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/time.h> | ||
18 | #include <linux/rtc.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/ioctl.h> | ||
21 | |||
22 | #include <asm/mach/time.h> | ||
23 | #include <asm/arch/board.h> | ||
24 | #include <asm/arch/at91_rtt.h> | ||
25 | |||
26 | |||
27 | /* | ||
28 | * This driver uses two configurable hardware resources that live in the | ||
29 | * AT91SAM9 backup power domain (intended to be powered at all times) | ||
30 | * to implement the Real Time Clock interfaces | ||
31 | * | ||
32 | * - A "Real-time Timer" (RTT) counts up in seconds from a base time. | ||
33 | * We can't assign the counter value (CRTV) ... but we can reset it. | ||
34 | * | ||
35 | * - One of the "General Purpose Backup Registers" (GPBRs) holds the | ||
36 | * base time, normally an offset from the beginning of the POSIX | ||
37 | * epoch (1970-Jan-1 00:00:00 UTC). Some systems also include the | ||
38 | * local timezone's offset. | ||
39 | * | ||
40 | * The RTC's value is the RTT counter plus that offset. The RTC's alarm | ||
41 | * is likewise a base (ALMV) plus that offset. | ||
42 | * | ||
43 | * Not all RTTs will be used as RTCs; some systems have multiple RTTs to | ||
44 | * choose from, or a "real" RTC module. All systems have multiple GPBR | ||
45 | * registers available, likewise usable for more than "RTC" support. | ||
46 | */ | ||
47 | |||
48 | /* | ||
49 | * We store ALARM_DISABLED in ALMV to record that no alarm is set. | ||
50 | * It's also the reset value for that field. | ||
51 | */ | ||
52 | #define ALARM_DISABLED ((u32)~0) | ||
53 | |||
54 | |||
55 | struct sam9_rtc { | ||
56 | void __iomem *rtt; | ||
57 | struct rtc_device *rtcdev; | ||
58 | u32 imr; | ||
59 | }; | ||
60 | |||
61 | #define rtt_readl(rtc, field) \ | ||
62 | __raw_readl((rtc)->rtt + AT91_RTT_ ## field) | ||
63 | #define rtt_writel(rtc, field, val) \ | ||
64 | __raw_writel((val), (rtc)->rtt + AT91_RTT_ ## field) | ||
65 | |||
66 | #define gpbr_readl(rtc) \ | ||
67 | at91_sys_read(AT91_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR) | ||
68 | #define gpbr_writel(rtc, val) \ | ||
69 | at91_sys_write(AT91_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR, (val)) | ||
70 | |||
71 | /* | ||
72 | * Read current time and date in RTC | ||
73 | */ | ||
74 | static int at91_rtc_readtime(struct device *dev, struct rtc_time *tm) | ||
75 | { | ||
76 | struct sam9_rtc *rtc = dev_get_drvdata(dev); | ||
77 | u32 secs, secs2; | ||
78 | u32 offset; | ||
79 | |||
80 | /* read current time offset */ | ||
81 | offset = gpbr_readl(rtc); | ||
82 | if (offset == 0) | ||
83 | return -EILSEQ; | ||
84 | |||
85 | /* reread the counter to help sync the two clock domains */ | ||
86 | secs = rtt_readl(rtc, VR); | ||
87 | secs2 = rtt_readl(rtc, VR); | ||
88 | if (secs != secs2) | ||
89 | secs = rtt_readl(rtc, VR); | ||
90 | |||
91 | rtc_time_to_tm(offset + secs, tm); | ||
92 | |||
93 | dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "readtime", | ||
94 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | ||
95 | tm->tm_hour, tm->tm_min, tm->tm_sec); | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | /* | ||
101 | * Set current time and date in RTC | ||
102 | */ | ||
103 | static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) | ||
104 | { | ||
105 | struct sam9_rtc *rtc = dev_get_drvdata(dev); | ||
106 | int err; | ||
107 | u32 offset, alarm, mr; | ||
108 | unsigned long secs; | ||
109 | |||
110 | dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "settime", | ||
111 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | ||
112 | tm->tm_hour, tm->tm_min, tm->tm_sec); | ||
113 | |||
114 | err = rtc_tm_to_time(tm, &secs); | ||
115 | if (err != 0) | ||
116 | return err; | ||
117 | |||
118 | mr = rtt_readl(rtc, MR); | ||
119 | |||
120 | /* disable interrupts */ | ||
121 | rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)); | ||
122 | |||
123 | /* read current time offset */ | ||
124 | offset = gpbr_readl(rtc); | ||
125 | |||
126 | /* store the new base time in a battery backup register */ | ||
127 | secs += 1; | ||
128 | gpbr_writel(rtc, secs); | ||
129 | |||
130 | /* adjust the alarm time for the new base */ | ||
131 | alarm = rtt_readl(rtc, AR); | ||
132 | if (alarm != ALARM_DISABLED) { | ||
133 | if (offset > secs) { | ||
134 | /* time jumped backwards, increase time until alarm */ | ||
135 | alarm += (offset - secs); | ||
136 | } else if ((alarm + offset) > secs) { | ||
137 | /* time jumped forwards, decrease time until alarm */ | ||
138 | alarm -= (secs - offset); | ||
139 | } else { | ||
140 | /* time jumped past the alarm, disable alarm */ | ||
141 | alarm = ALARM_DISABLED; | ||
142 | mr &= ~AT91_RTT_ALMIEN; | ||
143 | } | ||
144 | rtt_writel(rtc, AR, alarm); | ||
145 | } | ||
146 | |||
147 | /* reset the timer, and re-enable interrupts */ | ||
148 | rtt_writel(rtc, MR, mr | AT91_RTT_RTTRST); | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
154 | { | ||
155 | struct sam9_rtc *rtc = dev_get_drvdata(dev); | ||
156 | struct rtc_time *tm = &alrm->time; | ||
157 | u32 alarm = rtt_readl(rtc, AR); | ||
158 | u32 offset; | ||
159 | |||
160 | offset = gpbr_readl(rtc); | ||
161 | if (offset == 0) | ||
162 | return -EILSEQ; | ||
163 | |||
164 | memset(alrm, 0, sizeof(alrm)); | ||
165 | if (alarm != ALARM_DISABLED && offset != 0) { | ||
166 | rtc_time_to_tm(offset + alarm, tm); | ||
167 | |||
168 | dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "readalarm", | ||
169 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | ||
170 | tm->tm_hour, tm->tm_min, tm->tm_sec); | ||
171 | |||
172 | if (rtt_readl(rtc, MR) & AT91_RTT_ALMIEN) | ||
173 | alrm->enabled = 1; | ||
174 | } | ||
175 | |||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
180 | { | ||
181 | struct sam9_rtc *rtc = dev_get_drvdata(dev); | ||
182 | struct rtc_time *tm = &alrm->time; | ||
183 | unsigned long secs; | ||
184 | u32 offset; | ||
185 | u32 mr; | ||
186 | int err; | ||
187 | |||
188 | err = rtc_tm_to_time(tm, &secs); | ||
189 | if (err != 0) | ||
190 | return err; | ||
191 | |||
192 | offset = gpbr_readl(rtc); | ||
193 | if (offset == 0) { | ||
194 | /* time is not set */ | ||
195 | return -EILSEQ; | ||
196 | } | ||
197 | mr = rtt_readl(rtc, MR); | ||
198 | rtt_writel(rtc, MR, mr & ~AT91_RTT_ALMIEN); | ||
199 | |||
200 | /* alarm in the past? finish and leave disabled */ | ||
201 | if (secs <= offset) { | ||
202 | rtt_writel(rtc, AR, ALARM_DISABLED); | ||
203 | return 0; | ||
204 | } | ||
205 | |||
206 | /* else set alarm and maybe enable it */ | ||
207 | rtt_writel(rtc, AR, secs - offset); | ||
208 | if (alrm->enabled) | ||
209 | rtt_writel(rtc, MR, mr | AT91_RTT_ALMIEN); | ||
210 | |||
211 | dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "setalarm", | ||
212 | tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, | ||
213 | tm->tm_min, tm->tm_sec); | ||
214 | |||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | /* | ||
219 | * Handle commands from user-space | ||
220 | */ | ||
221 | static int at91_rtc_ioctl(struct device *dev, unsigned int cmd, | ||
222 | unsigned long arg) | ||
223 | { | ||
224 | struct sam9_rtc *rtc = dev_get_drvdata(dev); | ||
225 | int ret = 0; | ||
226 | u32 mr = rtt_readl(rtc, MR); | ||
227 | |||
228 | dev_dbg(dev, "ioctl: cmd=%08x, arg=%08lx, mr %08x\n", cmd, arg, mr); | ||
229 | |||
230 | switch (cmd) { | ||
231 | case RTC_AIE_OFF: /* alarm off */ | ||
232 | rtt_writel(rtc, MR, mr & ~AT91_RTT_ALMIEN); | ||
233 | break; | ||
234 | case RTC_AIE_ON: /* alarm on */ | ||
235 | rtt_writel(rtc, MR, mr | AT91_RTT_ALMIEN); | ||
236 | break; | ||
237 | case RTC_UIE_OFF: /* update off */ | ||
238 | rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN); | ||
239 | break; | ||
240 | case RTC_UIE_ON: /* update on */ | ||
241 | rtt_writel(rtc, MR, mr | AT91_RTT_RTTINCIEN); | ||
242 | break; | ||
243 | default: | ||
244 | ret = -ENOIOCTLCMD; | ||
245 | break; | ||
246 | } | ||
247 | |||
248 | return ret; | ||
249 | } | ||
250 | |||
251 | /* | ||
252 | * Provide additional RTC information in /proc/driver/rtc | ||
253 | */ | ||
254 | static int at91_rtc_proc(struct device *dev, struct seq_file *seq) | ||
255 | { | ||
256 | struct sam9_rtc *rtc = dev_get_drvdata(dev); | ||
257 | u32 mr = mr = rtt_readl(rtc, MR); | ||
258 | |||
259 | seq_printf(seq, "update_IRQ\t: %s\n", | ||
260 | (mr & AT91_RTT_RTTINCIEN) ? "yes" : "no"); | ||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | /* | ||
265 | * IRQ handler for the RTC | ||
266 | */ | ||
267 | static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc) | ||
268 | { | ||
269 | struct sam9_rtc *rtc = _rtc; | ||
270 | u32 sr, mr; | ||
271 | unsigned long events = 0; | ||
272 | |||
273 | /* Shared interrupt may be for another device. Note: reading | ||
274 | * SR clears it, so we must only read it in this irq handler! | ||
275 | */ | ||
276 | mr = rtt_readl(rtc, MR) & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); | ||
277 | sr = rtt_readl(rtc, SR) & mr; | ||
278 | if (!sr) | ||
279 | return IRQ_NONE; | ||
280 | |||
281 | /* alarm status */ | ||
282 | if (sr & AT91_RTT_ALMS) | ||
283 | events |= (RTC_AF | RTC_IRQF); | ||
284 | |||
285 | /* timer update/increment */ | ||
286 | if (sr & AT91_RTT_RTTINC) | ||
287 | events |= (RTC_UF | RTC_IRQF); | ||
288 | |||
289 | rtc_update_irq(rtc->rtcdev, 1, events); | ||
290 | |||
291 | pr_debug("%s: num=%ld, events=0x%02lx\n", __FUNCTION__, | ||
292 | events >> 8, events & 0x000000FF); | ||
293 | |||
294 | return IRQ_HANDLED; | ||
295 | } | ||
296 | |||
297 | static const struct rtc_class_ops at91_rtc_ops = { | ||
298 | .ioctl = at91_rtc_ioctl, | ||
299 | .read_time = at91_rtc_readtime, | ||
300 | .set_time = at91_rtc_settime, | ||
301 | .read_alarm = at91_rtc_readalarm, | ||
302 | .set_alarm = at91_rtc_setalarm, | ||
303 | .proc = at91_rtc_proc, | ||
304 | }; | ||
305 | |||
306 | /* | ||
307 | * Initialize and install RTC driver | ||
308 | */ | ||
309 | static int __init at91_rtc_probe(struct platform_device *pdev) | ||
310 | { | ||
311 | struct resource *r; | ||
312 | struct sam9_rtc *rtc; | ||
313 | int ret; | ||
314 | u32 mr; | ||
315 | |||
316 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
317 | if (!r) | ||
318 | return -ENODEV; | ||
319 | |||
320 | rtc = kzalloc(sizeof *rtc, GFP_KERNEL); | ||
321 | if (!rtc) | ||
322 | return -ENOMEM; | ||
323 | |||
324 | platform_set_drvdata(pdev, rtc); | ||
325 | rtc->rtt = (void __force __iomem *) (AT91_VA_BASE_SYS - AT91_BASE_SYS); | ||
326 | rtc->rtt += r->start; | ||
327 | |||
328 | mr = rtt_readl(rtc, MR); | ||
329 | |||
330 | /* unless RTT is counting at 1 Hz, re-initialize it */ | ||
331 | if ((mr & AT91_RTT_RTPRES) != AT91_SLOW_CLOCK) { | ||
332 | mr = AT91_RTT_RTTRST | (AT91_SLOW_CLOCK & AT91_RTT_RTPRES); | ||
333 | gpbr_writel(rtc, 0); | ||
334 | } | ||
335 | |||
336 | /* disable all interrupts (same as on shutdown path) */ | ||
337 | mr &= ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); | ||
338 | rtt_writel(rtc, MR, mr); | ||
339 | |||
340 | rtc->rtcdev = rtc_device_register(pdev->name, &pdev->dev, | ||
341 | &at91_rtc_ops, THIS_MODULE); | ||
342 | if (IS_ERR(rtc->rtcdev)) { | ||
343 | ret = PTR_ERR(rtc->rtcdev); | ||
344 | goto fail; | ||
345 | } | ||
346 | |||
347 | /* register irq handler after we know what name we'll use */ | ||
348 | ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt, | ||
349 | IRQF_DISABLED | IRQF_SHARED, | ||
350 | rtc->rtcdev->dev.bus_id, rtc); | ||
351 | if (ret) { | ||
352 | dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS); | ||
353 | rtc_device_unregister(rtc->rtcdev); | ||
354 | goto fail; | ||
355 | } | ||
356 | |||
357 | /* NOTE: sam9260 rev A silicon has a ROM bug which resets the | ||
358 | * RTT on at least some reboots. If you have that chip, you must | ||
359 | * initialize the time from some external source like a GPS, wall | ||
360 | * clock, discrete RTC, etc | ||
361 | */ | ||
362 | |||
363 | if (gpbr_readl(rtc) == 0) | ||
364 | dev_warn(&pdev->dev, "%s: SET TIME!\n", | ||
365 | rtc->rtcdev->dev.bus_id); | ||
366 | |||
367 | return 0; | ||
368 | |||
369 | fail: | ||
370 | platform_set_drvdata(pdev, NULL); | ||
371 | kfree(rtc); | ||
372 | return ret; | ||
373 | } | ||
374 | |||
375 | /* | ||
376 | * Disable and remove the RTC driver | ||
377 | */ | ||
378 | static int __exit at91_rtc_remove(struct platform_device *pdev) | ||
379 | { | ||
380 | struct sam9_rtc *rtc = platform_get_drvdata(pdev); | ||
381 | u32 mr = rtt_readl(rtc, MR); | ||
382 | |||
383 | /* disable all interrupts */ | ||
384 | rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)); | ||
385 | free_irq(AT91_ID_SYS, rtc); | ||
386 | |||
387 | rtc_device_unregister(rtc->rtcdev); | ||
388 | |||
389 | platform_set_drvdata(pdev, NULL); | ||
390 | kfree(rtc); | ||
391 | return 0; | ||
392 | } | ||
393 | |||
394 | static void at91_rtc_shutdown(struct platform_device *pdev) | ||
395 | { | ||
396 | struct sam9_rtc *rtc = platform_get_drvdata(pdev); | ||
397 | u32 mr = rtt_readl(rtc, MR); | ||
398 | |||
399 | rtc->imr = mr & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); | ||
400 | rtt_writel(rtc, MR, mr & ~rtc->imr); | ||
401 | } | ||
402 | |||
403 | #ifdef CONFIG_PM | ||
404 | |||
405 | /* AT91SAM9 RTC Power management control */ | ||
406 | |||
407 | static int at91_rtc_suspend(struct platform_device *pdev, | ||
408 | pm_message_t state) | ||
409 | { | ||
410 | struct sam9_rtc *rtc = platform_get_drvdata(pdev); | ||
411 | u32 mr = rtt_readl(rtc, MR); | ||
412 | |||
413 | /* | ||
414 | * This IRQ is shared with DBGU and other hardware which isn't | ||
415 | * necessarily a wakeup event source. | ||
416 | */ | ||
417 | rtc->imr = mr & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); | ||
418 | if (rtc->imr) { | ||
419 | if (device_may_wakeup(&pdev->dev) && (mr & AT91_RTT_ALMIEN)) { | ||
420 | enable_irq_wake(AT91_ID_SYS); | ||
421 | /* don't let RTTINC cause wakeups */ | ||
422 | if (mr & AT91_RTT_RTTINCIEN) | ||
423 | rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN); | ||
424 | } else | ||
425 | rtt_writel(rtc, MR, mr & ~rtc->imr); | ||
426 | } | ||
427 | |||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | static int at91_rtc_resume(struct platform_device *pdev) | ||
432 | { | ||
433 | struct sam9_rtc *rtc = platform_get_drvdata(pdev); | ||
434 | u32 mr; | ||
435 | |||
436 | if (rtc->imr) { | ||
437 | if (device_may_wakeup(&pdev->dev)) | ||
438 | disable_irq_wake(AT91_ID_SYS); | ||
439 | mr = rtt_readl(rtc, MR); | ||
440 | rtt_writel(rtc, MR, mr | rtc->imr); | ||
441 | } | ||
442 | |||
443 | return 0; | ||
444 | } | ||
445 | #else | ||
446 | #define at91_rtc_suspend NULL | ||
447 | #define at91_rtc_resume NULL | ||
448 | #endif | ||
449 | |||
450 | static struct platform_driver at91_rtc_driver = { | ||
451 | .driver.name = "rtc-at91sam9", | ||
452 | .driver.owner = THIS_MODULE, | ||
453 | .remove = __exit_p(at91_rtc_remove), | ||
454 | .shutdown = at91_rtc_shutdown, | ||
455 | .suspend = at91_rtc_suspend, | ||
456 | .resume = at91_rtc_resume, | ||
457 | }; | ||
458 | |||
459 | /* Chips can have more than one RTT module, and they can be used for more | ||
460 | * than just RTCs. So we can't just register as "the" RTT driver. | ||
461 | * | ||
462 | * A normal approach in such cases is to create a library to allocate and | ||
463 | * free the modules. Here we just use bus_find_device() as like such a | ||
464 | * library, binding directly ... no runtime "library" footprint is needed. | ||
465 | */ | ||
466 | static int __init at91_rtc_match(struct device *dev, void *v) | ||
467 | { | ||
468 | struct platform_device *pdev = to_platform_device(dev); | ||
469 | int ret; | ||
470 | |||
471 | /* continue searching if this isn't the RTT we need */ | ||
472 | if (strcmp("at91_rtt", pdev->name) != 0 | ||
473 | || pdev->id != CONFIG_RTC_DRV_AT91SAM9_RTT) | ||
474 | goto fail; | ||
475 | |||
476 | /* else we found it ... but fail unless we can bind to the RTC driver */ | ||
477 | if (dev->driver) { | ||
478 | dev_dbg(dev, "busy, can't use as RTC!\n"); | ||
479 | goto fail; | ||
480 | } | ||
481 | dev->driver = &at91_rtc_driver.driver; | ||
482 | if (device_attach(dev) == 0) { | ||
483 | dev_dbg(dev, "can't attach RTC!\n"); | ||
484 | goto fail; | ||
485 | } | ||
486 | ret = at91_rtc_probe(pdev); | ||
487 | if (ret == 0) | ||
488 | return true; | ||
489 | |||
490 | dev_dbg(dev, "RTC probe err %d!\n", ret); | ||
491 | fail: | ||
492 | return false; | ||
493 | } | ||
494 | |||
495 | static int __init at91_rtc_init(void) | ||
496 | { | ||
497 | int status; | ||
498 | struct device *rtc; | ||
499 | |||
500 | status = platform_driver_register(&at91_rtc_driver); | ||
501 | if (status) | ||
502 | return status; | ||
503 | rtc = bus_find_device(&platform_bus_type, NULL, | ||
504 | NULL, at91_rtc_match); | ||
505 | if (!rtc) | ||
506 | platform_driver_unregister(&at91_rtc_driver); | ||
507 | return rtc ? 0 : -ENODEV; | ||
508 | } | ||
509 | module_init(at91_rtc_init); | ||
510 | |||
511 | static void __exit at91_rtc_exit(void) | ||
512 | { | ||
513 | platform_driver_unregister(&at91_rtc_driver); | ||
514 | } | ||
515 | module_exit(at91_rtc_exit); | ||
516 | |||
517 | |||
518 | MODULE_AUTHOR("Michel Benoit"); | ||
519 | MODULE_DESCRIPTION("RTC driver for Atmel AT91SAM9x"); | ||
520 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index 1aa709dda0d6..d90ba860d216 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Blackfin On-Chip Real Time Clock Driver | 2 | * Blackfin On-Chip Real Time Clock Driver |
3 | * Supports BF53[123]/BF53[467]/BF54[2489] | 3 | * Supports BF52[257]/BF53[123]/BF53[467]/BF54[24789] |
4 | * | 4 | * |
5 | * Copyright 2004-2007 Analog Devices Inc. | 5 | * Copyright 2004-2007 Analog Devices Inc. |
6 | * | 6 | * |
@@ -32,26 +32,25 @@ | |||
32 | * writes to clear status registers complete immediately. | 32 | * writes to clear status registers complete immediately. |
33 | */ | 33 | */ |
34 | 34 | ||
35 | #include <linux/module.h> | ||
36 | #include <linux/kernel.h> | ||
37 | #include <linux/bcd.h> | 35 | #include <linux/bcd.h> |
38 | #include <linux/rtc.h> | 36 | #include <linux/completion.h> |
37 | #include <linux/delay.h> | ||
39 | #include <linux/init.h> | 38 | #include <linux/init.h> |
39 | #include <linux/interrupt.h> | ||
40 | #include <linux/kernel.h> | ||
41 | #include <linux/module.h> | ||
40 | #include <linux/platform_device.h> | 42 | #include <linux/platform_device.h> |
43 | #include <linux/rtc.h> | ||
41 | #include <linux/seq_file.h> | 44 | #include <linux/seq_file.h> |
42 | #include <linux/interrupt.h> | ||
43 | #include <linux/spinlock.h> | ||
44 | #include <linux/delay.h> | ||
45 | 45 | ||
46 | #include <asm/blackfin.h> | 46 | #include <asm/blackfin.h> |
47 | 47 | ||
48 | #define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __FUNCTION__, __LINE__, ## args) | 48 | #define dev_dbg_stamp(dev) dev_dbg(dev, "%s:%i: here i am\n", __func__, __LINE__) |
49 | #define stampit() stamp("here i am") | ||
50 | 49 | ||
51 | struct bfin_rtc { | 50 | struct bfin_rtc { |
52 | struct rtc_device *rtc_dev; | 51 | struct rtc_device *rtc_dev; |
53 | struct rtc_time rtc_alarm; | 52 | struct rtc_time rtc_alarm; |
54 | spinlock_t lock; | 53 | u16 rtc_wrote_regs; |
55 | }; | 54 | }; |
56 | 55 | ||
57 | /* Bit values for the ISTAT / ICTL registers */ | 56 | /* Bit values for the ISTAT / ICTL registers */ |
@@ -72,7 +71,7 @@ struct bfin_rtc { | |||
72 | #define SEC_BITS_OFF 0 | 71 | #define SEC_BITS_OFF 0 |
73 | 72 | ||
74 | /* Some helper functions to convert between the common RTC notion of time | 73 | /* Some helper functions to convert between the common RTC notion of time |
75 | * and the internal Blackfin notion that is stored in 32bits. | 74 | * and the internal Blackfin notion that is encoded in 32bits. |
76 | */ | 75 | */ |
77 | static inline u32 rtc_time_to_bfin(unsigned long now) | 76 | static inline u32 rtc_time_to_bfin(unsigned long now) |
78 | { | 77 | { |
@@ -97,7 +96,10 @@ static inline void rtc_bfin_to_tm(u32 rtc_bfin, struct rtc_time *tm) | |||
97 | rtc_time_to_tm(rtc_bfin_to_time(rtc_bfin), tm); | 96 | rtc_time_to_tm(rtc_bfin_to_time(rtc_bfin), tm); |
98 | } | 97 | } |
99 | 98 | ||
100 | /* Wait for the previous write to a RTC register to complete. | 99 | /** |
100 | * bfin_rtc_sync_pending - make sure pending writes have complete | ||
101 | * | ||
102 | * Wait for the previous write to a RTC register to complete. | ||
101 | * Unfortunately, we can't sleep here as that introduces a race condition when | 103 | * Unfortunately, we can't sleep here as that introduces a race condition when |
102 | * turning on interrupt events. Consider this: | 104 | * turning on interrupt events. Consider this: |
103 | * - process sets alarm | 105 | * - process sets alarm |
@@ -112,188 +114,202 @@ static inline void rtc_bfin_to_tm(u32 rtc_bfin, struct rtc_time *tm) | |||
112 | * If anyone can point out the obvious solution here, i'm listening :). This | 114 | * If anyone can point out the obvious solution here, i'm listening :). This |
113 | * shouldn't be an issue on an SMP or preempt system as this function should | 115 | * shouldn't be an issue on an SMP or preempt system as this function should |
114 | * only be called with the rtc lock held. | 116 | * only be called with the rtc lock held. |
117 | * | ||
118 | * Other options: | ||
119 | * - disable PREN so the sync happens at 32.768kHZ ... but this changes the | ||
120 | * inc rate for all RTC registers from 1HZ to 32.768kHZ ... | ||
121 | * - use the write complete IRQ | ||
115 | */ | 122 | */ |
116 | static void rtc_bfin_sync_pending(void) | 123 | /* |
124 | static void bfin_rtc_sync_pending_polled(void) | ||
117 | { | 125 | { |
118 | stampit(); | 126 | while (!(bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_COMPLETE)) |
119 | while (!(bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_COMPLETE)) { | ||
120 | if (!(bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_PENDING)) | 127 | if (!(bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_PENDING)) |
121 | break; | 128 | break; |
122 | } | ||
123 | bfin_write_RTC_ISTAT(RTC_ISTAT_WRITE_COMPLETE); | 129 | bfin_write_RTC_ISTAT(RTC_ISTAT_WRITE_COMPLETE); |
124 | } | 130 | } |
131 | */ | ||
132 | static DECLARE_COMPLETION(bfin_write_complete); | ||
133 | static void bfin_rtc_sync_pending(struct device *dev) | ||
134 | { | ||
135 | dev_dbg_stamp(dev); | ||
136 | while (bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_PENDING) | ||
137 | wait_for_completion_timeout(&bfin_write_complete, HZ * 5); | ||
138 | dev_dbg_stamp(dev); | ||
139 | } | ||
125 | 140 | ||
126 | static void rtc_bfin_reset(struct bfin_rtc *rtc) | 141 | /** |
142 | * bfin_rtc_reset - set RTC to sane/known state | ||
143 | * | ||
144 | * Initialize the RTC. Enable pre-scaler to scale RTC clock | ||
145 | * to 1Hz and clear interrupt/status registers. | ||
146 | */ | ||
147 | static void bfin_rtc_reset(struct device *dev) | ||
127 | { | 148 | { |
128 | /* Initialize the RTC. Enable pre-scaler to scale RTC clock | 149 | struct bfin_rtc *rtc = dev_get_drvdata(dev); |
129 | * to 1Hz and clear interrupt/status registers. */ | 150 | dev_dbg_stamp(dev); |
130 | spin_lock_irq(&rtc->lock); | 151 | bfin_rtc_sync_pending(dev); |
131 | rtc_bfin_sync_pending(); | ||
132 | bfin_write_RTC_PREN(0x1); | 152 | bfin_write_RTC_PREN(0x1); |
133 | bfin_write_RTC_ICTL(0); | 153 | bfin_write_RTC_ICTL(RTC_ISTAT_WRITE_COMPLETE); |
134 | bfin_write_RTC_SWCNT(0); | 154 | bfin_write_RTC_SWCNT(0); |
135 | bfin_write_RTC_ALARM(0); | 155 | bfin_write_RTC_ALARM(0); |
136 | bfin_write_RTC_ISTAT(0xFFFF); | 156 | bfin_write_RTC_ISTAT(0xFFFF); |
137 | spin_unlock_irq(&rtc->lock); | 157 | rtc->rtc_wrote_regs = 0; |
138 | } | 158 | } |
139 | 159 | ||
160 | /** | ||
161 | * bfin_rtc_interrupt - handle interrupt from RTC | ||
162 | * | ||
163 | * Since we handle all RTC events here, we have to make sure the requested | ||
164 | * interrupt is enabled (in RTC_ICTL) as the event status register (RTC_ISTAT) | ||
165 | * always gets updated regardless of the interrupt being enabled. So when one | ||
166 | * even we care about (e.g. stopwatch) goes off, we don't want to turn around | ||
167 | * and say that other events have happened as well (e.g. second). We do not | ||
168 | * have to worry about pending writes to the RTC_ICTL register as interrupts | ||
169 | * only fire if they are enabled in the RTC_ICTL register. | ||
170 | */ | ||
140 | static irqreturn_t bfin_rtc_interrupt(int irq, void *dev_id) | 171 | static irqreturn_t bfin_rtc_interrupt(int irq, void *dev_id) |
141 | { | 172 | { |
142 | struct platform_device *pdev = to_platform_device(dev_id); | 173 | struct device *dev = dev_id; |
143 | struct bfin_rtc *rtc = platform_get_drvdata(pdev); | 174 | struct bfin_rtc *rtc = dev_get_drvdata(dev); |
144 | unsigned long events = 0; | 175 | unsigned long events = 0; |
145 | u16 rtc_istat; | 176 | bool write_complete = false; |
146 | 177 | u16 rtc_istat, rtc_ictl; | |
147 | stampit(); | ||
148 | 178 | ||
149 | spin_lock_irq(&rtc->lock); | 179 | dev_dbg_stamp(dev); |
150 | 180 | ||
151 | rtc_istat = bfin_read_RTC_ISTAT(); | 181 | rtc_istat = bfin_read_RTC_ISTAT(); |
182 | rtc_ictl = bfin_read_RTC_ICTL(); | ||
152 | 183 | ||
153 | if (rtc_istat & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)) { | 184 | if (rtc_istat & RTC_ISTAT_WRITE_COMPLETE) { |
154 | bfin_write_RTC_ISTAT(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY); | 185 | bfin_write_RTC_ISTAT(RTC_ISTAT_WRITE_COMPLETE); |
155 | events |= RTC_AF | RTC_IRQF; | 186 | write_complete = true; |
187 | complete(&bfin_write_complete); | ||
156 | } | 188 | } |
157 | 189 | ||
158 | if (rtc_istat & RTC_ISTAT_STOPWATCH) { | 190 | if (rtc_ictl & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)) { |
159 | bfin_write_RTC_ISTAT(RTC_ISTAT_STOPWATCH); | 191 | if (rtc_istat & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)) { |
160 | events |= RTC_PF | RTC_IRQF; | 192 | bfin_write_RTC_ISTAT(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY); |
161 | bfin_write_RTC_SWCNT(rtc->rtc_dev->irq_freq); | 193 | events |= RTC_AF | RTC_IRQF; |
194 | } | ||
162 | } | 195 | } |
163 | 196 | ||
164 | if (rtc_istat & RTC_ISTAT_SEC) { | 197 | if (rtc_ictl & RTC_ISTAT_STOPWATCH) { |
165 | bfin_write_RTC_ISTAT(RTC_ISTAT_SEC); | 198 | if (rtc_istat & RTC_ISTAT_STOPWATCH) { |
166 | events |= RTC_UF | RTC_IRQF; | 199 | bfin_write_RTC_ISTAT(RTC_ISTAT_STOPWATCH); |
200 | events |= RTC_PF | RTC_IRQF; | ||
201 | bfin_write_RTC_SWCNT(rtc->rtc_dev->irq_freq); | ||
202 | } | ||
167 | } | 203 | } |
168 | 204 | ||
169 | rtc_update_irq(rtc->rtc_dev, 1, events); | 205 | if (rtc_ictl & RTC_ISTAT_SEC) { |
206 | if (rtc_istat & RTC_ISTAT_SEC) { | ||
207 | bfin_write_RTC_ISTAT(RTC_ISTAT_SEC); | ||
208 | events |= RTC_UF | RTC_IRQF; | ||
209 | } | ||
210 | } | ||
170 | 211 | ||
171 | spin_unlock_irq(&rtc->lock); | 212 | if (events) |
213 | rtc_update_irq(rtc->rtc_dev, 1, events); | ||
172 | 214 | ||
173 | return IRQ_HANDLED; | 215 | if (write_complete || events) |
216 | return IRQ_HANDLED; | ||
217 | else | ||
218 | return IRQ_NONE; | ||
174 | } | 219 | } |
175 | 220 | ||
176 | static int bfin_rtc_open(struct device *dev) | 221 | static int bfin_rtc_open(struct device *dev) |
177 | { | 222 | { |
178 | struct bfin_rtc *rtc = dev_get_drvdata(dev); | ||
179 | int ret; | 223 | int ret; |
180 | 224 | ||
181 | stampit(); | 225 | dev_dbg_stamp(dev); |
182 | 226 | ||
183 | ret = request_irq(IRQ_RTC, bfin_rtc_interrupt, IRQF_DISABLED, "rtc-bfin", dev); | 227 | ret = request_irq(IRQ_RTC, bfin_rtc_interrupt, IRQF_SHARED, to_platform_device(dev)->name, dev); |
184 | if (unlikely(ret)) { | 228 | if (!ret) |
185 | dev_err(dev, "request RTC IRQ failed with %d\n", ret); | 229 | bfin_rtc_reset(dev); |
186 | return ret; | ||
187 | } | ||
188 | |||
189 | rtc_bfin_reset(rtc); | ||
190 | 230 | ||
191 | return ret; | 231 | return ret; |
192 | } | 232 | } |
193 | 233 | ||
194 | static void bfin_rtc_release(struct device *dev) | 234 | static void bfin_rtc_release(struct device *dev) |
195 | { | 235 | { |
196 | struct bfin_rtc *rtc = dev_get_drvdata(dev); | 236 | dev_dbg_stamp(dev); |
197 | stampit(); | 237 | bfin_rtc_reset(dev); |
198 | rtc_bfin_reset(rtc); | ||
199 | free_irq(IRQ_RTC, dev); | 238 | free_irq(IRQ_RTC, dev); |
200 | } | 239 | } |
201 | 240 | ||
241 | static void bfin_rtc_int_set(struct bfin_rtc *rtc, u16 rtc_int) | ||
242 | { | ||
243 | bfin_write_RTC_ISTAT(rtc_int); | ||
244 | bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() | rtc_int); | ||
245 | } | ||
246 | static void bfin_rtc_int_clear(struct bfin_rtc *rtc, u16 rtc_int) | ||
247 | { | ||
248 | bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() & rtc_int); | ||
249 | } | ||
250 | static void bfin_rtc_int_set_alarm(struct bfin_rtc *rtc) | ||
251 | { | ||
252 | /* Blackfin has different bits for whether the alarm is | ||
253 | * more than 24 hours away. | ||
254 | */ | ||
255 | bfin_rtc_int_set(rtc, (rtc->rtc_alarm.tm_yday == -1 ? RTC_ISTAT_ALARM : RTC_ISTAT_ALARM_DAY)); | ||
256 | } | ||
202 | static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | 257 | static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) |
203 | { | 258 | { |
204 | struct bfin_rtc *rtc = dev_get_drvdata(dev); | 259 | struct bfin_rtc *rtc = dev_get_drvdata(dev); |
260 | int ret = 0; | ||
261 | |||
262 | dev_dbg_stamp(dev); | ||
205 | 263 | ||
206 | stampit(); | 264 | bfin_rtc_sync_pending(dev); |
207 | 265 | ||
208 | switch (cmd) { | 266 | switch (cmd) { |
209 | case RTC_PIE_ON: | 267 | case RTC_PIE_ON: |
210 | stampit(); | 268 | dev_dbg_stamp(dev); |
211 | spin_lock_irq(&rtc->lock); | 269 | bfin_rtc_int_set(rtc, RTC_ISTAT_STOPWATCH); |
212 | rtc_bfin_sync_pending(); | ||
213 | bfin_write_RTC_ISTAT(RTC_ISTAT_STOPWATCH); | ||
214 | bfin_write_RTC_SWCNT(rtc->rtc_dev->irq_freq); | 270 | bfin_write_RTC_SWCNT(rtc->rtc_dev->irq_freq); |
215 | bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() | RTC_ISTAT_STOPWATCH); | 271 | break; |
216 | spin_unlock_irq(&rtc->lock); | ||
217 | return 0; | ||
218 | case RTC_PIE_OFF: | 272 | case RTC_PIE_OFF: |
219 | stampit(); | 273 | dev_dbg_stamp(dev); |
220 | spin_lock_irq(&rtc->lock); | 274 | bfin_rtc_int_clear(rtc, ~RTC_ISTAT_STOPWATCH); |
221 | rtc_bfin_sync_pending(); | 275 | break; |
222 | bfin_write_RTC_SWCNT(0); | ||
223 | bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() & ~RTC_ISTAT_STOPWATCH); | ||
224 | spin_unlock_irq(&rtc->lock); | ||
225 | return 0; | ||
226 | 276 | ||
227 | case RTC_UIE_ON: | 277 | case RTC_UIE_ON: |
228 | stampit(); | 278 | dev_dbg_stamp(dev); |
229 | spin_lock_irq(&rtc->lock); | 279 | bfin_rtc_int_set(rtc, RTC_ISTAT_SEC); |
230 | rtc_bfin_sync_pending(); | 280 | break; |
231 | bfin_write_RTC_ISTAT(RTC_ISTAT_SEC); | ||
232 | bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() | RTC_ISTAT_SEC); | ||
233 | spin_unlock_irq(&rtc->lock); | ||
234 | return 0; | ||
235 | case RTC_UIE_OFF: | 281 | case RTC_UIE_OFF: |
236 | stampit(); | 282 | dev_dbg_stamp(dev); |
237 | spin_lock_irq(&rtc->lock); | 283 | bfin_rtc_int_clear(rtc, ~RTC_ISTAT_SEC); |
238 | rtc_bfin_sync_pending(); | 284 | break; |
239 | bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() & ~RTC_ISTAT_SEC); | 285 | |
240 | spin_unlock_irq(&rtc->lock); | 286 | case RTC_AIE_ON: |
241 | return 0; | 287 | dev_dbg_stamp(dev); |
242 | 288 | bfin_rtc_int_set_alarm(rtc); | |
243 | case RTC_AIE_ON: { | 289 | break; |
244 | unsigned long rtc_alarm; | ||
245 | u16 which_alarm; | ||
246 | int ret = 0; | ||
247 | |||
248 | stampit(); | ||
249 | |||
250 | spin_lock_irq(&rtc->lock); | ||
251 | |||
252 | rtc_bfin_sync_pending(); | ||
253 | if (rtc->rtc_alarm.tm_yday == -1) { | ||
254 | struct rtc_time now; | ||
255 | rtc_bfin_to_tm(bfin_read_RTC_STAT(), &now); | ||
256 | now.tm_sec = rtc->rtc_alarm.tm_sec; | ||
257 | now.tm_min = rtc->rtc_alarm.tm_min; | ||
258 | now.tm_hour = rtc->rtc_alarm.tm_hour; | ||
259 | ret = rtc_tm_to_time(&now, &rtc_alarm); | ||
260 | which_alarm = RTC_ISTAT_ALARM; | ||
261 | } else { | ||
262 | ret = rtc_tm_to_time(&rtc->rtc_alarm, &rtc_alarm); | ||
263 | which_alarm = RTC_ISTAT_ALARM_DAY; | ||
264 | } | ||
265 | if (ret == 0) { | ||
266 | bfin_write_RTC_ISTAT(which_alarm); | ||
267 | bfin_write_RTC_ALARM(rtc_time_to_bfin(rtc_alarm)); | ||
268 | bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() | which_alarm); | ||
269 | } | ||
270 | |||
271 | spin_unlock_irq(&rtc->lock); | ||
272 | |||
273 | return ret; | ||
274 | } | ||
275 | case RTC_AIE_OFF: | 290 | case RTC_AIE_OFF: |
276 | stampit(); | 291 | dev_dbg_stamp(dev); |
277 | spin_lock_irq(&rtc->lock); | 292 | bfin_rtc_int_clear(rtc, ~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)); |
278 | rtc_bfin_sync_pending(); | 293 | break; |
279 | bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() & ~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)); | 294 | |
280 | spin_unlock_irq(&rtc->lock); | 295 | default: |
281 | return 0; | 296 | dev_dbg_stamp(dev); |
297 | ret = -ENOIOCTLCMD; | ||
282 | } | 298 | } |
283 | 299 | ||
284 | return -ENOIOCTLCMD; | 300 | return ret; |
285 | } | 301 | } |
286 | 302 | ||
287 | static int bfin_rtc_read_time(struct device *dev, struct rtc_time *tm) | 303 | static int bfin_rtc_read_time(struct device *dev, struct rtc_time *tm) |
288 | { | 304 | { |
289 | struct bfin_rtc *rtc = dev_get_drvdata(dev); | 305 | struct bfin_rtc *rtc = dev_get_drvdata(dev); |
290 | 306 | ||
291 | stampit(); | 307 | dev_dbg_stamp(dev); |
308 | |||
309 | if (rtc->rtc_wrote_regs & 0x1) | ||
310 | bfin_rtc_sync_pending(dev); | ||
292 | 311 | ||
293 | spin_lock_irq(&rtc->lock); | ||
294 | rtc_bfin_sync_pending(); | ||
295 | rtc_bfin_to_tm(bfin_read_RTC_STAT(), tm); | 312 | rtc_bfin_to_tm(bfin_read_RTC_STAT(), tm); |
296 | spin_unlock_irq(&rtc->lock); | ||
297 | 313 | ||
298 | return 0; | 314 | return 0; |
299 | } | 315 | } |
@@ -304,64 +320,79 @@ static int bfin_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
304 | int ret; | 320 | int ret; |
305 | unsigned long now; | 321 | unsigned long now; |
306 | 322 | ||
307 | stampit(); | 323 | dev_dbg_stamp(dev); |
308 | |||
309 | spin_lock_irq(&rtc->lock); | ||
310 | 324 | ||
311 | ret = rtc_tm_to_time(tm, &now); | 325 | ret = rtc_tm_to_time(tm, &now); |
312 | if (ret == 0) { | 326 | if (ret == 0) { |
313 | rtc_bfin_sync_pending(); | 327 | if (rtc->rtc_wrote_regs & 0x1) |
328 | bfin_rtc_sync_pending(dev); | ||
314 | bfin_write_RTC_STAT(rtc_time_to_bfin(now)); | 329 | bfin_write_RTC_STAT(rtc_time_to_bfin(now)); |
330 | rtc->rtc_wrote_regs = 0x1; | ||
315 | } | 331 | } |
316 | 332 | ||
317 | spin_unlock_irq(&rtc->lock); | ||
318 | |||
319 | return ret; | 333 | return ret; |
320 | } | 334 | } |
321 | 335 | ||
322 | static int bfin_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | 336 | static int bfin_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
323 | { | 337 | { |
324 | struct bfin_rtc *rtc = dev_get_drvdata(dev); | 338 | struct bfin_rtc *rtc = dev_get_drvdata(dev); |
325 | stampit(); | 339 | dev_dbg_stamp(dev); |
326 | memcpy(&alrm->time, &rtc->rtc_alarm, sizeof(struct rtc_time)); | 340 | alrm->time = rtc->rtc_alarm; |
327 | alrm->pending = !!(bfin_read_RTC_ICTL() & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)); | 341 | bfin_rtc_sync_pending(dev); |
342 | alrm->enabled = !!(bfin_read_RTC_ICTL() & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)); | ||
328 | return 0; | 343 | return 0; |
329 | } | 344 | } |
330 | 345 | ||
331 | static int bfin_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | 346 | static int bfin_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
332 | { | 347 | { |
333 | struct bfin_rtc *rtc = dev_get_drvdata(dev); | 348 | struct bfin_rtc *rtc = dev_get_drvdata(dev); |
334 | stampit(); | 349 | unsigned long rtc_alarm; |
335 | memcpy(&rtc->rtc_alarm, &alrm->time, sizeof(struct rtc_time)); | 350 | |
351 | dev_dbg_stamp(dev); | ||
352 | |||
353 | if (rtc_tm_to_time(&alrm->time, &rtc_alarm)) | ||
354 | return -EINVAL; | ||
355 | |||
356 | rtc->rtc_alarm = alrm->time; | ||
357 | |||
358 | bfin_rtc_sync_pending(dev); | ||
359 | bfin_write_RTC_ALARM(rtc_time_to_bfin(rtc_alarm)); | ||
360 | if (alrm->enabled) | ||
361 | bfin_rtc_int_set_alarm(rtc); | ||
362 | |||
336 | return 0; | 363 | return 0; |
337 | } | 364 | } |
338 | 365 | ||
339 | static int bfin_rtc_proc(struct device *dev, struct seq_file *seq) | 366 | static int bfin_rtc_proc(struct device *dev, struct seq_file *seq) |
340 | { | 367 | { |
341 | #define yesno(x) (x ? "yes" : "no") | 368 | #define yesno(x) ((x) ? "yes" : "no") |
342 | u16 ictl = bfin_read_RTC_ICTL(); | 369 | u16 ictl = bfin_read_RTC_ICTL(); |
343 | stampit(); | 370 | dev_dbg_stamp(dev); |
344 | seq_printf(seq, "alarm_IRQ\t: %s\n", yesno(ictl & RTC_ISTAT_ALARM)); | 371 | seq_printf(seq, |
345 | seq_printf(seq, "wkalarm_IRQ\t: %s\n", yesno(ictl & RTC_ISTAT_ALARM_DAY)); | 372 | "alarm_IRQ\t: %s\n" |
346 | seq_printf(seq, "seconds_IRQ\t: %s\n", yesno(ictl & RTC_ISTAT_SEC)); | 373 | "wkalarm_IRQ\t: %s\n" |
347 | seq_printf(seq, "periodic_IRQ\t: %s\n", yesno(ictl & RTC_ISTAT_STOPWATCH)); | 374 | "seconds_IRQ\t: %s\n" |
348 | #ifdef DEBUG | 375 | "periodic_IRQ\t: %s\n", |
349 | seq_printf(seq, "RTC_STAT\t: 0x%08X\n", bfin_read_RTC_STAT()); | 376 | yesno(ictl & RTC_ISTAT_ALARM), |
350 | seq_printf(seq, "RTC_ICTL\t: 0x%04X\n", bfin_read_RTC_ICTL()); | 377 | yesno(ictl & RTC_ISTAT_ALARM_DAY), |
351 | seq_printf(seq, "RTC_ISTAT\t: 0x%04X\n", bfin_read_RTC_ISTAT()); | 378 | yesno(ictl & RTC_ISTAT_SEC), |
352 | seq_printf(seq, "RTC_SWCNT\t: 0x%04X\n", bfin_read_RTC_SWCNT()); | 379 | yesno(ictl & RTC_ISTAT_STOPWATCH)); |
353 | seq_printf(seq, "RTC_ALARM\t: 0x%08X\n", bfin_read_RTC_ALARM()); | ||
354 | seq_printf(seq, "RTC_PREN\t: 0x%04X\n", bfin_read_RTC_PREN()); | ||
355 | #endif | ||
356 | return 0; | 380 | return 0; |
381 | #undef yesno | ||
357 | } | 382 | } |
358 | 383 | ||
384 | /** | ||
385 | * bfin_irq_set_freq - make sure hardware supports requested freq | ||
386 | * @dev: pointer to RTC device structure | ||
387 | * @freq: requested frequency rate | ||
388 | * | ||
389 | * The Blackfin RTC can only generate periodic events at 1 per | ||
390 | * second (1 Hz), so reject any attempt at changing it. | ||
391 | */ | ||
359 | static int bfin_irq_set_freq(struct device *dev, int freq) | 392 | static int bfin_irq_set_freq(struct device *dev, int freq) |
360 | { | 393 | { |
361 | struct bfin_rtc *rtc = dev_get_drvdata(dev); | 394 | dev_dbg_stamp(dev); |
362 | stampit(); | 395 | return -ENOTTY; |
363 | rtc->rtc_dev->irq_freq = freq; | ||
364 | return 0; | ||
365 | } | 396 | } |
366 | 397 | ||
367 | static struct rtc_class_ops bfin_rtc_ops = { | 398 | static struct rtc_class_ops bfin_rtc_ops = { |
@@ -381,27 +412,24 @@ static int __devinit bfin_rtc_probe(struct platform_device *pdev) | |||
381 | struct bfin_rtc *rtc; | 412 | struct bfin_rtc *rtc; |
382 | int ret = 0; | 413 | int ret = 0; |
383 | 414 | ||
384 | stampit(); | 415 | dev_dbg_stamp(&pdev->dev); |
385 | 416 | ||
386 | rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); | 417 | rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); |
387 | if (unlikely(!rtc)) | 418 | if (unlikely(!rtc)) |
388 | return -ENOMEM; | 419 | return -ENOMEM; |
389 | 420 | ||
390 | spin_lock_init(&rtc->lock); | ||
391 | |||
392 | rtc->rtc_dev = rtc_device_register(pdev->name, &pdev->dev, &bfin_rtc_ops, THIS_MODULE); | 421 | rtc->rtc_dev = rtc_device_register(pdev->name, &pdev->dev, &bfin_rtc_ops, THIS_MODULE); |
393 | if (unlikely(IS_ERR(rtc))) { | 422 | if (unlikely(IS_ERR(rtc))) { |
394 | ret = PTR_ERR(rtc->rtc_dev); | 423 | ret = PTR_ERR(rtc->rtc_dev); |
395 | goto err; | 424 | goto err; |
396 | } | 425 | } |
397 | rtc->rtc_dev->irq_freq = 0; | 426 | rtc->rtc_dev->irq_freq = 1; |
398 | rtc->rtc_dev->max_user_freq = (2 << 16); /* stopwatch is an unsigned 16 bit reg */ | ||
399 | 427 | ||
400 | platform_set_drvdata(pdev, rtc); | 428 | platform_set_drvdata(pdev, rtc); |
401 | 429 | ||
402 | return 0; | 430 | return 0; |
403 | 431 | ||
404 | err: | 432 | err: |
405 | kfree(rtc); | 433 | kfree(rtc); |
406 | return ret; | 434 | return ret; |
407 | } | 435 | } |
@@ -428,7 +456,6 @@ static struct platform_driver bfin_rtc_driver = { | |||
428 | 456 | ||
429 | static int __init bfin_rtc_init(void) | 457 | static int __init bfin_rtc_init(void) |
430 | { | 458 | { |
431 | stampit(); | ||
432 | return platform_driver_register(&bfin_rtc_driver); | 459 | return platform_driver_register(&bfin_rtc_driver); |
433 | } | 460 | } |
434 | 461 | ||
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 29cf1457ca10..e059f94c79eb 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -36,9 +36,24 @@ | |||
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 | |||
39 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ | 43 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ |
40 | #include <asm-generic/rtc.h> | 44 | #include <asm-generic/rtc.h> |
41 | 45 | ||
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 | ||
42 | 57 | ||
43 | struct cmos_rtc { | 58 | struct cmos_rtc { |
44 | struct rtc_device *rtc; | 59 | struct rtc_device *rtc; |
@@ -199,6 +214,7 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
199 | sec = t->time.tm_sec; | 214 | sec = t->time.tm_sec; |
200 | sec = (sec < 60) ? BIN2BCD(sec) : 0xff; | 215 | sec = (sec < 60) ? BIN2BCD(sec) : 0xff; |
201 | 216 | ||
217 | hpet_set_alarm_time(t->time.tm_hour, t->time.tm_min, t->time.tm_sec); | ||
202 | spin_lock_irq(&rtc_lock); | 218 | spin_lock_irq(&rtc_lock); |
203 | 219 | ||
204 | /* next rtc irq must not be from previous alarm setting */ | 220 | /* next rtc irq must not be from previous alarm setting */ |
@@ -252,7 +268,8 @@ static int cmos_irq_set_freq(struct device *dev, int freq) | |||
252 | f = 16 - f; | 268 | f = 16 - f; |
253 | 269 | ||
254 | spin_lock_irqsave(&rtc_lock, flags); | 270 | spin_lock_irqsave(&rtc_lock, flags); |
255 | CMOS_WRITE(RTC_REF_CLCK_32KHZ | f, RTC_FREQ_SELECT); | 271 | if (!hpet_set_periodic_freq(freq)) |
272 | CMOS_WRITE(RTC_REF_CLCK_32KHZ | f, RTC_FREQ_SELECT); | ||
256 | spin_unlock_irqrestore(&rtc_lock, flags); | 273 | spin_unlock_irqrestore(&rtc_lock, flags); |
257 | 274 | ||
258 | return 0; | 275 | return 0; |
@@ -314,28 +331,37 @@ cmos_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | |||
314 | switch (cmd) { | 331 | switch (cmd) { |
315 | case RTC_AIE_OFF: /* alarm off */ | 332 | case RTC_AIE_OFF: /* alarm off */ |
316 | rtc_control &= ~RTC_AIE; | 333 | rtc_control &= ~RTC_AIE; |
334 | hpet_mask_rtc_irq_bit(RTC_AIE); | ||
317 | break; | 335 | break; |
318 | case RTC_AIE_ON: /* alarm on */ | 336 | case RTC_AIE_ON: /* alarm on */ |
319 | rtc_control |= RTC_AIE; | 337 | rtc_control |= RTC_AIE; |
338 | hpet_set_rtc_irq_bit(RTC_AIE); | ||
320 | break; | 339 | break; |
321 | case RTC_UIE_OFF: /* update off */ | 340 | case RTC_UIE_OFF: /* update off */ |
322 | rtc_control &= ~RTC_UIE; | 341 | rtc_control &= ~RTC_UIE; |
342 | hpet_mask_rtc_irq_bit(RTC_UIE); | ||
323 | break; | 343 | break; |
324 | case RTC_UIE_ON: /* update on */ | 344 | case RTC_UIE_ON: /* update on */ |
325 | rtc_control |= RTC_UIE; | 345 | rtc_control |= RTC_UIE; |
346 | hpet_set_rtc_irq_bit(RTC_UIE); | ||
326 | break; | 347 | break; |
327 | case RTC_PIE_OFF: /* periodic off */ | 348 | case RTC_PIE_OFF: /* periodic off */ |
328 | rtc_control &= ~RTC_PIE; | 349 | rtc_control &= ~RTC_PIE; |
350 | hpet_mask_rtc_irq_bit(RTC_PIE); | ||
329 | break; | 351 | break; |
330 | case RTC_PIE_ON: /* periodic on */ | 352 | case RTC_PIE_ON: /* periodic on */ |
331 | rtc_control |= RTC_PIE; | 353 | rtc_control |= RTC_PIE; |
354 | hpet_set_rtc_irq_bit(RTC_PIE); | ||
332 | break; | 355 | break; |
333 | } | 356 | } |
334 | CMOS_WRITE(rtc_control, RTC_CONTROL); | 357 | if (!is_hpet_enabled()) |
358 | CMOS_WRITE(rtc_control, RTC_CONTROL); | ||
359 | |||
335 | rtc_intr = CMOS_READ(RTC_INTR_FLAGS); | 360 | rtc_intr = CMOS_READ(RTC_INTR_FLAGS); |
336 | rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; | 361 | rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; |
337 | if (is_intr(rtc_intr)) | 362 | if (is_intr(rtc_intr)) |
338 | rtc_update_irq(cmos->rtc, 1, rtc_intr); | 363 | rtc_update_irq(cmos->rtc, 1, rtc_intr); |
364 | |||
339 | spin_unlock_irqrestore(&rtc_lock, flags); | 365 | spin_unlock_irqrestore(&rtc_lock, flags); |
340 | return 0; | 366 | return 0; |
341 | } | 367 | } |
@@ -393,15 +419,111 @@ static const struct rtc_class_ops cmos_rtc_ops = { | |||
393 | 419 | ||
394 | /*----------------------------------------------------------------*/ | 420 | /*----------------------------------------------------------------*/ |
395 | 421 | ||
422 | /* | ||
423 | * All these chips have at least 64 bytes of address space, shared by | ||
424 | * RTC registers and NVRAM. Most of those bytes of NVRAM are used | ||
425 | * by boot firmware. Modern chips have 128 or 256 bytes. | ||
426 | */ | ||
427 | |||
428 | #define NVRAM_OFFSET (RTC_REG_D + 1) | ||
429 | |||
430 | static ssize_t | ||
431 | cmos_nvram_read(struct kobject *kobj, struct bin_attribute *attr, | ||
432 | char *buf, loff_t off, size_t count) | ||
433 | { | ||
434 | int retval; | ||
435 | |||
436 | if (unlikely(off >= attr->size)) | ||
437 | return 0; | ||
438 | if ((off + count) > attr->size) | ||
439 | count = attr->size - off; | ||
440 | |||
441 | spin_lock_irq(&rtc_lock); | ||
442 | for (retval = 0, off += NVRAM_OFFSET; count--; retval++, off++) | ||
443 | *buf++ = CMOS_READ(off); | ||
444 | spin_unlock_irq(&rtc_lock); | ||
445 | |||
446 | return retval; | ||
447 | } | ||
448 | |||
449 | static ssize_t | ||
450 | cmos_nvram_write(struct kobject *kobj, struct bin_attribute *attr, | ||
451 | char *buf, loff_t off, size_t count) | ||
452 | { | ||
453 | struct cmos_rtc *cmos; | ||
454 | int retval; | ||
455 | |||
456 | cmos = dev_get_drvdata(container_of(kobj, struct device, kobj)); | ||
457 | if (unlikely(off >= attr->size)) | ||
458 | return -EFBIG; | ||
459 | if ((off + count) > attr->size) | ||
460 | count = attr->size - off; | ||
461 | |||
462 | /* NOTE: on at least PCs and Ataris, the boot firmware uses a | ||
463 | * checksum on part of the NVRAM data. That's currently ignored | ||
464 | * here. If userspace is smart enough to know what fields of | ||
465 | * NVRAM to update, updating checksums is also part of its job. | ||
466 | */ | ||
467 | spin_lock_irq(&rtc_lock); | ||
468 | for (retval = 0, off += NVRAM_OFFSET; count--; retval++, off++) { | ||
469 | /* don't trash RTC registers */ | ||
470 | if (off == cmos->day_alrm | ||
471 | || off == cmos->mon_alrm | ||
472 | || off == cmos->century) | ||
473 | buf++; | ||
474 | else | ||
475 | CMOS_WRITE(*buf++, off); | ||
476 | } | ||
477 | spin_unlock_irq(&rtc_lock); | ||
478 | |||
479 | return retval; | ||
480 | } | ||
481 | |||
482 | static struct bin_attribute nvram = { | ||
483 | .attr = { | ||
484 | .name = "nvram", | ||
485 | .mode = S_IRUGO | S_IWUSR, | ||
486 | .owner = THIS_MODULE, | ||
487 | }, | ||
488 | |||
489 | .read = cmos_nvram_read, | ||
490 | .write = cmos_nvram_write, | ||
491 | /* size gets set up later */ | ||
492 | }; | ||
493 | |||
494 | /*----------------------------------------------------------------*/ | ||
495 | |||
396 | static struct cmos_rtc cmos_rtc; | 496 | static struct cmos_rtc cmos_rtc; |
397 | 497 | ||
398 | static irqreturn_t cmos_interrupt(int irq, void *p) | 498 | static irqreturn_t cmos_interrupt(int irq, void *p) |
399 | { | 499 | { |
400 | u8 irqstat; | 500 | u8 irqstat; |
501 | u8 rtc_control; | ||
401 | 502 | ||
402 | spin_lock(&rtc_lock); | 503 | spin_lock(&rtc_lock); |
403 | irqstat = CMOS_READ(RTC_INTR_FLAGS); | 504 | /* |
404 | irqstat &= (CMOS_READ(RTC_CONTROL) & RTC_IRQMASK) | RTC_IRQF; | 505 | * In this case it is HPET RTC interrupt handler |
506 | * calling us, with the interrupt information | ||
507 | * passed as arg1, instead of irq. | ||
508 | */ | ||
509 | if (is_hpet_enabled()) | ||
510 | irqstat = (unsigned long)irq & 0xF0; | ||
511 | else { | ||
512 | irqstat = CMOS_READ(RTC_INTR_FLAGS); | ||
513 | rtc_control = CMOS_READ(RTC_CONTROL); | ||
514 | irqstat &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; | ||
515 | } | ||
516 | |||
517 | /* All Linux RTC alarms should be treated as if they were oneshot. | ||
518 | * Similar code may be needed in system wakeup paths, in case the | ||
519 | * alarm woke the system. | ||
520 | */ | ||
521 | if (irqstat & RTC_AIE) { | ||
522 | rtc_control = CMOS_READ(RTC_CONTROL); | ||
523 | rtc_control &= ~RTC_AIE; | ||
524 | CMOS_WRITE(rtc_control, RTC_CONTROL); | ||
525 | CMOS_READ(RTC_INTR_FLAGS); | ||
526 | } | ||
405 | spin_unlock(&rtc_lock); | 527 | spin_unlock(&rtc_lock); |
406 | 528 | ||
407 | if (is_intr(irqstat)) { | 529 | if (is_intr(irqstat)) { |
@@ -412,11 +534,9 @@ static irqreturn_t cmos_interrupt(int irq, void *p) | |||
412 | } | 534 | } |
413 | 535 | ||
414 | #ifdef CONFIG_PNP | 536 | #ifdef CONFIG_PNP |
415 | #define is_pnp() 1 | ||
416 | #define INITSECTION | 537 | #define INITSECTION |
417 | 538 | ||
418 | #else | 539 | #else |
419 | #define is_pnp() 0 | ||
420 | #define INITSECTION __init | 540 | #define INITSECTION __init |
421 | #endif | 541 | #endif |
422 | 542 | ||
@@ -426,6 +546,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
426 | struct cmos_rtc_board_info *info = dev->platform_data; | 546 | struct cmos_rtc_board_info *info = dev->platform_data; |
427 | int retval = 0; | 547 | int retval = 0; |
428 | unsigned char rtc_control; | 548 | unsigned char rtc_control; |
549 | unsigned address_space; | ||
429 | 550 | ||
430 | /* there can be only one ... */ | 551 | /* there can be only one ... */ |
431 | if (cmos_rtc.dev) | 552 | if (cmos_rtc.dev) |
@@ -450,15 +571,36 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
450 | cmos_rtc.irq = rtc_irq; | 571 | cmos_rtc.irq = rtc_irq; |
451 | cmos_rtc.iomem = ports; | 572 | cmos_rtc.iomem = ports; |
452 | 573 | ||
574 | /* Heuristic to deduce NVRAM size ... do what the legacy NVRAM | ||
575 | * driver did, but don't reject unknown configs. Old hardware | ||
576 | * won't address 128 bytes, and for now we ignore the way newer | ||
577 | * chips can address 256 bytes (using two more i/o ports). | ||
578 | */ | ||
579 | #if defined(CONFIG_ATARI) | ||
580 | address_space = 64; | ||
581 | #elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) | ||
582 | address_space = 128; | ||
583 | #else | ||
584 | #warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes. | ||
585 | address_space = 128; | ||
586 | #endif | ||
587 | |||
453 | /* For ACPI systems extension info comes from the FADT. On others, | 588 | /* For ACPI systems extension info comes from the FADT. On others, |
454 | * board specific setup provides it as appropriate. Systems where | 589 | * board specific setup provides it as appropriate. Systems where |
455 | * the alarm IRQ isn't automatically a wakeup IRQ (like ACPI, and | 590 | * the alarm IRQ isn't automatically a wakeup IRQ (like ACPI, and |
456 | * some almost-clones) can provide hooks to make that behave. | 591 | * some almost-clones) can provide hooks to make that behave. |
592 | * | ||
593 | * Note that ACPI doesn't preclude putting these registers into | ||
594 | * "extended" areas of the chip, including some that we won't yet | ||
595 | * expect CMOS_READ and friends to handle. | ||
457 | */ | 596 | */ |
458 | if (info) { | 597 | if (info) { |
459 | cmos_rtc.day_alrm = info->rtc_day_alarm; | 598 | if (info->rtc_day_alarm && info->rtc_day_alarm < 128) |
460 | cmos_rtc.mon_alrm = info->rtc_mon_alarm; | 599 | cmos_rtc.day_alrm = info->rtc_day_alarm; |
461 | cmos_rtc.century = info->rtc_century; | 600 | if (info->rtc_mon_alarm && info->rtc_mon_alarm < 128) |
601 | cmos_rtc.mon_alrm = info->rtc_mon_alarm; | ||
602 | if (info->rtc_century && info->rtc_century < 128) | ||
603 | cmos_rtc.century = info->rtc_century; | ||
462 | 604 | ||
463 | if (info->wake_on && info->wake_off) { | 605 | if (info->wake_on && info->wake_off) { |
464 | cmos_rtc.wake_on = info->wake_on; | 606 | cmos_rtc.wake_on = info->wake_on; |
@@ -485,8 +627,9 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
485 | * doesn't use 32KHz here ... for portability we might need to | 627 | * doesn't use 32KHz here ... for portability we might need to |
486 | * do something about other clock frequencies. | 628 | * do something about other clock frequencies. |
487 | */ | 629 | */ |
488 | CMOS_WRITE(RTC_REF_CLCK_32KHZ | 0x06, RTC_FREQ_SELECT); | ||
489 | cmos_rtc.rtc->irq_freq = 1024; | 630 | cmos_rtc.rtc->irq_freq = 1024; |
631 | if (!hpet_set_periodic_freq(cmos_rtc.rtc->irq_freq)) | ||
632 | CMOS_WRITE(RTC_REF_CLCK_32KHZ | 0x06, RTC_FREQ_SELECT); | ||
490 | 633 | ||
491 | /* disable irqs. | 634 | /* disable irqs. |
492 | * | 635 | * |
@@ -509,19 +652,39 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
509 | goto cleanup1; | 652 | goto cleanup1; |
510 | } | 653 | } |
511 | 654 | ||
512 | if (is_valid_irq(rtc_irq)) | 655 | if (is_valid_irq(rtc_irq)) { |
513 | retval = request_irq(rtc_irq, cmos_interrupt, IRQF_DISABLED, | 656 | irq_handler_t rtc_cmos_int_handler; |
514 | cmos_rtc.rtc->dev.bus_id, | 657 | |
658 | if (is_hpet_enabled()) { | ||
659 | int err; | ||
660 | |||
661 | rtc_cmos_int_handler = hpet_rtc_interrupt; | ||
662 | err = hpet_register_irq_handler(cmos_interrupt); | ||
663 | if (err != 0) { | ||
664 | printk(KERN_WARNING "hpet_register_irq_handler " | ||
665 | " failed in rtc_init()."); | ||
666 | goto cleanup1; | ||
667 | } | ||
668 | } else | ||
669 | rtc_cmos_int_handler = cmos_interrupt; | ||
670 | |||
671 | retval = request_irq(rtc_irq, rtc_cmos_int_handler, | ||
672 | IRQF_DISABLED, cmos_rtc.rtc->dev.bus_id, | ||
515 | cmos_rtc.rtc); | 673 | cmos_rtc.rtc); |
516 | if (retval < 0) { | 674 | if (retval < 0) { |
517 | dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq); | 675 | dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq); |
518 | goto cleanup1; | 676 | goto cleanup1; |
677 | } | ||
519 | } | 678 | } |
679 | hpet_rtc_timer_init(); | ||
520 | 680 | ||
521 | /* REVISIT optionally make 50 or 114 bytes NVRAM available, | 681 | /* export at least the first block of NVRAM */ |
522 | * like rtc-ds1553, rtc-ds1742 ... this will often include | 682 | nvram.size = address_space - NVRAM_OFFSET; |
523 | * registers for century, and day/month alarm. | 683 | retval = sysfs_create_bin_file(&dev->kobj, &nvram); |
524 | */ | 684 | if (retval < 0) { |
685 | dev_dbg(dev, "can't create nvram file? %d\n", retval); | ||
686 | goto cleanup2; | ||
687 | } | ||
525 | 688 | ||
526 | pr_info("%s: alarms up to one %s%s\n", | 689 | pr_info("%s: alarms up to one %s%s\n", |
527 | cmos_rtc.rtc->dev.bus_id, | 690 | cmos_rtc.rtc->dev.bus_id, |
@@ -536,6 +699,9 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
536 | 699 | ||
537 | return 0; | 700 | return 0; |
538 | 701 | ||
702 | cleanup2: | ||
703 | if (is_valid_irq(rtc_irq)) | ||
704 | free_irq(rtc_irq, cmos_rtc.rtc); | ||
539 | cleanup1: | 705 | cleanup1: |
540 | cmos_rtc.dev = NULL; | 706 | cmos_rtc.dev = NULL; |
541 | rtc_device_unregister(cmos_rtc.rtc); | 707 | rtc_device_unregister(cmos_rtc.rtc); |
@@ -563,8 +729,12 @@ static void __exit cmos_do_remove(struct device *dev) | |||
563 | 729 | ||
564 | cmos_do_shutdown(); | 730 | cmos_do_shutdown(); |
565 | 731 | ||
566 | if (is_valid_irq(cmos->irq)) | 732 | sysfs_remove_bin_file(&dev->kobj, &nvram); |
733 | |||
734 | if (is_valid_irq(cmos->irq)) { | ||
567 | free_irq(cmos->irq, cmos->rtc); | 735 | free_irq(cmos->irq, cmos->rtc); |
736 | hpet_unregister_irq_handler(cmos_interrupt); | ||
737 | } | ||
568 | 738 | ||
569 | rtc_device_unregister(cmos->rtc); | 739 | rtc_device_unregister(cmos->rtc); |
570 | cmos->rtc = NULL; | 740 | cmos->rtc = NULL; |
@@ -659,9 +829,12 @@ static int cmos_resume(struct device *dev) | |||
659 | 829 | ||
660 | /*----------------------------------------------------------------*/ | 830 | /*----------------------------------------------------------------*/ |
661 | 831 | ||
662 | /* The "CMOS" RTC normally lives on the platform_bus. On ACPI systems, | 832 | /* On non-x86 systems, a "CMOS" RTC lives most naturally on platform_bus. |
663 | * the device node will always be created as a PNPACPI device. Plus | 833 | * ACPI systems always list these as PNPACPI devices, and pre-ACPI PCs |
664 | * pre-ACPI PCs probably list it in the PNPBIOS tables. | 834 | * probably list them in similar PNPBIOS tables; so PNP is more common. |
835 | * | ||
836 | * We don't use legacy "poke at the hardware" probing. Ancient PCs that | ||
837 | * predate even PNPBIOS should set up platform_bus devices. | ||
665 | */ | 838 | */ |
666 | 839 | ||
667 | #ifdef CONFIG_PNP | 840 | #ifdef CONFIG_PNP |
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 025c60a17a4a..90dfa0df747a 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c | |||
@@ -246,6 +246,15 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, | |||
246 | /* if the driver does not provide the ioctl interface | 246 | /* if the driver does not provide the ioctl interface |
247 | * or if that particular ioctl was not implemented | 247 | * or if that particular ioctl was not implemented |
248 | * (-ENOIOCTLCMD), we will try to emulate here. | 248 | * (-ENOIOCTLCMD), we will try to emulate here. |
249 | * | ||
250 | * Drivers *SHOULD NOT* provide ioctl implementations | ||
251 | * for these requests. Instead, provide methods to | ||
252 | * support the following code, so that the RTC's main | ||
253 | * features are accessible without using ioctls. | ||
254 | * | ||
255 | * RTC and alarm times will be in UTC, by preference, | ||
256 | * but dual-booting with MS-Windows implies RTCs must | ||
257 | * use the local wall clock time. | ||
249 | */ | 258 | */ |
250 | 259 | ||
251 | switch (cmd) { | 260 | switch (cmd) { |
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c new file mode 100644 index 000000000000..7b002ceeaa7d --- /dev/null +++ b/drivers/rtc/rtc-ds1302.c | |||
@@ -0,0 +1,262 @@ | |||
1 | /* | ||
2 | * Dallas DS1302 RTC Support | ||
3 | * | ||
4 | * Copyright (C) 2002 David McCullough | ||
5 | * Copyright (C) 2003 - 2007 Paul Mundt | ||
6 | * | ||
7 | * This file is subject to the terms and conditions of the GNU General Public | ||
8 | * License version 2. See the file "COPYING" in the main directory of | ||
9 | * this archive for more details. | ||
10 | */ | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/time.h> | ||
16 | #include <linux/rtc.h> | ||
17 | #include <linux/spinlock.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/bcd.h> | ||
20 | #include <asm/rtc.h> | ||
21 | |||
22 | #define DRV_NAME "rtc-ds1302" | ||
23 | #define DRV_VERSION "0.1.0" | ||
24 | |||
25 | #define RTC_CMD_READ 0x81 /* Read command */ | ||
26 | #define RTC_CMD_WRITE 0x80 /* Write command */ | ||
27 | |||
28 | #define RTC_ADDR_RAM0 0x20 /* Address of RAM0 */ | ||
29 | #define RTC_ADDR_TCR 0x08 /* Address of trickle charge register */ | ||
30 | #define RTC_ADDR_YEAR 0x06 /* Address of year register */ | ||
31 | #define RTC_ADDR_DAY 0x05 /* Address of day of week register */ | ||
32 | #define RTC_ADDR_MON 0x04 /* Address of month register */ | ||
33 | #define RTC_ADDR_DATE 0x03 /* Address of day of month register */ | ||
34 | #define RTC_ADDR_HOUR 0x02 /* Address of hour register */ | ||
35 | #define RTC_ADDR_MIN 0x01 /* Address of minute register */ | ||
36 | #define RTC_ADDR_SEC 0x00 /* Address of second register */ | ||
37 | |||
38 | #define RTC_RESET 0x1000 | ||
39 | #define RTC_IODATA 0x0800 | ||
40 | #define RTC_SCLK 0x0400 | ||
41 | |||
42 | #ifdef CONFIG_SH_SECUREEDGE5410 | ||
43 | #include <asm/snapgear.h> | ||
44 | #define set_dp(x) SECUREEDGE_WRITE_IOPORT(x, 0x1c00) | ||
45 | #define get_dp() SECUREEDGE_READ_IOPORT() | ||
46 | #else | ||
47 | #error "Add support for your platform" | ||
48 | #endif | ||
49 | |||
50 | struct ds1302_rtc { | ||
51 | struct rtc_device *rtc_dev; | ||
52 | spinlock_t lock; | ||
53 | }; | ||
54 | |||
55 | static void ds1302_sendbits(unsigned int val) | ||
56 | { | ||
57 | int i; | ||
58 | |||
59 | for (i = 8; (i); i--, val >>= 1) { | ||
60 | set_dp((get_dp() & ~RTC_IODATA) | ((val & 0x1) ? | ||
61 | RTC_IODATA : 0)); | ||
62 | set_dp(get_dp() | RTC_SCLK); /* clock high */ | ||
63 | set_dp(get_dp() & ~RTC_SCLK); /* clock low */ | ||
64 | } | ||
65 | } | ||
66 | |||
67 | static unsigned int ds1302_recvbits(void) | ||
68 | { | ||
69 | unsigned int val; | ||
70 | int i; | ||
71 | |||
72 | for (i = 0, val = 0; (i < 8); i++) { | ||
73 | val |= (((get_dp() & RTC_IODATA) ? 1 : 0) << i); | ||
74 | set_dp(get_dp() | RTC_SCLK); /* clock high */ | ||
75 | set_dp(get_dp() & ~RTC_SCLK); /* clock low */ | ||
76 | } | ||
77 | |||
78 | return val; | ||
79 | } | ||
80 | |||
81 | static unsigned int ds1302_readbyte(unsigned int addr) | ||
82 | { | ||
83 | unsigned int val; | ||
84 | |||
85 | set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); | ||
86 | |||
87 | set_dp(get_dp() | RTC_RESET); | ||
88 | ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_READ); | ||
89 | val = ds1302_recvbits(); | ||
90 | set_dp(get_dp() & ~RTC_RESET); | ||
91 | |||
92 | return val; | ||
93 | } | ||
94 | |||
95 | static void ds1302_writebyte(unsigned int addr, unsigned int val) | ||
96 | { | ||
97 | set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); | ||
98 | set_dp(get_dp() | RTC_RESET); | ||
99 | ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_WRITE); | ||
100 | ds1302_sendbits(val); | ||
101 | set_dp(get_dp() & ~RTC_RESET); | ||
102 | } | ||
103 | |||
104 | static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
105 | { | ||
106 | struct ds1302_rtc *rtc = dev_get_drvdata(dev); | ||
107 | |||
108 | spin_lock_irq(&rtc->lock); | ||
109 | |||
110 | tm->tm_sec = BCD2BIN(ds1302_readbyte(RTC_ADDR_SEC)); | ||
111 | tm->tm_min = BCD2BIN(ds1302_readbyte(RTC_ADDR_MIN)); | ||
112 | tm->tm_hour = BCD2BIN(ds1302_readbyte(RTC_ADDR_HOUR)); | ||
113 | tm->tm_wday = BCD2BIN(ds1302_readbyte(RTC_ADDR_DAY)); | ||
114 | tm->tm_mday = BCD2BIN(ds1302_readbyte(RTC_ADDR_DATE)); | ||
115 | tm->tm_mon = BCD2BIN(ds1302_readbyte(RTC_ADDR_MON)) - 1; | ||
116 | tm->tm_year = BCD2BIN(ds1302_readbyte(RTC_ADDR_YEAR)); | ||
117 | |||
118 | if (tm->tm_year < 70) | ||
119 | tm->tm_year += 100; | ||
120 | |||
121 | spin_unlock_irq(&rtc->lock); | ||
122 | |||
123 | dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, " | ||
124 | "mday=%d, mon=%d, year=%d, wday=%d\n", | ||
125 | __FUNCTION__, | ||
126 | tm->tm_sec, tm->tm_min, tm->tm_hour, | ||
127 | tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday); | ||
128 | |||
129 | if (rtc_valid_tm(tm) < 0) | ||
130 | dev_err(dev, "invalid date\n"); | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
136 | { | ||
137 | struct ds1302_rtc *rtc = dev_get_drvdata(dev); | ||
138 | |||
139 | spin_lock_irq(&rtc->lock); | ||
140 | |||
141 | /* Stop RTC */ | ||
142 | ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80); | ||
143 | |||
144 | ds1302_writebyte(RTC_ADDR_SEC, BIN2BCD(tm->tm_sec)); | ||
145 | ds1302_writebyte(RTC_ADDR_MIN, BIN2BCD(tm->tm_min)); | ||
146 | ds1302_writebyte(RTC_ADDR_HOUR, BIN2BCD(tm->tm_hour)); | ||
147 | ds1302_writebyte(RTC_ADDR_DAY, BIN2BCD(tm->tm_wday)); | ||
148 | ds1302_writebyte(RTC_ADDR_DATE, BIN2BCD(tm->tm_mday)); | ||
149 | ds1302_writebyte(RTC_ADDR_MON, BIN2BCD(tm->tm_mon + 1)); | ||
150 | ds1302_writebyte(RTC_ADDR_YEAR, BIN2BCD(tm->tm_year % 100)); | ||
151 | |||
152 | /* Start RTC */ | ||
153 | ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80); | ||
154 | |||
155 | spin_unlock_irq(&rtc->lock); | ||
156 | |||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | static int ds1302_rtc_ioctl(struct device *dev, unsigned int cmd, | ||
161 | unsigned long arg) | ||
162 | { | ||
163 | switch (cmd) { | ||
164 | #ifdef RTC_SET_CHARGE | ||
165 | case RTC_SET_CHARGE: | ||
166 | { | ||
167 | struct ds1302_rtc *rtc = dev_get_drvdata(dev); | ||
168 | int tcs_val; | ||
169 | |||
170 | if (copy_from_user(&tcs_val, (int __user *)arg, sizeof(int))) | ||
171 | return -EFAULT; | ||
172 | |||
173 | spin_lock_irq(&rtc->lock); | ||
174 | ds1302_writebyte(RTC_ADDR_TCR, (0xa0 | tcs_val * 0xf)); | ||
175 | spin_unlock_irq(&rtc->lock); | ||
176 | return 0; | ||
177 | } | ||
178 | #endif | ||
179 | } | ||
180 | |||
181 | return -ENOIOCTLCMD; | ||
182 | } | ||
183 | |||
184 | static struct rtc_class_ops ds1302_rtc_ops = { | ||
185 | .read_time = ds1302_rtc_read_time, | ||
186 | .set_time = ds1302_rtc_set_time, | ||
187 | .ioctl = ds1302_rtc_ioctl, | ||
188 | }; | ||
189 | |||
190 | static int __devinit ds1302_rtc_probe(struct platform_device *pdev) | ||
191 | { | ||
192 | struct ds1302_rtc *rtc; | ||
193 | int ret; | ||
194 | |||
195 | /* Reset */ | ||
196 | set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); | ||
197 | |||
198 | /* Write a magic value to the DS1302 RAM, and see if it sticks. */ | ||
199 | ds1302_writebyte(RTC_ADDR_RAM0, 0x42); | ||
200 | if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42) | ||
201 | return -ENODEV; | ||
202 | |||
203 | rtc = kzalloc(sizeof(struct ds1302_rtc), GFP_KERNEL); | ||
204 | if (unlikely(!rtc)) | ||
205 | return -ENOMEM; | ||
206 | |||
207 | spin_lock_init(&rtc->lock); | ||
208 | rtc->rtc_dev = rtc_device_register("ds1302", &pdev->dev, | ||
209 | &ds1302_rtc_ops, THIS_MODULE); | ||
210 | if (IS_ERR(rtc->rtc_dev)) { | ||
211 | ret = PTR_ERR(rtc->rtc_dev); | ||
212 | goto out; | ||
213 | } | ||
214 | |||
215 | platform_set_drvdata(pdev, rtc); | ||
216 | |||
217 | return 0; | ||
218 | out: | ||
219 | kfree(rtc); | ||
220 | return ret; | ||
221 | } | ||
222 | |||
223 | static int __devexit ds1302_rtc_remove(struct platform_device *pdev) | ||
224 | { | ||
225 | struct ds1302_rtc *rtc = platform_get_drvdata(pdev); | ||
226 | |||
227 | if (likely(rtc->rtc_dev)) | ||
228 | rtc_device_unregister(rtc->rtc_dev); | ||
229 | |||
230 | platform_set_drvdata(pdev, NULL); | ||
231 | |||
232 | kfree(rtc); | ||
233 | |||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | static struct platform_driver ds1302_platform_driver = { | ||
238 | .driver = { | ||
239 | .name = DRV_NAME, | ||
240 | .owner = THIS_MODULE, | ||
241 | }, | ||
242 | .probe = ds1302_rtc_probe, | ||
243 | .remove = __devexit_p(ds1302_rtc_remove), | ||
244 | }; | ||
245 | |||
246 | static int __init ds1302_rtc_init(void) | ||
247 | { | ||
248 | return platform_driver_register(&ds1302_platform_driver); | ||
249 | } | ||
250 | |||
251 | static void __exit ds1302_rtc_exit(void) | ||
252 | { | ||
253 | platform_driver_unregister(&ds1302_platform_driver); | ||
254 | } | ||
255 | |||
256 | module_init(ds1302_rtc_init); | ||
257 | module_exit(ds1302_rtc_exit); | ||
258 | |||
259 | MODULE_DESCRIPTION("Dallas DS1302 RTC driver"); | ||
260 | MODULE_VERSION(DRV_VERSION); | ||
261 | MODULE_AUTHOR("Paul Mundt, David McCullough"); | ||
262 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index bc1c7fe94ad3..f389a28720d2 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c | |||
@@ -256,7 +256,7 @@ ds1307_nvram_read(struct kobject *kobj, struct bin_attribute *attr, | |||
256 | struct i2c_msg msg[2]; | 256 | struct i2c_msg msg[2]; |
257 | int result; | 257 | int result; |
258 | 258 | ||
259 | client = to_i2c_client(container_of(kobj, struct device, kobj)); | 259 | client = kobj_to_i2c_client(kobj); |
260 | ds1307 = i2c_get_clientdata(client); | 260 | ds1307 = i2c_get_clientdata(client); |
261 | 261 | ||
262 | if (unlikely(off >= NVRAM_SIZE)) | 262 | if (unlikely(off >= NVRAM_SIZE)) |
@@ -294,7 +294,7 @@ ds1307_nvram_write(struct kobject *kobj, struct bin_attribute *attr, | |||
294 | u8 buffer[NVRAM_SIZE + 1]; | 294 | u8 buffer[NVRAM_SIZE + 1]; |
295 | int ret; | 295 | int ret; |
296 | 296 | ||
297 | client = to_i2c_client(container_of(kobj, struct device, kobj)); | 297 | client = kobj_to_i2c_client(kobj); |
298 | 298 | ||
299 | if (unlikely(off >= NVRAM_SIZE)) | 299 | if (unlikely(off >= NVRAM_SIZE)) |
300 | return -EFBIG; | 300 | return -EFBIG; |
@@ -412,11 +412,6 @@ read_rtc: | |||
412 | */ | 412 | */ |
413 | tmp = ds1307->regs[DS1307_REG_SECS]; | 413 | tmp = ds1307->regs[DS1307_REG_SECS]; |
414 | switch (ds1307->type) { | 414 | switch (ds1307->type) { |
415 | case ds_1340: | ||
416 | /* FIXME read register with DS1340_BIT_OSF, use that to | ||
417 | * trigger the "set time" warning (*after* restarting the | ||
418 | * oscillator!) instead of this weaker ds1307/m41t00 test. | ||
419 | */ | ||
420 | case ds_1307: | 415 | case ds_1307: |
421 | case m41t00: | 416 | case m41t00: |
422 | /* clock halted? turn it on, so clock can tick. */ | 417 | /* clock halted? turn it on, so clock can tick. */ |
@@ -440,6 +435,24 @@ read_rtc: | |||
440 | goto read_rtc; | 435 | goto read_rtc; |
441 | } | 436 | } |
442 | break; | 437 | break; |
438 | case ds_1340: | ||
439 | /* clock halted? turn it on, so clock can tick. */ | ||
440 | if (tmp & DS1340_BIT_nEOSC) | ||
441 | i2c_smbus_write_byte_data(client, DS1307_REG_SECS, 0); | ||
442 | |||
443 | tmp = i2c_smbus_read_byte_data(client, DS1340_REG_FLAG); | ||
444 | if (tmp < 0) { | ||
445 | pr_debug("read error %d\n", tmp); | ||
446 | err = -EIO; | ||
447 | goto exit_free; | ||
448 | } | ||
449 | |||
450 | /* oscillator fault? clear flag, and warn */ | ||
451 | if (tmp & DS1340_BIT_OSF) { | ||
452 | i2c_smbus_write_byte_data(client, DS1340_REG_FLAG, 0); | ||
453 | dev_warn(&client->dev, "SET TIME!\n"); | ||
454 | } | ||
455 | break; | ||
443 | case ds_1337: | 456 | case ds_1337: |
444 | case ds_1339: | 457 | case ds_1339: |
445 | break; | 458 | break; |
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c new file mode 100644 index 000000000000..d74b8086fa31 --- /dev/null +++ b/drivers/rtc/rtc-ds1511.c | |||
@@ -0,0 +1,656 @@ | |||
1 | /* | ||
2 | * An rtc driver for the Dallas DS1511 | ||
3 | * | ||
4 | * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp> | ||
5 | * Copyright (C) 2007 Andrew Sharp <andy.sharp@onstor.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * Real time clock driver for the Dallas 1511 chip, which also | ||
12 | * contains a watchdog timer. There is a tiny amount of code that | ||
13 | * platform code could use to mess with the watchdog device a little | ||
14 | * bit, but not a full watchdog driver. | ||
15 | */ | ||
16 | |||
17 | #include <linux/bcd.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/rtc.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/io.h> | ||
25 | |||
26 | #define DRV_VERSION "0.6" | ||
27 | |||
28 | enum ds1511reg { | ||
29 | DS1511_SEC = 0x0, | ||
30 | DS1511_MIN = 0x1, | ||
31 | DS1511_HOUR = 0x2, | ||
32 | DS1511_DOW = 0x3, | ||
33 | DS1511_DOM = 0x4, | ||
34 | DS1511_MONTH = 0x5, | ||
35 | DS1511_YEAR = 0x6, | ||
36 | DS1511_CENTURY = 0x7, | ||
37 | DS1511_AM1_SEC = 0x8, | ||
38 | DS1511_AM2_MIN = 0x9, | ||
39 | DS1511_AM3_HOUR = 0xa, | ||
40 | DS1511_AM4_DATE = 0xb, | ||
41 | DS1511_WD_MSEC = 0xc, | ||
42 | DS1511_WD_SEC = 0xd, | ||
43 | DS1511_CONTROL_A = 0xe, | ||
44 | DS1511_CONTROL_B = 0xf, | ||
45 | DS1511_RAMADDR_LSB = 0x10, | ||
46 | DS1511_RAMDATA = 0x13 | ||
47 | }; | ||
48 | |||
49 | #define DS1511_BLF1 0x80 | ||
50 | #define DS1511_BLF2 0x40 | ||
51 | #define DS1511_PRS 0x20 | ||
52 | #define DS1511_PAB 0x10 | ||
53 | #define DS1511_TDF 0x08 | ||
54 | #define DS1511_KSF 0x04 | ||
55 | #define DS1511_WDF 0x02 | ||
56 | #define DS1511_IRQF 0x01 | ||
57 | #define DS1511_TE 0x80 | ||
58 | #define DS1511_CS 0x40 | ||
59 | #define DS1511_BME 0x20 | ||
60 | #define DS1511_TPE 0x10 | ||
61 | #define DS1511_TIE 0x08 | ||
62 | #define DS1511_KIE 0x04 | ||
63 | #define DS1511_WDE 0x02 | ||
64 | #define DS1511_WDS 0x01 | ||
65 | #define DS1511_RAM_MAX 0xff | ||
66 | |||
67 | #define RTC_CMD DS1511_CONTROL_B | ||
68 | #define RTC_CMD1 DS1511_CONTROL_A | ||
69 | |||
70 | #define RTC_ALARM_SEC DS1511_AM1_SEC | ||
71 | #define RTC_ALARM_MIN DS1511_AM2_MIN | ||
72 | #define RTC_ALARM_HOUR DS1511_AM3_HOUR | ||
73 | #define RTC_ALARM_DATE DS1511_AM4_DATE | ||
74 | |||
75 | #define RTC_SEC DS1511_SEC | ||
76 | #define RTC_MIN DS1511_MIN | ||
77 | #define RTC_HOUR DS1511_HOUR | ||
78 | #define RTC_DOW DS1511_DOW | ||
79 | #define RTC_DOM DS1511_DOM | ||
80 | #define RTC_MON DS1511_MONTH | ||
81 | #define RTC_YEAR DS1511_YEAR | ||
82 | #define RTC_CENTURY DS1511_CENTURY | ||
83 | |||
84 | #define RTC_TIE DS1511_TIE | ||
85 | #define RTC_TE DS1511_TE | ||
86 | |||
87 | struct rtc_plat_data { | ||
88 | struct rtc_device *rtc; | ||
89 | void __iomem *ioaddr; /* virtual base address */ | ||
90 | unsigned long baseaddr; /* physical base address */ | ||
91 | int size; /* amount of memory mapped */ | ||
92 | int irq; | ||
93 | unsigned int irqen; | ||
94 | int alrm_sec; | ||
95 | int alrm_min; | ||
96 | int alrm_hour; | ||
97 | int alrm_mday; | ||
98 | }; | ||
99 | |||
100 | static DEFINE_SPINLOCK(ds1511_lock); | ||
101 | |||
102 | static __iomem char *ds1511_base; | ||
103 | static u32 reg_spacing = 1; | ||
104 | |||
105 | static noinline void | ||
106 | rtc_write(uint8_t val, uint32_t reg) | ||
107 | { | ||
108 | writeb(val, ds1511_base + (reg * reg_spacing)); | ||
109 | } | ||
110 | |||
111 | static inline void | ||
112 | rtc_write_alarm(uint8_t val, enum ds1511reg reg) | ||
113 | { | ||
114 | rtc_write((val | 0x80), reg); | ||
115 | } | ||
116 | |||
117 | static noinline uint8_t | ||
118 | rtc_read(enum ds1511reg reg) | ||
119 | { | ||
120 | return readb(ds1511_base + (reg * reg_spacing)); | ||
121 | } | ||
122 | |||
123 | static inline void | ||
124 | rtc_disable_update(void) | ||
125 | { | ||
126 | rtc_write((rtc_read(RTC_CMD) & ~RTC_TE), RTC_CMD); | ||
127 | } | ||
128 | |||
129 | static void | ||
130 | rtc_enable_update(void) | ||
131 | { | ||
132 | rtc_write((rtc_read(RTC_CMD) | RTC_TE), RTC_CMD); | ||
133 | } | ||
134 | |||
135 | /* | ||
136 | * #define DS1511_WDOG_RESET_SUPPORT | ||
137 | * | ||
138 | * Uncomment this if you want to use these routines in | ||
139 | * some platform code. | ||
140 | */ | ||
141 | #ifdef DS1511_WDOG_RESET_SUPPORT | ||
142 | /* | ||
143 | * just enough code to set the watchdog timer so that it | ||
144 | * will reboot the system | ||
145 | */ | ||
146 | void | ||
147 | ds1511_wdog_set(unsigned long deciseconds) | ||
148 | { | ||
149 | /* | ||
150 | * the wdog timer can take 99.99 seconds | ||
151 | */ | ||
152 | deciseconds %= 10000; | ||
153 | /* | ||
154 | * set the wdog values in the wdog registers | ||
155 | */ | ||
156 | rtc_write(BIN2BCD(deciseconds % 100), DS1511_WD_MSEC); | ||
157 | rtc_write(BIN2BCD(deciseconds / 100), DS1511_WD_SEC); | ||
158 | /* | ||
159 | * set wdog enable and wdog 'steering' bit to issue a reset | ||
160 | */ | ||
161 | rtc_write(DS1511_WDE | DS1511_WDS, RTC_CMD); | ||
162 | } | ||
163 | |||
164 | void | ||
165 | ds1511_wdog_disable(void) | ||
166 | { | ||
167 | /* | ||
168 | * clear wdog enable and wdog 'steering' bits | ||
169 | */ | ||
170 | rtc_write(rtc_read(RTC_CMD) & ~(DS1511_WDE | DS1511_WDS), RTC_CMD); | ||
171 | /* | ||
172 | * clear the wdog counter | ||
173 | */ | ||
174 | rtc_write(0, DS1511_WD_MSEC); | ||
175 | rtc_write(0, DS1511_WD_SEC); | ||
176 | } | ||
177 | #endif | ||
178 | |||
179 | /* | ||
180 | * set the rtc chip's idea of the time. | ||
181 | * stupidly, some callers call with year unmolested; | ||
182 | * and some call with year = year - 1900. thanks. | ||
183 | */ | ||
184 | int | ||
185 | ds1511_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm) | ||
186 | { | ||
187 | u8 mon, day, dow, hrs, min, sec, yrs, cen; | ||
188 | unsigned int flags; | ||
189 | |||
190 | /* | ||
191 | * won't have to change this for a while | ||
192 | */ | ||
193 | if (rtc_tm->tm_year < 1900) { | ||
194 | rtc_tm->tm_year += 1900; | ||
195 | } | ||
196 | |||
197 | if (rtc_tm->tm_year < 1970) { | ||
198 | return -EINVAL; | ||
199 | } | ||
200 | yrs = rtc_tm->tm_year % 100; | ||
201 | cen = rtc_tm->tm_year / 100; | ||
202 | mon = rtc_tm->tm_mon + 1; /* tm_mon starts at zero */ | ||
203 | day = rtc_tm->tm_mday; | ||
204 | dow = rtc_tm->tm_wday & 0x7; /* automatic BCD */ | ||
205 | hrs = rtc_tm->tm_hour; | ||
206 | min = rtc_tm->tm_min; | ||
207 | sec = rtc_tm->tm_sec; | ||
208 | |||
209 | if ((mon > 12) || (day == 0)) { | ||
210 | return -EINVAL; | ||
211 | } | ||
212 | |||
213 | if (day > rtc_month_days(rtc_tm->tm_mon, rtc_tm->tm_year)) { | ||
214 | return -EINVAL; | ||
215 | } | ||
216 | |||
217 | if ((hrs >= 24) || (min >= 60) || (sec >= 60)) { | ||
218 | return -EINVAL; | ||
219 | } | ||
220 | |||
221 | /* | ||
222 | * each register is a different number of valid bits | ||
223 | */ | ||
224 | sec = BIN2BCD(sec) & 0x7f; | ||
225 | min = BIN2BCD(min) & 0x7f; | ||
226 | hrs = BIN2BCD(hrs) & 0x3f; | ||
227 | day = BIN2BCD(day) & 0x3f; | ||
228 | mon = BIN2BCD(mon) & 0x1f; | ||
229 | yrs = BIN2BCD(yrs) & 0xff; | ||
230 | cen = BIN2BCD(cen) & 0xff; | ||
231 | |||
232 | spin_lock_irqsave(&ds1511_lock, flags); | ||
233 | rtc_disable_update(); | ||
234 | rtc_write(cen, RTC_CENTURY); | ||
235 | rtc_write(yrs, RTC_YEAR); | ||
236 | rtc_write((rtc_read(RTC_MON) & 0xe0) | mon, RTC_MON); | ||
237 | rtc_write(day, RTC_DOM); | ||
238 | rtc_write(hrs, RTC_HOUR); | ||
239 | rtc_write(min, RTC_MIN); | ||
240 | rtc_write(sec, RTC_SEC); | ||
241 | rtc_write(dow, RTC_DOW); | ||
242 | rtc_enable_update(); | ||
243 | spin_unlock_irqrestore(&ds1511_lock, flags); | ||
244 | |||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | int | ||
249 | ds1511_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm) | ||
250 | { | ||
251 | unsigned int century; | ||
252 | unsigned int flags; | ||
253 | |||
254 | spin_lock_irqsave(&ds1511_lock, flags); | ||
255 | rtc_disable_update(); | ||
256 | |||
257 | rtc_tm->tm_sec = rtc_read(RTC_SEC) & 0x7f; | ||
258 | rtc_tm->tm_min = rtc_read(RTC_MIN) & 0x7f; | ||
259 | rtc_tm->tm_hour = rtc_read(RTC_HOUR) & 0x3f; | ||
260 | rtc_tm->tm_mday = rtc_read(RTC_DOM) & 0x3f; | ||
261 | rtc_tm->tm_wday = rtc_read(RTC_DOW) & 0x7; | ||
262 | rtc_tm->tm_mon = rtc_read(RTC_MON) & 0x1f; | ||
263 | rtc_tm->tm_year = rtc_read(RTC_YEAR) & 0x7f; | ||
264 | century = rtc_read(RTC_CENTURY); | ||
265 | |||
266 | rtc_enable_update(); | ||
267 | spin_unlock_irqrestore(&ds1511_lock, flags); | ||
268 | |||
269 | rtc_tm->tm_sec = BCD2BIN(rtc_tm->tm_sec); | ||
270 | rtc_tm->tm_min = BCD2BIN(rtc_tm->tm_min); | ||
271 | rtc_tm->tm_hour = BCD2BIN(rtc_tm->tm_hour); | ||
272 | rtc_tm->tm_mday = BCD2BIN(rtc_tm->tm_mday); | ||
273 | rtc_tm->tm_wday = BCD2BIN(rtc_tm->tm_wday); | ||
274 | rtc_tm->tm_mon = BCD2BIN(rtc_tm->tm_mon); | ||
275 | rtc_tm->tm_year = BCD2BIN(rtc_tm->tm_year); | ||
276 | century = BCD2BIN(century) * 100; | ||
277 | |||
278 | /* | ||
279 | * Account for differences between how the RTC uses the values | ||
280 | * and how they are defined in a struct rtc_time; | ||
281 | */ | ||
282 | century += rtc_tm->tm_year; | ||
283 | rtc_tm->tm_year = century - 1900; | ||
284 | |||
285 | rtc_tm->tm_mon--; | ||
286 | |||
287 | if (rtc_valid_tm(rtc_tm) < 0) { | ||
288 | dev_err(dev, "retrieved date/time is not valid.\n"); | ||
289 | rtc_time_to_tm(0, rtc_tm); | ||
290 | } | ||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | /* | ||
295 | * write the alarm register settings | ||
296 | * | ||
297 | * we only have the use to interrupt every second, otherwise | ||
298 | * known as the update interrupt, or the interrupt if the whole | ||
299 | * date/hours/mins/secs matches. the ds1511 has many more | ||
300 | * permutations, but the kernel doesn't. | ||
301 | */ | ||
302 | static void | ||
303 | ds1511_rtc_update_alarm(struct rtc_plat_data *pdata) | ||
304 | { | ||
305 | unsigned long flags; | ||
306 | |||
307 | spin_lock_irqsave(&pdata->rtc->irq_lock, flags); | ||
308 | rtc_write(pdata->alrm_mday < 0 || (pdata->irqen & RTC_UF) ? | ||
309 | 0x80 : BIN2BCD(pdata->alrm_mday) & 0x3f, | ||
310 | RTC_ALARM_DATE); | ||
311 | rtc_write(pdata->alrm_hour < 0 || (pdata->irqen & RTC_UF) ? | ||
312 | 0x80 : BIN2BCD(pdata->alrm_hour) & 0x3f, | ||
313 | RTC_ALARM_HOUR); | ||
314 | rtc_write(pdata->alrm_min < 0 || (pdata->irqen & RTC_UF) ? | ||
315 | 0x80 : BIN2BCD(pdata->alrm_min) & 0x7f, | ||
316 | RTC_ALARM_MIN); | ||
317 | rtc_write(pdata->alrm_sec < 0 || (pdata->irqen & RTC_UF) ? | ||
318 | 0x80 : BIN2BCD(pdata->alrm_sec) & 0x7f, | ||
319 | RTC_ALARM_SEC); | ||
320 | rtc_write(rtc_read(RTC_CMD) | (pdata->irqen ? RTC_TIE : 0), RTC_CMD); | ||
321 | rtc_read(RTC_CMD1); /* clear interrupts */ | ||
322 | spin_unlock_irqrestore(&pdata->rtc->irq_lock, flags); | ||
323 | } | ||
324 | |||
325 | static int | ||
326 | ds1511_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
327 | { | ||
328 | struct platform_device *pdev = to_platform_device(dev); | ||
329 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | ||
330 | |||
331 | if (pdata->irq < 0) { | ||
332 | return -EINVAL; | ||
333 | } | ||
334 | pdata->alrm_mday = alrm->time.tm_mday; | ||
335 | pdata->alrm_hour = alrm->time.tm_hour; | ||
336 | pdata->alrm_min = alrm->time.tm_min; | ||
337 | pdata->alrm_sec = alrm->time.tm_sec; | ||
338 | if (alrm->enabled) { | ||
339 | pdata->irqen |= RTC_AF; | ||
340 | } | ||
341 | ds1511_rtc_update_alarm(pdata); | ||
342 | return 0; | ||
343 | } | ||
344 | |||
345 | static int | ||
346 | ds1511_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
347 | { | ||
348 | struct platform_device *pdev = to_platform_device(dev); | ||
349 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | ||
350 | |||
351 | if (pdata->irq < 0) { | ||
352 | return -EINVAL; | ||
353 | } | ||
354 | alrm->time.tm_mday = pdata->alrm_mday < 0 ? 0 : pdata->alrm_mday; | ||
355 | alrm->time.tm_hour = pdata->alrm_hour < 0 ? 0 : pdata->alrm_hour; | ||
356 | alrm->time.tm_min = pdata->alrm_min < 0 ? 0 : pdata->alrm_min; | ||
357 | alrm->time.tm_sec = pdata->alrm_sec < 0 ? 0 : pdata->alrm_sec; | ||
358 | alrm->enabled = (pdata->irqen & RTC_AF) ? 1 : 0; | ||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | static irqreturn_t | ||
363 | ds1511_interrupt(int irq, void *dev_id) | ||
364 | { | ||
365 | struct platform_device *pdev = dev_id; | ||
366 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | ||
367 | unsigned long events = RTC_IRQF; | ||
368 | |||
369 | /* | ||
370 | * read and clear interrupt | ||
371 | */ | ||
372 | if (!(rtc_read(RTC_CMD1) & DS1511_IRQF)) { | ||
373 | return IRQ_NONE; | ||
374 | } | ||
375 | if (rtc_read(RTC_ALARM_SEC) & 0x80) { | ||
376 | events |= RTC_UF; | ||
377 | } else { | ||
378 | events |= RTC_AF; | ||
379 | } | ||
380 | rtc_update_irq(pdata->rtc, 1, events); | ||
381 | return IRQ_HANDLED; | ||
382 | } | ||
383 | |||
384 | static void | ||
385 | ds1511_rtc_release(struct device *dev) | ||
386 | { | ||
387 | struct platform_device *pdev = to_platform_device(dev); | ||
388 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | ||
389 | |||
390 | if (pdata->irq >= 0) { | ||
391 | pdata->irqen = 0; | ||
392 | ds1511_rtc_update_alarm(pdata); | ||
393 | } | ||
394 | } | ||
395 | |||
396 | static int | ||
397 | ds1511_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | ||
398 | { | ||
399 | struct platform_device *pdev = to_platform_device(dev); | ||
400 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | ||
401 | |||
402 | if (pdata->irq < 0) { | ||
403 | return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */ | ||
404 | } | ||
405 | switch (cmd) { | ||
406 | case RTC_AIE_OFF: | ||
407 | pdata->irqen &= ~RTC_AF; | ||
408 | ds1511_rtc_update_alarm(pdata); | ||
409 | break; | ||
410 | case RTC_AIE_ON: | ||
411 | pdata->irqen |= RTC_AF; | ||
412 | ds1511_rtc_update_alarm(pdata); | ||
413 | break; | ||
414 | case RTC_UIE_OFF: | ||
415 | pdata->irqen &= ~RTC_UF; | ||
416 | ds1511_rtc_update_alarm(pdata); | ||
417 | break; | ||
418 | case RTC_UIE_ON: | ||
419 | pdata->irqen |= RTC_UF; | ||
420 | ds1511_rtc_update_alarm(pdata); | ||
421 | break; | ||
422 | default: | ||
423 | return -ENOIOCTLCMD; | ||
424 | } | ||
425 | return 0; | ||
426 | } | ||
427 | |||
428 | static const struct rtc_class_ops ds1511_rtc_ops = { | ||
429 | .read_time = ds1511_rtc_read_time, | ||
430 | .set_time = ds1511_rtc_set_time, | ||
431 | .read_alarm = ds1511_rtc_read_alarm, | ||
432 | .set_alarm = ds1511_rtc_set_alarm, | ||
433 | .release = ds1511_rtc_release, | ||
434 | .ioctl = ds1511_rtc_ioctl, | ||
435 | }; | ||
436 | |||
437 | static ssize_t | ||
438 | ds1511_nvram_read(struct kobject *kobj, struct bin_attribute *ba, | ||
439 | char *buf, loff_t pos, size_t size) | ||
440 | { | ||
441 | ssize_t count; | ||
442 | |||
443 | /* | ||
444 | * if count is more than one, turn on "burst" mode | ||
445 | * turn it off when you're done | ||
446 | */ | ||
447 | if (size > 1) { | ||
448 | rtc_write((rtc_read(RTC_CMD) | DS1511_BME), RTC_CMD); | ||
449 | } | ||
450 | if (pos > DS1511_RAM_MAX) { | ||
451 | pos = DS1511_RAM_MAX; | ||
452 | } | ||
453 | if (size + pos > DS1511_RAM_MAX + 1) { | ||
454 | size = DS1511_RAM_MAX - pos + 1; | ||
455 | } | ||
456 | rtc_write(pos, DS1511_RAMADDR_LSB); | ||
457 | for (count = 0; size > 0; count++, size--) { | ||
458 | *buf++ = rtc_read(DS1511_RAMDATA); | ||
459 | } | ||
460 | if (count > 1) { | ||
461 | rtc_write((rtc_read(RTC_CMD) & ~DS1511_BME), RTC_CMD); | ||
462 | } | ||
463 | return count; | ||
464 | } | ||
465 | |||
466 | static ssize_t | ||
467 | ds1511_nvram_write(struct kobject *kobj, struct bin_attribute *bin_attr, | ||
468 | char *buf, loff_t pos, size_t size) | ||
469 | { | ||
470 | ssize_t count; | ||
471 | |||
472 | /* | ||
473 | * if count is more than one, turn on "burst" mode | ||
474 | * turn it off when you're done | ||
475 | */ | ||
476 | if (size > 1) { | ||
477 | rtc_write((rtc_read(RTC_CMD) | DS1511_BME), RTC_CMD); | ||
478 | } | ||
479 | if (pos > DS1511_RAM_MAX) { | ||
480 | pos = DS1511_RAM_MAX; | ||
481 | } | ||
482 | if (size + pos > DS1511_RAM_MAX + 1) { | ||
483 | size = DS1511_RAM_MAX - pos + 1; | ||
484 | } | ||
485 | rtc_write(pos, DS1511_RAMADDR_LSB); | ||
486 | for (count = 0; size > 0; count++, size--) { | ||
487 | rtc_write(*buf++, DS1511_RAMDATA); | ||
488 | } | ||
489 | if (count > 1) { | ||
490 | rtc_write((rtc_read(RTC_CMD) & ~DS1511_BME), RTC_CMD); | ||
491 | } | ||
492 | return count; | ||
493 | } | ||
494 | |||
495 | static struct bin_attribute ds1511_nvram_attr = { | ||
496 | .attr = { | ||
497 | .name = "nvram", | ||
498 | .mode = S_IRUGO | S_IWUGO, | ||
499 | .owner = THIS_MODULE, | ||
500 | }, | ||
501 | .size = DS1511_RAM_MAX, | ||
502 | .read = ds1511_nvram_read, | ||
503 | .write = ds1511_nvram_write, | ||
504 | }; | ||
505 | |||
506 | static int __devinit | ||
507 | ds1511_rtc_probe(struct platform_device *pdev) | ||
508 | { | ||
509 | struct rtc_device *rtc; | ||
510 | struct resource *res; | ||
511 | struct rtc_plat_data *pdata = NULL; | ||
512 | int ret = 0; | ||
513 | |||
514 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
515 | if (!res) { | ||
516 | return -ENODEV; | ||
517 | } | ||
518 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); | ||
519 | if (!pdata) { | ||
520 | return -ENOMEM; | ||
521 | } | ||
522 | pdata->irq = -1; | ||
523 | pdata->size = res->end - res->start + 1; | ||
524 | if (!request_mem_region(res->start, pdata->size, pdev->name)) { | ||
525 | ret = -EBUSY; | ||
526 | goto out; | ||
527 | } | ||
528 | pdata->baseaddr = res->start; | ||
529 | pdata->size = pdata->size; | ||
530 | ds1511_base = ioremap(pdata->baseaddr, pdata->size); | ||
531 | if (!ds1511_base) { | ||
532 | ret = -ENOMEM; | ||
533 | goto out; | ||
534 | } | ||
535 | pdata->ioaddr = ds1511_base; | ||
536 | pdata->irq = platform_get_irq(pdev, 0); | ||
537 | |||
538 | /* | ||
539 | * turn on the clock and the crystal, etc. | ||
540 | */ | ||
541 | rtc_write(0, RTC_CMD); | ||
542 | rtc_write(0, RTC_CMD1); | ||
543 | /* | ||
544 | * clear the wdog counter | ||
545 | */ | ||
546 | rtc_write(0, DS1511_WD_MSEC); | ||
547 | rtc_write(0, DS1511_WD_SEC); | ||
548 | /* | ||
549 | * start the clock | ||
550 | */ | ||
551 | rtc_enable_update(); | ||
552 | |||
553 | /* | ||
554 | * check for a dying bat-tree | ||
555 | */ | ||
556 | if (rtc_read(RTC_CMD1) & DS1511_BLF1) { | ||
557 | dev_warn(&pdev->dev, "voltage-low detected.\n"); | ||
558 | } | ||
559 | |||
560 | /* | ||
561 | * if the platform has an interrupt in mind for this device, | ||
562 | * then by all means, set it | ||
563 | */ | ||
564 | if (pdata->irq >= 0) { | ||
565 | rtc_read(RTC_CMD1); | ||
566 | if (request_irq(pdata->irq, ds1511_interrupt, | ||
567 | IRQF_DISABLED | IRQF_SHARED, pdev->name, pdev) < 0) { | ||
568 | |||
569 | dev_warn(&pdev->dev, "interrupt not available.\n"); | ||
570 | pdata->irq = -1; | ||
571 | } | ||
572 | } | ||
573 | |||
574 | rtc = rtc_device_register(pdev->name, &pdev->dev, &ds1511_rtc_ops, | ||
575 | THIS_MODULE); | ||
576 | if (IS_ERR(rtc)) { | ||
577 | ret = PTR_ERR(rtc); | ||
578 | goto out; | ||
579 | } | ||
580 | pdata->rtc = rtc; | ||
581 | platform_set_drvdata(pdev, pdata); | ||
582 | ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr); | ||
583 | if (ret) { | ||
584 | goto out; | ||
585 | } | ||
586 | return 0; | ||
587 | out: | ||
588 | if (pdata->rtc) { | ||
589 | rtc_device_unregister(pdata->rtc); | ||
590 | } | ||
591 | if (pdata->irq >= 0) { | ||
592 | free_irq(pdata->irq, pdev); | ||
593 | } | ||
594 | if (ds1511_base) { | ||
595 | iounmap(ds1511_base); | ||
596 | ds1511_base = NULL; | ||
597 | } | ||
598 | if (pdata->baseaddr) { | ||
599 | release_mem_region(pdata->baseaddr, pdata->size); | ||
600 | } | ||
601 | |||
602 | kfree(pdata); | ||
603 | return ret; | ||
604 | } | ||
605 | |||
606 | static int __devexit | ||
607 | ds1511_rtc_remove(struct platform_device *pdev) | ||
608 | { | ||
609 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | ||
610 | |||
611 | sysfs_remove_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr); | ||
612 | rtc_device_unregister(pdata->rtc); | ||
613 | pdata->rtc = NULL; | ||
614 | if (pdata->irq >= 0) { | ||
615 | /* | ||
616 | * disable the alarm interrupt | ||
617 | */ | ||
618 | rtc_write(rtc_read(RTC_CMD) & ~RTC_TIE, RTC_CMD); | ||
619 | rtc_read(RTC_CMD1); | ||
620 | free_irq(pdata->irq, pdev); | ||
621 | } | ||
622 | iounmap(pdata->ioaddr); | ||
623 | ds1511_base = NULL; | ||
624 | release_mem_region(pdata->baseaddr, pdata->size); | ||
625 | kfree(pdata); | ||
626 | return 0; | ||
627 | } | ||
628 | |||
629 | static struct platform_driver ds1511_rtc_driver = { | ||
630 | .probe = ds1511_rtc_probe, | ||
631 | .remove = __devexit_p(ds1511_rtc_remove), | ||
632 | .driver = { | ||
633 | .name = "ds1511", | ||
634 | .owner = THIS_MODULE, | ||
635 | }, | ||
636 | }; | ||
637 | |||
638 | static int __init | ||
639 | ds1511_rtc_init(void) | ||
640 | { | ||
641 | return platform_driver_register(&ds1511_rtc_driver); | ||
642 | } | ||
643 | |||
644 | static void __exit | ||
645 | ds1511_rtc_exit(void) | ||
646 | { | ||
647 | return platform_driver_unregister(&ds1511_rtc_driver); | ||
648 | } | ||
649 | |||
650 | module_init(ds1511_rtc_init); | ||
651 | module_exit(ds1511_rtc_exit); | ||
652 | |||
653 | MODULE_AUTHOR("Andrew Sharp <andy.sharp@onstor.com>"); | ||
654 | MODULE_DESCRIPTION("Dallas DS1511 RTC driver"); | ||
655 | MODULE_LICENSE("GPL"); | ||
656 | MODULE_VERSION(DRV_VERSION); | ||
diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c index c973ba94c422..8b3997007506 100644 --- a/drivers/rtc/rtc-pcf8583.c +++ b/drivers/rtc/rtc-pcf8583.c | |||
@@ -163,27 +163,17 @@ static int pcf8583_read_mem(struct i2c_client *client, struct rtc_mem *mem) | |||
163 | 163 | ||
164 | static int pcf8583_write_mem(struct i2c_client *client, struct rtc_mem *mem) | 164 | static int pcf8583_write_mem(struct i2c_client *client, struct rtc_mem *mem) |
165 | { | 165 | { |
166 | unsigned char addr[1]; | 166 | unsigned char buf[9]; |
167 | struct i2c_msg msgs[2] = { | 167 | int ret; |
168 | { | ||
169 | .addr = client->addr, | ||
170 | .flags = 0, | ||
171 | .len = 1, | ||
172 | .buf = addr, | ||
173 | }, { | ||
174 | .addr = client->addr, | ||
175 | .flags = I2C_M_NOSTART, | ||
176 | .len = mem->nr, | ||
177 | .buf = mem->data, | ||
178 | } | ||
179 | }; | ||
180 | 168 | ||
181 | if (mem->loc < 8) | 169 | if (mem->loc < 8 || mem->nr > 8) |
182 | return -EINVAL; | 170 | return -EINVAL; |
183 | 171 | ||
184 | addr[0] = mem->loc; | 172 | buf[0] = mem->loc; |
173 | memcpy(buf + 1, mem->data, mem->nr); | ||
185 | 174 | ||
186 | return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO; | 175 | ret = i2c_master_send(client, buf, mem->nr + 1); |
176 | return ret == mem->nr + 1 ? 0 : -EIO; | ||
187 | } | 177 | } |
188 | 178 | ||
189 | static int pcf8583_rtc_read_time(struct device *dev, struct rtc_time *tm) | 179 | static int pcf8583_rtc_read_time(struct device *dev, struct rtc_time *tm) |
diff --git a/drivers/rtc/rtc-r9701.c b/drivers/rtc/rtc-r9701.c new file mode 100644 index 000000000000..a64626a82d0b --- /dev/null +++ b/drivers/rtc/rtc-r9701.c | |||
@@ -0,0 +1,178 @@ | |||
1 | /* | ||
2 | * Driver for Epson RTC-9701JE | ||
3 | * | ||
4 | * Copyright (C) 2008 Magnus Damm | ||
5 | * | ||
6 | * Based on rtc-max6902.c | ||
7 | * | ||
8 | * Copyright (C) 2006 8D Technologies inc. | ||
9 | * Copyright (C) 2004 Compulab Ltd. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #include <linux/module.h> | ||
17 | #include <linux/version.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/device.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/rtc.h> | ||
23 | #include <linux/spi/spi.h> | ||
24 | #include <linux/bcd.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/bitops.h> | ||
27 | |||
28 | #define RSECCNT 0x00 /* Second Counter */ | ||
29 | #define RMINCNT 0x01 /* Minute Counter */ | ||
30 | #define RHRCNT 0x02 /* Hour Counter */ | ||
31 | #define RWKCNT 0x03 /* Week Counter */ | ||
32 | #define RDAYCNT 0x04 /* Day Counter */ | ||
33 | #define RMONCNT 0x05 /* Month Counter */ | ||
34 | #define RYRCNT 0x06 /* Year Counter */ | ||
35 | #define R100CNT 0x07 /* Y100 Counter */ | ||
36 | #define RMINAR 0x08 /* Minute Alarm */ | ||
37 | #define RHRAR 0x09 /* Hour Alarm */ | ||
38 | #define RWKAR 0x0a /* Week/Day Alarm */ | ||
39 | #define RTIMCNT 0x0c /* Interval Timer */ | ||
40 | #define REXT 0x0d /* Extension Register */ | ||
41 | #define RFLAG 0x0e /* RTC Flag Register */ | ||
42 | #define RCR 0x0f /* RTC Control Register */ | ||
43 | |||
44 | static int write_reg(struct device *dev, int address, unsigned char data) | ||
45 | { | ||
46 | struct spi_device *spi = to_spi_device(dev); | ||
47 | unsigned char buf[2]; | ||
48 | |||
49 | buf[0] = address & 0x7f; | ||
50 | buf[1] = data; | ||
51 | |||
52 | return spi_write(spi, buf, ARRAY_SIZE(buf)); | ||
53 | } | ||
54 | |||
55 | static int read_regs(struct device *dev, unsigned char *regs, int no_regs) | ||
56 | { | ||
57 | struct spi_device *spi = to_spi_device(dev); | ||
58 | u8 txbuf[1], rxbuf[1]; | ||
59 | int k, ret; | ||
60 | |||
61 | ret = 0; | ||
62 | |||
63 | for (k = 0; ret == 0 && k < no_regs; k++) { | ||
64 | txbuf[0] = 0x80 | regs[k]; | ||
65 | ret = spi_write_then_read(spi, txbuf, 1, rxbuf, 1); | ||
66 | regs[k] = rxbuf[0]; | ||
67 | } | ||
68 | |||
69 | return ret; | ||
70 | } | ||
71 | |||
72 | static int r9701_get_datetime(struct device *dev, struct rtc_time *dt) | ||
73 | { | ||
74 | unsigned long time; | ||
75 | int ret; | ||
76 | unsigned char buf[] = { RSECCNT, RMINCNT, RHRCNT, | ||
77 | RDAYCNT, RMONCNT, RYRCNT }; | ||
78 | |||
79 | ret = read_regs(dev, buf, ARRAY_SIZE(buf)); | ||
80 | if (ret) | ||
81 | return ret; | ||
82 | |||
83 | memset(dt, 0, sizeof(*dt)); | ||
84 | |||
85 | dt->tm_sec = BCD2BIN(buf[0]); /* RSECCNT */ | ||
86 | dt->tm_min = BCD2BIN(buf[1]); /* RMINCNT */ | ||
87 | dt->tm_hour = BCD2BIN(buf[2]); /* RHRCNT */ | ||
88 | |||
89 | dt->tm_mday = BCD2BIN(buf[3]); /* RDAYCNT */ | ||
90 | dt->tm_mon = BCD2BIN(buf[4]) - 1; /* RMONCNT */ | ||
91 | dt->tm_year = BCD2BIN(buf[5]) + 100; /* RYRCNT */ | ||
92 | |||
93 | /* the rtc device may contain illegal values on power up | ||
94 | * according to the data sheet. make sure they are valid. | ||
95 | */ | ||
96 | |||
97 | return rtc_valid_tm(dt); | ||
98 | } | ||
99 | |||
100 | static int r9701_set_datetime(struct device *dev, struct rtc_time *dt) | ||
101 | { | ||
102 | int ret, year; | ||
103 | |||
104 | year = dt->tm_year + 1900; | ||
105 | if (year >= 2100 || year < 2000) | ||
106 | return -EINVAL; | ||
107 | |||
108 | ret = write_reg(dev, RHRCNT, BIN2BCD(dt->tm_hour)); | ||
109 | ret = ret ? ret : write_reg(dev, RMINCNT, BIN2BCD(dt->tm_min)); | ||
110 | ret = ret ? ret : write_reg(dev, RSECCNT, BIN2BCD(dt->tm_sec)); | ||
111 | ret = ret ? ret : write_reg(dev, RDAYCNT, BIN2BCD(dt->tm_mday)); | ||
112 | ret = ret ? ret : write_reg(dev, RMONCNT, BIN2BCD(dt->tm_mon + 1)); | ||
113 | ret = ret ? ret : write_reg(dev, RYRCNT, BIN2BCD(dt->tm_year - 100)); | ||
114 | ret = ret ? ret : write_reg(dev, RWKCNT, 1 << dt->tm_wday); | ||
115 | |||
116 | return ret; | ||
117 | } | ||
118 | |||
119 | static const struct rtc_class_ops r9701_rtc_ops = { | ||
120 | .read_time = r9701_get_datetime, | ||
121 | .set_time = r9701_set_datetime, | ||
122 | }; | ||
123 | |||
124 | static int __devinit r9701_probe(struct spi_device *spi) | ||
125 | { | ||
126 | struct rtc_device *rtc; | ||
127 | unsigned char tmp; | ||
128 | int res; | ||
129 | |||
130 | rtc = rtc_device_register("r9701", | ||
131 | &spi->dev, &r9701_rtc_ops, THIS_MODULE); | ||
132 | if (IS_ERR(rtc)) | ||
133 | return PTR_ERR(rtc); | ||
134 | |||
135 | dev_set_drvdata(&spi->dev, rtc); | ||
136 | |||
137 | tmp = R100CNT; | ||
138 | res = read_regs(&spi->dev, &tmp, 1); | ||
139 | if (res || tmp != 0x20) { | ||
140 | rtc_device_unregister(rtc); | ||
141 | return res; | ||
142 | } | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | static int __devexit r9701_remove(struct spi_device *spi) | ||
148 | { | ||
149 | struct rtc_device *rtc = dev_get_drvdata(&spi->dev); | ||
150 | |||
151 | rtc_device_unregister(rtc); | ||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | static struct spi_driver r9701_driver = { | ||
156 | .driver = { | ||
157 | .name = "rtc-r9701", | ||
158 | .owner = THIS_MODULE, | ||
159 | }, | ||
160 | .probe = r9701_probe, | ||
161 | .remove = __devexit_p(r9701_remove), | ||
162 | }; | ||
163 | |||
164 | static __init int r9701_init(void) | ||
165 | { | ||
166 | return spi_register_driver(&r9701_driver); | ||
167 | } | ||
168 | module_init(r9701_init); | ||
169 | |||
170 | static __exit void r9701_exit(void) | ||
171 | { | ||
172 | spi_unregister_driver(&r9701_driver); | ||
173 | } | ||
174 | module_exit(r9701_exit); | ||
175 | |||
176 | MODULE_DESCRIPTION("r9701 spi RTC driver"); | ||
177 | MODULE_AUTHOR("Magnus Damm <damm@opensource.se>"); | ||
178 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index e2041b4d0c85..86766f1f2496 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/rtc.h> | 20 | #include <linux/rtc.h> |
21 | #include <linux/bcd.h> | 21 | #include <linux/bcd.h> |
22 | #include <linux/clk.h> | 22 | #include <linux/clk.h> |
23 | #include <linux/log2.h> | ||
23 | 24 | ||
24 | #include <asm/hardware.h> | 25 | #include <asm/hardware.h> |
25 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
@@ -309,9 +310,7 @@ static int s3c_rtc_ioctl(struct device *dev, | |||
309 | break; | 310 | break; |
310 | 311 | ||
311 | case RTC_IRQP_SET: | 312 | case RTC_IRQP_SET: |
312 | /* check for power of 2 */ | 313 | if (!is_power_of_2(arg)) { |
313 | |||
314 | if ((arg & (arg-1)) != 0 || arg < 1) { | ||
315 | ret = -EINVAL; | 314 | ret = -EINVAL; |
316 | goto exit; | 315 | goto exit; |
317 | } | 316 | } |
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index 2eb38520f0c8..ee253cc45de1 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c | |||
@@ -357,23 +357,15 @@ static int sa1100_rtc_remove(struct platform_device *pdev) | |||
357 | #ifdef CONFIG_PM | 357 | #ifdef CONFIG_PM |
358 | static int sa1100_rtc_suspend(struct platform_device *pdev, pm_message_t state) | 358 | static int sa1100_rtc_suspend(struct platform_device *pdev, pm_message_t state) |
359 | { | 359 | { |
360 | if (pdev->dev.power.power_state.event != state.event) { | 360 | if (device_may_wakeup(&pdev->dev)) |
361 | if (state.event == PM_EVENT_SUSPEND && | 361 | enable_irq_wake(IRQ_RTCAlrm); |
362 | device_may_wakeup(&pdev->dev)) | ||
363 | enable_irq_wake(IRQ_RTCAlrm); | ||
364 | |||
365 | pdev->dev.power.power_state = state; | ||
366 | } | ||
367 | return 0; | 362 | return 0; |
368 | } | 363 | } |
369 | 364 | ||
370 | static int sa1100_rtc_resume(struct platform_device *pdev) | 365 | static int sa1100_rtc_resume(struct platform_device *pdev) |
371 | { | 366 | { |
372 | if (pdev->dev.power.power_state.event != PM_EVENT_ON) { | 367 | if (device_may_wakeup(&pdev->dev)) |
373 | if (device_may_wakeup(&pdev->dev)) | 368 | disable_irq_wake(IRQ_RTCAlrm); |
374 | disable_irq_wake(IRQ_RTCAlrm); | ||
375 | pdev->dev.power.power_state = PMSG_ON; | ||
376 | } | ||
377 | return 0; | 369 | return 0; |
378 | } | 370 | } |
379 | #else | 371 | #else |
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c index 2ae0e8304d3a..4d27ccc4fc06 100644 --- a/drivers/rtc/rtc-sysfs.c +++ b/drivers/rtc/rtc-sysfs.c | |||
@@ -17,6 +17,13 @@ | |||
17 | 17 | ||
18 | /* device attributes */ | 18 | /* device attributes */ |
19 | 19 | ||
20 | /* | ||
21 | * NOTE: RTC times displayed in sysfs use the RTC's timezone. That's | ||
22 | * ideally UTC. However, PCs that also boot to MS-Windows normally use | ||
23 | * the local time and change to match daylight savings time. That affects | ||
24 | * attributes including date, time, since_epoch, and wakealarm. | ||
25 | */ | ||
26 | |||
20 | static ssize_t | 27 | static ssize_t |
21 | rtc_sysfs_show_name(struct device *dev, struct device_attribute *attr, | 28 | rtc_sysfs_show_name(struct device *dev, struct device_attribute *attr, |
22 | char *buf) | 29 | char *buf) |
@@ -113,13 +120,13 @@ rtc_sysfs_show_wakealarm(struct device *dev, struct device_attribute *attr, | |||
113 | unsigned long alarm; | 120 | unsigned long alarm; |
114 | struct rtc_wkalrm alm; | 121 | struct rtc_wkalrm alm; |
115 | 122 | ||
116 | /* Don't show disabled alarms; but the RTC could leave the | 123 | /* Don't show disabled alarms. For uniformity, RTC alarms are |
117 | * alarm enabled after it's already triggered. Alarms are | 124 | * conceptually one-shot, even though some common RTCs (on PCs) |
118 | * conceptually one-shot, even though some common hardware | 125 | * don't actually work that way. |
119 | * (PCs) doesn't actually work that way. | ||
120 | * | 126 | * |
121 | * REVISIT maybe we should require RTC implementations to | 127 | * NOTE: RTC implementations where the alarm doesn't match an |
122 | * disable the RTC alarm after it triggers, for uniformity. | 128 | * exact YYYY-MM-DD HH:MM[:SS] date *must* disable their RTC |
129 | * alarms after they trigger, to ensure one-shot semantics. | ||
123 | */ | 130 | */ |
124 | retval = rtc_read_alarm(to_rtc_device(dev), &alm); | 131 | retval = rtc_read_alarm(to_rtc_device(dev), &alm); |
125 | if (retval == 0 && alm.enabled) { | 132 | if (retval == 0 && alm.enabled) { |