diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-05 09:48:22 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-05 09:48:22 -0400 |
commit | 6c84239d595dc6ffe39f0f03dae2f64ed200db95 (patch) | |
tree | 3aea4368a644be16e44612c964aa26152854e1ae | |
parent | d4c06c708123c652025d04fe77b7e39448077395 (diff) | |
parent | 6f367788d6333a41fefd013975b0b160d5c0a1c8 (diff) |
Merge tag 'rtc-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
Pull RTC updates from Alexandre Belloni:
"RTC for 4.8
Cleanups:
- huge cleanup of rtc-generic and char/genrtc this allowed to cleanup
rtc-cmos, rtc-sh, rtc-m68k, rtc-powerpc and rtc-parisc
- move mn10300 to rtc-cmos
Subsystem:
- fix wakealarms after hibernate
- multiples fixes for rctest
- simplify implementations of .read_alarm
New drivers:
- Maxim MAX6916
Drivers:
- ds1307: fix weekday
- m41t80: add wakeup support
- pcf85063: add support for PCF85063A variant
- rv8803: extend i2c fix and other fixes
- s35390a: fix alarm reading, this fixes instant reboot after
shutdown for QNAP TS-41x
- s3c: clock fixes"
* tag 'rtc-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (65 commits)
rtc: rv8803: Clear V1F when setting the time
rtc: rv8803: Stop the clock while setting the time
rtc: rv8803: Always apply the I²C workaround
rtc: rv8803: Fix read day of week
rtc: rv8803: Remove the check for valid time
rtc: rv8803: Kconfig: Indicate rx8900 support
rtc: asm9260: remove .owner field for driver
rtc: at91sam9: Fix missing spin_lock_init()
rtc: m41t80: add suspend handlers for alarm IRQ
rtc: m41t80: make it a real error message
rtc: pcf85063: Add support for the PCF85063A device
rtc: pcf85063: fix year range
rtc: hym8563: in .read_alarm set .tm_sec to 0 to signal minute accuracy
rtc: explicitly set tm_sec = 0 for drivers with minute accurancy
rtc: s3c: Add s3c_rtc_{enable/disable}_clk in s3c_rtc_setfreq()
rtc: s3c: Remove unnecessary call to disable already disabled clock
rtc: abx80x: use devm_add_action_or_reset()
rtc: m41t80: use devm_add_action_or_reset()
rtc: fix a typo and reduce three empty lines to one
rtc: s35390a: improve two comments in .set_alarm
...
105 files changed, 850 insertions, 1582 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index efc203109a62..e9c75275405d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -9828,10 +9828,14 @@ L: rtc-linux@googlegroups.com | |||
9828 | Q: http://patchwork.ozlabs.org/project/rtc-linux/list/ | 9828 | Q: http://patchwork.ozlabs.org/project/rtc-linux/list/ |
9829 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git | 9829 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git |
9830 | S: Maintained | 9830 | S: Maintained |
9831 | F: Documentation/devicetree/bindings/rtc/ | ||
9831 | F: Documentation/rtc.txt | 9832 | F: Documentation/rtc.txt |
9832 | F: drivers/rtc/ | 9833 | F: drivers/rtc/ |
9833 | F: include/linux/rtc.h | 9834 | F: include/linux/rtc.h |
9834 | F: include/uapi/linux/rtc.h | 9835 | F: include/uapi/linux/rtc.h |
9836 | F: include/linux/rtc/ | ||
9837 | F: include/linux/platform_data/rtc-* | ||
9838 | F: tools/testing/selftests/timers/rtctest.c | ||
9835 | 9839 | ||
9836 | REALTEK AUDIO CODECS | 9840 | REALTEK AUDIO CODECS |
9837 | M: Bard Liao <bardliao@realtek.com> | 9841 | M: Bard Liao <bardliao@realtek.com> |
diff --git a/arch/alpha/include/asm/rtc.h b/arch/alpha/include/asm/rtc.h deleted file mode 100644 index f71c3b0ed360..000000000000 --- a/arch/alpha/include/asm/rtc.h +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | #include <asm-generic/rtc.h> | ||
diff --git a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c index 53dd2f1a53aa..d5f0580746a5 100644 --- a/arch/alpha/kernel/core_marvel.c +++ b/arch/alpha/kernel/core_marvel.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <asm/gct.h> | 24 | #include <asm/gct.h> |
25 | #include <asm/pgalloc.h> | 25 | #include <asm/pgalloc.h> |
26 | #include <asm/tlbflush.h> | 26 | #include <asm/tlbflush.h> |
27 | #include <asm/rtc.h> | ||
28 | #include <asm/vga.h> | 27 | #include <asm/vga.h> |
29 | 28 | ||
30 | #include "proto.h" | 29 | #include "proto.h" |
diff --git a/arch/alpha/kernel/rtc.c b/arch/alpha/kernel/rtc.c index f535a3fd0f60..ceed68c7500b 100644 --- a/arch/alpha/kernel/rtc.c +++ b/arch/alpha/kernel/rtc.c | |||
@@ -15,8 +15,6 @@ | |||
15 | #include <linux/rtc.h> | 15 | #include <linux/rtc.h> |
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | 17 | ||
18 | #include <asm/rtc.h> | ||
19 | |||
20 | #include "proto.h" | 18 | #include "proto.h" |
21 | 19 | ||
22 | 20 | ||
@@ -81,7 +79,7 @@ init_rtc_epoch(void) | |||
81 | static int | 79 | static int |
82 | alpha_rtc_read_time(struct device *dev, struct rtc_time *tm) | 80 | alpha_rtc_read_time(struct device *dev, struct rtc_time *tm) |
83 | { | 81 | { |
84 | __get_rtc_time(tm); | 82 | mc146818_get_time(tm); |
85 | 83 | ||
86 | /* Adjust for non-default epochs. It's easier to depend on the | 84 | /* Adjust for non-default epochs. It's easier to depend on the |
87 | generic __get_rtc_time and adjust the epoch here than create | 85 | generic __get_rtc_time and adjust the epoch here than create |
@@ -112,7 +110,7 @@ alpha_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
112 | tm = &xtm; | 110 | tm = &xtm; |
113 | } | 111 | } |
114 | 112 | ||
115 | return __set_rtc_time(tm); | 113 | return mc146818_set_time(tm); |
116 | } | 114 | } |
117 | 115 | ||
118 | static int | 116 | static int |
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c index 45b81a2bcd4b..3b39ea353d30 100644 --- a/arch/arm/mach-ep93xx/ts72xx.c +++ b/arch/arm/mach-ep93xx/ts72xx.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
19 | #include <linux/m48t86.h> | 19 | #include <linux/platform_data/rtc-m48t86.h> |
20 | #include <linux/mtd/nand.h> | 20 | #include <linux/mtd/nand.h> |
21 | #include <linux/mtd/partitions.h> | 21 | #include <linux/mtd/partitions.h> |
22 | 22 | ||
diff --git a/arch/arm/mach-orion5x/ts78xx-setup.c b/arch/arm/mach-orion5x/ts78xx-setup.c index 3a58a5d4a28a..8d597267d0c4 100644 --- a/arch/arm/mach-orion5x/ts78xx-setup.c +++ b/arch/arm/mach-orion5x/ts78xx-setup.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/mv643xx_eth.h> | 17 | #include <linux/mv643xx_eth.h> |
18 | #include <linux/ata_platform.h> | 18 | #include <linux/ata_platform.h> |
19 | #include <linux/m48t86.h> | 19 | #include <linux/platform_data/rtc-m48t86.h> |
20 | #include <linux/mtd/nand.h> | 20 | #include <linux/mtd/nand.h> |
21 | #include <linux/mtd/partitions.h> | 21 | #include <linux/mtd/partitions.h> |
22 | #include <linux/timeriomem-rng.h> | 22 | #include <linux/timeriomem-rng.h> |
diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c index fa5f51d633a3..be4a66166d61 100644 --- a/arch/arm/mach-pxa/cm-x270.c +++ b/arch/arm/mach-pxa/cm-x270.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/gpio.h> | 14 | #include <linux/gpio.h> |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | 16 | ||
17 | #include <linux/rtc-v3020.h> | 17 | #include <linux/platform_data/rtc-v3020.h> |
18 | #include <video/mbxfb.h> | 18 | #include <video/mbxfb.h> |
19 | 19 | ||
20 | #include <linux/spi/spi.h> | 20 | #include <linux/spi/spi.h> |
diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index 5f5ac7c8faf0..868448d2cd82 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/gpio.h> | 25 | #include <linux/gpio.h> |
26 | #include <linux/dm9000.h> | 26 | #include <linux/dm9000.h> |
27 | #include <linux/leds.h> | 27 | #include <linux/leds.h> |
28 | #include <linux/rtc-v3020.h> | 28 | #include <linux/platform_data/rtc-v3020.h> |
29 | #include <linux/pwm.h> | 29 | #include <linux/pwm.h> |
30 | #include <linux/pwm_backlight.h> | 30 | #include <linux/pwm_backlight.h> |
31 | 31 | ||
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index 6e0268deec43..03354c21e1f2 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
15 | 15 | ||
16 | #include <linux/dm9000.h> | 16 | #include <linux/dm9000.h> |
17 | #include <linux/rtc-v3020.h> | 17 | #include <linux/platform_data/rtc-v3020.h> |
18 | #include <linux/mtd/nand.h> | 18 | #include <linux/mtd/nand.h> |
19 | #include <linux/mtd/partitions.h> | 19 | #include <linux/mtd/partitions.h> |
20 | #include <linux/mtd/physmap.h> | 20 | #include <linux/mtd/physmap.h> |
diff --git a/arch/frv/include/asm/mc146818rtc.h b/arch/frv/include/asm/mc146818rtc.h deleted file mode 100644 index 90dfb7a633d1..000000000000 --- a/arch/frv/include/asm/mc146818rtc.h +++ /dev/null | |||
@@ -1,16 +0,0 @@ | |||
1 | /* mc146818rtc.h: RTC defs | ||
2 | * | ||
3 | * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #ifndef _ASM_MC146818RTC_H | ||
13 | #define _ASM_MC146818RTC_H | ||
14 | |||
15 | |||
16 | #endif /* _ASM_MC146818RTC_H */ | ||
diff --git a/arch/h8300/include/asm/mc146818rtc.h b/arch/h8300/include/asm/mc146818rtc.h deleted file mode 100644 index ab9d9646d241..000000000000 --- a/arch/h8300/include/asm/mc146818rtc.h +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | /* | ||
2 | * Machine dependent access functions for RTC registers. | ||
3 | */ | ||
4 | #ifndef _H8300_MC146818RTC_H | ||
5 | #define _H8300_MC146818RTC_H | ||
6 | |||
7 | /* empty include file to satisfy the include in genrtc.c/ide-geometry.c */ | ||
8 | |||
9 | #endif /* _H8300_MC146818RTC_H */ | ||
diff --git a/arch/ia64/include/asm/mc146818rtc.h b/arch/ia64/include/asm/mc146818rtc.h deleted file mode 100644 index 407787a237ba..000000000000 --- a/arch/ia64/include/asm/mc146818rtc.h +++ /dev/null | |||
@@ -1,10 +0,0 @@ | |||
1 | #ifndef _ASM_IA64_MC146818RTC_H | ||
2 | #define _ASM_IA64_MC146818RTC_H | ||
3 | |||
4 | /* | ||
5 | * Machine dependent access functions for RTC registers. | ||
6 | */ | ||
7 | |||
8 | /* empty include file to satisfy the include in genrtc.c */ | ||
9 | |||
10 | #endif /* _ASM_IA64_MC146818RTC_H */ | ||
diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c index 01693df7f2f6..ec9cc1fdd237 100644 --- a/arch/m68k/amiga/config.c +++ b/arch/m68k/amiga/config.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <asm/amigahw.h> | 35 | #include <asm/amigahw.h> |
36 | #include <asm/amigaints.h> | 36 | #include <asm/amigaints.h> |
37 | #include <asm/irq.h> | 37 | #include <asm/irq.h> |
38 | #include <asm/rtc.h> | ||
39 | #include <asm/machdep.h> | 38 | #include <asm/machdep.h> |
40 | #include <asm/io.h> | 39 | #include <asm/io.h> |
41 | 40 | ||
diff --git a/arch/m68k/apollo/config.c b/arch/m68k/apollo/config.c index 6e62d66c396e..432bc8bacfc2 100644 --- a/arch/m68k/apollo/config.c +++ b/arch/m68k/apollo/config.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <asm/pgtable.h> | 15 | #include <asm/pgtable.h> |
16 | #include <asm/apollohw.h> | 16 | #include <asm/apollohw.h> |
17 | #include <asm/irq.h> | 17 | #include <asm/irq.h> |
18 | #include <asm/rtc.h> | ||
19 | #include <asm/machdep.h> | 18 | #include <asm/machdep.h> |
20 | 19 | ||
21 | u_long sio01_physaddr; | 20 | u_long sio01_physaddr; |
diff --git a/arch/m68k/bvme6000/config.c b/arch/m68k/bvme6000/config.c index 478623dbb209..611d4d9ea2bd 100644 --- a/arch/m68k/bvme6000/config.c +++ b/arch/m68k/bvme6000/config.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <asm/setup.h> | 34 | #include <asm/setup.h> |
35 | #include <asm/irq.h> | 35 | #include <asm/irq.h> |
36 | #include <asm/traps.h> | 36 | #include <asm/traps.h> |
37 | #include <asm/rtc.h> | ||
38 | #include <asm/machdep.h> | 37 | #include <asm/machdep.h> |
39 | #include <asm/bvme6000hw.h> | 38 | #include <asm/bvme6000hw.h> |
40 | 39 | ||
diff --git a/arch/m68k/hp300/config.c b/arch/m68k/hp300/config.c index a9befe65adc4..7cfab158fb61 100644 --- a/arch/m68k/hp300/config.c +++ b/arch/m68k/hp300/config.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/string.h> | 12 | #include <linux/string.h> |
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/console.h> | 14 | #include <linux/console.h> |
15 | #include <linux/rtc.h> | ||
15 | 16 | ||
16 | #include <asm/bootinfo.h> | 17 | #include <asm/bootinfo.h> |
17 | #include <asm/bootinfo-hp300.h> | 18 | #include <asm/bootinfo-hp300.h> |
@@ -20,7 +21,6 @@ | |||
20 | #include <asm/blinken.h> | 21 | #include <asm/blinken.h> |
21 | #include <asm/io.h> /* readb() and writeb() */ | 22 | #include <asm/io.h> /* readb() and writeb() */ |
22 | #include <asm/hp300hw.h> | 23 | #include <asm/hp300hw.h> |
23 | #include <asm/rtc.h> | ||
24 | 24 | ||
25 | #include "time.h" | 25 | #include "time.h" |
26 | 26 | ||
diff --git a/arch/m68k/include/asm/rtc.h b/arch/m68k/include/asm/rtc.h deleted file mode 100644 index a4d08ea122ee..000000000000 --- a/arch/m68k/include/asm/rtc.h +++ /dev/null | |||
@@ -1,79 +0,0 @@ | |||
1 | /* include/asm-m68k/rtc.h | ||
2 | * | ||
3 | * Copyright Richard Zidlicky | ||
4 | * implementation details for genrtc/q40rtc driver | ||
5 | */ | ||
6 | /* permission is hereby granted to copy, modify and redistribute this code | ||
7 | * in terms of the GNU Library General Public License, Version 2 or later, | ||
8 | * at your option. | ||
9 | */ | ||
10 | |||
11 | #ifndef _ASM_RTC_H | ||
12 | #define _ASM_RTC_H | ||
13 | |||
14 | #ifdef __KERNEL__ | ||
15 | |||
16 | #include <linux/rtc.h> | ||
17 | #include <asm/errno.h> | ||
18 | #include <asm/machdep.h> | ||
19 | |||
20 | #define RTC_PIE 0x40 /* periodic interrupt enable */ | ||
21 | #define RTC_AIE 0x20 /* alarm interrupt enable */ | ||
22 | #define RTC_UIE 0x10 /* update-finished interrupt enable */ | ||
23 | |||
24 | /* some dummy definitions */ | ||
25 | #define RTC_BATT_BAD 0x100 /* battery bad */ | ||
26 | #define RTC_SQWE 0x08 /* enable square-wave output */ | ||
27 | #define RTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */ | ||
28 | #define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */ | ||
29 | #define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */ | ||
30 | |||
31 | static inline unsigned int get_rtc_time(struct rtc_time *time) | ||
32 | { | ||
33 | /* | ||
34 | * Only the values that we read from the RTC are set. We leave | ||
35 | * tm_wday, tm_yday and tm_isdst untouched. Even though the | ||
36 | * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated | ||
37 | * by the RTC when initially set to a non-zero value. | ||
38 | */ | ||
39 | if (mach_hwclk) | ||
40 | mach_hwclk(0, time); | ||
41 | return RTC_24H; | ||
42 | } | ||
43 | |||
44 | static inline int set_rtc_time(struct rtc_time *time) | ||
45 | { | ||
46 | if (mach_hwclk) | ||
47 | return mach_hwclk(1, time); | ||
48 | return -EINVAL; | ||
49 | } | ||
50 | |||
51 | static inline unsigned int get_rtc_ss(void) | ||
52 | { | ||
53 | if (mach_get_ss) | ||
54 | return mach_get_ss(); | ||
55 | else{ | ||
56 | struct rtc_time h; | ||
57 | |||
58 | get_rtc_time(&h); | ||
59 | return h.tm_sec; | ||
60 | } | ||
61 | } | ||
62 | |||
63 | static inline int get_rtc_pll(struct rtc_pll_info *pll) | ||
64 | { | ||
65 | if (mach_get_rtc_pll) | ||
66 | return mach_get_rtc_pll(pll); | ||
67 | else | ||
68 | return -EINVAL; | ||
69 | } | ||
70 | static inline int set_rtc_pll(struct rtc_pll_info *pll) | ||
71 | { | ||
72 | if (mach_set_rtc_pll) | ||
73 | return mach_set_rtc_pll(pll); | ||
74 | else | ||
75 | return -EINVAL; | ||
76 | } | ||
77 | #endif /* __KERNEL__ */ | ||
78 | |||
79 | #endif /* _ASM__RTC_H */ | ||
diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c index 3857737e3958..4e5aa2f4f522 100644 --- a/arch/m68k/kernel/time.c +++ b/arch/m68k/kernel/time.c | |||
@@ -86,7 +86,49 @@ void read_persistent_clock(struct timespec *ts) | |||
86 | } | 86 | } |
87 | } | 87 | } |
88 | 88 | ||
89 | #ifdef CONFIG_ARCH_USES_GETTIMEOFFSET | 89 | #if defined(CONFIG_ARCH_USES_GETTIMEOFFSET) && IS_ENABLED(CONFIG_RTC_DRV_GENERIC) |
90 | static int rtc_generic_get_time(struct device *dev, struct rtc_time *tm) | ||
91 | { | ||
92 | mach_hwclk(0, tm); | ||
93 | return rtc_valid_tm(tm); | ||
94 | } | ||
95 | |||
96 | static int rtc_generic_set_time(struct device *dev, struct rtc_time *tm) | ||
97 | { | ||
98 | if (mach_hwclk(1, tm) < 0) | ||
99 | return -EOPNOTSUPP; | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | static int rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | ||
104 | { | ||
105 | struct rtc_pll_info pll; | ||
106 | struct rtc_pll_info __user *argp = (void __user *)arg; | ||
107 | |||
108 | switch (cmd) { | ||
109 | case RTC_PLL_GET: | ||
110 | if (!mach_get_rtc_pll || mach_get_rtc_pll(&pll)) | ||
111 | return -EINVAL; | ||
112 | return copy_to_user(argp, &pll, sizeof pll) ? -EFAULT : 0; | ||
113 | |||
114 | case RTC_PLL_SET: | ||
115 | if (!mach_set_rtc_pll) | ||
116 | return -EINVAL; | ||
117 | if (!capable(CAP_SYS_TIME)) | ||
118 | return -EACCES; | ||
119 | if (copy_from_user(&pll, argp, sizeof(pll))) | ||
120 | return -EFAULT; | ||
121 | return mach_set_rtc_pll(&pll); | ||
122 | } | ||
123 | |||
124 | return -ENOIOCTLCMD; | ||
125 | } | ||
126 | |||
127 | static const struct rtc_class_ops generic_rtc_ops = { | ||
128 | .ioctl = rtc_ioctl, | ||
129 | .read_time = rtc_generic_get_time, | ||
130 | .set_time = rtc_generic_set_time, | ||
131 | }; | ||
90 | 132 | ||
91 | static int __init rtc_init(void) | 133 | static int __init rtc_init(void) |
92 | { | 134 | { |
@@ -95,7 +137,9 @@ static int __init rtc_init(void) | |||
95 | if (!mach_hwclk) | 137 | if (!mach_hwclk) |
96 | return -ENODEV; | 138 | return -ENODEV; |
97 | 139 | ||
98 | pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0); | 140 | pdev = platform_device_register_data(NULL, "rtc-generic", -1, |
141 | &generic_rtc_ops, | ||
142 | sizeof(generic_rtc_ops)); | ||
99 | return PTR_ERR_OR_ZERO(pdev); | 143 | return PTR_ERR_OR_ZERO(pdev); |
100 | } | 144 | } |
101 | 145 | ||
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c index 689b47d292ac..2f33a33001e5 100644 --- a/arch/m68k/mac/config.c +++ b/arch/m68k/mac/config.c | |||
@@ -10,6 +10,7 @@ | |||
10 | * Miscellaneous linux stuff | 10 | * Miscellaneous linux stuff |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/errno.h> | ||
13 | #include <linux/module.h> | 14 | #include <linux/module.h> |
14 | #include <linux/types.h> | 15 | #include <linux/types.h> |
15 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
@@ -25,6 +26,7 @@ | |||
25 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
26 | #include <linux/adb.h> | 27 | #include <linux/adb.h> |
27 | #include <linux/cuda.h> | 28 | #include <linux/cuda.h> |
29 | #include <linux/rtc.h> | ||
28 | 30 | ||
29 | #include <asm/setup.h> | 31 | #include <asm/setup.h> |
30 | #include <asm/bootinfo.h> | 32 | #include <asm/bootinfo.h> |
@@ -34,7 +36,6 @@ | |||
34 | #include <asm/io.h> | 36 | #include <asm/io.h> |
35 | #include <asm/irq.h> | 37 | #include <asm/irq.h> |
36 | #include <asm/pgtable.h> | 38 | #include <asm/pgtable.h> |
37 | #include <asm/rtc.h> | ||
38 | #include <asm/machdep.h> | 39 | #include <asm/machdep.h> |
39 | 40 | ||
40 | #include <asm/macintosh.h> | 41 | #include <asm/macintosh.h> |
diff --git a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c index 707b61aea203..0fb54a90eac2 100644 --- a/arch/m68k/mac/misc.c +++ b/arch/m68k/mac/misc.c | |||
@@ -18,7 +18,6 @@ | |||
18 | 18 | ||
19 | #include <asm/uaccess.h> | 19 | #include <asm/uaccess.h> |
20 | #include <asm/io.h> | 20 | #include <asm/io.h> |
21 | #include <asm/rtc.h> | ||
22 | #include <asm/segment.h> | 21 | #include <asm/segment.h> |
23 | #include <asm/setup.h> | 22 | #include <asm/setup.h> |
24 | #include <asm/macintosh.h> | 23 | #include <asm/macintosh.h> |
diff --git a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c index e6a3b56c6481..c11d38dfad08 100644 --- a/arch/m68k/mvme147/config.c +++ b/arch/m68k/mvme147/config.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <asm/setup.h> | 32 | #include <asm/setup.h> |
33 | #include <asm/irq.h> | 33 | #include <asm/irq.h> |
34 | #include <asm/traps.h> | 34 | #include <asm/traps.h> |
35 | #include <asm/rtc.h> | ||
36 | #include <asm/machdep.h> | 35 | #include <asm/machdep.h> |
37 | #include <asm/mvme147hw.h> | 36 | #include <asm/mvme147hw.h> |
38 | 37 | ||
diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c index a53803cc66cd..58e240939d26 100644 --- a/arch/m68k/mvme16x/config.c +++ b/arch/m68k/mvme16x/config.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <asm/setup.h> | 35 | #include <asm/setup.h> |
36 | #include <asm/irq.h> | 36 | #include <asm/irq.h> |
37 | #include <asm/traps.h> | 37 | #include <asm/traps.h> |
38 | #include <asm/rtc.h> | ||
39 | #include <asm/machdep.h> | 38 | #include <asm/machdep.h> |
40 | #include <asm/mvme16xhw.h> | 39 | #include <asm/mvme16xhw.h> |
41 | 40 | ||
diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c index e90fe903613e..fcb7f05b60b6 100644 --- a/arch/m68k/q40/config.c +++ b/arch/m68k/q40/config.c | |||
@@ -12,6 +12,7 @@ | |||
12 | * for more details. | 12 | * for more details. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/errno.h> | ||
15 | #include <linux/types.h> | 16 | #include <linux/types.h> |
16 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
17 | #include <linux/mm.h> | 18 | #include <linux/mm.h> |
@@ -27,7 +28,6 @@ | |||
27 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
28 | 29 | ||
29 | #include <asm/io.h> | 30 | #include <asm/io.h> |
30 | #include <asm/rtc.h> | ||
31 | #include <asm/bootinfo.h> | 31 | #include <asm/bootinfo.h> |
32 | #include <asm/pgtable.h> | 32 | #include <asm/pgtable.h> |
33 | #include <asm/setup.h> | 33 | #include <asm/setup.h> |
diff --git a/arch/m68k/sun3/config.c b/arch/m68k/sun3/config.c index 71884bf01d72..3af34fa3a344 100644 --- a/arch/m68k/sun3/config.c +++ b/arch/m68k/sun3/config.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <asm/pgalloc.h> | 26 | #include <asm/pgalloc.h> |
27 | #include <asm/sun3-head.h> | 27 | #include <asm/sun3-head.h> |
28 | #include <asm/sun3mmu.h> | 28 | #include <asm/sun3mmu.h> |
29 | #include <asm/rtc.h> | ||
30 | #include <asm/machdep.h> | 29 | #include <asm/machdep.h> |
31 | #include <asm/machines.h> | 30 | #include <asm/machines.h> |
32 | #include <asm/idprom.h> | 31 | #include <asm/idprom.h> |
diff --git a/arch/m68k/sun3/intersil.c b/arch/m68k/sun3/intersil.c index 889829e11f1d..2cd0bcbe6f30 100644 --- a/arch/m68k/sun3/intersil.c +++ b/arch/m68k/sun3/intersil.c | |||
@@ -14,8 +14,8 @@ | |||
14 | #include <linux/rtc.h> | 14 | #include <linux/rtc.h> |
15 | 15 | ||
16 | #include <asm/errno.h> | 16 | #include <asm/errno.h> |
17 | #include <asm/rtc.h> | ||
18 | #include <asm/intersil.h> | 17 | #include <asm/intersil.h> |
18 | #include <asm/machdep.h> | ||
19 | 19 | ||
20 | 20 | ||
21 | /* bits to set for start/run of the intersil */ | 21 | /* bits to set for start/run of the intersil */ |
diff --git a/arch/m68k/sun3x/time.c b/arch/m68k/sun3x/time.c index c8eb08add6b0..431d3c4306dd 100644 --- a/arch/m68k/sun3x/time.c +++ b/arch/m68k/sun3x/time.c | |||
@@ -15,10 +15,10 @@ | |||
15 | 15 | ||
16 | #include <asm/irq.h> | 16 | #include <asm/irq.h> |
17 | #include <asm/io.h> | 17 | #include <asm/io.h> |
18 | #include <asm/machdep.h> | ||
18 | #include <asm/traps.h> | 19 | #include <asm/traps.h> |
19 | #include <asm/sun3x.h> | 20 | #include <asm/sun3x.h> |
20 | #include <asm/sun3ints.h> | 21 | #include <asm/sun3ints.h> |
21 | #include <asm/rtc.h> | ||
22 | 22 | ||
23 | #include "time.h" | 23 | #include "time.h" |
24 | 24 | ||
diff --git a/arch/mips/sgi-ip22/ip22-reset.c b/arch/mips/sgi-ip22/ip22-reset.c index 063c2dd31e72..2f45b0357021 100644 --- a/arch/mips/sgi-ip22/ip22-reset.c +++ b/arch/mips/sgi-ip22/ip22-reset.c | |||
@@ -7,7 +7,7 @@ | |||
7 | */ | 7 | */ |
8 | #include <linux/linkage.h> | 8 | #include <linux/linkage.h> |
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/ds1286.h> | 10 | #include <linux/rtc/ds1286.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/interrupt.h> | 12 | #include <linux/interrupt.h> |
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
diff --git a/arch/mips/sni/time.c b/arch/mips/sni/time.c index fb4b3520cdc6..7ee14f41fc25 100644 --- a/arch/mips/sni/time.c +++ b/arch/mips/sni/time.c | |||
@@ -8,7 +8,6 @@ | |||
8 | 8 | ||
9 | #include <asm/sni.h> | 9 | #include <asm/sni.h> |
10 | #include <asm/time.h> | 10 | #include <asm/time.h> |
11 | #include <asm-generic/rtc.h> | ||
12 | 11 | ||
13 | #define SNI_CLOCK_TICK_RATE 3686400 | 12 | #define SNI_CLOCK_TICK_RATE 3686400 |
14 | #define SNI_COUNTER2_DIV 64 | 13 | #define SNI_COUNTER2_DIV 64 |
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig index 9627e81a6cbb..38e3494bfb63 100644 --- a/arch/mn10300/Kconfig +++ b/arch/mn10300/Kconfig | |||
@@ -236,7 +236,9 @@ source "kernel/Kconfig.hz" | |||
236 | config MN10300_RTC | 236 | config MN10300_RTC |
237 | bool "Using MN10300 RTC" | 237 | bool "Using MN10300 RTC" |
238 | depends on MN10300_PROC_MN103E010 || MN10300_PROC_MN2WS0050 | 238 | depends on MN10300_PROC_MN103E010 || MN10300_PROC_MN2WS0050 |
239 | select GENERIC_CMOS_UPDATE | 239 | select RTC_CLASS |
240 | select RTC_DRV_CMOS | ||
241 | select RTC_SYSTOHC | ||
240 | default n | 242 | default n |
241 | help | 243 | help |
242 | This option enables support for the RTC, thus enabling time to be | 244 | This option enables support for the RTC, thus enabling time to be |
diff --git a/arch/mn10300/include/asm/rtc-regs.h b/arch/mn10300/include/asm/rtc-regs.h index c42deefaec11..c81cacecb6e3 100644 --- a/arch/mn10300/include/asm/rtc-regs.h +++ b/arch/mn10300/include/asm/rtc-regs.h | |||
@@ -75,9 +75,9 @@ | |||
75 | #define RTC_PORT(x) 0xd8600000 | 75 | #define RTC_PORT(x) 0xd8600000 |
76 | #define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */ | 76 | #define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */ |
77 | 77 | ||
78 | #define CMOS_READ(addr) __SYSREG(0xd8600000 + (addr), u8) | 78 | #define CMOS_READ(addr) __SYSREG(0xd8600000 + (u32)(addr), u8) |
79 | #define CMOS_WRITE(val, addr) \ | 79 | #define CMOS_WRITE(val, addr) \ |
80 | do { __SYSREG(0xd8600000 + (addr), u8) = val; } while (0) | 80 | do { __SYSREG(0xd8600000 + (u32)(addr), u8) = val; } while (0) |
81 | 81 | ||
82 | #define RTC_IRQ RTIRQ | 82 | #define RTC_IRQ RTIRQ |
83 | 83 | ||
diff --git a/arch/mn10300/include/asm/rtc.h b/arch/mn10300/include/asm/rtc.h index 6c14bb1d0d9b..07dc87656197 100644 --- a/arch/mn10300/include/asm/rtc.h +++ b/arch/mn10300/include/asm/rtc.h | |||
@@ -25,6 +25,4 @@ static inline void calibrate_clock(void) | |||
25 | 25 | ||
26 | #endif /* !CONFIG_MN10300_RTC */ | 26 | #endif /* !CONFIG_MN10300_RTC */ |
27 | 27 | ||
28 | #include <asm-generic/rtc.h> | ||
29 | |||
30 | #endif /* _ASM_RTC_H */ | 28 | #endif /* _ASM_RTC_H */ |
diff --git a/arch/mn10300/kernel/rtc.c b/arch/mn10300/kernel/rtc.c index 48d7058b3295..f81f37025072 100644 --- a/arch/mn10300/kernel/rtc.c +++ b/arch/mn10300/kernel/rtc.c | |||
@@ -12,107 +12,19 @@ | |||
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/mc146818rtc.h> | 14 | #include <linux/mc146818rtc.h> |
15 | #include <linux/bcd.h> | 15 | #include <linux/ioport.h> |
16 | #include <linux/timex.h> | 16 | #include <linux/platform_device.h> |
17 | |||
17 | #include <asm/rtc-regs.h> | 18 | #include <asm/rtc-regs.h> |
18 | #include <asm/rtc.h> | 19 | #include <asm/rtc.h> |
19 | 20 | ||
20 | DEFINE_SPINLOCK(rtc_lock); | 21 | DEFINE_SPINLOCK(rtc_lock); |
21 | EXPORT_SYMBOL(rtc_lock); | 22 | EXPORT_SYMBOL(rtc_lock); |
22 | 23 | ||
23 | /* | 24 | static const __initdata struct resource res[] = { |
24 | * Read the current RTC time | 25 | DEFINE_RES_IO(RTC_PORT(0), RTC_IO_EXTENT), |
25 | */ | 26 | DEFINE_RES_IRQ(RTC_IRQ), |
26 | void read_persistent_clock(struct timespec *ts) | 27 | }; |
27 | { | ||
28 | struct rtc_time tm; | ||
29 | |||
30 | get_rtc_time(&tm); | ||
31 | |||
32 | ts->tv_nsec = 0; | ||
33 | ts->tv_sec = mktime(tm.tm_year, tm.tm_mon, tm.tm_mday, | ||
34 | tm.tm_hour, tm.tm_min, tm.tm_sec); | ||
35 | |||
36 | /* if rtc is way off in the past, set something reasonable */ | ||
37 | if (ts->tv_sec < 0) | ||
38 | ts->tv_sec = mktime(2009, 1, 1, 12, 0, 0); | ||
39 | } | ||
40 | |||
41 | /* | ||
42 | * In order to set the CMOS clock precisely, set_rtc_mmss has to be called 500 | ||
43 | * ms after the second nowtime has started, because when nowtime is written | ||
44 | * into the registers of the CMOS clock, it will jump to the next second | ||
45 | * precisely 500 ms later. Check the Motorola MC146818A or Dallas DS12887 data | ||
46 | * sheet for details. | ||
47 | * | ||
48 | * BUG: This routine does not handle hour overflow properly; it just | ||
49 | * sets the minutes. Usually you'll only notice that after reboot! | ||
50 | */ | ||
51 | static int set_rtc_mmss(unsigned long nowtime) | ||
52 | { | ||
53 | unsigned char save_control, save_freq_select; | ||
54 | int retval = 0; | ||
55 | int real_seconds, real_minutes, cmos_minutes; | ||
56 | |||
57 | /* gets recalled with irq locally disabled */ | ||
58 | spin_lock(&rtc_lock); | ||
59 | save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being | ||
60 | * set */ | ||
61 | CMOS_WRITE(save_control | RTC_SET, RTC_CONTROL); | ||
62 | |||
63 | save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset | ||
64 | * prescaler */ | ||
65 | CMOS_WRITE(save_freq_select | RTC_DIV_RESET2, RTC_FREQ_SELECT); | ||
66 | |||
67 | cmos_minutes = CMOS_READ(RTC_MINUTES); | ||
68 | if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) | ||
69 | cmos_minutes = bcd2bin(cmos_minutes); | ||
70 | |||
71 | /* | ||
72 | * since we're only adjusting minutes and seconds, | ||
73 | * don't interfere with hour overflow. This avoids | ||
74 | * messing with unknown time zones but requires your | ||
75 | * RTC not to be off by more than 15 minutes | ||
76 | */ | ||
77 | real_seconds = nowtime % 60; | ||
78 | real_minutes = nowtime / 60; | ||
79 | if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1) | ||
80 | /* correct for half hour time zone */ | ||
81 | real_minutes += 30; | ||
82 | real_minutes %= 60; | ||
83 | |||
84 | if (abs(real_minutes - cmos_minutes) < 30) { | ||
85 | if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { | ||
86 | real_seconds = bin2bcd(real_seconds); | ||
87 | real_minutes = bin2bcd(real_minutes); | ||
88 | } | ||
89 | CMOS_WRITE(real_seconds, RTC_SECONDS); | ||
90 | CMOS_WRITE(real_minutes, RTC_MINUTES); | ||
91 | } else { | ||
92 | printk_once(KERN_NOTICE | ||
93 | "set_rtc_mmss: can't update from %d to %d\n", | ||
94 | cmos_minutes, real_minutes); | ||
95 | retval = -1; | ||
96 | } | ||
97 | |||
98 | /* The following flags have to be released exactly in this order, | ||
99 | * otherwise the DS12887 (popular MC146818A clone with integrated | ||
100 | * battery and quartz) will not reset the oscillator and will not | ||
101 | * update precisely 500 ms later. You won't find this mentioned in | ||
102 | * the Dallas Semiconductor data sheets, but who believes data | ||
103 | * sheets anyway ... -- Markus Kuhn | ||
104 | */ | ||
105 | CMOS_WRITE(save_control, RTC_CONTROL); | ||
106 | CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); | ||
107 | spin_unlock(&rtc_lock); | ||
108 | |||
109 | return retval; | ||
110 | } | ||
111 | |||
112 | int update_persistent_clock(struct timespec now) | ||
113 | { | ||
114 | return set_rtc_mmss(now.tv_sec); | ||
115 | } | ||
116 | 28 | ||
117 | /* | 29 | /* |
118 | * calibrate the TSC clock against the RTC | 30 | * calibrate the TSC clock against the RTC |
@@ -129,4 +41,6 @@ void __init calibrate_clock(void) | |||
129 | RTCRA |= RTCRA_DVR; | 41 | RTCRA |= RTCRA_DVR; |
130 | RTCRA &= ~RTCRA_DVR; | 42 | RTCRA &= ~RTCRA_DVR; |
131 | RTCRB &= ~RTCRB_SET; | 43 | RTCRB &= ~RTCRB_SET; |
44 | |||
45 | platform_device_register_simple("rtc_cmos", -1, res, ARRAY_SIZE(res)); | ||
132 | } | 46 | } |
diff --git a/arch/mn10300/proc-mn103e010/proc-init.c b/arch/mn10300/proc-mn103e010/proc-init.c index 27b97980dca4..102d86a6ae56 100644 --- a/arch/mn10300/proc-mn103e010/proc-init.c +++ b/arch/mn10300/proc-mn103e010/proc-init.c | |||
@@ -9,7 +9,10 @@ | |||
9 | * 2 of the Licence, or (at your option) any later version. | 9 | * 2 of the Licence, or (at your option) any later version. |
10 | */ | 10 | */ |
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/irq.h> | ||
13 | #include <asm/cacheflush.h> | ||
12 | #include <asm/fpu.h> | 14 | #include <asm/fpu.h> |
15 | #include <asm/irq.h> | ||
13 | #include <asm/rtc.h> | 16 | #include <asm/rtc.h> |
14 | #include <asm/busctl-regs.h> | 17 | #include <asm/busctl-regs.h> |
15 | 18 | ||
diff --git a/arch/mn10300/proc-mn2ws0050/proc-init.c b/arch/mn10300/proc-mn2ws0050/proc-init.c index ee6d03dbc8d8..950cc8dbb284 100644 --- a/arch/mn10300/proc-mn2ws0050/proc-init.c +++ b/arch/mn10300/proc-mn2ws0050/proc-init.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
15 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
16 | 16 | ||
17 | #include <asm/cacheflush.h> | ||
17 | #include <asm/processor.h> | 18 | #include <asm/processor.h> |
18 | #include <asm/uaccess.h> | 19 | #include <asm/uaccess.h> |
19 | #include <asm/io.h> | 20 | #include <asm/io.h> |
diff --git a/arch/parisc/include/asm/mc146818rtc.h b/arch/parisc/include/asm/mc146818rtc.h deleted file mode 100644 index adf41631449f..000000000000 --- a/arch/parisc/include/asm/mc146818rtc.h +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | /* | ||
2 | * Machine dependent access functions for RTC registers. | ||
3 | */ | ||
4 | #ifndef _ASM_MC146818RTC_H | ||
5 | #define _ASM_MC146818RTC_H | ||
6 | |||
7 | /* empty include file to satisfy the include in genrtc.c */ | ||
8 | |||
9 | #endif /* _ASM_MC146818RTC_H */ | ||
diff --git a/arch/parisc/include/asm/rtc.h b/arch/parisc/include/asm/rtc.h deleted file mode 100644 index 099d641a42c2..000000000000 --- a/arch/parisc/include/asm/rtc.h +++ /dev/null | |||
@@ -1,131 +0,0 @@ | |||
1 | /* | ||
2 | * include/asm-parisc/rtc.h | ||
3 | * | ||
4 | * Copyright 2002 Randolph CHung <tausq@debian.org> | ||
5 | * | ||
6 | * Based on: include/asm-ppc/rtc.h and the genrtc driver in the | ||
7 | * 2.4 parisc linux tree | ||
8 | */ | ||
9 | |||
10 | #ifndef __ASM_RTC_H__ | ||
11 | #define __ASM_RTC_H__ | ||
12 | |||
13 | #ifdef __KERNEL__ | ||
14 | |||
15 | #include <linux/rtc.h> | ||
16 | |||
17 | #include <asm/pdc.h> | ||
18 | |||
19 | #define SECS_PER_HOUR (60 * 60) | ||
20 | #define SECS_PER_DAY (SECS_PER_HOUR * 24) | ||
21 | |||
22 | |||
23 | #define RTC_PIE 0x40 /* periodic interrupt enable */ | ||
24 | #define RTC_AIE 0x20 /* alarm interrupt enable */ | ||
25 | #define RTC_UIE 0x10 /* update-finished interrupt enable */ | ||
26 | |||
27 | #define RTC_BATT_BAD 0x100 /* battery bad */ | ||
28 | |||
29 | /* some dummy definitions */ | ||
30 | #define RTC_SQWE 0x08 /* enable square-wave output */ | ||
31 | #define RTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */ | ||
32 | #define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */ | ||
33 | #define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */ | ||
34 | |||
35 | # define __isleap(year) \ | ||
36 | ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) | ||
37 | |||
38 | /* How many days come before each month (0-12). */ | ||
39 | static const unsigned short int __mon_yday[2][13] = | ||
40 | { | ||
41 | /* Normal years. */ | ||
42 | { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, | ||
43 | /* Leap years. */ | ||
44 | { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } | ||
45 | }; | ||
46 | |||
47 | static inline unsigned int get_rtc_time(struct rtc_time *wtime) | ||
48 | { | ||
49 | struct pdc_tod tod_data; | ||
50 | long int days, rem, y; | ||
51 | const unsigned short int *ip; | ||
52 | |||
53 | memset(wtime, 0, sizeof(*wtime)); | ||
54 | if (pdc_tod_read(&tod_data) < 0) | ||
55 | return RTC_24H | RTC_BATT_BAD; | ||
56 | |||
57 | // most of the remainder of this function is: | ||
58 | // Copyright (C) 1991, 1993, 1997, 1998 Free Software Foundation, Inc. | ||
59 | // This was originally a part of the GNU C Library. | ||
60 | // It is distributed under the GPL, and was swiped from offtime.c | ||
61 | |||
62 | |||
63 | days = tod_data.tod_sec / SECS_PER_DAY; | ||
64 | rem = tod_data.tod_sec % SECS_PER_DAY; | ||
65 | |||
66 | wtime->tm_hour = rem / SECS_PER_HOUR; | ||
67 | rem %= SECS_PER_HOUR; | ||
68 | wtime->tm_min = rem / 60; | ||
69 | wtime->tm_sec = rem % 60; | ||
70 | |||
71 | y = 1970; | ||
72 | |||
73 | #define DIV(a, b) ((a) / (b) - ((a) % (b) < 0)) | ||
74 | #define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400)) | ||
75 | |||
76 | while (days < 0 || days >= (__isleap (y) ? 366 : 365)) | ||
77 | { | ||
78 | /* Guess a corrected year, assuming 365 days per year. */ | ||
79 | long int yg = y + days / 365 - (days % 365 < 0); | ||
80 | |||
81 | /* Adjust DAYS and Y to match the guessed year. */ | ||
82 | days -= ((yg - y) * 365 | ||
83 | + LEAPS_THRU_END_OF (yg - 1) | ||
84 | - LEAPS_THRU_END_OF (y - 1)); | ||
85 | y = yg; | ||
86 | } | ||
87 | wtime->tm_year = y - 1900; | ||
88 | |||
89 | ip = __mon_yday[__isleap(y)]; | ||
90 | for (y = 11; days < (long int) ip[y]; --y) | ||
91 | continue; | ||
92 | days -= ip[y]; | ||
93 | wtime->tm_mon = y; | ||
94 | wtime->tm_mday = days + 1; | ||
95 | |||
96 | return RTC_24H; | ||
97 | } | ||
98 | |||
99 | static int set_rtc_time(struct rtc_time *wtime) | ||
100 | { | ||
101 | u_int32_t secs; | ||
102 | |||
103 | secs = mktime(wtime->tm_year + 1900, wtime->tm_mon + 1, wtime->tm_mday, | ||
104 | wtime->tm_hour, wtime->tm_min, wtime->tm_sec); | ||
105 | |||
106 | if(pdc_tod_set(secs, 0) < 0) | ||
107 | return -1; | ||
108 | else | ||
109 | return 0; | ||
110 | |||
111 | } | ||
112 | |||
113 | static inline unsigned int get_rtc_ss(void) | ||
114 | { | ||
115 | struct rtc_time h; | ||
116 | |||
117 | get_rtc_time(&h); | ||
118 | return h.tm_sec; | ||
119 | } | ||
120 | |||
121 | static inline int get_rtc_pll(struct rtc_pll_info *pll) | ||
122 | { | ||
123 | return -EINVAL; | ||
124 | } | ||
125 | static inline int set_rtc_pll(struct rtc_pll_info *pll) | ||
126 | { | ||
127 | return -EINVAL; | ||
128 | } | ||
129 | |||
130 | #endif /* __KERNEL__ */ | ||
131 | #endif /* __ASM_RTC_H__ */ | ||
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index 31ec99a5f119..505cf1ac5af2 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c | |||
@@ -12,6 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/rtc.h> | ||
15 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
16 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
17 | #include <linux/param.h> | 18 | #include <linux/param.h> |
@@ -248,14 +249,47 @@ void __init start_cpu_itimer(void) | |||
248 | per_cpu(cpu_data, cpu).it_value = next_tick; | 249 | per_cpu(cpu_data, cpu).it_value = next_tick; |
249 | } | 250 | } |
250 | 251 | ||
252 | #if IS_ENABLED(CONFIG_RTC_DRV_GENERIC) | ||
253 | static int rtc_generic_get_time(struct device *dev, struct rtc_time *tm) | ||
254 | { | ||
255 | struct pdc_tod tod_data; | ||
256 | |||
257 | memset(tm, 0, sizeof(*tm)); | ||
258 | if (pdc_tod_read(&tod_data) < 0) | ||
259 | return -EOPNOTSUPP; | ||
260 | |||
261 | /* we treat tod_sec as unsigned, so this can work until year 2106 */ | ||
262 | rtc_time64_to_tm(tod_data.tod_sec, tm); | ||
263 | return rtc_valid_tm(tm); | ||
264 | } | ||
265 | |||
266 | static int rtc_generic_set_time(struct device *dev, struct rtc_time *tm) | ||
267 | { | ||
268 | time64_t secs = rtc_tm_to_time64(tm); | ||
269 | |||
270 | if (pdc_tod_set(secs, 0) < 0) | ||
271 | return -EOPNOTSUPP; | ||
272 | |||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static const struct rtc_class_ops rtc_generic_ops = { | ||
277 | .read_time = rtc_generic_get_time, | ||
278 | .set_time = rtc_generic_set_time, | ||
279 | }; | ||
280 | |||
251 | static int __init rtc_init(void) | 281 | static int __init rtc_init(void) |
252 | { | 282 | { |
253 | struct platform_device *pdev; | 283 | struct platform_device *pdev; |
254 | 284 | ||
255 | pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0); | 285 | pdev = platform_device_register_data(NULL, "rtc-generic", -1, |
286 | &rtc_generic_ops, | ||
287 | sizeof(rtc_generic_ops)); | ||
288 | |||
256 | return PTR_ERR_OR_ZERO(pdev); | 289 | return PTR_ERR_OR_ZERO(pdev); |
257 | } | 290 | } |
258 | device_initcall(rtc_init); | 291 | device_initcall(rtc_init); |
292 | #endif | ||
259 | 293 | ||
260 | void read_persistent_clock(struct timespec *ts) | 294 | void read_persistent_clock(struct timespec *ts) |
261 | { | 295 | { |
diff --git a/arch/powerpc/include/asm/rtc.h b/arch/powerpc/include/asm/rtc.h deleted file mode 100644 index f5802926b6c0..000000000000 --- a/arch/powerpc/include/asm/rtc.h +++ /dev/null | |||
@@ -1,78 +0,0 @@ | |||
1 | /* | ||
2 | * Real-time clock definitions and interfaces | ||
3 | * | ||
4 | * Author: Tom Rini <trini@mvista.com> | ||
5 | * | ||
6 | * 2002 (c) MontaVista, Software, Inc. This file is licensed under | ||
7 | * the terms of the GNU General Public License version 2. This program | ||
8 | * is licensed "as is" without any warranty of any kind, whether express | ||
9 | * or implied. | ||
10 | * | ||
11 | * Based on: | ||
12 | * include/asm-m68k/rtc.h | ||
13 | * | ||
14 | * Copyright Richard Zidlicky | ||
15 | * implementation details for genrtc/q40rtc driver | ||
16 | * | ||
17 | * And the old drivers/macintosh/rtc.c which was heavily based on: | ||
18 | * Linux/SPARC Real Time Clock Driver | ||
19 | * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu) | ||
20 | * | ||
21 | * With additional work by Paul Mackerras and Franz Sirl. | ||
22 | */ | ||
23 | |||
24 | #ifndef __ASM_POWERPC_RTC_H__ | ||
25 | #define __ASM_POWERPC_RTC_H__ | ||
26 | |||
27 | #ifdef __KERNEL__ | ||
28 | |||
29 | #include <linux/rtc.h> | ||
30 | |||
31 | #include <asm/machdep.h> | ||
32 | #include <asm/time.h> | ||
33 | |||
34 | #define RTC_PIE 0x40 /* periodic interrupt enable */ | ||
35 | #define RTC_AIE 0x20 /* alarm interrupt enable */ | ||
36 | #define RTC_UIE 0x10 /* update-finished interrupt enable */ | ||
37 | |||
38 | /* some dummy definitions */ | ||
39 | #define RTC_BATT_BAD 0x100 /* battery bad */ | ||
40 | #define RTC_SQWE 0x08 /* enable square-wave output */ | ||
41 | #define RTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */ | ||
42 | #define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */ | ||
43 | #define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */ | ||
44 | |||
45 | static inline unsigned int get_rtc_time(struct rtc_time *time) | ||
46 | { | ||
47 | if (ppc_md.get_rtc_time) | ||
48 | ppc_md.get_rtc_time(time); | ||
49 | return RTC_24H; | ||
50 | } | ||
51 | |||
52 | /* Set the current date and time in the real time clock. */ | ||
53 | static inline int set_rtc_time(struct rtc_time *time) | ||
54 | { | ||
55 | if (ppc_md.set_rtc_time) | ||
56 | return ppc_md.set_rtc_time(time); | ||
57 | return -EINVAL; | ||
58 | } | ||
59 | |||
60 | static inline unsigned int get_rtc_ss(void) | ||
61 | { | ||
62 | struct rtc_time h; | ||
63 | |||
64 | get_rtc_time(&h); | ||
65 | return h.tm_sec; | ||
66 | } | ||
67 | |||
68 | static inline int get_rtc_pll(struct rtc_pll_info *pll) | ||
69 | { | ||
70 | return -EINVAL; | ||
71 | } | ||
72 | static inline int set_rtc_pll(struct rtc_pll_info *pll) | ||
73 | { | ||
74 | return -EINVAL; | ||
75 | } | ||
76 | |||
77 | #endif /* __KERNEL__ */ | ||
78 | #endif /* __ASM_POWERPC_RTC_H__ */ | ||
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 4e7759c8ca30..3efbedefba6a 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #include <linux/irq_work.h> | 56 | #include <linux/irq_work.h> |
57 | #include <linux/clk-provider.h> | 57 | #include <linux/clk-provider.h> |
58 | #include <linux/suspend.h> | 58 | #include <linux/suspend.h> |
59 | #include <linux/rtc.h> | ||
59 | #include <asm/trace.h> | 60 | #include <asm/trace.h> |
60 | 61 | ||
61 | #include <asm/io.h> | 62 | #include <asm/io.h> |
@@ -1159,6 +1160,29 @@ void calibrate_delay(void) | |||
1159 | loops_per_jiffy = tb_ticks_per_jiffy; | 1160 | loops_per_jiffy = tb_ticks_per_jiffy; |
1160 | } | 1161 | } |
1161 | 1162 | ||
1163 | #if IS_ENABLED(CONFIG_RTC_DRV_GENERIC) | ||
1164 | static int rtc_generic_get_time(struct device *dev, struct rtc_time *tm) | ||
1165 | { | ||
1166 | ppc_md.get_rtc_time(tm); | ||
1167 | return rtc_valid_tm(tm); | ||
1168 | } | ||
1169 | |||
1170 | static int rtc_generic_set_time(struct device *dev, struct rtc_time *tm) | ||
1171 | { | ||
1172 | if (!ppc_md.set_rtc_time) | ||
1173 | return -EOPNOTSUPP; | ||
1174 | |||
1175 | if (ppc_md.set_rtc_time(tm) < 0) | ||
1176 | return -EOPNOTSUPP; | ||
1177 | |||
1178 | return 0; | ||
1179 | } | ||
1180 | |||
1181 | static const struct rtc_class_ops rtc_generic_ops = { | ||
1182 | .read_time = rtc_generic_get_time, | ||
1183 | .set_time = rtc_generic_set_time, | ||
1184 | }; | ||
1185 | |||
1162 | static int __init rtc_init(void) | 1186 | static int __init rtc_init(void) |
1163 | { | 1187 | { |
1164 | struct platform_device *pdev; | 1188 | struct platform_device *pdev; |
@@ -1166,9 +1190,12 @@ static int __init rtc_init(void) | |||
1166 | if (!ppc_md.get_rtc_time) | 1190 | if (!ppc_md.get_rtc_time) |
1167 | return -ENODEV; | 1191 | return -ENODEV; |
1168 | 1192 | ||
1169 | pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0); | 1193 | pdev = platform_device_register_data(NULL, "rtc-generic", -1, |
1194 | &rtc_generic_ops, | ||
1195 | sizeof(rtc_generic_ops)); | ||
1170 | 1196 | ||
1171 | return PTR_ERR_OR_ZERO(pdev); | 1197 | return PTR_ERR_OR_ZERO(pdev); |
1172 | } | 1198 | } |
1173 | 1199 | ||
1174 | device_initcall(rtc_init); | 1200 | device_initcall(rtc_init); |
1201 | #endif | ||
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index 3663f71fd913..fbdae8377b71 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig | |||
@@ -321,6 +321,17 @@ config OF_RTC | |||
321 | Uses information from the OF or flattened device tree to instantiate | 321 | Uses information from the OF or flattened device tree to instantiate |
322 | platform devices for direct mapped RTC chips like the DS1742 or DS1743. | 322 | platform devices for direct mapped RTC chips like the DS1742 or DS1743. |
323 | 323 | ||
324 | config GEN_RTC | ||
325 | bool "Use the platform RTC operations from user space" | ||
326 | select RTC_CLASS | ||
327 | select RTC_DRV_GENERIC | ||
328 | help | ||
329 | This option provides backwards compatibility with the old gen_rtc.ko | ||
330 | module that was traditionally used for old PowerPC machines. | ||
331 | Platforms should migrate to enabling the RTC_DRV_GENERIC by hand | ||
332 | replacing their get_rtc_time/set_rtc_time callbacks with | ||
333 | a proper RTC device driver. | ||
334 | |||
324 | config SIMPLE_GPIO | 335 | config SIMPLE_GPIO |
325 | bool "Support for simple, memory-mapped GPIO controllers" | 336 | bool "Support for simple, memory-mapped GPIO controllers" |
326 | depends on PPC | 337 | depends on PPC |
diff --git a/arch/powerpc/platforms/ps3/time.c b/arch/powerpc/platforms/ps3/time.c index 791c6142c4a7..11b45b58c81b 100644 --- a/arch/powerpc/platforms/ps3/time.c +++ b/arch/powerpc/platforms/ps3/time.c | |||
@@ -20,9 +20,9 @@ | |||
20 | 20 | ||
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/rtc.h> | ||
23 | 24 | ||
24 | #include <asm/firmware.h> | 25 | #include <asm/firmware.h> |
25 | #include <asm/rtc.h> | ||
26 | #include <asm/lv1call.h> | 26 | #include <asm/lv1call.h> |
27 | #include <asm/ps3.h> | 27 | #include <asm/ps3.h> |
28 | 28 | ||
diff --git a/arch/sh/include/asm/mc146818rtc.h b/arch/sh/include/asm/mc146818rtc.h deleted file mode 100644 index 0aee96a97330..000000000000 --- a/arch/sh/include/asm/mc146818rtc.h +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | /* | ||
2 | * Machine dependent access functions for RTC registers. | ||
3 | */ | ||
4 | #ifndef _ASM_MC146818RTC_H | ||
5 | #define _ASM_MC146818RTC_H | ||
6 | |||
7 | #endif /* _ASM_MC146818RTC_H */ | ||
diff --git a/arch/sh/include/asm/rtc.h b/arch/sh/include/asm/rtc.h index 52b0c2dba979..f7b010d48af7 100644 --- a/arch/sh/include/asm/rtc.h +++ b/arch/sh/include/asm/rtc.h | |||
@@ -6,17 +6,6 @@ extern void (*board_time_init)(void); | |||
6 | extern void (*rtc_sh_get_time)(struct timespec *); | 6 | extern void (*rtc_sh_get_time)(struct timespec *); |
7 | extern int (*rtc_sh_set_time)(const time_t); | 7 | extern int (*rtc_sh_set_time)(const time_t); |
8 | 8 | ||
9 | /* some dummy definitions */ | ||
10 | #define RTC_BATT_BAD 0x100 /* battery bad */ | ||
11 | #define RTC_SQWE 0x08 /* enable square-wave output */ | ||
12 | #define RTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */ | ||
13 | #define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */ | ||
14 | #define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */ | ||
15 | |||
16 | struct rtc_time; | ||
17 | unsigned int get_rtc_time(struct rtc_time *); | ||
18 | int set_rtc_time(struct rtc_time *); | ||
19 | |||
20 | #define RTC_CAP_4_DIGIT_YEAR (1 << 0) | 9 | #define RTC_CAP_4_DIGIT_YEAR (1 << 0) |
21 | 10 | ||
22 | struct sh_rtc_platform_info { | 11 | struct sh_rtc_platform_info { |
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c index d6d0a986c6e9..a4a7862b489a 100644 --- a/arch/sh/kernel/time.c +++ b/arch/sh/kernel/time.c | |||
@@ -50,27 +50,31 @@ int update_persistent_clock(struct timespec now) | |||
50 | } | 50 | } |
51 | #endif | 51 | #endif |
52 | 52 | ||
53 | unsigned int get_rtc_time(struct rtc_time *tm) | 53 | static int rtc_generic_get_time(struct device *dev, struct rtc_time *tm) |
54 | { | 54 | { |
55 | if (rtc_sh_get_time != null_rtc_get_time) { | 55 | struct timespec tv; |
56 | struct timespec tv; | ||
57 | 56 | ||
58 | rtc_sh_get_time(&tv); | 57 | rtc_sh_get_time(&tv); |
59 | rtc_time_to_tm(tv.tv_sec, tm); | 58 | rtc_time_to_tm(tv.tv_sec, tm); |
60 | } | 59 | return 0; |
61 | |||
62 | return RTC_24H; | ||
63 | } | 60 | } |
64 | EXPORT_SYMBOL(get_rtc_time); | ||
65 | 61 | ||
66 | int set_rtc_time(struct rtc_time *tm) | 62 | static int rtc_generic_set_time(struct device *dev, struct rtc_time *tm) |
67 | { | 63 | { |
68 | unsigned long secs; | 64 | unsigned long secs; |
69 | 65 | ||
70 | rtc_tm_to_time(tm, &secs); | 66 | rtc_tm_to_time(tm, &secs); |
71 | return rtc_sh_set_time(secs); | 67 | if ((rtc_sh_set_time == null_rtc_set_time) || |
68 | (rtc_sh_set_time(secs) < 0)) | ||
69 | return -EOPNOTSUPP; | ||
70 | |||
71 | return 0; | ||
72 | } | 72 | } |
73 | EXPORT_SYMBOL(set_rtc_time); | 73 | |
74 | static const struct rtc_class_ops rtc_generic_ops = { | ||
75 | .read_time = rtc_generic_get_time, | ||
76 | .set_time = rtc_generic_set_time, | ||
77 | }; | ||
74 | 78 | ||
75 | static int __init rtc_generic_init(void) | 79 | static int __init rtc_generic_init(void) |
76 | { | 80 | { |
@@ -79,7 +83,10 @@ static int __init rtc_generic_init(void) | |||
79 | if (rtc_sh_get_time == null_rtc_get_time) | 83 | if (rtc_sh_get_time == null_rtc_get_time) |
80 | return -ENODEV; | 84 | return -ENODEV; |
81 | 85 | ||
82 | pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0); | 86 | pdev = platform_device_register_data(NULL, "rtc-generic", -1, |
87 | &rtc_generic_ops, | ||
88 | sizeof(rtc_generic_ops)); | ||
89 | |||
83 | 90 | ||
84 | return PTR_ERR_OR_ZERO(pdev); | 91 | return PTR_ERR_OR_ZERO(pdev); |
85 | } | 92 | } |
diff --git a/arch/sparc/include/asm/io_32.h b/arch/sparc/include/asm/io_32.h index 57f26c398dc9..4dd268a3a8b0 100644 --- a/arch/sparc/include/asm/io_32.h +++ b/arch/sparc/include/asm/io_32.h | |||
@@ -140,16 +140,6 @@ void ioport_unmap(void __iomem *); | |||
140 | struct pci_dev; | 140 | struct pci_dev; |
141 | void pci_iounmap(struct pci_dev *dev, void __iomem *); | 141 | void pci_iounmap(struct pci_dev *dev, void __iomem *); |
142 | 142 | ||
143 | |||
144 | |||
145 | /* | ||
146 | * At the moment, we do not use CMOS_READ anywhere outside of rtc.c, | ||
147 | * so rtc_port is static in it. This should not change unless a new | ||
148 | * hardware pops up. | ||
149 | */ | ||
150 | #define RTC_PORT(x) (rtc_port + (x)) | ||
151 | #define RTC_ALWAYS_BCD 0 | ||
152 | |||
153 | static inline int sbus_can_dma_64bit(void) | 143 | static inline int sbus_can_dma_64bit(void) |
154 | { | 144 | { |
155 | return 0; /* actually, sparc_cpu_model==sun4d */ | 145 | return 0; /* actually, sparc_cpu_model==sun4d */ |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 3a9add58d794..5c6e7471b732 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -152,6 +152,7 @@ config X86 | |||
152 | select OLD_SIGSUSPEND3 if X86_32 || IA32_EMULATION | 152 | select OLD_SIGSUSPEND3 if X86_32 || IA32_EMULATION |
153 | select PERF_EVENTS | 153 | select PERF_EVENTS |
154 | select RTC_LIB | 154 | select RTC_LIB |
155 | select RTC_MC146818_LIB | ||
155 | select SPARSE_IRQ | 156 | select SPARSE_IRQ |
156 | select SRCU | 157 | select SRCU |
157 | select SYSCTL_EXCEPTION_TRACE | 158 | select SYSCTL_EXCEPTION_TRACE |
diff --git a/arch/x86/include/asm/mc146818rtc.h b/arch/x86/include/asm/mc146818rtc.h index 0f555cc31984..24acd9ba7837 100644 --- a/arch/x86/include/asm/mc146818rtc.h +++ b/arch/x86/include/asm/mc146818rtc.h | |||
@@ -6,7 +6,6 @@ | |||
6 | 6 | ||
7 | #include <asm/io.h> | 7 | #include <asm/io.h> |
8 | #include <asm/processor.h> | 8 | #include <asm/processor.h> |
9 | #include <linux/mc146818rtc.h> | ||
10 | 9 | ||
11 | #ifndef RTC_PORT | 10 | #ifndef RTC_PORT |
12 | #define RTC_PORT(x) (0x70 + (x)) | 11 | #define RTC_PORT(x) (0x70 + (x)) |
diff --git a/arch/x86/include/asm/rtc.h b/arch/x86/include/asm/rtc.h deleted file mode 100644 index f71c3b0ed360..000000000000 --- a/arch/x86/include/asm/rtc.h +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | #include <asm-generic/rtc.h> | ||
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 3d747070fe67..ed16e58658a4 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c | |||
@@ -1019,7 +1019,6 @@ void hpet_disable(void) | |||
1019 | */ | 1019 | */ |
1020 | #include <linux/mc146818rtc.h> | 1020 | #include <linux/mc146818rtc.h> |
1021 | #include <linux/rtc.h> | 1021 | #include <linux/rtc.h> |
1022 | #include <asm/rtc.h> | ||
1023 | 1022 | ||
1024 | #define DEFAULT_RTC_INT_FREQ 64 | 1023 | #define DEFAULT_RTC_INT_FREQ 64 |
1025 | #define DEFAULT_RTC_SHIFT 6 | 1024 | #define DEFAULT_RTC_SHIFT 6 |
@@ -1243,7 +1242,7 @@ irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) | |||
1243 | memset(&curr_time, 0, sizeof(struct rtc_time)); | 1242 | memset(&curr_time, 0, sizeof(struct rtc_time)); |
1244 | 1243 | ||
1245 | if (hpet_rtc_flags & (RTC_UIE | RTC_AIE)) | 1244 | if (hpet_rtc_flags & (RTC_UIE | RTC_AIE)) |
1246 | get_rtc_time(&curr_time); | 1245 | mc146818_set_time(&curr_time); |
1247 | 1246 | ||
1248 | if (hpet_rtc_flags & RTC_UIE && | 1247 | if (hpet_rtc_flags & RTC_UIE && |
1249 | curr_time.tm_sec != hpet_prev_update_sec) { | 1248 | curr_time.tm_sec != hpet_prev_update_sec) { |
diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c index 04b132a767f1..bfe4d6c96fbd 100644 --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/debugfs.h> | 17 | #include <linux/debugfs.h> |
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/hardirq.h> | 19 | #include <linux/hardirq.h> |
20 | #include <linux/ratelimit.h> | ||
20 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
21 | #include <linux/export.h> | 22 | #include <linux/export.h> |
22 | 23 | ||
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c index eceaa082ec3f..79c6311cd912 100644 --- a/arch/x86/kernel/rtc.c +++ b/arch/x86/kernel/rtc.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <asm/x86_init.h> | 13 | #include <asm/x86_init.h> |
14 | #include <asm/time.h> | 14 | #include <asm/time.h> |
15 | #include <asm/intel-mid.h> | 15 | #include <asm/intel-mid.h> |
16 | #include <asm/rtc.h> | ||
17 | #include <asm/setup.h> | 16 | #include <asm/setup.h> |
18 | 17 | ||
19 | #ifdef CONFIG_X86_32 | 18 | #ifdef CONFIG_X86_32 |
@@ -47,7 +46,7 @@ int mach_set_rtc_mmss(const struct timespec *now) | |||
47 | 46 | ||
48 | rtc_time_to_tm(nowtime, &tm); | 47 | rtc_time_to_tm(nowtime, &tm); |
49 | if (!rtc_valid_tm(&tm)) { | 48 | if (!rtc_valid_tm(&tm)) { |
50 | retval = set_rtc_time(&tm); | 49 | retval = mc146818_set_time(&tm); |
51 | if (retval) | 50 | if (retval) |
52 | printk(KERN_ERR "%s: RTC write failed with error %d\n", | 51 | printk(KERN_ERR "%s: RTC write failed with error %d\n", |
53 | __func__, retval); | 52 | __func__, retval); |
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 17c8bbd4e2f0..1fbb408e2e72 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
@@ -51,7 +51,6 @@ | |||
51 | #include <asm/cacheflush.h> | 51 | #include <asm/cacheflush.h> |
52 | #include <asm/tlbflush.h> | 52 | #include <asm/tlbflush.h> |
53 | #include <asm/x86_init.h> | 53 | #include <asm/x86_init.h> |
54 | #include <asm/rtc.h> | ||
55 | #include <asm/uv/uv.h> | 54 | #include <asm/uv/uv.h> |
56 | 55 | ||
57 | static struct efi efi_phys __initdata; | 56 | static struct efi efi_phys __initdata; |
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 04db6fbce96d..677e29e29473 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/bootmem.h> | 25 | #include <linux/bootmem.h> |
26 | #include <linux/ioport.h> | 26 | #include <linux/ioport.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/mc146818rtc.h> | ||
28 | #include <linux/efi.h> | 29 | #include <linux/efi.h> |
29 | #include <linux/uaccess.h> | 30 | #include <linux/uaccess.h> |
30 | #include <linux/io.h> | 31 | #include <linux/io.h> |
diff --git a/arch/x86/platform/intel-mid/intel_mid_vrtc.c b/arch/x86/platform/intel-mid/intel_mid_vrtc.c index ee40fcb6e54d..58024862a7eb 100644 --- a/arch/x86/platform/intel-mid/intel_mid_vrtc.c +++ b/arch/x86/platform/intel-mid/intel_mid_vrtc.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/sfi.h> | 23 | #include <linux/sfi.h> |
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/mc146818rtc.h> | ||
25 | 26 | ||
26 | #include <asm/intel-mid.h> | 27 | #include <asm/intel-mid.h> |
27 | #include <asm/intel_mid_vrtc.h> | 28 | #include <asm/intel_mid_vrtc.h> |
diff --git a/drivers/acpi/acpi_cmos_rtc.c b/drivers/acpi/acpi_cmos_rtc.c index 81dc75033f15..0980a133916f 100644 --- a/drivers/acpi/acpi_cmos_rtc.c +++ b/drivers/acpi/acpi_cmos_rtc.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <asm-generic/rtc.h> | 17 | #include <linux/mc146818rtc.h> |
18 | 18 | ||
19 | #include "internal.h" | 19 | #include "internal.h" |
20 | 20 | ||
diff --git a/drivers/base/power/trace.c b/drivers/base/power/trace.c index a6975795e7f3..efec10b49d59 100644 --- a/drivers/base/power/trace.c +++ b/drivers/base/power/trace.c | |||
@@ -11,7 +11,7 @@ | |||
11 | #include <linux/export.h> | 11 | #include <linux/export.h> |
12 | #include <linux/rtc.h> | 12 | #include <linux/rtc.h> |
13 | 13 | ||
14 | #include <asm/rtc.h> | 14 | #include <linux/mc146818rtc.h> |
15 | 15 | ||
16 | #include "power.h" | 16 | #include "power.h" |
17 | 17 | ||
@@ -103,7 +103,7 @@ static int set_magic_time(unsigned int user, unsigned int file, unsigned int dev | |||
103 | n /= 24; | 103 | n /= 24; |
104 | time.tm_min = (n % 20) * 3; | 104 | time.tm_min = (n % 20) * 3; |
105 | n /= 20; | 105 | n /= 20; |
106 | set_rtc_time(&time); | 106 | mc146818_set_time(&time); |
107 | return n ? -1 : 0; | 107 | return n ? -1 : 0; |
108 | } | 108 | } |
109 | 109 | ||
@@ -112,7 +112,7 @@ static unsigned int read_magic_time(void) | |||
112 | struct rtc_time time; | 112 | struct rtc_time time; |
113 | unsigned int val; | 113 | unsigned int val; |
114 | 114 | ||
115 | get_rtc_time(&time); | 115 | mc146818_get_time(&time); |
116 | pr_info("RTC time: %2d:%02d:%02d, date: %02d/%02d/%02d\n", | 116 | pr_info("RTC time: %2d:%02d:%02d, date: %02d/%02d/%02d\n", |
117 | time.tm_hour, time.tm_min, time.tm_sec, | 117 | time.tm_hour, time.tm_min, time.tm_sec, |
118 | time.tm_mon + 1, time.tm_mday, time.tm_year % 100); | 118 | time.tm_mon + 1, time.tm_mday, time.tm_year % 100); |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index fdb8f3e10b6f..dcc09739a54e 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -293,7 +293,7 @@ if RTC_LIB=n | |||
293 | 293 | ||
294 | config RTC | 294 | config RTC |
295 | tristate "Enhanced Real Time Clock Support (legacy PC RTC driver)" | 295 | tristate "Enhanced Real Time Clock Support (legacy PC RTC driver)" |
296 | depends on ALPHA || (MIPS && MACH_LOONGSON64) || MN10300 | 296 | depends on ALPHA || (MIPS && MACH_LOONGSON64) |
297 | ---help--- | 297 | ---help--- |
298 | If you say Y here and create a character special file /dev/rtc with | 298 | If you say Y here and create a character special file /dev/rtc with |
299 | major number 10 and minor number 135 using mknod ("man mknod"), you | 299 | major number 10 and minor number 135 using mknod ("man mknod"), you |
@@ -339,32 +339,6 @@ config JS_RTC | |||
339 | To compile this driver as a module, choose M here: the | 339 | To compile this driver as a module, choose M here: the |
340 | module will be called js-rtc. | 340 | module will be called js-rtc. |
341 | 341 | ||
342 | config GEN_RTC | ||
343 | tristate "Generic /dev/rtc emulation" | ||
344 | depends on RTC!=y | ||
345 | depends on ALPHA || M68K || MN10300 || PARISC || PPC || X86 | ||
346 | ---help--- | ||
347 | If you say Y here and create a character special file /dev/rtc with | ||
348 | major number 10 and minor number 135 using mknod ("man mknod"), you | ||
349 | will get access to the real time clock (or hardware clock) built | ||
350 | into your computer. | ||
351 | |||
352 | It reports status information via the file /proc/driver/rtc and its | ||
353 | behaviour is set by various ioctls on /dev/rtc. If you enable the | ||
354 | "extended RTC operation" below it will also provide an emulation | ||
355 | for RTC_UIE which is required by some programs and may improve | ||
356 | precision in some cases. | ||
357 | |||
358 | To compile this driver as a module, choose M here: the | ||
359 | module will be called genrtc. | ||
360 | |||
361 | config GEN_RTC_X | ||
362 | bool "Extended RTC operation" | ||
363 | depends on GEN_RTC | ||
364 | help | ||
365 | Provides an emulation for RTC_UIE which is required by some programs | ||
366 | and may improve precision of the generic RTC support in some cases. | ||
367 | |||
368 | config EFI_RTC | 342 | config EFI_RTC |
369 | bool "EFI Real Time Clock Services" | 343 | bool "EFI Real Time Clock Services" |
370 | depends on IA64 | 344 | depends on IA64 |
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 55d16bf3ccc5..6e6c244a66a0 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
@@ -25,7 +25,6 @@ obj-$(CONFIG_APPLICOM) += applicom.o | |||
25 | obj-$(CONFIG_SONYPI) += sonypi.o | 25 | obj-$(CONFIG_SONYPI) += sonypi.o |
26 | obj-$(CONFIG_RTC) += rtc.o | 26 | obj-$(CONFIG_RTC) += rtc.o |
27 | obj-$(CONFIG_HPET) += hpet.o | 27 | obj-$(CONFIG_HPET) += hpet.o |
28 | obj-$(CONFIG_GEN_RTC) += genrtc.o | ||
29 | obj-$(CONFIG_EFI_RTC) += efirtc.o | 28 | obj-$(CONFIG_EFI_RTC) += efirtc.o |
30 | obj-$(CONFIG_DS1302) += ds1302.o | 29 | obj-$(CONFIG_DS1302) += ds1302.o |
31 | obj-$(CONFIG_XILINX_HWICAP) += xilinx_hwicap/ | 30 | obj-$(CONFIG_XILINX_HWICAP) += xilinx_hwicap/ |
diff --git a/drivers/char/genrtc.c b/drivers/char/genrtc.c deleted file mode 100644 index 4f943759d376..000000000000 --- a/drivers/char/genrtc.c +++ /dev/null | |||
@@ -1,539 +0,0 @@ | |||
1 | /* | ||
2 | * Real Time Clock interface for | ||
3 | * - q40 and other m68k machines, | ||
4 | * - HP PARISC machines | ||
5 | * - PowerPC machines | ||
6 | * emulate some RTC irq capabilities in software | ||
7 | * | ||
8 | * Copyright (C) 1999 Richard Zidlicky | ||
9 | * | ||
10 | * based on Paul Gortmaker's rtc.c device and | ||
11 | * Sam Creasey Generic rtc driver | ||
12 | * | ||
13 | * This driver allows use of the real time clock (built into | ||
14 | * nearly all computers) from user space. It exports the /dev/rtc | ||
15 | * interface supporting various ioctl() and also the /proc/driver/rtc | ||
16 | * pseudo-file for status information. | ||
17 | * | ||
18 | * The ioctls can be used to set the interrupt behaviour where | ||
19 | * supported. | ||
20 | * | ||
21 | * The /dev/rtc interface will block on reads until an interrupt | ||
22 | * has been received. If a RTC interrupt has already happened, | ||
23 | * it will output an unsigned long and then block. The output value | ||
24 | * contains the interrupt status in the low byte and the number of | ||
25 | * interrupts since the last read in the remaining high bytes. The | ||
26 | * /dev/rtc interface can also be used with the select(2) call. | ||
27 | * | ||
28 | * This program is free software; you can redistribute it and/or | ||
29 | * modify it under the terms of the GNU General Public License | ||
30 | * as published by the Free Software Foundation; either version | ||
31 | * 2 of the License, or (at your option) any later version. | ||
32 | * | ||
33 | |||
34 | * 1.01 fix for 2.3.X rz@linux-m68k.org | ||
35 | * 1.02 merged with code from genrtc.c rz@linux-m68k.org | ||
36 | * 1.03 make it more portable zippel@linux-m68k.org | ||
37 | * 1.04 removed useless timer code rz@linux-m68k.org | ||
38 | * 1.05 portable RTC_UIE emulation rz@linux-m68k.org | ||
39 | * 1.06 set_rtc_time can return an error trini@kernel.crashing.org | ||
40 | * 1.07 ported to HP PARISC (hppa) Helge Deller <deller@gmx.de> | ||
41 | */ | ||
42 | |||
43 | #define RTC_VERSION "1.07" | ||
44 | |||
45 | #include <linux/module.h> | ||
46 | #include <linux/sched.h> | ||
47 | #include <linux/errno.h> | ||
48 | #include <linux/miscdevice.h> | ||
49 | #include <linux/fcntl.h> | ||
50 | |||
51 | #include <linux/rtc.h> | ||
52 | #include <linux/init.h> | ||
53 | #include <linux/poll.h> | ||
54 | #include <linux/proc_fs.h> | ||
55 | #include <linux/seq_file.h> | ||
56 | #include <linux/mutex.h> | ||
57 | #include <linux/workqueue.h> | ||
58 | |||
59 | #include <asm/uaccess.h> | ||
60 | #include <asm/rtc.h> | ||
61 | |||
62 | /* | ||
63 | * We sponge a minor off of the misc major. No need slurping | ||
64 | * up another valuable major dev number for this. If you add | ||
65 | * an ioctl, make sure you don't conflict with SPARC's RTC | ||
66 | * ioctls. | ||
67 | */ | ||
68 | |||
69 | static DEFINE_MUTEX(gen_rtc_mutex); | ||
70 | static DECLARE_WAIT_QUEUE_HEAD(gen_rtc_wait); | ||
71 | |||
72 | /* | ||
73 | * Bits in gen_rtc_status. | ||
74 | */ | ||
75 | |||
76 | #define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ | ||
77 | |||
78 | static unsigned char gen_rtc_status; /* bitmapped status byte. */ | ||
79 | static unsigned long gen_rtc_irq_data; /* our output to the world */ | ||
80 | |||
81 | /* months start at 0 now */ | ||
82 | static unsigned char days_in_mo[] = | ||
83 | {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; | ||
84 | |||
85 | static int irq_active; | ||
86 | |||
87 | #ifdef CONFIG_GEN_RTC_X | ||
88 | static struct work_struct genrtc_task; | ||
89 | static struct timer_list timer_task; | ||
90 | |||
91 | static unsigned int oldsecs; | ||
92 | static int lostint; | ||
93 | static unsigned long tt_exp; | ||
94 | |||
95 | static void gen_rtc_timer(unsigned long data); | ||
96 | |||
97 | static volatile int stask_active; /* schedule_work */ | ||
98 | static volatile int ttask_active; /* timer_task */ | ||
99 | static int stop_rtc_timers; /* don't requeue tasks */ | ||
100 | static DEFINE_SPINLOCK(gen_rtc_lock); | ||
101 | |||
102 | static void gen_rtc_interrupt(unsigned long arg); | ||
103 | |||
104 | /* | ||
105 | * Routine to poll RTC seconds field for change as often as possible, | ||
106 | * after first RTC_UIE use timer to reduce polling | ||
107 | */ | ||
108 | static void genrtc_troutine(struct work_struct *work) | ||
109 | { | ||
110 | unsigned int tmp = get_rtc_ss(); | ||
111 | |||
112 | if (stop_rtc_timers) { | ||
113 | stask_active = 0; | ||
114 | return; | ||
115 | } | ||
116 | |||
117 | if (oldsecs != tmp){ | ||
118 | oldsecs = tmp; | ||
119 | |||
120 | timer_task.function = gen_rtc_timer; | ||
121 | timer_task.expires = jiffies + HZ - (HZ/10); | ||
122 | tt_exp=timer_task.expires; | ||
123 | ttask_active=1; | ||
124 | stask_active=0; | ||
125 | add_timer(&timer_task); | ||
126 | |||
127 | gen_rtc_interrupt(0); | ||
128 | } else if (schedule_work(&genrtc_task) == 0) | ||
129 | stask_active = 0; | ||
130 | } | ||
131 | |||
132 | static void gen_rtc_timer(unsigned long data) | ||
133 | { | ||
134 | lostint = get_rtc_ss() - oldsecs ; | ||
135 | if (lostint<0) | ||
136 | lostint = 60 - lostint; | ||
137 | if (time_after(jiffies, tt_exp)) | ||
138 | printk(KERN_INFO "genrtc: timer task delayed by %ld jiffies\n", | ||
139 | jiffies-tt_exp); | ||
140 | ttask_active=0; | ||
141 | stask_active=1; | ||
142 | if ((schedule_work(&genrtc_task) == 0)) | ||
143 | stask_active = 0; | ||
144 | } | ||
145 | |||
146 | /* | ||
147 | * call gen_rtc_interrupt function to signal an RTC_UIE, | ||
148 | * arg is unused. | ||
149 | * Could be invoked either from a real interrupt handler or | ||
150 | * from some routine that periodically (eg 100HZ) monitors | ||
151 | * whether RTC_SECS changed | ||
152 | */ | ||
153 | static void gen_rtc_interrupt(unsigned long arg) | ||
154 | { | ||
155 | /* We store the status in the low byte and the number of | ||
156 | * interrupts received since the last read in the remainder | ||
157 | * of rtc_irq_data. */ | ||
158 | |||
159 | gen_rtc_irq_data += 0x100; | ||
160 | gen_rtc_irq_data &= ~0xff; | ||
161 | gen_rtc_irq_data |= RTC_UIE; | ||
162 | |||
163 | if (lostint){ | ||
164 | printk("genrtc: system delaying clock ticks?\n"); | ||
165 | /* increment count so that userspace knows something is wrong */ | ||
166 | gen_rtc_irq_data += ((lostint-1)<<8); | ||
167 | lostint = 0; | ||
168 | } | ||
169 | |||
170 | wake_up_interruptible(&gen_rtc_wait); | ||
171 | } | ||
172 | |||
173 | /* | ||
174 | * Now all the various file operations that we export. | ||
175 | */ | ||
176 | static ssize_t gen_rtc_read(struct file *file, char __user *buf, | ||
177 | size_t count, loff_t *ppos) | ||
178 | { | ||
179 | unsigned long data; | ||
180 | ssize_t retval; | ||
181 | |||
182 | if (count != sizeof (unsigned int) && count != sizeof (unsigned long)) | ||
183 | return -EINVAL; | ||
184 | |||
185 | if (file->f_flags & O_NONBLOCK && !gen_rtc_irq_data) | ||
186 | return -EAGAIN; | ||
187 | |||
188 | retval = wait_event_interruptible(gen_rtc_wait, | ||
189 | (data = xchg(&gen_rtc_irq_data, 0))); | ||
190 | if (retval) | ||
191 | goto out; | ||
192 | |||
193 | /* first test allows optimizer to nuke this case for 32-bit machines */ | ||
194 | if (sizeof (int) != sizeof (long) && count == sizeof (unsigned int)) { | ||
195 | unsigned int uidata = data; | ||
196 | retval = put_user(uidata, (unsigned int __user *)buf) ?: | ||
197 | sizeof(unsigned int); | ||
198 | } | ||
199 | else { | ||
200 | retval = put_user(data, (unsigned long __user *)buf) ?: | ||
201 | sizeof(unsigned long); | ||
202 | } | ||
203 | out: | ||
204 | return retval; | ||
205 | } | ||
206 | |||
207 | static unsigned int gen_rtc_poll(struct file *file, | ||
208 | struct poll_table_struct *wait) | ||
209 | { | ||
210 | poll_wait(file, &gen_rtc_wait, wait); | ||
211 | if (gen_rtc_irq_data != 0) | ||
212 | return POLLIN | POLLRDNORM; | ||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | #endif | ||
217 | |||
218 | /* | ||
219 | * Used to disable/enable interrupts, only RTC_UIE supported | ||
220 | * We also clear out any old irq data after an ioctl() that | ||
221 | * meddles with the interrupt enable/disable bits. | ||
222 | */ | ||
223 | |||
224 | static inline void gen_clear_rtc_irq_bit(unsigned char bit) | ||
225 | { | ||
226 | #ifdef CONFIG_GEN_RTC_X | ||
227 | stop_rtc_timers = 1; | ||
228 | if (ttask_active){ | ||
229 | del_timer_sync(&timer_task); | ||
230 | ttask_active = 0; | ||
231 | } | ||
232 | while (stask_active) | ||
233 | schedule(); | ||
234 | |||
235 | spin_lock(&gen_rtc_lock); | ||
236 | irq_active = 0; | ||
237 | spin_unlock(&gen_rtc_lock); | ||
238 | #endif | ||
239 | } | ||
240 | |||
241 | static inline int gen_set_rtc_irq_bit(unsigned char bit) | ||
242 | { | ||
243 | #ifdef CONFIG_GEN_RTC_X | ||
244 | spin_lock(&gen_rtc_lock); | ||
245 | if ( !irq_active ) { | ||
246 | irq_active = 1; | ||
247 | stop_rtc_timers = 0; | ||
248 | lostint = 0; | ||
249 | INIT_WORK(&genrtc_task, genrtc_troutine); | ||
250 | oldsecs = get_rtc_ss(); | ||
251 | init_timer(&timer_task); | ||
252 | |||
253 | stask_active = 1; | ||
254 | if (schedule_work(&genrtc_task) == 0){ | ||
255 | stask_active = 0; | ||
256 | } | ||
257 | } | ||
258 | spin_unlock(&gen_rtc_lock); | ||
259 | gen_rtc_irq_data = 0; | ||
260 | return 0; | ||
261 | #else | ||
262 | return -EINVAL; | ||
263 | #endif | ||
264 | } | ||
265 | |||
266 | static int gen_rtc_ioctl(struct file *file, | ||
267 | unsigned int cmd, unsigned long arg) | ||
268 | { | ||
269 | struct rtc_time wtime; | ||
270 | struct rtc_pll_info pll; | ||
271 | void __user *argp = (void __user *)arg; | ||
272 | |||
273 | switch (cmd) { | ||
274 | |||
275 | case RTC_PLL_GET: | ||
276 | if (get_rtc_pll(&pll)) | ||
277 | return -EINVAL; | ||
278 | else | ||
279 | return copy_to_user(argp, &pll, sizeof pll) ? -EFAULT : 0; | ||
280 | |||
281 | case RTC_PLL_SET: | ||
282 | if (!capable(CAP_SYS_TIME)) | ||
283 | return -EACCES; | ||
284 | if (copy_from_user(&pll, argp, sizeof(pll))) | ||
285 | return -EFAULT; | ||
286 | return set_rtc_pll(&pll); | ||
287 | |||
288 | case RTC_UIE_OFF: /* disable ints from RTC updates. */ | ||
289 | gen_clear_rtc_irq_bit(RTC_UIE); | ||
290 | return 0; | ||
291 | |||
292 | case RTC_UIE_ON: /* enable ints for RTC updates. */ | ||
293 | return gen_set_rtc_irq_bit(RTC_UIE); | ||
294 | |||
295 | case RTC_RD_TIME: /* Read the time/date from RTC */ | ||
296 | /* this doesn't get week-day, who cares */ | ||
297 | memset(&wtime, 0, sizeof(wtime)); | ||
298 | get_rtc_time(&wtime); | ||
299 | |||
300 | return copy_to_user(argp, &wtime, sizeof(wtime)) ? -EFAULT : 0; | ||
301 | |||
302 | case RTC_SET_TIME: /* Set the RTC */ | ||
303 | { | ||
304 | int year; | ||
305 | unsigned char leap_yr; | ||
306 | |||
307 | if (!capable(CAP_SYS_TIME)) | ||
308 | return -EACCES; | ||
309 | |||
310 | if (copy_from_user(&wtime, argp, sizeof(wtime))) | ||
311 | return -EFAULT; | ||
312 | |||
313 | year = wtime.tm_year + 1900; | ||
314 | leap_yr = ((!(year % 4) && (year % 100)) || | ||
315 | !(year % 400)); | ||
316 | |||
317 | if ((wtime.tm_mon < 0 || wtime.tm_mon > 11) || (wtime.tm_mday < 1)) | ||
318 | return -EINVAL; | ||
319 | |||
320 | if (wtime.tm_mday < 0 || wtime.tm_mday > | ||
321 | (days_in_mo[wtime.tm_mon] + ((wtime.tm_mon == 1) && leap_yr))) | ||
322 | return -EINVAL; | ||
323 | |||
324 | if (wtime.tm_hour < 0 || wtime.tm_hour >= 24 || | ||
325 | wtime.tm_min < 0 || wtime.tm_min >= 60 || | ||
326 | wtime.tm_sec < 0 || wtime.tm_sec >= 60) | ||
327 | return -EINVAL; | ||
328 | |||
329 | return set_rtc_time(&wtime); | ||
330 | } | ||
331 | } | ||
332 | |||
333 | return -EINVAL; | ||
334 | } | ||
335 | |||
336 | static long gen_rtc_unlocked_ioctl(struct file *file, unsigned int cmd, | ||
337 | unsigned long arg) | ||
338 | { | ||
339 | int ret; | ||
340 | |||
341 | mutex_lock(&gen_rtc_mutex); | ||
342 | ret = gen_rtc_ioctl(file, cmd, arg); | ||
343 | mutex_unlock(&gen_rtc_mutex); | ||
344 | |||
345 | return ret; | ||
346 | } | ||
347 | |||
348 | /* | ||
349 | * We enforce only one user at a time here with the open/close. | ||
350 | * Also clear the previous interrupt data on an open, and clean | ||
351 | * up things on a close. | ||
352 | */ | ||
353 | |||
354 | static int gen_rtc_open(struct inode *inode, struct file *file) | ||
355 | { | ||
356 | mutex_lock(&gen_rtc_mutex); | ||
357 | if (gen_rtc_status & RTC_IS_OPEN) { | ||
358 | mutex_unlock(&gen_rtc_mutex); | ||
359 | return -EBUSY; | ||
360 | } | ||
361 | |||
362 | gen_rtc_status |= RTC_IS_OPEN; | ||
363 | gen_rtc_irq_data = 0; | ||
364 | irq_active = 0; | ||
365 | mutex_unlock(&gen_rtc_mutex); | ||
366 | |||
367 | return 0; | ||
368 | } | ||
369 | |||
370 | static int gen_rtc_release(struct inode *inode, struct file *file) | ||
371 | { | ||
372 | /* | ||
373 | * Turn off all interrupts once the device is no longer | ||
374 | * in use and clear the data. | ||
375 | */ | ||
376 | |||
377 | gen_clear_rtc_irq_bit(RTC_PIE|RTC_AIE|RTC_UIE); | ||
378 | |||
379 | gen_rtc_status &= ~RTC_IS_OPEN; | ||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | |||
384 | #ifdef CONFIG_PROC_FS | ||
385 | |||
386 | /* | ||
387 | * Info exported via "/proc/driver/rtc". | ||
388 | */ | ||
389 | |||
390 | static int gen_rtc_proc_show(struct seq_file *m, void *v) | ||
391 | { | ||
392 | struct rtc_time tm; | ||
393 | unsigned int flags; | ||
394 | struct rtc_pll_info pll; | ||
395 | |||
396 | flags = get_rtc_time(&tm); | ||
397 | |||
398 | seq_printf(m, | ||
399 | "rtc_time\t: %02d:%02d:%02d\n" | ||
400 | "rtc_date\t: %04d-%02d-%02d\n" | ||
401 | "rtc_epoch\t: %04u\n", | ||
402 | tm.tm_hour, tm.tm_min, tm.tm_sec, | ||
403 | tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 1900); | ||
404 | |||
405 | tm.tm_hour = tm.tm_min = tm.tm_sec = 0; | ||
406 | |||
407 | seq_puts(m, "alarm\t\t: "); | ||
408 | if (tm.tm_hour <= 24) | ||
409 | seq_printf(m, "%02d:", tm.tm_hour); | ||
410 | else | ||
411 | seq_puts(m, "**:"); | ||
412 | |||
413 | if (tm.tm_min <= 59) | ||
414 | seq_printf(m, "%02d:", tm.tm_min); | ||
415 | else | ||
416 | seq_puts(m, "**:"); | ||
417 | |||
418 | if (tm.tm_sec <= 59) | ||
419 | seq_printf(m, "%02d\n", tm.tm_sec); | ||
420 | else | ||
421 | seq_puts(m, "**\n"); | ||
422 | |||
423 | seq_printf(m, | ||
424 | "DST_enable\t: %s\n" | ||
425 | "BCD\t\t: %s\n" | ||
426 | "24hr\t\t: %s\n" | ||
427 | "square_wave\t: %s\n" | ||
428 | "alarm_IRQ\t: %s\n" | ||
429 | "update_IRQ\t: %s\n" | ||
430 | "periodic_IRQ\t: %s\n" | ||
431 | "periodic_freq\t: %ld\n" | ||
432 | "batt_status\t: %s\n", | ||
433 | (flags & RTC_DST_EN) ? "yes" : "no", | ||
434 | (flags & RTC_DM_BINARY) ? "no" : "yes", | ||
435 | (flags & RTC_24H) ? "yes" : "no", | ||
436 | (flags & RTC_SQWE) ? "yes" : "no", | ||
437 | (flags & RTC_AIE) ? "yes" : "no", | ||
438 | irq_active ? "yes" : "no", | ||
439 | (flags & RTC_PIE) ? "yes" : "no", | ||
440 | 0L /* freq */, | ||
441 | (flags & RTC_BATT_BAD) ? "bad" : "okay"); | ||
442 | if (!get_rtc_pll(&pll)) | ||
443 | seq_printf(m, | ||
444 | "PLL adjustment\t: %d\n" | ||
445 | "PLL max +ve adjustment\t: %d\n" | ||
446 | "PLL max -ve adjustment\t: %d\n" | ||
447 | "PLL +ve adjustment factor\t: %d\n" | ||
448 | "PLL -ve adjustment factor\t: %d\n" | ||
449 | "PLL frequency\t: %ld\n", | ||
450 | pll.pll_value, | ||
451 | pll.pll_max, | ||
452 | pll.pll_min, | ||
453 | pll.pll_posmult, | ||
454 | pll.pll_negmult, | ||
455 | pll.pll_clock); | ||
456 | return 0; | ||
457 | } | ||
458 | |||
459 | static int gen_rtc_proc_open(struct inode *inode, struct file *file) | ||
460 | { | ||
461 | return single_open(file, gen_rtc_proc_show, NULL); | ||
462 | } | ||
463 | |||
464 | static const struct file_operations gen_rtc_proc_fops = { | ||
465 | .open = gen_rtc_proc_open, | ||
466 | .read = seq_read, | ||
467 | .llseek = seq_lseek, | ||
468 | .release = single_release, | ||
469 | }; | ||
470 | |||
471 | static int __init gen_rtc_proc_init(void) | ||
472 | { | ||
473 | struct proc_dir_entry *r; | ||
474 | |||
475 | r = proc_create("driver/rtc", 0, NULL, &gen_rtc_proc_fops); | ||
476 | if (!r) | ||
477 | return -ENOMEM; | ||
478 | return 0; | ||
479 | } | ||
480 | #else | ||
481 | static inline int gen_rtc_proc_init(void) { return 0; } | ||
482 | #endif /* CONFIG_PROC_FS */ | ||
483 | |||
484 | |||
485 | /* | ||
486 | * The various file operations we support. | ||
487 | */ | ||
488 | |||
489 | static const struct file_operations gen_rtc_fops = { | ||
490 | .owner = THIS_MODULE, | ||
491 | #ifdef CONFIG_GEN_RTC_X | ||
492 | .read = gen_rtc_read, | ||
493 | .poll = gen_rtc_poll, | ||
494 | #endif | ||
495 | .unlocked_ioctl = gen_rtc_unlocked_ioctl, | ||
496 | .open = gen_rtc_open, | ||
497 | .release = gen_rtc_release, | ||
498 | .llseek = noop_llseek, | ||
499 | }; | ||
500 | |||
501 | static struct miscdevice rtc_gen_dev = | ||
502 | { | ||
503 | .minor = RTC_MINOR, | ||
504 | .name = "rtc", | ||
505 | .fops = &gen_rtc_fops, | ||
506 | }; | ||
507 | |||
508 | static int __init rtc_generic_init(void) | ||
509 | { | ||
510 | int retval; | ||
511 | |||
512 | printk(KERN_INFO "Generic RTC Driver v%s\n", RTC_VERSION); | ||
513 | |||
514 | retval = misc_register(&rtc_gen_dev); | ||
515 | if (retval < 0) | ||
516 | return retval; | ||
517 | |||
518 | retval = gen_rtc_proc_init(); | ||
519 | if (retval) { | ||
520 | misc_deregister(&rtc_gen_dev); | ||
521 | return retval; | ||
522 | } | ||
523 | |||
524 | return 0; | ||
525 | } | ||
526 | |||
527 | static void __exit rtc_generic_exit(void) | ||
528 | { | ||
529 | remove_proc_entry ("driver/rtc", NULL); | ||
530 | misc_deregister(&rtc_gen_dev); | ||
531 | } | ||
532 | |||
533 | |||
534 | module_init(rtc_generic_init); | ||
535 | module_exit(rtc_generic_exit); | ||
536 | |||
537 | MODULE_AUTHOR("Richard Zidlicky"); | ||
538 | MODULE_LICENSE("GPL"); | ||
539 | MODULE_ALIAS_MISCDEV(RTC_MINOR); | ||
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 18639e0cb6e2..e215f50794b6 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -5,6 +5,10 @@ | |||
5 | config RTC_LIB | 5 | config RTC_LIB |
6 | bool | 6 | bool |
7 | 7 | ||
8 | config RTC_MC146818_LIB | ||
9 | bool | ||
10 | select RTC_LIB | ||
11 | |||
8 | menuconfig RTC_CLASS | 12 | menuconfig RTC_CLASS |
9 | bool "Real Time Clock" | 13 | bool "Real Time Clock" |
10 | default n | 14 | default n |
@@ -574,10 +578,10 @@ config RTC_DRV_EM3027 | |||
574 | will be called rtc-em3027. | 578 | will be called rtc-em3027. |
575 | 579 | ||
576 | config RTC_DRV_RV8803 | 580 | config RTC_DRV_RV8803 |
577 | tristate "Micro Crystal RV8803" | 581 | tristate "Micro Crystal RV8803, Epson RX8900" |
578 | help | 582 | help |
579 | If you say yes here you get support for the Micro Crystal | 583 | If you say yes here you get support for the Micro Crystal RV8803 and |
580 | RV8803 RTC chips. | 584 | Epson RX8900 RTC chips. |
581 | 585 | ||
582 | This driver can also be built as a module. If so, the module | 586 | This driver can also be built as a module. If so, the module |
583 | will be called rtc-rv8803. | 587 | will be called rtc-rv8803. |
@@ -670,6 +674,18 @@ config RTC_DRV_DS1390 | |||
670 | This driver can also be built as a module. If so, the module | 674 | This driver can also be built as a module. If so, the module |
671 | will be called rtc-ds1390. | 675 | will be called rtc-ds1390. |
672 | 676 | ||
677 | config RTC_DRV_MAX6916 | ||
678 | tristate "Maxim MAX6916" | ||
679 | help | ||
680 | If you say yes here you will get support for the | ||
681 | Maxim MAX6916 SPI RTC chip. | ||
682 | |||
683 | This driver only supports the RTC feature, and not other chip | ||
684 | features such as alarms. | ||
685 | |||
686 | This driver can also be built as a module. If so, the module | ||
687 | will be called rtc-max6916. | ||
688 | |||
673 | config RTC_DRV_R9701 | 689 | config RTC_DRV_R9701 |
674 | tristate "Epson RTC-9701JE" | 690 | tristate "Epson RTC-9701JE" |
675 | help | 691 | help |
@@ -795,8 +811,9 @@ comment "Platform RTC drivers" | |||
795 | 811 | ||
796 | config RTC_DRV_CMOS | 812 | config RTC_DRV_CMOS |
797 | tristate "PC-style 'CMOS'" | 813 | tristate "PC-style 'CMOS'" |
798 | depends on X86 || ARM || M32R || PPC || MIPS || SPARC64 | 814 | depends on X86 || ARM || M32R || PPC || MIPS || SPARC64 || MN10300 |
799 | default y if X86 | 815 | default y if X86 |
816 | select RTC_MC146818_LIB | ||
800 | help | 817 | help |
801 | Say "yes" here to get direct support for the real time clock | 818 | Say "yes" here to get direct support for the real time clock |
802 | found in every PC or ACPI-based system, and some other boards. | 819 | found in every PC or ACPI-based system, and some other boards. |
@@ -815,6 +832,7 @@ config RTC_DRV_CMOS | |||
815 | config RTC_DRV_ALPHA | 832 | config RTC_DRV_ALPHA |
816 | bool "Alpha PC-style CMOS" | 833 | bool "Alpha PC-style CMOS" |
817 | depends on ALPHA | 834 | depends on ALPHA |
835 | select RTC_MC146818_LIB | ||
818 | default y | 836 | default y |
819 | help | 837 | help |
820 | Direct support for the real-time clock found on every Alpha | 838 | Direct support for the real-time clock found on every Alpha |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index ea2833723fa9..7cf7ad559c79 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -8,6 +8,7 @@ obj-$(CONFIG_RTC_LIB) += rtc-lib.o | |||
8 | obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o | 8 | obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o |
9 | obj-$(CONFIG_RTC_SYSTOHC) += systohc.o | 9 | obj-$(CONFIG_RTC_SYSTOHC) += systohc.o |
10 | obj-$(CONFIG_RTC_CLASS) += rtc-core.o | 10 | obj-$(CONFIG_RTC_CLASS) += rtc-core.o |
11 | obj-$(CONFIG_RTC_MC146818_LIB) += rtc-mc146818-lib.o | ||
11 | rtc-core-y := class.o interface.o | 12 | rtc-core-y := class.o interface.o |
12 | 13 | ||
13 | ifdef CONFIG_RTC_DRV_EFI | 14 | ifdef CONFIG_RTC_DRV_EFI |
@@ -85,6 +86,7 @@ obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o | |||
85 | obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o | 86 | obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o |
86 | obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o | 87 | obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o |
87 | obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o | 88 | obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o |
89 | obj-$(CONFIG_RTC_DRV_MAX6916) += rtc-max6916.o | ||
88 | obj-$(CONFIG_RTC_DRV_MAX77686) += rtc-max77686.o | 90 | obj-$(CONFIG_RTC_DRV_MAX77686) += rtc-max77686.o |
89 | obj-$(CONFIG_RTC_DRV_MAX8907) += rtc-max8907.o | 91 | obj-$(CONFIG_RTC_DRV_MAX8907) += rtc-max8907.o |
90 | obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o | 92 | obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o |
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 9ef5f6f89f98..84a52db9b05f 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
@@ -104,7 +104,17 @@ static int rtc_read_alarm_internal(struct rtc_device *rtc, struct rtc_wkalrm *al | |||
104 | else if (!rtc->ops->read_alarm) | 104 | else if (!rtc->ops->read_alarm) |
105 | err = -EINVAL; | 105 | err = -EINVAL; |
106 | else { | 106 | else { |
107 | memset(alarm, 0, sizeof(struct rtc_wkalrm)); | 107 | alarm->enabled = 0; |
108 | alarm->pending = 0; | ||
109 | alarm->time.tm_sec = -1; | ||
110 | alarm->time.tm_min = -1; | ||
111 | alarm->time.tm_hour = -1; | ||
112 | alarm->time.tm_mday = -1; | ||
113 | alarm->time.tm_mon = -1; | ||
114 | alarm->time.tm_year = -1; | ||
115 | alarm->time.tm_wday = -1; | ||
116 | alarm->time.tm_yday = -1; | ||
117 | alarm->time.tm_isdst = -1; | ||
108 | err = rtc->ops->read_alarm(rtc->dev.parent, alarm); | 118 | err = rtc->ops->read_alarm(rtc->dev.parent, alarm); |
109 | } | 119 | } |
110 | 120 | ||
@@ -383,7 +393,7 @@ int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | |||
383 | rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time); | 393 | rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time); |
384 | rtc->aie_timer.period = ktime_set(0, 0); | 394 | rtc->aie_timer.period = ktime_set(0, 0); |
385 | 395 | ||
386 | /* Alarm has to be enabled & in the futrure for us to enqueue it */ | 396 | /* Alarm has to be enabled & in the future for us to enqueue it */ |
387 | if (alarm->enabled && (rtc_tm_to_ktime(now).tv64 < | 397 | if (alarm->enabled && (rtc_tm_to_ktime(now).tv64 < |
388 | rtc->aie_timer.node.expires.tv64)) { | 398 | rtc->aie_timer.node.expires.tv64)) { |
389 | 399 | ||
@@ -395,8 +405,6 @@ int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | |||
395 | } | 405 | } |
396 | EXPORT_SYMBOL_GPL(rtc_initialize_alarm); | 406 | EXPORT_SYMBOL_GPL(rtc_initialize_alarm); |
397 | 407 | ||
398 | |||
399 | |||
400 | int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled) | 408 | int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled) |
401 | { | 409 | { |
402 | int err = mutex_lock_interruptible(&rtc->ops_lock); | 410 | int err = mutex_lock_interruptible(&rtc->ops_lock); |
@@ -748,9 +756,23 @@ EXPORT_SYMBOL_GPL(rtc_irq_set_freq); | |||
748 | */ | 756 | */ |
749 | static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) | 757 | static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) |
750 | { | 758 | { |
759 | struct timerqueue_node *next = timerqueue_getnext(&rtc->timerqueue); | ||
760 | struct rtc_time tm; | ||
761 | ktime_t now; | ||
762 | |||
751 | timer->enabled = 1; | 763 | timer->enabled = 1; |
764 | __rtc_read_time(rtc, &tm); | ||
765 | now = rtc_tm_to_ktime(tm); | ||
766 | |||
767 | /* Skip over expired timers */ | ||
768 | while (next) { | ||
769 | if (next->expires.tv64 >= now.tv64) | ||
770 | break; | ||
771 | next = timerqueue_iterate_next(next); | ||
772 | } | ||
773 | |||
752 | timerqueue_add(&rtc->timerqueue, &timer->node); | 774 | timerqueue_add(&rtc->timerqueue, &timer->node); |
753 | if (&timer->node == timerqueue_getnext(&rtc->timerqueue)) { | 775 | if (!next) { |
754 | struct rtc_wkalrm alarm; | 776 | struct rtc_wkalrm alarm; |
755 | int err; | 777 | int err; |
756 | alarm.time = rtc_ktime_to_tm(timer->node.expires); | 778 | alarm.time = rtc_ktime_to_tm(timer->node.expires); |
diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c index ba0d61934d35..fea9a60b06cf 100644 --- a/drivers/rtc/rtc-abx80x.c +++ b/drivers/rtc/rtc-abx80x.c | |||
@@ -643,17 +643,15 @@ static int abx80x_probe(struct i2c_client *client, | |||
643 | return err; | 643 | return err; |
644 | } | 644 | } |
645 | 645 | ||
646 | err = devm_add_action(&client->dev, rtc_calib_remove_sysfs_group, | 646 | err = devm_add_action_or_reset(&client->dev, |
647 | &client->dev); | 647 | rtc_calib_remove_sysfs_group, |
648 | if (err) { | 648 | &client->dev); |
649 | rtc_calib_remove_sysfs_group(&client->dev); | 649 | if (err) |
650 | dev_err(&client->dev, | 650 | dev_err(&client->dev, |
651 | "Failed to add sysfs cleanup action: %d\n", | 651 | "Failed to add sysfs cleanup action: %d\n", |
652 | err); | 652 | err); |
653 | return err; | ||
654 | } | ||
655 | 653 | ||
656 | return 0; | 654 | return err; |
657 | } | 655 | } |
658 | 656 | ||
659 | static int abx80x_remove(struct i2c_client *client) | 657 | static int abx80x_remove(struct i2c_client *client) |
diff --git a/drivers/rtc/rtc-asm9260.c b/drivers/rtc/rtc-asm9260.c index 355fdb97a006..5219916ce11d 100644 --- a/drivers/rtc/rtc-asm9260.c +++ b/drivers/rtc/rtc-asm9260.c | |||
@@ -343,7 +343,6 @@ static struct platform_driver asm9260_rtc_driver = { | |||
343 | .remove = asm9260_rtc_remove, | 343 | .remove = asm9260_rtc_remove, |
344 | .driver = { | 344 | .driver = { |
345 | .name = "asm9260-rtc", | 345 | .name = "asm9260-rtc", |
346 | .owner = THIS_MODULE, | ||
347 | .of_match_table = asm9260_dt_ids, | 346 | .of_match_table = asm9260_dt_ids, |
348 | }, | 347 | }, |
349 | }; | 348 | }; |
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 99732e6f8c3b..7418a763ce52 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c | |||
@@ -375,6 +375,7 @@ static int at91_rtc_probe(struct platform_device *pdev) | |||
375 | if (!rtc) | 375 | if (!rtc) |
376 | return -ENOMEM; | 376 | return -ENOMEM; |
377 | 377 | ||
378 | spin_lock_init(&rtc->lock); | ||
378 | rtc->irq = irq; | 379 | rtc->irq = irq; |
379 | 380 | ||
380 | /* platform setup code should have handled this; sigh */ | 381 | /* platform setup code should have handled this; sigh */ |
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index fbe9c72438e1..43745cac0141 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -43,7 +43,7 @@ | |||
43 | #include <linux/of_platform.h> | 43 | #include <linux/of_platform.h> |
44 | 44 | ||
45 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ | 45 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ |
46 | #include <asm-generic/rtc.h> | 46 | #include <linux/mc146818rtc.h> |
47 | 47 | ||
48 | struct cmos_rtc { | 48 | struct cmos_rtc { |
49 | struct rtc_device *rtc; | 49 | struct rtc_device *rtc; |
@@ -190,10 +190,10 @@ static inline void cmos_write_bank2(unsigned char val, unsigned char addr) | |||
190 | static int cmos_read_time(struct device *dev, struct rtc_time *t) | 190 | static int cmos_read_time(struct device *dev, struct rtc_time *t) |
191 | { | 191 | { |
192 | /* REVISIT: if the clock has a "century" register, use | 192 | /* REVISIT: if the clock has a "century" register, use |
193 | * that instead of the heuristic in get_rtc_time(). | 193 | * that instead of the heuristic in mc146818_get_time(). |
194 | * That'll make Y3K compatility (year > 2070) easy! | 194 | * That'll make Y3K compatility (year > 2070) easy! |
195 | */ | 195 | */ |
196 | get_rtc_time(t); | 196 | mc146818_get_time(t); |
197 | return 0; | 197 | return 0; |
198 | } | 198 | } |
199 | 199 | ||
@@ -205,7 +205,7 @@ static int cmos_set_time(struct device *dev, struct rtc_time *t) | |||
205 | * takes effect exactly 500ms after we write the register. | 205 | * takes effect exactly 500ms after we write the register. |
206 | * (Also queueing and other delays before we get this far.) | 206 | * (Also queueing and other delays before we get this far.) |
207 | */ | 207 | */ |
208 | return set_rtc_time(t); | 208 | return mc146818_set_time(t); |
209 | } | 209 | } |
210 | 210 | ||
211 | static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t) | 211 | static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t) |
@@ -220,8 +220,6 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
220 | * Some also support day and month, for alarms up to a year in | 220 | * Some also support day and month, for alarms up to a year in |
221 | * the future. | 221 | * the future. |
222 | */ | 222 | */ |
223 | t->time.tm_mday = -1; | ||
224 | t->time.tm_mon = -1; | ||
225 | 223 | ||
226 | spin_lock_irq(&rtc_lock); | 224 | spin_lock_irq(&rtc_lock); |
227 | t->time.tm_sec = CMOS_READ(RTC_SECONDS_ALARM); | 225 | t->time.tm_sec = CMOS_READ(RTC_SECONDS_ALARM); |
@@ -272,7 +270,6 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
272 | } | 270 | } |
273 | } | 271 | } |
274 | } | 272 | } |
275 | t->time.tm_year = -1; | ||
276 | 273 | ||
277 | t->enabled = !!(rtc_control & RTC_AIE); | 274 | t->enabled = !!(rtc_control & RTC_AIE); |
278 | t->pending = 0; | 275 | t->pending = 0; |
@@ -630,7 +627,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
630 | address_space = 64; | 627 | address_space = 64; |
631 | #elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) \ | 628 | #elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) \ |
632 | || defined(__sparc__) || defined(__mips__) \ | 629 | || defined(__sparc__) || defined(__mips__) \ |
633 | || defined(__powerpc__) | 630 | || defined(__powerpc__) || defined(CONFIG_MN10300) |
634 | address_space = 128; | 631 | address_space = 128; |
635 | #else | 632 | #else |
636 | #warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes. | 633 | #warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes. |
@@ -1142,14 +1139,14 @@ static __init void cmos_of_init(struct platform_device *pdev) | |||
1142 | if (val) | 1139 | if (val) |
1143 | CMOS_WRITE(be32_to_cpup(val), RTC_FREQ_SELECT); | 1140 | CMOS_WRITE(be32_to_cpup(val), RTC_FREQ_SELECT); |
1144 | 1141 | ||
1145 | get_rtc_time(&time); | 1142 | cmos_read_time(&pdev->dev, &time); |
1146 | ret = rtc_valid_tm(&time); | 1143 | ret = rtc_valid_tm(&time); |
1147 | if (ret) { | 1144 | if (ret) { |
1148 | struct rtc_time def_time = { | 1145 | struct rtc_time def_time = { |
1149 | .tm_year = 1, | 1146 | .tm_year = 1, |
1150 | .tm_mday = 1, | 1147 | .tm_mday = 1, |
1151 | }; | 1148 | }; |
1152 | set_rtc_time(&def_time); | 1149 | cmos_set_time(&pdev->dev, &def_time); |
1153 | } | 1150 | } |
1154 | } | 1151 | } |
1155 | #else | 1152 | #else |
diff --git a/drivers/rtc/rtc-da9052.c b/drivers/rtc/rtc-da9052.c index a20bcf0e33cd..4273377562ec 100644 --- a/drivers/rtc/rtc-da9052.c +++ b/drivers/rtc/rtc-da9052.c | |||
@@ -85,6 +85,7 @@ static int da9052_read_alarm(struct da9052_rtc *rtc, struct rtc_time *rtc_tm) | |||
85 | rtc_tm->tm_mday = v[0][2] & DA9052_RTC_DAY; | 85 | rtc_tm->tm_mday = v[0][2] & DA9052_RTC_DAY; |
86 | rtc_tm->tm_hour = v[0][1] & DA9052_RTC_HOUR; | 86 | rtc_tm->tm_hour = v[0][1] & DA9052_RTC_HOUR; |
87 | rtc_tm->tm_min = v[0][0] & DA9052_RTC_MIN; | 87 | rtc_tm->tm_min = v[0][0] & DA9052_RTC_MIN; |
88 | rtc_tm->tm_sec = 0; | ||
88 | 89 | ||
89 | ret = rtc_valid_tm(rtc_tm); | 90 | ret = rtc_valid_tm(rtc_tm); |
90 | return ret; | 91 | return ret; |
diff --git a/drivers/rtc/rtc-da9055.c b/drivers/rtc/rtc-da9055.c index 7ec0872d5e3b..678af8648c45 100644 --- a/drivers/rtc/rtc-da9055.c +++ b/drivers/rtc/rtc-da9055.c | |||
@@ -74,6 +74,7 @@ static int da9055_read_alarm(struct da9055 *da9055, struct rtc_time *rtc_tm) | |||
74 | rtc_tm->tm_mday = v[2] & DA9055_RTC_ALM_DAY; | 74 | rtc_tm->tm_mday = v[2] & DA9055_RTC_ALM_DAY; |
75 | rtc_tm->tm_hour = v[1] & DA9055_RTC_ALM_HOUR; | 75 | rtc_tm->tm_hour = v[1] & DA9055_RTC_ALM_HOUR; |
76 | rtc_tm->tm_min = v[0] & DA9055_RTC_ALM_MIN; | 76 | rtc_tm->tm_min = v[0] & DA9055_RTC_ALM_MIN; |
77 | rtc_tm->tm_sec = 0; | ||
77 | 78 | ||
78 | return rtc_valid_tm(rtc_tm); | 79 | return rtc_valid_tm(rtc_tm); |
79 | } | 80 | } |
diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c index c5432bf64e1c..dba60c1dfce2 100644 --- a/drivers/rtc/rtc-davinci.c +++ b/drivers/rtc/rtc-davinci.c | |||
@@ -388,6 +388,8 @@ static int davinci_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
388 | u8 day0, day1; | 388 | u8 day0, day1; |
389 | unsigned long flags; | 389 | unsigned long flags; |
390 | 390 | ||
391 | alm->time.tm_sec = 0; | ||
392 | |||
391 | spin_lock_irqsave(&davinci_rtc_lock, flags); | 393 | spin_lock_irqsave(&davinci_rtc_lock, flags); |
392 | 394 | ||
393 | davinci_rtcss_calendar_wait(davinci_rtc); | 395 | davinci_rtcss_calendar_wait(davinci_rtc); |
diff --git a/drivers/rtc/rtc-ds1286.c b/drivers/rtc/rtc-ds1286.c index 756e509f6ed2..ef75c349dff9 100644 --- a/drivers/rtc/rtc-ds1286.c +++ b/drivers/rtc/rtc-ds1286.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include <linux/rtc.h> | 16 | #include <linux/rtc.h> |
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/bcd.h> | 18 | #include <linux/bcd.h> |
19 | #include <linux/ds1286.h> | 19 | #include <linux/rtc/ds1286.h> |
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | 22 | ||
diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index 8e41c4613e51..72b22935eb62 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c | |||
@@ -313,13 +313,6 @@ static int ds1305_get_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
313 | alm->time.tm_sec = bcd2bin(buf[DS1305_SEC]); | 313 | alm->time.tm_sec = bcd2bin(buf[DS1305_SEC]); |
314 | alm->time.tm_min = bcd2bin(buf[DS1305_MIN]); | 314 | alm->time.tm_min = bcd2bin(buf[DS1305_MIN]); |
315 | alm->time.tm_hour = bcd2hour(buf[DS1305_HOUR]); | 315 | alm->time.tm_hour = bcd2hour(buf[DS1305_HOUR]); |
316 | alm->time.tm_mday = -1; | ||
317 | alm->time.tm_mon = -1; | ||
318 | alm->time.tm_year = -1; | ||
319 | /* next three fields are unused by Linux */ | ||
320 | alm->time.tm_wday = -1; | ||
321 | alm->time.tm_mday = -1; | ||
322 | alm->time.tm_isdst = -1; | ||
323 | 316 | ||
324 | return 0; | 317 | return 0; |
325 | } | 318 | } |
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 821d9c089cdb..8e1c5cb6ece6 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c | |||
@@ -482,11 +482,6 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
482 | t->time.tm_min = bcd2bin(ds1307->regs[1] & 0x7f); | 482 | t->time.tm_min = bcd2bin(ds1307->regs[1] & 0x7f); |
483 | t->time.tm_hour = bcd2bin(ds1307->regs[2] & 0x3f); | 483 | t->time.tm_hour = bcd2bin(ds1307->regs[2] & 0x3f); |
484 | t->time.tm_mday = bcd2bin(ds1307->regs[3] & 0x3f); | 484 | t->time.tm_mday = bcd2bin(ds1307->regs[3] & 0x3f); |
485 | t->time.tm_mon = -1; | ||
486 | t->time.tm_year = -1; | ||
487 | t->time.tm_wday = -1; | ||
488 | t->time.tm_yday = -1; | ||
489 | t->time.tm_isdst = -1; | ||
490 | 485 | ||
491 | /* ... and status */ | 486 | /* ... and status */ |
492 | t->enabled = !!(ds1307->regs[7] & DS1337_BIT_A1IE); | 487 | t->enabled = !!(ds1307->regs[7] & DS1337_BIT_A1IE); |
@@ -602,6 +597,8 @@ static const struct rtc_class_ops ds13xx_rtc_ops = { | |||
602 | * Alarm support for mcp794xx devices. | 597 | * Alarm support for mcp794xx devices. |
603 | */ | 598 | */ |
604 | 599 | ||
600 | #define MCP794XX_REG_WEEKDAY 0x3 | ||
601 | #define MCP794XX_REG_WEEKDAY_WDAY_MASK 0x7 | ||
605 | #define MCP794XX_REG_CONTROL 0x07 | 602 | #define MCP794XX_REG_CONTROL 0x07 |
606 | # define MCP794XX_BIT_ALM0_EN 0x10 | 603 | # define MCP794XX_BIT_ALM0_EN 0x10 |
607 | # define MCP794XX_BIT_ALM1_EN 0x20 | 604 | # define MCP794XX_BIT_ALM1_EN 0x20 |
@@ -1231,13 +1228,16 @@ static int ds1307_probe(struct i2c_client *client, | |||
1231 | { | 1228 | { |
1232 | struct ds1307 *ds1307; | 1229 | struct ds1307 *ds1307; |
1233 | int err = -ENODEV; | 1230 | int err = -ENODEV; |
1234 | int tmp; | 1231 | int tmp, wday; |
1235 | struct chip_desc *chip = &chips[id->driver_data]; | 1232 | struct chip_desc *chip = &chips[id->driver_data]; |
1236 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 1233 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
1237 | bool want_irq = false; | 1234 | bool want_irq = false; |
1238 | bool ds1307_can_wakeup_device = false; | 1235 | bool ds1307_can_wakeup_device = false; |
1239 | unsigned char *buf; | 1236 | unsigned char *buf; |
1240 | struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev); | 1237 | struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev); |
1238 | struct rtc_time tm; | ||
1239 | unsigned long timestamp; | ||
1240 | |||
1241 | irq_handler_t irq_handler = ds1307_irq; | 1241 | irq_handler_t irq_handler = ds1307_irq; |
1242 | 1242 | ||
1243 | static const int bbsqi_bitpos[] = { | 1243 | static const int bbsqi_bitpos[] = { |
@@ -1526,6 +1526,27 @@ read_rtc: | |||
1526 | bin2bcd(tmp)); | 1526 | bin2bcd(tmp)); |
1527 | } | 1527 | } |
1528 | 1528 | ||
1529 | /* | ||
1530 | * Some IPs have weekday reset value = 0x1 which might not correct | ||
1531 | * hence compute the wday using the current date/month/year values | ||
1532 | */ | ||
1533 | ds1307_get_time(&client->dev, &tm); | ||
1534 | wday = tm.tm_wday; | ||
1535 | timestamp = rtc_tm_to_time64(&tm); | ||
1536 | rtc_time64_to_tm(timestamp, &tm); | ||
1537 | |||
1538 | /* | ||
1539 | * Check if reset wday is different from the computed wday | ||
1540 | * If different then set the wday which we computed using | ||
1541 | * timestamp | ||
1542 | */ | ||
1543 | if (wday != tm.tm_wday) { | ||
1544 | wday = i2c_smbus_read_byte_data(client, MCP794XX_REG_WEEKDAY); | ||
1545 | wday = wday & ~MCP794XX_REG_WEEKDAY_WDAY_MASK; | ||
1546 | wday = wday | (tm.tm_wday + 1); | ||
1547 | i2c_smbus_write_byte_data(client, MCP794XX_REG_WEEKDAY, wday); | ||
1548 | } | ||
1549 | |||
1529 | if (want_irq) { | 1550 | if (want_irq) { |
1530 | device_set_wakeup_capable(&client->dev, true); | 1551 | device_set_wakeup_capable(&client->dev, true); |
1531 | set_bit(HAS_ALARM, &ds1307->flags); | 1552 | set_bit(HAS_ALARM, &ds1307->flags); |
diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c index 23fa9f0cb5e3..895fbeeb47fe 100644 --- a/drivers/rtc/rtc-ds1343.c +++ b/drivers/rtc/rtc-ds1343.c | |||
@@ -504,12 +504,6 @@ static int ds1343_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
504 | alarm->time.tm_hour = priv->alarm_hour < 0 ? 0 : priv->alarm_hour; | 504 | alarm->time.tm_hour = priv->alarm_hour < 0 ? 0 : priv->alarm_hour; |
505 | alarm->time.tm_mday = priv->alarm_mday < 0 ? 0 : priv->alarm_mday; | 505 | alarm->time.tm_mday = priv->alarm_mday < 0 ? 0 : priv->alarm_mday; |
506 | 506 | ||
507 | alarm->time.tm_mon = -1; | ||
508 | alarm->time.tm_year = -1; | ||
509 | alarm->time.tm_wday = -1; | ||
510 | alarm->time.tm_yday = -1; | ||
511 | alarm->time.tm_isdst = -1; | ||
512 | |||
513 | out: | 507 | out: |
514 | mutex_unlock(&priv->mutex); | 508 | mutex_unlock(&priv->mutex); |
515 | return res; | 509 | return res; |
diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c index b3ce3c652fcd..ed43b4311660 100644 --- a/drivers/rtc/rtc-ds1685.c +++ b/drivers/rtc/rtc-ds1685.c | |||
@@ -103,6 +103,26 @@ ds1685_rtc_bin2bcd(struct ds1685_priv *rtc, u8 val, u8 bin_mask, u8 bcd_mask) | |||
103 | } | 103 | } |
104 | 104 | ||
105 | /** | 105 | /** |
106 | * s1685_rtc_check_mday - check validity of the day of month. | ||
107 | * @rtc: pointer to the ds1685 rtc structure. | ||
108 | * @mday: day of month. | ||
109 | * | ||
110 | * Returns -EDOM if the day of month is not within 1..31 range. | ||
111 | */ | ||
112 | static inline int | ||
113 | ds1685_rtc_check_mday(struct ds1685_priv *rtc, u8 mday) | ||
114 | { | ||
115 | if (rtc->bcd_mode) { | ||
116 | if (mday < 0x01 || mday > 0x31 || (mday & 0x0f) > 0x09) | ||
117 | return -EDOM; | ||
118 | } else { | ||
119 | if (mday < 1 || mday > 31) | ||
120 | return -EDOM; | ||
121 | } | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | /** | ||
106 | * ds1685_rtc_switch_to_bank0 - switch the rtc to bank 0. | 126 | * ds1685_rtc_switch_to_bank0 - switch the rtc to bank 0. |
107 | * @rtc: pointer to the ds1685 rtc structure. | 127 | * @rtc: pointer to the ds1685 rtc structure. |
108 | */ | 128 | */ |
@@ -377,6 +397,7 @@ ds1685_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
377 | struct platform_device *pdev = to_platform_device(dev); | 397 | struct platform_device *pdev = to_platform_device(dev); |
378 | struct ds1685_priv *rtc = platform_get_drvdata(pdev); | 398 | struct ds1685_priv *rtc = platform_get_drvdata(pdev); |
379 | u8 seconds, minutes, hours, mday, ctrlb, ctrlc; | 399 | u8 seconds, minutes, hours, mday, ctrlb, ctrlc; |
400 | int ret; | ||
380 | 401 | ||
381 | /* Fetch the alarm info from the RTC alarm registers. */ | 402 | /* Fetch the alarm info from the RTC alarm registers. */ |
382 | ds1685_rtc_begin_data_access(rtc); | 403 | ds1685_rtc_begin_data_access(rtc); |
@@ -388,34 +409,29 @@ ds1685_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
388 | ctrlc = rtc->read(rtc, RTC_CTRL_C); | 409 | ctrlc = rtc->read(rtc, RTC_CTRL_C); |
389 | ds1685_rtc_end_data_access(rtc); | 410 | ds1685_rtc_end_data_access(rtc); |
390 | 411 | ||
391 | /* Check month date. */ | 412 | /* Check the month date for validity. */ |
392 | if (!(mday >= 1) && (mday <= 31)) | 413 | ret = ds1685_rtc_check_mday(rtc, mday); |
393 | return -EDOM; | 414 | if (ret) |
415 | return ret; | ||
394 | 416 | ||
395 | /* | 417 | /* |
396 | * Check the three alarm bytes. | 418 | * Check the three alarm bytes. |
397 | * | 419 | * |
398 | * The Linux RTC system doesn't support the "don't care" capability | 420 | * The Linux RTC system doesn't support the "don't care" capability |
399 | * of this RTC chip. We check for it anyways in case support is | 421 | * of this RTC chip. We check for it anyways in case support is |
400 | * added in the future. | 422 | * added in the future and only assign when we care. |
401 | */ | 423 | */ |
402 | if (unlikely(seconds >= 0xc0)) | 424 | if (likely(seconds < 0xc0)) |
403 | alrm->time.tm_sec = -1; | ||
404 | else | ||
405 | alrm->time.tm_sec = ds1685_rtc_bcd2bin(rtc, seconds, | 425 | alrm->time.tm_sec = ds1685_rtc_bcd2bin(rtc, seconds, |
406 | RTC_SECS_BCD_MASK, | 426 | RTC_SECS_BCD_MASK, |
407 | RTC_SECS_BIN_MASK); | 427 | RTC_SECS_BIN_MASK); |
408 | 428 | ||
409 | if (unlikely(minutes >= 0xc0)) | 429 | if (likely(minutes < 0xc0)) |
410 | alrm->time.tm_min = -1; | ||
411 | else | ||
412 | alrm->time.tm_min = ds1685_rtc_bcd2bin(rtc, minutes, | 430 | alrm->time.tm_min = ds1685_rtc_bcd2bin(rtc, minutes, |
413 | RTC_MINS_BCD_MASK, | 431 | RTC_MINS_BCD_MASK, |
414 | RTC_MINS_BIN_MASK); | 432 | RTC_MINS_BIN_MASK); |
415 | 433 | ||
416 | if (unlikely(hours >= 0xc0)) | 434 | if (likely(hours < 0xc0)) |
417 | alrm->time.tm_hour = -1; | ||
418 | else | ||
419 | alrm->time.tm_hour = ds1685_rtc_bcd2bin(rtc, hours, | 435 | alrm->time.tm_hour = ds1685_rtc_bcd2bin(rtc, hours, |
420 | RTC_HRS_24_BCD_MASK, | 436 | RTC_HRS_24_BCD_MASK, |
421 | RTC_HRS_24_BIN_MASK); | 437 | RTC_HRS_24_BIN_MASK); |
@@ -423,11 +439,6 @@ ds1685_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
423 | /* Write the data to rtc_wkalrm. */ | 439 | /* Write the data to rtc_wkalrm. */ |
424 | alrm->time.tm_mday = ds1685_rtc_bcd2bin(rtc, mday, RTC_MDAY_BCD_MASK, | 440 | alrm->time.tm_mday = ds1685_rtc_bcd2bin(rtc, mday, RTC_MDAY_BCD_MASK, |
425 | RTC_MDAY_BIN_MASK); | 441 | RTC_MDAY_BIN_MASK); |
426 | alrm->time.tm_mon = -1; | ||
427 | alrm->time.tm_year = -1; | ||
428 | alrm->time.tm_wday = -1; | ||
429 | alrm->time.tm_yday = -1; | ||
430 | alrm->time.tm_isdst = -1; | ||
431 | alrm->enabled = !!(ctrlb & RTC_CTRL_B_AIE); | 442 | alrm->enabled = !!(ctrlb & RTC_CTRL_B_AIE); |
432 | alrm->pending = !!(ctrlc & RTC_CTRL_C_AF); | 443 | alrm->pending = !!(ctrlc & RTC_CTRL_C_AF); |
433 | 444 | ||
@@ -445,6 +456,7 @@ ds1685_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
445 | struct platform_device *pdev = to_platform_device(dev); | 456 | struct platform_device *pdev = to_platform_device(dev); |
446 | struct ds1685_priv *rtc = platform_get_drvdata(pdev); | 457 | struct ds1685_priv *rtc = platform_get_drvdata(pdev); |
447 | u8 ctrlb, seconds, minutes, hours, mday; | 458 | u8 ctrlb, seconds, minutes, hours, mday; |
459 | int ret; | ||
448 | 460 | ||
449 | /* Fetch the alarm info and convert to BCD. */ | 461 | /* Fetch the alarm info and convert to BCD. */ |
450 | seconds = ds1685_rtc_bin2bcd(rtc, alrm->time.tm_sec, | 462 | seconds = ds1685_rtc_bin2bcd(rtc, alrm->time.tm_sec, |
@@ -461,8 +473,9 @@ ds1685_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
461 | RTC_MDAY_BCD_MASK); | 473 | RTC_MDAY_BCD_MASK); |
462 | 474 | ||
463 | /* Check the month date for validity. */ | 475 | /* Check the month date for validity. */ |
464 | if (!(mday >= 1) && (mday <= 31)) | 476 | ret = ds1685_rtc_check_mday(rtc, mday); |
465 | return -EDOM; | 477 | if (ret) |
478 | return ret; | ||
466 | 479 | ||
467 | /* | 480 | /* |
468 | * Check the three alarm bytes. | 481 | * Check the three alarm bytes. |
diff --git a/drivers/rtc/rtc-ds2404.c b/drivers/rtc/rtc-ds2404.c index 16310fe79d76..9a1582ed7070 100644 --- a/drivers/rtc/rtc-ds2404.c +++ b/drivers/rtc/rtc-ds2404.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include <linux/rtc.h> | 13 | #include <linux/rtc.h> |
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #include <linux/bcd.h> | 15 | #include <linux/bcd.h> |
16 | #include <linux/rtc-ds2404.h> | 16 | #include <linux/platform_data/rtc-ds2404.h> |
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/gpio.h> | 18 | #include <linux/gpio.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index 04fbd7fffd0d..b1f20d8c358f 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c | |||
@@ -197,12 +197,6 @@ static int ds3232_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
197 | alarm->time.tm_hour = bcd2bin(buf[2] & 0x7F); | 197 | alarm->time.tm_hour = bcd2bin(buf[2] & 0x7F); |
198 | alarm->time.tm_mday = bcd2bin(buf[3] & 0x7F); | 198 | alarm->time.tm_mday = bcd2bin(buf[3] & 0x7F); |
199 | 199 | ||
200 | alarm->time.tm_mon = -1; | ||
201 | alarm->time.tm_year = -1; | ||
202 | alarm->time.tm_wday = -1; | ||
203 | alarm->time.tm_yday = -1; | ||
204 | alarm->time.tm_isdst = -1; | ||
205 | |||
206 | alarm->enabled = !!(control & DS3232_REG_CR_A1IE); | 200 | alarm->enabled = !!(control & DS3232_REG_CR_A1IE); |
207 | alarm->pending = !!(stat & DS3232_REG_SR_A1F); | 201 | alarm->pending = !!(stat & DS3232_REG_SR_A1F); |
208 | 202 | ||
diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c index 96d38609d803..0130afd7fe88 100644 --- a/drivers/rtc/rtc-efi.c +++ b/drivers/rtc/rtc-efi.c | |||
@@ -259,6 +259,12 @@ static const struct rtc_class_ops efi_rtc_ops = { | |||
259 | static int __init efi_rtc_probe(struct platform_device *dev) | 259 | static int __init efi_rtc_probe(struct platform_device *dev) |
260 | { | 260 | { |
261 | struct rtc_device *rtc; | 261 | struct rtc_device *rtc; |
262 | efi_time_t eft; | ||
263 | efi_time_cap_t cap; | ||
264 | |||
265 | /* First check if the RTC is usable */ | ||
266 | if (efi.get_time(&eft, &cap) != EFI_SUCCESS) | ||
267 | return -ENODEV; | ||
262 | 268 | ||
263 | rtc = devm_rtc_device_register(&dev->dev, "rtc-efi", &efi_rtc_ops, | 269 | rtc = devm_rtc_device_register(&dev->dev, "rtc-efi", &efi_rtc_ops, |
264 | THIS_MODULE); | 270 | THIS_MODULE); |
diff --git a/drivers/rtc/rtc-generic.c b/drivers/rtc/rtc-generic.c index d726c6aa96a8..1bf5d2347928 100644 --- a/drivers/rtc/rtc-generic.c +++ b/drivers/rtc/rtc-generic.c | |||
@@ -9,44 +9,10 @@ | |||
9 | #include <linux/platform_device.h> | 9 | #include <linux/platform_device.h> |
10 | #include <linux/rtc.h> | 10 | #include <linux/rtc.h> |
11 | 11 | ||
12 | #if defined(CONFIG_M68K) || defined(CONFIG_PARISC) || \ | ||
13 | defined(CONFIG_PPC) || defined(CONFIG_SUPERH32) | ||
14 | #include <asm/rtc.h> | ||
15 | |||
16 | static int generic_get_time(struct device *dev, struct rtc_time *tm) | ||
17 | { | ||
18 | unsigned int ret = get_rtc_time(tm); | ||
19 | |||
20 | if (ret & RTC_BATT_BAD) | ||
21 | return -EOPNOTSUPP; | ||
22 | |||
23 | return rtc_valid_tm(tm); | ||
24 | } | ||
25 | |||
26 | static int generic_set_time(struct device *dev, struct rtc_time *tm) | ||
27 | { | ||
28 | if (set_rtc_time(tm) < 0) | ||
29 | return -EOPNOTSUPP; | ||
30 | |||
31 | return 0; | ||
32 | } | ||
33 | |||
34 | static const struct rtc_class_ops generic_rtc_ops = { | ||
35 | .read_time = generic_get_time, | ||
36 | .set_time = generic_set_time, | ||
37 | }; | ||
38 | #else | ||
39 | #define generic_rtc_ops *(struct rtc_class_ops*)NULL | ||
40 | #endif | ||
41 | |||
42 | static int __init generic_rtc_probe(struct platform_device *dev) | 12 | static int __init generic_rtc_probe(struct platform_device *dev) |
43 | { | 13 | { |
44 | struct rtc_device *rtc; | 14 | struct rtc_device *rtc; |
45 | const struct rtc_class_ops *ops; | 15 | const struct rtc_class_ops *ops = dev_get_platdata(&dev->dev); |
46 | |||
47 | ops = dev_get_platdata(&dev->dev); | ||
48 | if (!ops) | ||
49 | ops = &generic_rtc_ops; | ||
50 | 16 | ||
51 | rtc = devm_rtc_device_register(&dev->dev, "rtc-generic", | 17 | rtc = devm_rtc_device_register(&dev->dev, "rtc-generic", |
52 | ops, THIS_MODULE); | 18 | ops, THIS_MODULE); |
diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c index 207270376b55..e5ad527cb75e 100644 --- a/drivers/rtc/rtc-hym8563.c +++ b/drivers/rtc/rtc-hym8563.c | |||
@@ -198,7 +198,7 @@ static int hym8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
198 | return ret; | 198 | return ret; |
199 | 199 | ||
200 | /* The alarm only has a minute accuracy */ | 200 | /* The alarm only has a minute accuracy */ |
201 | alm_tm->tm_sec = -1; | 201 | alm_tm->tm_sec = 0; |
202 | 202 | ||
203 | alm_tm->tm_min = (buf[0] & HYM8563_ALM_BIT_DISABLE) ? | 203 | alm_tm->tm_min = (buf[0] & HYM8563_ALM_BIT_DISABLE) ? |
204 | -1 : | 204 | -1 : |
@@ -213,9 +213,6 @@ static int hym8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
213 | -1 : | 213 | -1 : |
214 | bcd2bin(buf[3] & HYM8563_WEEKDAY_MASK); | 214 | bcd2bin(buf[3] & HYM8563_WEEKDAY_MASK); |
215 | 215 | ||
216 | alm_tm->tm_mon = -1; | ||
217 | alm_tm->tm_year = -1; | ||
218 | |||
219 | ret = i2c_smbus_read_byte_data(client, HYM8563_CTL2); | 216 | ret = i2c_smbus_read_byte_data(client, HYM8563_CTL2); |
220 | if (ret < 0) | 217 | if (ret < 0) |
221 | return ret; | 218 | return ret; |
diff --git a/drivers/rtc/rtc-isl12057.c b/drivers/rtc/rtc-isl12057.c index 54328d4ac0d3..0e7f0f52bfe4 100644 --- a/drivers/rtc/rtc-isl12057.c +++ b/drivers/rtc/rtc-isl12057.c | |||
@@ -245,8 +245,7 @@ static int isl12057_rtc_update_alarm(struct device *dev, int enable) | |||
245 | static int isl12057_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | 245 | static int isl12057_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) |
246 | { | 246 | { |
247 | struct isl12057_rtc_data *data = dev_get_drvdata(dev); | 247 | struct isl12057_rtc_data *data = dev_get_drvdata(dev); |
248 | struct rtc_time rtc_tm, *alarm_tm = &alarm->time; | 248 | struct rtc_time *alarm_tm = &alarm->time; |
249 | unsigned long rtc_secs, alarm_secs; | ||
250 | u8 regs[ISL12057_A1_SEC_LEN]; | 249 | u8 regs[ISL12057_A1_SEC_LEN]; |
251 | unsigned int ir; | 250 | unsigned int ir; |
252 | int ret; | 251 | int ret; |
@@ -264,36 +263,6 @@ static int isl12057_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
264 | alarm_tm->tm_min = bcd2bin(regs[1] & 0x7f); | 263 | alarm_tm->tm_min = bcd2bin(regs[1] & 0x7f); |
265 | alarm_tm->tm_hour = bcd2bin(regs[2] & 0x3f); | 264 | alarm_tm->tm_hour = bcd2bin(regs[2] & 0x3f); |
266 | alarm_tm->tm_mday = bcd2bin(regs[3] & 0x3f); | 265 | alarm_tm->tm_mday = bcd2bin(regs[3] & 0x3f); |
267 | alarm_tm->tm_wday = -1; | ||
268 | |||
269 | /* | ||
270 | * The alarm section does not store year/month. We use the ones in rtc | ||
271 | * section as a basis and increment month and then year if needed to get | ||
272 | * alarm after current time. | ||
273 | */ | ||
274 | ret = _isl12057_rtc_read_time(dev, &rtc_tm); | ||
275 | if (ret) | ||
276 | goto err_unlock; | ||
277 | |||
278 | alarm_tm->tm_year = rtc_tm.tm_year; | ||
279 | alarm_tm->tm_mon = rtc_tm.tm_mon; | ||
280 | |||
281 | ret = rtc_tm_to_time(&rtc_tm, &rtc_secs); | ||
282 | if (ret) | ||
283 | goto err_unlock; | ||
284 | |||
285 | ret = rtc_tm_to_time(alarm_tm, &alarm_secs); | ||
286 | if (ret) | ||
287 | goto err_unlock; | ||
288 | |||
289 | if (alarm_secs < rtc_secs) { | ||
290 | if (alarm_tm->tm_mon == 11) { | ||
291 | alarm_tm->tm_mon = 0; | ||
292 | alarm_tm->tm_year += 1; | ||
293 | } else { | ||
294 | alarm_tm->tm_mon += 1; | ||
295 | } | ||
296 | } | ||
297 | 266 | ||
298 | ret = regmap_read(data->regmap, ISL12057_REG_INT, &ir); | 267 | ret = regmap_read(data->regmap, ISL12057_REG_INT, &ir); |
299 | if (ret) { | 268 | if (ret) { |
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index d1bf93a87200..58698d21c2c3 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c | |||
@@ -244,7 +244,7 @@ static int m41t80_alarm_irq_enable(struct device *dev, unsigned int enabled) | |||
244 | 244 | ||
245 | retval = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, flags); | 245 | retval = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, flags); |
246 | if (retval < 0) { | 246 | if (retval < 0) { |
247 | dev_info(dev, "Unable to enable alarm IRQ %d\n", retval); | 247 | dev_err(dev, "Unable to enable alarm IRQ %d\n", retval); |
248 | return retval; | 248 | return retval; |
249 | } | 249 | } |
250 | return 0; | 250 | return 0; |
@@ -320,10 +320,8 @@ static int m41t80_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
320 | alrm->time.tm_sec = bcd2bin(alarmvals[4] & 0x7f); | 320 | alrm->time.tm_sec = bcd2bin(alarmvals[4] & 0x7f); |
321 | alrm->time.tm_min = bcd2bin(alarmvals[3] & 0x7f); | 321 | alrm->time.tm_min = bcd2bin(alarmvals[3] & 0x7f); |
322 | alrm->time.tm_hour = bcd2bin(alarmvals[2] & 0x3f); | 322 | alrm->time.tm_hour = bcd2bin(alarmvals[2] & 0x3f); |
323 | alrm->time.tm_wday = -1; | ||
324 | alrm->time.tm_mday = bcd2bin(alarmvals[1] & 0x3f); | 323 | alrm->time.tm_mday = bcd2bin(alarmvals[1] & 0x3f); |
325 | alrm->time.tm_mon = bcd2bin(alarmvals[0] & 0x3f); | 324 | alrm->time.tm_mon = bcd2bin(alarmvals[0] & 0x3f); |
326 | alrm->time.tm_year = -1; | ||
327 | 325 | ||
328 | alrm->enabled = !!(alarmvals[0] & M41T80_ALMON_AFE); | 326 | alrm->enabled = !!(alarmvals[0] & M41T80_ALMON_AFE); |
329 | alrm->pending = (flags & M41T80_FLAGS_AF) && alrm->enabled; | 327 | alrm->pending = (flags & M41T80_FLAGS_AF) && alrm->enabled; |
@@ -337,6 +335,30 @@ static struct rtc_class_ops m41t80_rtc_ops = { | |||
337 | .proc = m41t80_rtc_proc, | 335 | .proc = m41t80_rtc_proc, |
338 | }; | 336 | }; |
339 | 337 | ||
338 | #ifdef CONFIG_PM_SLEEP | ||
339 | static int m41t80_suspend(struct device *dev) | ||
340 | { | ||
341 | struct i2c_client *client = to_i2c_client(dev); | ||
342 | |||
343 | if (client->irq >= 0 && device_may_wakeup(dev)) | ||
344 | enable_irq_wake(client->irq); | ||
345 | |||
346 | return 0; | ||
347 | } | ||
348 | |||
349 | static int m41t80_resume(struct device *dev) | ||
350 | { | ||
351 | struct i2c_client *client = to_i2c_client(dev); | ||
352 | |||
353 | if (client->irq >= 0 && device_may_wakeup(dev)) | ||
354 | disable_irq_wake(client->irq); | ||
355 | |||
356 | return 0; | ||
357 | } | ||
358 | #endif | ||
359 | |||
360 | static SIMPLE_DEV_PM_OPS(m41t80_pm, m41t80_suspend, m41t80_resume); | ||
361 | |||
340 | static ssize_t flags_show(struct device *dev, | 362 | static ssize_t flags_show(struct device *dev, |
341 | struct device_attribute *attr, char *buf) | 363 | struct device_attribute *attr, char *buf) |
342 | { | 364 | { |
@@ -831,10 +853,9 @@ static int m41t80_probe(struct i2c_client *client, | |||
831 | return rc; | 853 | return rc; |
832 | } | 854 | } |
833 | 855 | ||
834 | rc = devm_add_action(&client->dev, m41t80_remove_sysfs_group, | 856 | rc = devm_add_action_or_reset(&client->dev, m41t80_remove_sysfs_group, |
835 | &client->dev); | 857 | &client->dev); |
836 | if (rc) { | 858 | if (rc) { |
837 | m41t80_remove_sysfs_group(&client->dev); | ||
838 | dev_err(&client->dev, | 859 | dev_err(&client->dev, |
839 | "Failed to add sysfs cleanup action: %d\n", rc); | 860 | "Failed to add sysfs cleanup action: %d\n", rc); |
840 | return rc; | 861 | return rc; |
@@ -873,6 +894,7 @@ static int m41t80_remove(struct i2c_client *client) | |||
873 | static struct i2c_driver m41t80_driver = { | 894 | static struct i2c_driver m41t80_driver = { |
874 | .driver = { | 895 | .driver = { |
875 | .name = "rtc-m41t80", | 896 | .name = "rtc-m41t80", |
897 | .pm = &m41t80_pm, | ||
876 | }, | 898 | }, |
877 | .probe = m41t80_probe, | 899 | .probe = m41t80_probe, |
878 | .remove = m41t80_remove, | 900 | .remove = m41t80_remove, |
diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c index f72b91f2501f..0eeb5714c00f 100644 --- a/drivers/rtc/rtc-m48t86.c +++ b/drivers/rtc/rtc-m48t86.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/rtc.h> | 17 | #include <linux/rtc.h> |
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/m48t86.h> | 19 | #include <linux/platform_data/rtc-m48t86.h> |
20 | #include <linux/bcd.h> | 20 | #include <linux/bcd.h> |
21 | 21 | ||
22 | #define M48T86_REG_SEC 0x00 | 22 | #define M48T86_REG_SEC 0x00 |
diff --git a/drivers/rtc/rtc-max6916.c b/drivers/rtc/rtc-max6916.c new file mode 100644 index 000000000000..623ab27b2757 --- /dev/null +++ b/drivers/rtc/rtc-max6916.c | |||
@@ -0,0 +1,164 @@ | |||
1 | /* rtc-max6916.c | ||
2 | * | ||
3 | * Driver for MAXIM max6916 Low Current, SPI Compatible | ||
4 | * Real Time Clock | ||
5 | * | ||
6 | * Author : Venkat Prashanth B U <venkat.prashanth2498@gmail.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/init.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/device.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/rtc.h> | ||
19 | #include <linux/spi/spi.h> | ||
20 | #include <linux/bcd.h> | ||
21 | |||
22 | /* Registers in max6916 rtc */ | ||
23 | |||
24 | #define MAX6916_SECONDS_REG 0x01 | ||
25 | #define MAX6916_MINUTES_REG 0x02 | ||
26 | #define MAX6916_HOURS_REG 0x03 | ||
27 | #define MAX6916_DATE_REG 0x04 | ||
28 | #define MAX6916_MONTH_REG 0x05 | ||
29 | #define MAX6916_DAY_REG 0x06 | ||
30 | #define MAX6916_YEAR_REG 0x07 | ||
31 | #define MAX6916_CONTROL_REG 0x08 | ||
32 | #define MAX6916_STATUS_REG 0x0C | ||
33 | #define MAX6916_CLOCK_BURST 0x3F | ||
34 | |||
35 | static int max6916_read_reg(struct device *dev, unsigned char address, | ||
36 | unsigned char *data) | ||
37 | { | ||
38 | struct spi_device *spi = to_spi_device(dev); | ||
39 | |||
40 | *data = address | 0x80; | ||
41 | |||
42 | return spi_write_then_read(spi, data, 1, data, 1); | ||
43 | } | ||
44 | |||
45 | static int max6916_write_reg(struct device *dev, unsigned char address, | ||
46 | unsigned char data) | ||
47 | { | ||
48 | struct spi_device *spi = to_spi_device(dev); | ||
49 | unsigned char buf[2]; | ||
50 | |||
51 | buf[0] = address & 0x7F; | ||
52 | buf[1] = data; | ||
53 | |||
54 | return spi_write_then_read(spi, buf, 2, NULL, 0); | ||
55 | } | ||
56 | |||
57 | static int max6916_read_time(struct device *dev, struct rtc_time *dt) | ||
58 | { | ||
59 | struct spi_device *spi = to_spi_device(dev); | ||
60 | int err; | ||
61 | unsigned char buf[8]; | ||
62 | |||
63 | buf[0] = MAX6916_CLOCK_BURST | 0x80; | ||
64 | |||
65 | err = spi_write_then_read(spi, buf, 1, buf, 8); | ||
66 | |||
67 | if (err) | ||
68 | return err; | ||
69 | |||
70 | dt->tm_sec = bcd2bin(buf[0]); | ||
71 | dt->tm_min = bcd2bin(buf[1]); | ||
72 | dt->tm_hour = bcd2bin(buf[2] & 0x3F); | ||
73 | dt->tm_mday = bcd2bin(buf[3]); | ||
74 | dt->tm_mon = bcd2bin(buf[4]) - 1; | ||
75 | dt->tm_wday = bcd2bin(buf[5]) - 1; | ||
76 | dt->tm_year = bcd2bin(buf[6]) + 100; | ||
77 | |||
78 | return rtc_valid_tm(dt); | ||
79 | } | ||
80 | |||
81 | static int max6916_set_time(struct device *dev, struct rtc_time *dt) | ||
82 | { | ||
83 | struct spi_device *spi = to_spi_device(dev); | ||
84 | unsigned char buf[9]; | ||
85 | |||
86 | if (dt->tm_year < 100 || dt->tm_year > 199) { | ||
87 | dev_err(&spi->dev, "Year must be between 2000 and 2099. It's %d.\n", | ||
88 | dt->tm_year + 1900); | ||
89 | return -EINVAL; | ||
90 | } | ||
91 | |||
92 | buf[0] = MAX6916_CLOCK_BURST & 0x7F; | ||
93 | buf[1] = bin2bcd(dt->tm_sec); | ||
94 | buf[2] = bin2bcd(dt->tm_min); | ||
95 | buf[3] = (bin2bcd(dt->tm_hour) & 0X3F); | ||
96 | buf[4] = bin2bcd(dt->tm_mday); | ||
97 | buf[5] = bin2bcd(dt->tm_mon + 1); | ||
98 | buf[6] = bin2bcd(dt->tm_wday + 1); | ||
99 | buf[7] = bin2bcd(dt->tm_year % 100); | ||
100 | buf[8] = bin2bcd(0x00); | ||
101 | |||
102 | /* write the rtc settings */ | ||
103 | return spi_write_then_read(spi, buf, 9, NULL, 0); | ||
104 | } | ||
105 | |||
106 | static const struct rtc_class_ops max6916_rtc_ops = { | ||
107 | .read_time = max6916_read_time, | ||
108 | .set_time = max6916_set_time, | ||
109 | }; | ||
110 | |||
111 | static int max6916_probe(struct spi_device *spi) | ||
112 | { | ||
113 | struct rtc_device *rtc; | ||
114 | unsigned char data; | ||
115 | int res; | ||
116 | |||
117 | /* spi setup with max6916 in mode 3 and bits per word as 8 */ | ||
118 | spi->mode = SPI_MODE_3; | ||
119 | spi->bits_per_word = 8; | ||
120 | spi_setup(spi); | ||
121 | |||
122 | /* RTC Settings */ | ||
123 | res = max6916_read_reg(&spi->dev, MAX6916_SECONDS_REG, &data); | ||
124 | if (res) | ||
125 | return res; | ||
126 | |||
127 | /* Disable the write protect of rtc */ | ||
128 | max6916_read_reg(&spi->dev, MAX6916_CONTROL_REG, &data); | ||
129 | data = data & ~(1 << 7); | ||
130 | max6916_write_reg(&spi->dev, MAX6916_CONTROL_REG, data); | ||
131 | |||
132 | /*Enable oscillator,disable oscillator stop flag, glitch filter*/ | ||
133 | max6916_read_reg(&spi->dev, MAX6916_STATUS_REG, &data); | ||
134 | data = data & 0x1B; | ||
135 | max6916_write_reg(&spi->dev, MAX6916_STATUS_REG, data); | ||
136 | |||
137 | /* display the settings */ | ||
138 | max6916_read_reg(&spi->dev, MAX6916_CONTROL_REG, &data); | ||
139 | dev_info(&spi->dev, "MAX6916 RTC CTRL Reg = 0x%02x\n", data); | ||
140 | |||
141 | max6916_read_reg(&spi->dev, MAX6916_STATUS_REG, &data); | ||
142 | dev_info(&spi->dev, "MAX6916 RTC Status Reg = 0x%02x\n", data); | ||
143 | |||
144 | rtc = devm_rtc_device_register(&spi->dev, "max6916", | ||
145 | &max6916_rtc_ops, THIS_MODULE); | ||
146 | if (IS_ERR(rtc)) | ||
147 | return PTR_ERR(rtc); | ||
148 | |||
149 | spi_set_drvdata(spi, rtc); | ||
150 | |||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | static struct spi_driver max6916_driver = { | ||
155 | .driver = { | ||
156 | .name = "max6916", | ||
157 | }, | ||
158 | .probe = max6916_probe, | ||
159 | }; | ||
160 | module_spi_driver(max6916_driver); | ||
161 | |||
162 | MODULE_DESCRIPTION("MAX6916 SPI RTC DRIVER"); | ||
163 | MODULE_AUTHOR("Venkat Prashanth B U <venkat.prashanth2498@gmail.com>"); | ||
164 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/include/asm-generic/rtc.h b/drivers/rtc/rtc-mc146818-lib.c index 4e3b6558331e..2f1772a358ca 100644 --- a/include/asm-generic/rtc.h +++ b/drivers/rtc/rtc-mc146818-lib.c | |||
@@ -1,40 +1,16 @@ | |||
1 | /* | ||
2 | * include/asm-generic/rtc.h | ||
3 | * | ||
4 | * Author: Tom Rini <trini@mvista.com> | ||
5 | * | ||
6 | * Based on: | ||
7 | * drivers/char/rtc.c | ||
8 | * | ||
9 | * Please read the COPYING file for all license details. | ||
10 | */ | ||
11 | |||
12 | #ifndef __ASM_RTC_H__ | ||
13 | #define __ASM_RTC_H__ | ||
14 | |||
15 | #include <linux/mc146818rtc.h> | ||
16 | #include <linux/rtc.h> | ||
17 | #include <linux/bcd.h> | 1 | #include <linux/bcd.h> |
18 | #include <linux/delay.h> | 2 | #include <linux/delay.h> |
3 | #include <linux/export.h> | ||
4 | #include <linux/mc146818rtc.h> | ||
5 | |||
19 | #ifdef CONFIG_ACPI | 6 | #ifdef CONFIG_ACPI |
20 | #include <linux/acpi.h> | 7 | #include <linux/acpi.h> |
21 | #endif | 8 | #endif |
22 | 9 | ||
23 | #define RTC_PIE 0x40 /* periodic interrupt enable */ | ||
24 | #define RTC_AIE 0x20 /* alarm interrupt enable */ | ||
25 | #define RTC_UIE 0x10 /* update-finished interrupt enable */ | ||
26 | |||
27 | /* some dummy definitions */ | ||
28 | #define RTC_BATT_BAD 0x100 /* battery bad */ | ||
29 | #define RTC_SQWE 0x08 /* enable square-wave output */ | ||
30 | #define RTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */ | ||
31 | #define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */ | ||
32 | #define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */ | ||
33 | |||
34 | /* | 10 | /* |
35 | * Returns true if a clock update is in progress | 11 | * Returns true if a clock update is in progress |
36 | */ | 12 | */ |
37 | static inline unsigned char rtc_is_updating(void) | 13 | static inline unsigned char mc146818_is_updating(void) |
38 | { | 14 | { |
39 | unsigned char uip; | 15 | unsigned char uip; |
40 | unsigned long flags; | 16 | unsigned long flags; |
@@ -45,7 +21,7 @@ static inline unsigned char rtc_is_updating(void) | |||
45 | return uip; | 21 | return uip; |
46 | } | 22 | } |
47 | 23 | ||
48 | static inline unsigned int __get_rtc_time(struct rtc_time *time) | 24 | unsigned int mc146818_get_time(struct rtc_time *time) |
49 | { | 25 | { |
50 | unsigned char ctrl; | 26 | unsigned char ctrl; |
51 | unsigned long flags; | 27 | unsigned long flags; |
@@ -60,11 +36,11 @@ static inline unsigned int __get_rtc_time(struct rtc_time *time) | |||
60 | * can take just over 2ms. We wait 20ms. There is no need to | 36 | * can take just over 2ms. We wait 20ms. There is no need to |
61 | * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP. | 37 | * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP. |
62 | * If you need to know *exactly* when a second has started, enable | 38 | * If you need to know *exactly* when a second has started, enable |
63 | * periodic update complete interrupts, (via ioctl) and then | 39 | * periodic update complete interrupts, (via ioctl) and then |
64 | * immediately read /dev/rtc which will block until you get the IRQ. | 40 | * immediately read /dev/rtc which will block until you get the IRQ. |
65 | * Once the read clears, read the RTC time (again via ioctl). Easy. | 41 | * Once the read clears, read the RTC time (again via ioctl). Easy. |
66 | */ | 42 | */ |
67 | if (rtc_is_updating()) | 43 | if (mc146818_is_updating()) |
68 | mdelay(20); | 44 | mdelay(20); |
69 | 45 | ||
70 | /* | 46 | /* |
@@ -120,13 +96,10 @@ static inline unsigned int __get_rtc_time(struct rtc_time *time) | |||
120 | 96 | ||
121 | return RTC_24H; | 97 | return RTC_24H; |
122 | } | 98 | } |
123 | 99 | EXPORT_SYMBOL_GPL(mc146818_get_time); | |
124 | #ifndef get_rtc_time | ||
125 | #define get_rtc_time __get_rtc_time | ||
126 | #endif | ||
127 | 100 | ||
128 | /* Set the current date and time in the real time clock. */ | 101 | /* Set the current date and time in the real time clock. */ |
129 | static inline int __set_rtc_time(struct rtc_time *time) | 102 | int mc146818_set_time(struct rtc_time *time) |
130 | { | 103 | { |
131 | unsigned long flags; | 104 | unsigned long flags; |
132 | unsigned char mon, day, hrs, min, sec; | 105 | unsigned char mon, day, hrs, min, sec; |
@@ -222,26 +195,4 @@ static inline int __set_rtc_time(struct rtc_time *time) | |||
222 | 195 | ||
223 | return 0; | 196 | return 0; |
224 | } | 197 | } |
225 | 198 | EXPORT_SYMBOL_GPL(mc146818_set_time); | |
226 | #ifndef set_rtc_time | ||
227 | #define set_rtc_time __set_rtc_time | ||
228 | #endif | ||
229 | |||
230 | static inline unsigned int get_rtc_ss(void) | ||
231 | { | ||
232 | struct rtc_time h; | ||
233 | |||
234 | get_rtc_time(&h); | ||
235 | return h.tm_sec; | ||
236 | } | ||
237 | |||
238 | static inline int get_rtc_pll(struct rtc_pll_info *pll) | ||
239 | { | ||
240 | return -EINVAL; | ||
241 | } | ||
242 | static inline int set_rtc_pll(struct rtc_pll_info *pll) | ||
243 | { | ||
244 | return -EINVAL; | ||
245 | } | ||
246 | |||
247 | #endif /* __ASM_RTC_H__ */ | ||
diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c index 0094d9bdd1e6..7334c44fa7c3 100644 --- a/drivers/rtc/rtc-mrst.c +++ b/drivers/rtc/rtc-mrst.c | |||
@@ -32,11 +32,11 @@ | |||
32 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
33 | #include <linux/spinlock.h> | 33 | #include <linux/spinlock.h> |
34 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
35 | #include <linux/mc146818rtc.h> | ||
35 | #include <linux/module.h> | 36 | #include <linux/module.h> |
36 | #include <linux/init.h> | 37 | #include <linux/init.h> |
37 | #include <linux/sfi.h> | 38 | #include <linux/sfi.h> |
38 | 39 | ||
39 | #include <asm-generic/rtc.h> | ||
40 | #include <asm/intel_scu_ipc.h> | 40 | #include <asm/intel_scu_ipc.h> |
41 | #include <asm/intel-mid.h> | 41 | #include <asm/intel-mid.h> |
42 | #include <asm/intel_mid_vrtc.h> | 42 | #include <asm/intel_mid_vrtc.h> |
@@ -149,14 +149,6 @@ static int mrst_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
149 | if (mrst->irq <= 0) | 149 | if (mrst->irq <= 0) |
150 | return -EIO; | 150 | return -EIO; |
151 | 151 | ||
152 | /* Basic alarms only support hour, minute, and seconds fields. | ||
153 | * Some also support day and month, for alarms up to a year in | ||
154 | * the future. | ||
155 | */ | ||
156 | t->time.tm_mday = -1; | ||
157 | t->time.tm_mon = -1; | ||
158 | t->time.tm_year = -1; | ||
159 | |||
160 | /* vRTC only supports binary mode */ | 152 | /* vRTC only supports binary mode */ |
161 | spin_lock_irq(&rtc_lock); | 153 | spin_lock_irq(&rtc_lock); |
162 | t->time.tm_sec = vrtc_cmos_read(RTC_SECONDS_ALARM); | 154 | t->time.tm_sec = vrtc_cmos_read(RTC_SECONDS_ALARM); |
diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c index f22e060709e5..b4478cc92b55 100644 --- a/drivers/rtc/rtc-pcf2123.c +++ b/drivers/rtc/rtc-pcf2123.c | |||
@@ -96,7 +96,7 @@ | |||
96 | #define CD_TMR_TE BIT(3) /* Countdown timer enable */ | 96 | #define CD_TMR_TE BIT(3) /* Countdown timer enable */ |
97 | 97 | ||
98 | /* PCF2123_REG_OFFSET BITS */ | 98 | /* PCF2123_REG_OFFSET BITS */ |
99 | #define OFFSET_SIGN_BIT BIT(6) /* 2's complement sign bit */ | 99 | #define OFFSET_SIGN_BIT 6 /* 2's complement sign bit */ |
100 | #define OFFSET_COARSE BIT(7) /* Coarse mode offset */ | 100 | #define OFFSET_COARSE BIT(7) /* Coarse mode offset */ |
101 | #define OFFSET_STEP (2170) /* Offset step in parts per billion */ | 101 | #define OFFSET_STEP (2170) /* Offset step in parts per billion */ |
102 | 102 | ||
@@ -217,7 +217,7 @@ static int pcf2123_read_offset(struct device *dev, long *offset) | |||
217 | if (reg & OFFSET_COARSE) | 217 | if (reg & OFFSET_COARSE) |
218 | reg <<= 1; /* multiply by 2 and sign extend */ | 218 | reg <<= 1; /* multiply by 2 and sign extend */ |
219 | else | 219 | else |
220 | reg |= (reg & OFFSET_SIGN_BIT) << 1; /* sign extend only */ | 220 | reg = sign_extend32(reg, OFFSET_SIGN_BIT); |
221 | 221 | ||
222 | *offset = ((long)reg) * OFFSET_STEP; | 222 | *offset = ((long)reg) * OFFSET_STEP; |
223 | 223 | ||
diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c index e8ddbb359d11..efb0a08ac117 100644 --- a/drivers/rtc/rtc-pcf85063.c +++ b/drivers/rtc/rtc-pcf85063.c | |||
@@ -16,6 +16,16 @@ | |||
16 | #include <linux/rtc.h> | 16 | #include <linux/rtc.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | 18 | ||
19 | /* | ||
20 | * Information for this driver was pulled from the following datasheets. | ||
21 | * | ||
22 | * http://www.nxp.com/documents/data_sheet/PCF85063A.pdf | ||
23 | * http://www.nxp.com/documents/data_sheet/PCF85063TP.pdf | ||
24 | * | ||
25 | * PCF85063A -- Rev. 6 — 18 November 2015 | ||
26 | * PCF85063TP -- Rev. 4 — 6 May 2015 | ||
27 | */ | ||
28 | |||
19 | #define PCF85063_REG_CTRL1 0x00 /* status */ | 29 | #define PCF85063_REG_CTRL1 0x00 /* status */ |
20 | #define PCF85063_REG_CTRL1_STOP BIT(5) | 30 | #define PCF85063_REG_CTRL1_STOP BIT(5) |
21 | #define PCF85063_REG_CTRL2 0x01 | 31 | #define PCF85063_REG_CTRL2 0x01 |
@@ -55,10 +65,22 @@ static int pcf85063_stop_clock(struct i2c_client *client, u8 *ctrl1) | |||
55 | return 0; | 65 | return 0; |
56 | } | 66 | } |
57 | 67 | ||
58 | /* | 68 | static int pcf85063_start_clock(struct i2c_client *client, u8 ctrl1) |
59 | * In the routines that deal directly with the pcf85063 hardware, we use | 69 | { |
60 | * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch. | 70 | s32 ret; |
61 | */ | 71 | |
72 | /* start the clock */ | ||
73 | ctrl1 &= PCF85063_REG_CTRL1_STOP; | ||
74 | |||
75 | ret = i2c_smbus_write_byte_data(client, PCF85063_REG_CTRL1, ctrl1); | ||
76 | if (ret < 0) { | ||
77 | dev_err(&client->dev, "Failing to start the clock\n"); | ||
78 | return -EIO; | ||
79 | } | ||
80 | |||
81 | return 0; | ||
82 | } | ||
83 | |||
62 | static int pcf85063_get_datetime(struct i2c_client *client, struct rtc_time *tm) | 84 | static int pcf85063_get_datetime(struct i2c_client *client, struct rtc_time *tm) |
63 | { | 85 | { |
64 | int rc; | 86 | int rc; |
@@ -90,8 +112,7 @@ static int pcf85063_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
90 | tm->tm_wday = regs[4] & 0x07; | 112 | tm->tm_wday = regs[4] & 0x07; |
91 | tm->tm_mon = bcd2bin(regs[5] & 0x1F) - 1; /* rtc mn 1-12 */ | 113 | tm->tm_mon = bcd2bin(regs[5] & 0x1F) - 1; /* rtc mn 1-12 */ |
92 | tm->tm_year = bcd2bin(regs[6]); | 114 | tm->tm_year = bcd2bin(regs[6]); |
93 | if (tm->tm_year < 70) | 115 | tm->tm_year += 100; |
94 | tm->tm_year += 100; /* assume we are in 1970...2069 */ | ||
95 | 116 | ||
96 | return rtc_valid_tm(tm); | 117 | return rtc_valid_tm(tm); |
97 | } | 118 | } |
@@ -99,13 +120,17 @@ static int pcf85063_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
99 | static int pcf85063_set_datetime(struct i2c_client *client, struct rtc_time *tm) | 120 | static int pcf85063_set_datetime(struct i2c_client *client, struct rtc_time *tm) |
100 | { | 121 | { |
101 | int rc; | 122 | int rc; |
102 | u8 regs[8]; | 123 | u8 regs[7]; |
124 | u8 ctrl1; | ||
125 | |||
126 | if ((tm->tm_year < 100) || (tm->tm_year > 199)) | ||
127 | return -EINVAL; | ||
103 | 128 | ||
104 | /* | 129 | /* |
105 | * to accurately set the time, reset the divider chain and keep it in | 130 | * to accurately set the time, reset the divider chain and keep it in |
106 | * reset state until all time/date registers are written | 131 | * reset state until all time/date registers are written |
107 | */ | 132 | */ |
108 | rc = pcf85063_stop_clock(client, ®s[7]); | 133 | rc = pcf85063_stop_clock(client, &ctrl1); |
109 | if (rc != 0) | 134 | if (rc != 0) |
110 | return rc; | 135 | return rc; |
111 | 136 | ||
@@ -125,14 +150,7 @@ static int pcf85063_set_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
125 | regs[5] = bin2bcd(tm->tm_mon + 1); | 150 | regs[5] = bin2bcd(tm->tm_mon + 1); |
126 | 151 | ||
127 | /* year and century */ | 152 | /* year and century */ |
128 | regs[6] = bin2bcd(tm->tm_year % 100); | 153 | regs[6] = bin2bcd(tm->tm_year - 100); |
129 | |||
130 | /* | ||
131 | * after all time/date registers are written, let the 'address auto | ||
132 | * increment' feature wrap around and write register CTRL1 to re-enable | ||
133 | * the clock divider chain again | ||
134 | */ | ||
135 | regs[7] &= ~PCF85063_REG_CTRL1_STOP; | ||
136 | 154 | ||
137 | /* write all registers at once */ | 155 | /* write all registers at once */ |
138 | rc = i2c_smbus_write_i2c_block_data(client, PCF85063_REG_SC, | 156 | rc = i2c_smbus_write_i2c_block_data(client, PCF85063_REG_SC, |
@@ -142,6 +160,15 @@ static int pcf85063_set_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
142 | return rc; | 160 | return rc; |
143 | } | 161 | } |
144 | 162 | ||
163 | /* | ||
164 | * Write the control register as a separate action since the size of | ||
165 | * the register space is different between the PCF85063TP and | ||
166 | * PCF85063A devices. The rollover point can not be used. | ||
167 | */ | ||
168 | rc = pcf85063_start_clock(client, ctrl1); | ||
169 | if (rc != 0) | ||
170 | return rc; | ||
171 | |||
145 | return 0; | 172 | return 0; |
146 | } | 173 | } |
147 | 174 | ||
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index b9ddbb001283..1227ceab61ee 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c | |||
@@ -341,14 +341,11 @@ static int pcf8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm) | |||
341 | "%s: raw data is min=%02x, hr=%02x, mday=%02x, wday=%02x\n", | 341 | "%s: raw data is min=%02x, hr=%02x, mday=%02x, wday=%02x\n", |
342 | __func__, buf[0], buf[1], buf[2], buf[3]); | 342 | __func__, buf[0], buf[1], buf[2], buf[3]); |
343 | 343 | ||
344 | tm->time.tm_sec = 0; | ||
344 | tm->time.tm_min = bcd2bin(buf[0] & 0x7F); | 345 | tm->time.tm_min = bcd2bin(buf[0] & 0x7F); |
345 | tm->time.tm_hour = bcd2bin(buf[1] & 0x3F); | 346 | tm->time.tm_hour = bcd2bin(buf[1] & 0x3F); |
346 | tm->time.tm_mday = bcd2bin(buf[2] & 0x3F); | 347 | tm->time.tm_mday = bcd2bin(buf[2] & 0x3F); |
347 | tm->time.tm_wday = bcd2bin(buf[3] & 0x7); | 348 | tm->time.tm_wday = bcd2bin(buf[3] & 0x7); |
348 | tm->time.tm_mon = -1; | ||
349 | tm->time.tm_year = -1; | ||
350 | tm->time.tm_yday = -1; | ||
351 | tm->time.tm_isdst = -1; | ||
352 | 349 | ||
353 | err = pcf8563_get_alarm_mode(client, &tm->enabled, &tm->pending); | 350 | err = pcf8563_get_alarm_mode(client, &tm->enabled, &tm->pending); |
354 | if (err < 0) | 351 | if (err < 0) |
diff --git a/drivers/rtc/rtc-rc5t583.c b/drivers/rtc/rtc-rc5t583.c index f28d57788951..68ce77414bdc 100644 --- a/drivers/rtc/rtc-rc5t583.c +++ b/drivers/rtc/rtc-rc5t583.c | |||
@@ -128,6 +128,7 @@ static int rc5t583_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
128 | return ret; | 128 | return ret; |
129 | } | 129 | } |
130 | 130 | ||
131 | alm->time.tm_sec = 0; | ||
131 | alm->time.tm_min = bcd2bin(alarm_data[0]); | 132 | alm->time.tm_min = bcd2bin(alarm_data[0]); |
132 | alm->time.tm_hour = bcd2bin(alarm_data[1]); | 133 | alm->time.tm_hour = bcd2bin(alarm_data[1]); |
133 | alm->time.tm_mday = bcd2bin(alarm_data[2]); | 134 | alm->time.tm_mday = bcd2bin(alarm_data[2]); |
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index ef86229428fc..c8c757466783 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c | |||
@@ -341,12 +341,6 @@ static int rs5c_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
341 | t->time.tm_sec = 0; | 341 | t->time.tm_sec = 0; |
342 | t->time.tm_min = bcd2bin(rs5c->regs[RS5C_REG_ALARM_A_MIN] & 0x7f); | 342 | t->time.tm_min = bcd2bin(rs5c->regs[RS5C_REG_ALARM_A_MIN] & 0x7f); |
343 | t->time.tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C_REG_ALARM_A_HOURS]); | 343 | t->time.tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C_REG_ALARM_A_HOURS]); |
344 | t->time.tm_mday = -1; | ||
345 | t->time.tm_mon = -1; | ||
346 | t->time.tm_year = -1; | ||
347 | t->time.tm_wday = -1; | ||
348 | t->time.tm_yday = -1; | ||
349 | t->time.tm_isdst = -1; | ||
350 | 344 | ||
351 | /* ... and status */ | 345 | /* ... and status */ |
352 | t->enabled = !!(rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE); | 346 | t->enabled = !!(rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE); |
diff --git a/drivers/rtc/rtc-rv8803.c b/drivers/rtc/rtc-rv8803.c index f623038e586e..9a2f6a95d5a7 100644 --- a/drivers/rtc/rtc-rv8803.c +++ b/drivers/rtc/rtc-rv8803.c | |||
@@ -13,12 +13,15 @@ | |||
13 | 13 | ||
14 | #include <linux/bcd.h> | 14 | #include <linux/bcd.h> |
15 | #include <linux/bitops.h> | 15 | #include <linux/bitops.h> |
16 | #include <linux/log2.h> | ||
16 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
17 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
18 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
19 | #include <linux/module.h> | 20 | #include <linux/module.h> |
20 | #include <linux/rtc.h> | 21 | #include <linux/rtc.h> |
21 | 22 | ||
23 | #define RV8803_I2C_TRY_COUNT 4 | ||
24 | |||
22 | #define RV8803_SEC 0x00 | 25 | #define RV8803_SEC 0x00 |
23 | #define RV8803_MIN 0x01 | 26 | #define RV8803_MIN 0x01 |
24 | #define RV8803_HOUR 0x02 | 27 | #define RV8803_HOUR 0x02 |
@@ -56,19 +59,85 @@ struct rv8803_data { | |||
56 | u8 ctrl; | 59 | u8 ctrl; |
57 | }; | 60 | }; |
58 | 61 | ||
62 | static int rv8803_read_reg(const struct i2c_client *client, u8 reg) | ||
63 | { | ||
64 | int try = RV8803_I2C_TRY_COUNT; | ||
65 | s32 ret; | ||
66 | |||
67 | /* | ||
68 | * There is a 61µs window during which the RTC does not acknowledge I2C | ||
69 | * transfers. In that case, ensure that there are multiple attempts. | ||
70 | */ | ||
71 | do | ||
72 | ret = i2c_smbus_read_byte_data(client, reg); | ||
73 | while ((ret == -ENXIO || ret == -EIO) && --try); | ||
74 | if (ret < 0) | ||
75 | dev_err(&client->dev, "Unable to read register 0x%02x\n", reg); | ||
76 | |||
77 | return ret; | ||
78 | } | ||
79 | |||
80 | static int rv8803_read_regs(const struct i2c_client *client, | ||
81 | u8 reg, u8 count, u8 *values) | ||
82 | { | ||
83 | int try = RV8803_I2C_TRY_COUNT; | ||
84 | s32 ret; | ||
85 | |||
86 | do | ||
87 | ret = i2c_smbus_read_i2c_block_data(client, reg, count, values); | ||
88 | while ((ret == -ENXIO || ret == -EIO) && --try); | ||
89 | if (ret != count) { | ||
90 | dev_err(&client->dev, | ||
91 | "Unable to read registers 0x%02x..0x%02x\n", | ||
92 | reg, reg + count - 1); | ||
93 | return ret < 0 ? ret : -EIO; | ||
94 | } | ||
95 | |||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | static int rv8803_write_reg(const struct i2c_client *client, u8 reg, u8 value) | ||
100 | { | ||
101 | int try = RV8803_I2C_TRY_COUNT; | ||
102 | s32 ret; | ||
103 | |||
104 | do | ||
105 | ret = i2c_smbus_write_byte_data(client, reg, value); | ||
106 | while ((ret == -ENXIO || ret == -EIO) && --try); | ||
107 | if (ret) | ||
108 | dev_err(&client->dev, "Unable to write register 0x%02x\n", reg); | ||
109 | |||
110 | return ret; | ||
111 | } | ||
112 | |||
113 | static int rv8803_write_regs(const struct i2c_client *client, | ||
114 | u8 reg, u8 count, const u8 *values) | ||
115 | { | ||
116 | int try = RV8803_I2C_TRY_COUNT; | ||
117 | s32 ret; | ||
118 | |||
119 | do | ||
120 | ret = i2c_smbus_write_i2c_block_data(client, reg, count, | ||
121 | values); | ||
122 | while ((ret == -ENXIO || ret == -EIO) && --try); | ||
123 | if (ret) | ||
124 | dev_err(&client->dev, | ||
125 | "Unable to write registers 0x%02x..0x%02x\n", | ||
126 | reg, reg + count - 1); | ||
127 | |||
128 | return ret; | ||
129 | } | ||
130 | |||
59 | static irqreturn_t rv8803_handle_irq(int irq, void *dev_id) | 131 | static irqreturn_t rv8803_handle_irq(int irq, void *dev_id) |
60 | { | 132 | { |
61 | struct i2c_client *client = dev_id; | 133 | struct i2c_client *client = dev_id; |
62 | struct rv8803_data *rv8803 = i2c_get_clientdata(client); | 134 | struct rv8803_data *rv8803 = i2c_get_clientdata(client); |
63 | unsigned long events = 0; | 135 | unsigned long events = 0; |
64 | int flags, try = 0; | 136 | int flags; |
65 | 137 | ||
66 | mutex_lock(&rv8803->flags_lock); | 138 | mutex_lock(&rv8803->flags_lock); |
67 | 139 | ||
68 | do { | 140 | flags = rv8803_read_reg(client, RV8803_FLAG); |
69 | flags = i2c_smbus_read_byte_data(client, RV8803_FLAG); | ||
70 | try++; | ||
71 | } while ((flags == -ENXIO) && (try < 3)); | ||
72 | if (flags <= 0) { | 141 | if (flags <= 0) { |
73 | mutex_unlock(&rv8803->flags_lock); | 142 | mutex_unlock(&rv8803->flags_lock); |
74 | return IRQ_NONE; | 143 | return IRQ_NONE; |
@@ -100,9 +169,8 @@ static irqreturn_t rv8803_handle_irq(int irq, void *dev_id) | |||
100 | 169 | ||
101 | if (events) { | 170 | if (events) { |
102 | rtc_update_irq(rv8803->rtc, 1, events); | 171 | rtc_update_irq(rv8803->rtc, 1, events); |
103 | i2c_smbus_write_byte_data(client, RV8803_FLAG, flags); | 172 | rv8803_write_reg(client, RV8803_FLAG, flags); |
104 | i2c_smbus_write_byte_data(rv8803->client, RV8803_CTRL, | 173 | rv8803_write_reg(rv8803->client, RV8803_CTRL, rv8803->ctrl); |
105 | rv8803->ctrl); | ||
106 | } | 174 | } |
107 | 175 | ||
108 | mutex_unlock(&rv8803->flags_lock); | 176 | mutex_unlock(&rv8803->flags_lock); |
@@ -118,7 +186,7 @@ static int rv8803_get_time(struct device *dev, struct rtc_time *tm) | |||
118 | u8 *date = date1; | 186 | u8 *date = date1; |
119 | int ret, flags; | 187 | int ret, flags; |
120 | 188 | ||
121 | flags = i2c_smbus_read_byte_data(rv8803->client, RV8803_FLAG); | 189 | flags = rv8803_read_reg(rv8803->client, RV8803_FLAG); |
122 | if (flags < 0) | 190 | if (flags < 0) |
123 | return flags; | 191 | return flags; |
124 | 192 | ||
@@ -127,16 +195,14 @@ static int rv8803_get_time(struct device *dev, struct rtc_time *tm) | |||
127 | return -EINVAL; | 195 | return -EINVAL; |
128 | } | 196 | } |
129 | 197 | ||
130 | ret = i2c_smbus_read_i2c_block_data(rv8803->client, RV8803_SEC, | 198 | ret = rv8803_read_regs(rv8803->client, RV8803_SEC, 7, date); |
131 | 7, date); | 199 | if (ret) |
132 | if (ret != 7) | 200 | return ret; |
133 | return ret < 0 ? ret : -EIO; | ||
134 | 201 | ||
135 | if ((date1[RV8803_SEC] & 0x7f) == bin2bcd(59)) { | 202 | if ((date1[RV8803_SEC] & 0x7f) == bin2bcd(59)) { |
136 | ret = i2c_smbus_read_i2c_block_data(rv8803->client, RV8803_SEC, | 203 | ret = rv8803_read_regs(rv8803->client, RV8803_SEC, 7, date2); |
137 | 7, date2); | 204 | if (ret) |
138 | if (ret != 7) | 205 | return ret; |
139 | return ret < 0 ? ret : -EIO; | ||
140 | 206 | ||
141 | if ((date2[RV8803_SEC] & 0x7f) != bin2bcd(59)) | 207 | if ((date2[RV8803_SEC] & 0x7f) != bin2bcd(59)) |
142 | date = date2; | 208 | date = date2; |
@@ -145,23 +211,33 @@ static int rv8803_get_time(struct device *dev, struct rtc_time *tm) | |||
145 | tm->tm_sec = bcd2bin(date[RV8803_SEC] & 0x7f); | 211 | tm->tm_sec = bcd2bin(date[RV8803_SEC] & 0x7f); |
146 | tm->tm_min = bcd2bin(date[RV8803_MIN] & 0x7f); | 212 | tm->tm_min = bcd2bin(date[RV8803_MIN] & 0x7f); |
147 | tm->tm_hour = bcd2bin(date[RV8803_HOUR] & 0x3f); | 213 | tm->tm_hour = bcd2bin(date[RV8803_HOUR] & 0x3f); |
148 | tm->tm_wday = ffs(date[RV8803_WEEK] & 0x7f); | 214 | tm->tm_wday = ilog2(date[RV8803_WEEK] & 0x7f); |
149 | tm->tm_mday = bcd2bin(date[RV8803_DAY] & 0x3f); | 215 | tm->tm_mday = bcd2bin(date[RV8803_DAY] & 0x3f); |
150 | tm->tm_mon = bcd2bin(date[RV8803_MONTH] & 0x1f) - 1; | 216 | tm->tm_mon = bcd2bin(date[RV8803_MONTH] & 0x1f) - 1; |
151 | tm->tm_year = bcd2bin(date[RV8803_YEAR]) + 100; | 217 | tm->tm_year = bcd2bin(date[RV8803_YEAR]) + 100; |
152 | 218 | ||
153 | return rtc_valid_tm(tm); | 219 | return 0; |
154 | } | 220 | } |
155 | 221 | ||
156 | static int rv8803_set_time(struct device *dev, struct rtc_time *tm) | 222 | static int rv8803_set_time(struct device *dev, struct rtc_time *tm) |
157 | { | 223 | { |
158 | struct rv8803_data *rv8803 = dev_get_drvdata(dev); | 224 | struct rv8803_data *rv8803 = dev_get_drvdata(dev); |
159 | u8 date[7]; | 225 | u8 date[7]; |
160 | int flags, ret; | 226 | int ctrl, flags, ret; |
161 | 227 | ||
162 | if ((tm->tm_year < 100) || (tm->tm_year > 199)) | 228 | if ((tm->tm_year < 100) || (tm->tm_year > 199)) |
163 | return -EINVAL; | 229 | return -EINVAL; |
164 | 230 | ||
231 | ctrl = rv8803_read_reg(rv8803->client, RV8803_CTRL); | ||
232 | if (ctrl < 0) | ||
233 | return ctrl; | ||
234 | |||
235 | /* Stop the clock */ | ||
236 | ret = rv8803_write_reg(rv8803->client, RV8803_CTRL, | ||
237 | ctrl | RV8803_CTRL_RESET); | ||
238 | if (ret) | ||
239 | return ret; | ||
240 | |||
165 | date[RV8803_SEC] = bin2bcd(tm->tm_sec); | 241 | date[RV8803_SEC] = bin2bcd(tm->tm_sec); |
166 | date[RV8803_MIN] = bin2bcd(tm->tm_min); | 242 | date[RV8803_MIN] = bin2bcd(tm->tm_min); |
167 | date[RV8803_HOUR] = bin2bcd(tm->tm_hour); | 243 | date[RV8803_HOUR] = bin2bcd(tm->tm_hour); |
@@ -170,21 +246,26 @@ static int rv8803_set_time(struct device *dev, struct rtc_time *tm) | |||
170 | date[RV8803_MONTH] = bin2bcd(tm->tm_mon + 1); | 246 | date[RV8803_MONTH] = bin2bcd(tm->tm_mon + 1); |
171 | date[RV8803_YEAR] = bin2bcd(tm->tm_year - 100); | 247 | date[RV8803_YEAR] = bin2bcd(tm->tm_year - 100); |
172 | 248 | ||
173 | ret = i2c_smbus_write_i2c_block_data(rv8803->client, RV8803_SEC, | 249 | ret = rv8803_write_regs(rv8803->client, RV8803_SEC, 7, date); |
174 | 7, date); | 250 | if (ret) |
175 | if (ret < 0) | 251 | return ret; |
252 | |||
253 | /* Restart the clock */ | ||
254 | ret = rv8803_write_reg(rv8803->client, RV8803_CTRL, | ||
255 | ctrl & ~RV8803_CTRL_RESET); | ||
256 | if (ret) | ||
176 | return ret; | 257 | return ret; |
177 | 258 | ||
178 | mutex_lock(&rv8803->flags_lock); | 259 | mutex_lock(&rv8803->flags_lock); |
179 | 260 | ||
180 | flags = i2c_smbus_read_byte_data(rv8803->client, RV8803_FLAG); | 261 | flags = rv8803_read_reg(rv8803->client, RV8803_FLAG); |
181 | if (flags < 0) { | 262 | if (flags < 0) { |
182 | mutex_unlock(&rv8803->flags_lock); | 263 | mutex_unlock(&rv8803->flags_lock); |
183 | return flags; | 264 | return flags; |
184 | } | 265 | } |
185 | 266 | ||
186 | ret = i2c_smbus_write_byte_data(rv8803->client, RV8803_FLAG, | 267 | ret = rv8803_write_reg(rv8803->client, RV8803_FLAG, |
187 | flags & ~RV8803_FLAG_V2F); | 268 | flags & ~(RV8803_FLAG_V1F | RV8803_FLAG_V2F)); |
188 | 269 | ||
189 | mutex_unlock(&rv8803->flags_lock); | 270 | mutex_unlock(&rv8803->flags_lock); |
190 | 271 | ||
@@ -198,22 +279,18 @@ static int rv8803_get_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
198 | u8 alarmvals[3]; | 279 | u8 alarmvals[3]; |
199 | int flags, ret; | 280 | int flags, ret; |
200 | 281 | ||
201 | ret = i2c_smbus_read_i2c_block_data(client, RV8803_ALARM_MIN, | 282 | ret = rv8803_read_regs(client, RV8803_ALARM_MIN, 3, alarmvals); |
202 | 3, alarmvals); | 283 | if (ret) |
203 | if (ret != 3) | 284 | return ret; |
204 | return ret < 0 ? ret : -EIO; | ||
205 | 285 | ||
206 | flags = i2c_smbus_read_byte_data(client, RV8803_FLAG); | 286 | flags = rv8803_read_reg(client, RV8803_FLAG); |
207 | if (flags < 0) | 287 | if (flags < 0) |
208 | return flags; | 288 | return flags; |
209 | 289 | ||
210 | alrm->time.tm_sec = 0; | 290 | alrm->time.tm_sec = 0; |
211 | alrm->time.tm_min = bcd2bin(alarmvals[0] & 0x7f); | 291 | alrm->time.tm_min = bcd2bin(alarmvals[0] & 0x7f); |
212 | alrm->time.tm_hour = bcd2bin(alarmvals[1] & 0x3f); | 292 | alrm->time.tm_hour = bcd2bin(alarmvals[1] & 0x3f); |
213 | alrm->time.tm_wday = -1; | ||
214 | alrm->time.tm_mday = bcd2bin(alarmvals[2] & 0x3f); | 293 | alrm->time.tm_mday = bcd2bin(alarmvals[2] & 0x3f); |
215 | alrm->time.tm_mon = -1; | ||
216 | alrm->time.tm_year = -1; | ||
217 | 294 | ||
218 | alrm->enabled = !!(rv8803->ctrl & RV8803_CTRL_AIE); | 295 | alrm->enabled = !!(rv8803->ctrl & RV8803_CTRL_AIE); |
219 | alrm->pending = (flags & RV8803_FLAG_AF) && alrm->enabled; | 296 | alrm->pending = (flags & RV8803_FLAG_AF) && alrm->enabled; |
@@ -239,10 +316,10 @@ static int rv8803_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
239 | 316 | ||
240 | mutex_lock(&rv8803->flags_lock); | 317 | mutex_lock(&rv8803->flags_lock); |
241 | 318 | ||
242 | ret = i2c_smbus_read_i2c_block_data(client, RV8803_FLAG, 2, ctrl); | 319 | ret = rv8803_read_regs(client, RV8803_FLAG, 2, ctrl); |
243 | if (ret != 2) { | 320 | if (ret) { |
244 | mutex_unlock(&rv8803->flags_lock); | 321 | mutex_unlock(&rv8803->flags_lock); |
245 | return ret < 0 ? ret : -EIO; | 322 | return ret; |
246 | } | 323 | } |
247 | 324 | ||
248 | alarmvals[0] = bin2bcd(alrm->time.tm_min); | 325 | alarmvals[0] = bin2bcd(alrm->time.tm_min); |
@@ -251,8 +328,8 @@ static int rv8803_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
251 | 328 | ||
252 | if (rv8803->ctrl & (RV8803_CTRL_AIE | RV8803_CTRL_UIE)) { | 329 | if (rv8803->ctrl & (RV8803_CTRL_AIE | RV8803_CTRL_UIE)) { |
253 | rv8803->ctrl &= ~(RV8803_CTRL_AIE | RV8803_CTRL_UIE); | 330 | rv8803->ctrl &= ~(RV8803_CTRL_AIE | RV8803_CTRL_UIE); |
254 | err = i2c_smbus_write_byte_data(rv8803->client, RV8803_CTRL, | 331 | err = rv8803_write_reg(rv8803->client, RV8803_CTRL, |
255 | rv8803->ctrl); | 332 | rv8803->ctrl); |
256 | if (err) { | 333 | if (err) { |
257 | mutex_unlock(&rv8803->flags_lock); | 334 | mutex_unlock(&rv8803->flags_lock); |
258 | return err; | 335 | return err; |
@@ -260,13 +337,12 @@ static int rv8803_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
260 | } | 337 | } |
261 | 338 | ||
262 | ctrl[1] &= ~RV8803_FLAG_AF; | 339 | ctrl[1] &= ~RV8803_FLAG_AF; |
263 | err = i2c_smbus_write_byte_data(rv8803->client, RV8803_FLAG, ctrl[1]); | 340 | err = rv8803_write_reg(rv8803->client, RV8803_FLAG, ctrl[1]); |
264 | mutex_unlock(&rv8803->flags_lock); | 341 | mutex_unlock(&rv8803->flags_lock); |
265 | if (err) | 342 | if (err) |
266 | return err; | 343 | return err; |
267 | 344 | ||
268 | err = i2c_smbus_write_i2c_block_data(rv8803->client, RV8803_ALARM_MIN, | 345 | err = rv8803_write_regs(rv8803->client, RV8803_ALARM_MIN, 3, alarmvals); |
269 | 3, alarmvals); | ||
270 | if (err) | 346 | if (err) |
271 | return err; | 347 | return err; |
272 | 348 | ||
@@ -276,8 +352,8 @@ static int rv8803_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
276 | if (rv8803->rtc->aie_timer.enabled) | 352 | if (rv8803->rtc->aie_timer.enabled) |
277 | rv8803->ctrl |= RV8803_CTRL_AIE; | 353 | rv8803->ctrl |= RV8803_CTRL_AIE; |
278 | 354 | ||
279 | err = i2c_smbus_write_byte_data(rv8803->client, RV8803_CTRL, | 355 | err = rv8803_write_reg(rv8803->client, RV8803_CTRL, |
280 | rv8803->ctrl); | 356 | rv8803->ctrl); |
281 | if (err) | 357 | if (err) |
282 | return err; | 358 | return err; |
283 | } | 359 | } |
@@ -306,21 +382,20 @@ static int rv8803_alarm_irq_enable(struct device *dev, unsigned int enabled) | |||
306 | } | 382 | } |
307 | 383 | ||
308 | mutex_lock(&rv8803->flags_lock); | 384 | mutex_lock(&rv8803->flags_lock); |
309 | flags = i2c_smbus_read_byte_data(client, RV8803_FLAG); | 385 | flags = rv8803_read_reg(client, RV8803_FLAG); |
310 | if (flags < 0) { | 386 | if (flags < 0) { |
311 | mutex_unlock(&rv8803->flags_lock); | 387 | mutex_unlock(&rv8803->flags_lock); |
312 | return flags; | 388 | return flags; |
313 | } | 389 | } |
314 | flags &= ~(RV8803_FLAG_AF | RV8803_FLAG_UF); | 390 | flags &= ~(RV8803_FLAG_AF | RV8803_FLAG_UF); |
315 | err = i2c_smbus_write_byte_data(client, RV8803_FLAG, flags); | 391 | err = rv8803_write_reg(client, RV8803_FLAG, flags); |
316 | mutex_unlock(&rv8803->flags_lock); | 392 | mutex_unlock(&rv8803->flags_lock); |
317 | if (err) | 393 | if (err) |
318 | return err; | 394 | return err; |
319 | 395 | ||
320 | if (ctrl != rv8803->ctrl) { | 396 | if (ctrl != rv8803->ctrl) { |
321 | rv8803->ctrl = ctrl; | 397 | rv8803->ctrl = ctrl; |
322 | err = i2c_smbus_write_byte_data(client, RV8803_CTRL, | 398 | err = rv8803_write_reg(client, RV8803_CTRL, rv8803->ctrl); |
323 | rv8803->ctrl); | ||
324 | if (err) | 399 | if (err) |
325 | return err; | 400 | return err; |
326 | } | 401 | } |
@@ -336,7 +411,7 @@ static int rv8803_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | |||
336 | 411 | ||
337 | switch (cmd) { | 412 | switch (cmd) { |
338 | case RTC_VL_READ: | 413 | case RTC_VL_READ: |
339 | flags = i2c_smbus_read_byte_data(client, RV8803_FLAG); | 414 | flags = rv8803_read_reg(client, RV8803_FLAG); |
340 | if (flags < 0) | 415 | if (flags < 0) |
341 | return flags; | 416 | return flags; |
342 | 417 | ||
@@ -355,16 +430,16 @@ static int rv8803_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | |||
355 | 430 | ||
356 | case RTC_VL_CLR: | 431 | case RTC_VL_CLR: |
357 | mutex_lock(&rv8803->flags_lock); | 432 | mutex_lock(&rv8803->flags_lock); |
358 | flags = i2c_smbus_read_byte_data(client, RV8803_FLAG); | 433 | flags = rv8803_read_reg(client, RV8803_FLAG); |
359 | if (flags < 0) { | 434 | if (flags < 0) { |
360 | mutex_unlock(&rv8803->flags_lock); | 435 | mutex_unlock(&rv8803->flags_lock); |
361 | return flags; | 436 | return flags; |
362 | } | 437 | } |
363 | 438 | ||
364 | flags &= ~(RV8803_FLAG_V1F | RV8803_FLAG_V2F); | 439 | flags &= ~(RV8803_FLAG_V1F | RV8803_FLAG_V2F); |
365 | ret = i2c_smbus_write_byte_data(client, RV8803_FLAG, flags); | 440 | ret = rv8803_write_reg(client, RV8803_FLAG, flags); |
366 | mutex_unlock(&rv8803->flags_lock); | 441 | mutex_unlock(&rv8803->flags_lock); |
367 | if (ret < 0) | 442 | if (ret) |
368 | return ret; | 443 | return ret; |
369 | 444 | ||
370 | return 0; | 445 | return 0; |
@@ -382,8 +457,8 @@ static ssize_t rv8803_nvram_write(struct file *filp, struct kobject *kobj, | |||
382 | struct i2c_client *client = to_i2c_client(dev); | 457 | struct i2c_client *client = to_i2c_client(dev); |
383 | int ret; | 458 | int ret; |
384 | 459 | ||
385 | ret = i2c_smbus_write_byte_data(client, RV8803_RAM, buf[0]); | 460 | ret = rv8803_write_reg(client, RV8803_RAM, buf[0]); |
386 | if (ret < 0) | 461 | if (ret) |
387 | return ret; | 462 | return ret; |
388 | 463 | ||
389 | return 1; | 464 | return 1; |
@@ -397,7 +472,7 @@ static ssize_t rv8803_nvram_read(struct file *filp, struct kobject *kobj, | |||
397 | struct i2c_client *client = to_i2c_client(dev); | 472 | struct i2c_client *client = to_i2c_client(dev); |
398 | int ret; | 473 | int ret; |
399 | 474 | ||
400 | ret = i2c_smbus_read_byte_data(client, RV8803_RAM); | 475 | ret = rv8803_read_reg(client, RV8803_RAM); |
401 | if (ret < 0) | 476 | if (ret < 0) |
402 | return ret; | 477 | return ret; |
403 | 478 | ||
@@ -427,7 +502,7 @@ static int rv8803_probe(struct i2c_client *client, | |||
427 | { | 502 | { |
428 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 503 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
429 | struct rv8803_data *rv8803; | 504 | struct rv8803_data *rv8803; |
430 | int err, flags, try = 0; | 505 | int err, flags; |
431 | 506 | ||
432 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | | 507 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | |
433 | I2C_FUNC_SMBUS_I2C_BLOCK)) { | 508 | I2C_FUNC_SMBUS_I2C_BLOCK)) { |
@@ -444,16 +519,7 @@ static int rv8803_probe(struct i2c_client *client, | |||
444 | rv8803->client = client; | 519 | rv8803->client = client; |
445 | i2c_set_clientdata(client, rv8803); | 520 | i2c_set_clientdata(client, rv8803); |
446 | 521 | ||
447 | /* | 522 | flags = rv8803_read_reg(client, RV8803_FLAG); |
448 | * There is a 60µs window where the RTC may not reply on the i2c bus in | ||
449 | * that case, the transfer is not ACKed. In that case, ensure there are | ||
450 | * multiple attempts. | ||
451 | */ | ||
452 | do { | ||
453 | flags = i2c_smbus_read_byte_data(client, RV8803_FLAG); | ||
454 | try++; | ||
455 | } while ((flags == -ENXIO) && (try < 3)); | ||
456 | |||
457 | if (flags < 0) | 523 | if (flags < 0) |
458 | return flags; | 524 | return flags; |
459 | 525 | ||
@@ -488,12 +554,7 @@ static int rv8803_probe(struct i2c_client *client, | |||
488 | return PTR_ERR(rv8803->rtc); | 554 | return PTR_ERR(rv8803->rtc); |
489 | } | 555 | } |
490 | 556 | ||
491 | try = 0; | 557 | err = rv8803_write_reg(rv8803->client, RV8803_EXT, RV8803_EXT_WADA); |
492 | do { | ||
493 | err = i2c_smbus_write_byte_data(rv8803->client, RV8803_EXT, | ||
494 | RV8803_EXT_WADA); | ||
495 | try++; | ||
496 | } while ((err == -ENXIO) && (try < 3)); | ||
497 | if (err) | 558 | if (err) |
498 | return err; | 559 | return err; |
499 | 560 | ||
diff --git a/drivers/rtc/rtc-rx8010.c b/drivers/rtc/rtc-rx8010.c index 772d221ec2d9..7163b91bb773 100644 --- a/drivers/rtc/rtc-rx8010.c +++ b/drivers/rtc/rtc-rx8010.c | |||
@@ -272,15 +272,9 @@ static int rx8010_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
272 | t->time.tm_min = bcd2bin(alarmvals[0] & 0x7f); | 272 | t->time.tm_min = bcd2bin(alarmvals[0] & 0x7f); |
273 | t->time.tm_hour = bcd2bin(alarmvals[1] & 0x3f); | 273 | t->time.tm_hour = bcd2bin(alarmvals[1] & 0x3f); |
274 | 274 | ||
275 | if (alarmvals[2] & RX8010_ALARM_AE) | 275 | if (!(alarmvals[2] & RX8010_ALARM_AE)) |
276 | t->time.tm_mday = -1; | ||
277 | else | ||
278 | t->time.tm_mday = bcd2bin(alarmvals[2] & 0x7f); | 276 | t->time.tm_mday = bcd2bin(alarmvals[2] & 0x7f); |
279 | 277 | ||
280 | t->time.tm_wday = -1; | ||
281 | t->time.tm_mon = -1; | ||
282 | t->time.tm_year = -1; | ||
283 | |||
284 | t->enabled = !!(rx8010->ctrlreg & RX8010_CTRL_AIE); | 278 | t->enabled = !!(rx8010->ctrlreg & RX8010_CTRL_AIE); |
285 | t->pending = (flagreg & RX8010_FLAG_AF) && t->enabled; | 279 | t->pending = (flagreg & RX8010_FLAG_AF) && t->enabled; |
286 | 280 | ||
diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c index 9f105efbc546..2b85cc7a24e7 100644 --- a/drivers/rtc/rtc-rx8025.c +++ b/drivers/rtc/rtc-rx8025.c | |||
@@ -319,11 +319,6 @@ static int rx8025_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
319 | t->time.tm_hour = bcd2bin(ald[1] & 0x1f) % 12 | 319 | t->time.tm_hour = bcd2bin(ald[1] & 0x1f) % 12 |
320 | + (ald[1] & 0x20 ? 12 : 0); | 320 | + (ald[1] & 0x20 ? 12 : 0); |
321 | 321 | ||
322 | t->time.tm_wday = -1; | ||
323 | t->time.tm_mday = -1; | ||
324 | t->time.tm_mon = -1; | ||
325 | t->time.tm_year = -1; | ||
326 | |||
327 | dev_dbg(dev, "%s: date: %ds %dm %dh %dmd %dm %dy\n", | 322 | dev_dbg(dev, "%s: date: %ds %dm %dh %dmd %dm %dy\n", |
328 | __func__, | 323 | __func__, |
329 | t->time.tm_sec, t->time.tm_min, t->time.tm_hour, | 324 | t->time.tm_sec, t->time.tm_min, t->time.tm_hour, |
diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index f40afdd0e5f5..5dab4665ca3b 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/bitrev.h> | 15 | #include <linux/bitrev.h> |
16 | #include <linux/bcd.h> | 16 | #include <linux/bcd.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/delay.h> | ||
18 | 19 | ||
19 | #define S35390A_CMD_STATUS1 0 | 20 | #define S35390A_CMD_STATUS1 0 |
20 | #define S35390A_CMD_STATUS2 1 | 21 | #define S35390A_CMD_STATUS2 1 |
@@ -34,10 +35,14 @@ | |||
34 | #define S35390A_ALRM_BYTE_HOURS 1 | 35 | #define S35390A_ALRM_BYTE_HOURS 1 |
35 | #define S35390A_ALRM_BYTE_MINS 2 | 36 | #define S35390A_ALRM_BYTE_MINS 2 |
36 | 37 | ||
38 | /* flags for STATUS1 */ | ||
37 | #define S35390A_FLAG_POC 0x01 | 39 | #define S35390A_FLAG_POC 0x01 |
38 | #define S35390A_FLAG_BLD 0x02 | 40 | #define S35390A_FLAG_BLD 0x02 |
41 | #define S35390A_FLAG_INT2 0x04 | ||
39 | #define S35390A_FLAG_24H 0x40 | 42 | #define S35390A_FLAG_24H 0x40 |
40 | #define S35390A_FLAG_RESET 0x80 | 43 | #define S35390A_FLAG_RESET 0x80 |
44 | |||
45 | /* flag for STATUS2 */ | ||
41 | #define S35390A_FLAG_TEST 0x01 | 46 | #define S35390A_FLAG_TEST 0x01 |
42 | 47 | ||
43 | #define S35390A_INT2_MODE_MASK 0xF0 | 48 | #define S35390A_INT2_MODE_MASK 0xF0 |
@@ -94,19 +99,63 @@ static int s35390a_get_reg(struct s35390a *s35390a, int reg, char *buf, int len) | |||
94 | return 0; | 99 | return 0; |
95 | } | 100 | } |
96 | 101 | ||
97 | static int s35390a_reset(struct s35390a *s35390a) | 102 | /* |
103 | * Returns <0 on error, 0 if rtc is setup fine and 1 if the chip was reset. | ||
104 | * To keep the information if an irq is pending, pass the value read from | ||
105 | * STATUS1 to the caller. | ||
106 | */ | ||
107 | static int s35390a_reset(struct s35390a *s35390a, char *status1) | ||
98 | { | 108 | { |
99 | char buf[1]; | 109 | char buf; |
100 | 110 | int ret; | |
101 | if (s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf)) < 0) | 111 | unsigned initcount = 0; |
102 | return -EIO; | 112 | |
103 | 113 | ret = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, status1, 1); | |
104 | if (!(buf[0] & (S35390A_FLAG_POC | S35390A_FLAG_BLD))) | 114 | if (ret < 0) |
115 | return ret; | ||
116 | |||
117 | if (*status1 & S35390A_FLAG_POC) | ||
118 | /* | ||
119 | * Do not communicate for 0.5 seconds since the power-on | ||
120 | * detection circuit is in operation. | ||
121 | */ | ||
122 | msleep(500); | ||
123 | else if (!(*status1 & S35390A_FLAG_BLD)) | ||
124 | /* | ||
125 | * If both POC and BLD are unset everything is fine. | ||
126 | */ | ||
105 | return 0; | 127 | return 0; |
106 | 128 | ||
107 | buf[0] |= (S35390A_FLAG_RESET | S35390A_FLAG_24H); | 129 | /* |
108 | buf[0] &= 0xf0; | 130 | * At least one of POC and BLD are set, so reinitialise chip. Keeping |
109 | return s35390a_set_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf)); | 131 | * this information in the hardware to know later that the time isn't |
132 | * valid is unfortunately not possible because POC and BLD are cleared | ||
133 | * on read. So the reset is best done now. | ||
134 | * | ||
135 | * The 24H bit is kept over reset, so set it already here. | ||
136 | */ | ||
137 | initialize: | ||
138 | *status1 = S35390A_FLAG_24H; | ||
139 | buf = S35390A_FLAG_RESET | S35390A_FLAG_24H; | ||
140 | ret = s35390a_set_reg(s35390a, S35390A_CMD_STATUS1, &buf, 1); | ||
141 | |||
142 | if (ret < 0) | ||
143 | return ret; | ||
144 | |||
145 | ret = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, &buf, 1); | ||
146 | if (ret < 0) | ||
147 | return ret; | ||
148 | |||
149 | if (buf & (S35390A_FLAG_POC | S35390A_FLAG_BLD)) { | ||
150 | /* Try up to five times to reset the chip */ | ||
151 | if (initcount < 5) { | ||
152 | ++initcount; | ||
153 | goto initialize; | ||
154 | } else | ||
155 | return -EIO; | ||
156 | } | ||
157 | |||
158 | return 1; | ||
110 | } | 159 | } |
111 | 160 | ||
112 | static int s35390a_disable_test_mode(struct s35390a *s35390a) | 161 | static int s35390a_disable_test_mode(struct s35390a *s35390a) |
@@ -217,12 +266,12 @@ static int s35390a_set_alarm(struct i2c_client *client, struct rtc_wkalrm *alm) | |||
217 | alm->time.tm_min, alm->time.tm_hour, alm->time.tm_mday, | 266 | alm->time.tm_min, alm->time.tm_hour, alm->time.tm_mday, |
218 | alm->time.tm_mon, alm->time.tm_year, alm->time.tm_wday); | 267 | alm->time.tm_mon, alm->time.tm_year, alm->time.tm_wday); |
219 | 268 | ||
220 | /* disable interrupt */ | 269 | /* disable interrupt (which deasserts the irq line) */ |
221 | err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts)); | 270 | err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts)); |
222 | if (err < 0) | 271 | if (err < 0) |
223 | return err; | 272 | return err; |
224 | 273 | ||
225 | /* clear pending interrupt, if any */ | 274 | /* clear pending interrupt (in STATUS1 only), if any */ |
226 | err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, &sts, sizeof(sts)); | 275 | err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, &sts, sizeof(sts)); |
227 | if (err < 0) | 276 | if (err < 0) |
228 | return err; | 277 | return err; |
@@ -242,6 +291,8 @@ static int s35390a_set_alarm(struct i2c_client *client, struct rtc_wkalrm *alm) | |||
242 | 291 | ||
243 | if (alm->time.tm_wday != -1) | 292 | if (alm->time.tm_wday != -1) |
244 | buf[S35390A_ALRM_BYTE_WDAY] = bin2bcd(alm->time.tm_wday) | 0x80; | 293 | buf[S35390A_ALRM_BYTE_WDAY] = bin2bcd(alm->time.tm_wday) | 0x80; |
294 | else | ||
295 | buf[S35390A_ALRM_BYTE_WDAY] = 0; | ||
245 | 296 | ||
246 | buf[S35390A_ALRM_BYTE_HOURS] = s35390a_hr2reg(s35390a, | 297 | buf[S35390A_ALRM_BYTE_HOURS] = s35390a_hr2reg(s35390a, |
247 | alm->time.tm_hour) | 0x80; | 298 | alm->time.tm_hour) | 0x80; |
@@ -269,23 +320,43 @@ static int s35390a_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alm) | |||
269 | if (err < 0) | 320 | if (err < 0) |
270 | return err; | 321 | return err; |
271 | 322 | ||
272 | if (bitrev8(sts) != S35390A_INT2_MODE_ALARM) | 323 | if ((bitrev8(sts) & S35390A_INT2_MODE_MASK) != S35390A_INT2_MODE_ALARM) { |
273 | return -EINVAL; | 324 | /* |
325 | * When the alarm isn't enabled, the register to configure | ||
326 | * the alarm time isn't accessible. | ||
327 | */ | ||
328 | alm->enabled = 0; | ||
329 | return 0; | ||
330 | } else { | ||
331 | alm->enabled = 1; | ||
332 | } | ||
274 | 333 | ||
275 | err = s35390a_get_reg(s35390a, S35390A_CMD_INT2_REG1, buf, sizeof(buf)); | 334 | err = s35390a_get_reg(s35390a, S35390A_CMD_INT2_REG1, buf, sizeof(buf)); |
276 | if (err < 0) | 335 | if (err < 0) |
277 | return err; | 336 | return err; |
278 | 337 | ||
279 | /* This chip returns the bits of each byte in reverse order */ | 338 | /* This chip returns the bits of each byte in reverse order */ |
280 | for (i = 0; i < 3; ++i) { | 339 | for (i = 0; i < 3; ++i) |
281 | buf[i] = bitrev8(buf[i]); | 340 | buf[i] = bitrev8(buf[i]); |
282 | buf[i] &= ~0x80; | ||
283 | } | ||
284 | 341 | ||
285 | alm->time.tm_wday = bcd2bin(buf[S35390A_ALRM_BYTE_WDAY]); | 342 | /* |
286 | alm->time.tm_hour = s35390a_reg2hr(s35390a, | 343 | * B0 of the three matching registers is an enable flag. Iff it is set |
287 | buf[S35390A_ALRM_BYTE_HOURS]); | 344 | * the configured value is used for matching. |
288 | alm->time.tm_min = bcd2bin(buf[S35390A_ALRM_BYTE_MINS]); | 345 | */ |
346 | if (buf[S35390A_ALRM_BYTE_WDAY] & 0x80) | ||
347 | alm->time.tm_wday = | ||
348 | bcd2bin(buf[S35390A_ALRM_BYTE_WDAY] & ~0x80); | ||
349 | |||
350 | if (buf[S35390A_ALRM_BYTE_HOURS] & 0x80) | ||
351 | alm->time.tm_hour = | ||
352 | s35390a_reg2hr(s35390a, | ||
353 | buf[S35390A_ALRM_BYTE_HOURS] & ~0x80); | ||
354 | |||
355 | if (buf[S35390A_ALRM_BYTE_MINS] & 0x80) | ||
356 | alm->time.tm_min = bcd2bin(buf[S35390A_ALRM_BYTE_MINS] & ~0x80); | ||
357 | |||
358 | /* alarm triggers always at s=0 */ | ||
359 | alm->time.tm_sec = 0; | ||
289 | 360 | ||
290 | dev_dbg(&client->dev, "%s: alm is mins=%d, hours=%d, wday=%d\n", | 361 | dev_dbg(&client->dev, "%s: alm is mins=%d, hours=%d, wday=%d\n", |
291 | __func__, alm->time.tm_min, alm->time.tm_hour, | 362 | __func__, alm->time.tm_min, alm->time.tm_hour, |
@@ -327,11 +398,11 @@ static struct i2c_driver s35390a_driver; | |||
327 | static int s35390a_probe(struct i2c_client *client, | 398 | static int s35390a_probe(struct i2c_client *client, |
328 | const struct i2c_device_id *id) | 399 | const struct i2c_device_id *id) |
329 | { | 400 | { |
330 | int err; | 401 | int err, err_reset; |
331 | unsigned int i; | 402 | unsigned int i; |
332 | struct s35390a *s35390a; | 403 | struct s35390a *s35390a; |
333 | struct rtc_time tm; | 404 | struct rtc_time tm; |
334 | char buf[1]; | 405 | char buf, status1; |
335 | 406 | ||
336 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | 407 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { |
337 | err = -ENODEV; | 408 | err = -ENODEV; |
@@ -360,29 +431,35 @@ static int s35390a_probe(struct i2c_client *client, | |||
360 | } | 431 | } |
361 | } | 432 | } |
362 | 433 | ||
363 | err = s35390a_reset(s35390a); | 434 | err_reset = s35390a_reset(s35390a, &status1); |
364 | if (err < 0) { | 435 | if (err_reset < 0) { |
436 | err = err_reset; | ||
365 | dev_err(&client->dev, "error resetting chip\n"); | 437 | dev_err(&client->dev, "error resetting chip\n"); |
366 | goto exit_dummy; | 438 | goto exit_dummy; |
367 | } | 439 | } |
368 | 440 | ||
369 | err = s35390a_disable_test_mode(s35390a); | 441 | if (status1 & S35390A_FLAG_24H) |
370 | if (err < 0) { | ||
371 | dev_err(&client->dev, "error disabling test mode\n"); | ||
372 | goto exit_dummy; | ||
373 | } | ||
374 | |||
375 | err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf)); | ||
376 | if (err < 0) { | ||
377 | dev_err(&client->dev, "error checking 12/24 hour mode\n"); | ||
378 | goto exit_dummy; | ||
379 | } | ||
380 | if (buf[0] & S35390A_FLAG_24H) | ||
381 | s35390a->twentyfourhour = 1; | 442 | s35390a->twentyfourhour = 1; |
382 | else | 443 | else |
383 | s35390a->twentyfourhour = 0; | 444 | s35390a->twentyfourhour = 0; |
384 | 445 | ||
385 | if (s35390a_get_datetime(client, &tm) < 0) | 446 | if (status1 & S35390A_FLAG_INT2) { |
447 | /* disable alarm (and maybe test mode) */ | ||
448 | buf = 0; | ||
449 | err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &buf, 1); | ||
450 | if (err < 0) { | ||
451 | dev_err(&client->dev, "error disabling alarm"); | ||
452 | goto exit_dummy; | ||
453 | } | ||
454 | } else { | ||
455 | err = s35390a_disable_test_mode(s35390a); | ||
456 | if (err < 0) { | ||
457 | dev_err(&client->dev, "error disabling test mode\n"); | ||
458 | goto exit_dummy; | ||
459 | } | ||
460 | } | ||
461 | |||
462 | if (err_reset > 0 || s35390a_get_datetime(client, &tm) < 0) | ||
386 | dev_warn(&client->dev, "clock needs to be set\n"); | 463 | dev_warn(&client->dev, "clock needs to be set\n"); |
387 | 464 | ||
388 | device_set_wakeup_capable(&client->dev, 1); | 465 | device_set_wakeup_capable(&client->dev, 1); |
@@ -395,6 +472,10 @@ static int s35390a_probe(struct i2c_client *client, | |||
395 | err = PTR_ERR(s35390a->rtc); | 472 | err = PTR_ERR(s35390a->rtc); |
396 | goto exit_dummy; | 473 | goto exit_dummy; |
397 | } | 474 | } |
475 | |||
476 | if (status1 & S35390A_FLAG_INT2) | ||
477 | rtc_update_irq(s35390a->rtc, 1, RTC_AF); | ||
478 | |||
398 | return 0; | 479 | return 0; |
399 | 480 | ||
400 | exit_dummy: | 481 | exit_dummy: |
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index d01ad7e8078e..d44fb34df8fe 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -149,12 +149,14 @@ static int s3c_rtc_setfreq(struct s3c_rtc *info, int freq) | |||
149 | if (!is_power_of_2(freq)) | 149 | if (!is_power_of_2(freq)) |
150 | return -EINVAL; | 150 | return -EINVAL; |
151 | 151 | ||
152 | s3c_rtc_enable_clk(info); | ||
152 | spin_lock_irq(&info->pie_lock); | 153 | spin_lock_irq(&info->pie_lock); |
153 | 154 | ||
154 | if (info->data->set_freq) | 155 | if (info->data->set_freq) |
155 | info->data->set_freq(info, freq); | 156 | info->data->set_freq(info, freq); |
156 | 157 | ||
157 | spin_unlock_irq(&info->pie_lock); | 158 | spin_unlock_irq(&info->pie_lock); |
159 | s3c_rtc_disable_clk(info); | ||
158 | 160 | ||
159 | return 0; | 161 | return 0; |
160 | } | 162 | } |
@@ -264,35 +266,23 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
264 | /* decode the alarm enable field */ | 266 | /* decode the alarm enable field */ |
265 | if (alm_en & S3C2410_RTCALM_SECEN) | 267 | if (alm_en & S3C2410_RTCALM_SECEN) |
266 | alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec); | 268 | alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec); |
267 | else | ||
268 | alm_tm->tm_sec = -1; | ||
269 | 269 | ||
270 | if (alm_en & S3C2410_RTCALM_MINEN) | 270 | if (alm_en & S3C2410_RTCALM_MINEN) |
271 | alm_tm->tm_min = bcd2bin(alm_tm->tm_min); | 271 | alm_tm->tm_min = bcd2bin(alm_tm->tm_min); |
272 | else | ||
273 | alm_tm->tm_min = -1; | ||
274 | 272 | ||
275 | if (alm_en & S3C2410_RTCALM_HOUREN) | 273 | if (alm_en & S3C2410_RTCALM_HOUREN) |
276 | alm_tm->tm_hour = bcd2bin(alm_tm->tm_hour); | 274 | alm_tm->tm_hour = bcd2bin(alm_tm->tm_hour); |
277 | else | ||
278 | alm_tm->tm_hour = -1; | ||
279 | 275 | ||
280 | if (alm_en & S3C2410_RTCALM_DAYEN) | 276 | if (alm_en & S3C2410_RTCALM_DAYEN) |
281 | alm_tm->tm_mday = bcd2bin(alm_tm->tm_mday); | 277 | alm_tm->tm_mday = bcd2bin(alm_tm->tm_mday); |
282 | else | ||
283 | alm_tm->tm_mday = -1; | ||
284 | 278 | ||
285 | if (alm_en & S3C2410_RTCALM_MONEN) { | 279 | if (alm_en & S3C2410_RTCALM_MONEN) { |
286 | alm_tm->tm_mon = bcd2bin(alm_tm->tm_mon); | 280 | alm_tm->tm_mon = bcd2bin(alm_tm->tm_mon); |
287 | alm_tm->tm_mon -= 1; | 281 | alm_tm->tm_mon -= 1; |
288 | } else { | ||
289 | alm_tm->tm_mon = -1; | ||
290 | } | 282 | } |
291 | 283 | ||
292 | if (alm_en & S3C2410_RTCALM_YEAREN) | 284 | if (alm_en & S3C2410_RTCALM_YEAREN) |
293 | alm_tm->tm_year = bcd2bin(alm_tm->tm_year); | 285 | alm_tm->tm_year = bcd2bin(alm_tm->tm_year); |
294 | else | ||
295 | alm_tm->tm_year = -1; | ||
296 | 286 | ||
297 | return 0; | 287 | return 0; |
298 | } | 288 | } |
@@ -577,8 +567,6 @@ static int s3c_rtc_probe(struct platform_device *pdev) | |||
577 | 567 | ||
578 | s3c_rtc_setfreq(info, 1); | 568 | s3c_rtc_setfreq(info, 1); |
579 | 569 | ||
580 | s3c_rtc_disable_clk(info); | ||
581 | |||
582 | return 0; | 570 | return 0; |
583 | 571 | ||
584 | err_nortc: | 572 | err_nortc: |
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index a45845a571e5..17b6235d67a5 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c | |||
@@ -481,7 +481,6 @@ static int sh_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | |||
481 | tm->tm_mon = sh_rtc_read_alarm_value(rtc, RMONAR); | 481 | tm->tm_mon = sh_rtc_read_alarm_value(rtc, RMONAR); |
482 | if (tm->tm_mon > 0) | 482 | if (tm->tm_mon > 0) |
483 | tm->tm_mon -= 1; /* RTC is 1-12, tm_mon is 0-11 */ | 483 | tm->tm_mon -= 1; /* RTC is 1-12, tm_mon is 0-11 */ |
484 | tm->tm_year = 0xffff; | ||
485 | 484 | ||
486 | wkalrm->enabled = (readb(rtc->regbase + RCR1) & RCR1_AIE) ? 1 : 0; | 485 | wkalrm->enabled = (readb(rtc->regbase + RCR1) & RCR1_AIE) ? 1 : 0; |
487 | 486 | ||
@@ -500,52 +499,13 @@ static inline void sh_rtc_write_alarm_value(struct sh_rtc *rtc, | |||
500 | writeb(bin2bcd(value) | AR_ENB, rtc->regbase + reg_off); | 499 | writeb(bin2bcd(value) | AR_ENB, rtc->regbase + reg_off); |
501 | } | 500 | } |
502 | 501 | ||
503 | static int sh_rtc_check_alarm(struct rtc_time *tm) | ||
504 | { | ||
505 | /* | ||
506 | * The original rtc says anything > 0xc0 is "don't care" or "match | ||
507 | * all" - most users use 0xff but rtc-dev uses -1 for the same thing. | ||
508 | * The original rtc doesn't support years - some things use -1 and | ||
509 | * some 0xffff. We use -1 to make out tests easier. | ||
510 | */ | ||
511 | if (tm->tm_year == 0xffff) | ||
512 | tm->tm_year = -1; | ||
513 | if (tm->tm_mon >= 0xff) | ||
514 | tm->tm_mon = -1; | ||
515 | if (tm->tm_mday >= 0xff) | ||
516 | tm->tm_mday = -1; | ||
517 | if (tm->tm_wday >= 0xff) | ||
518 | tm->tm_wday = -1; | ||
519 | if (tm->tm_hour >= 0xff) | ||
520 | tm->tm_hour = -1; | ||
521 | if (tm->tm_min >= 0xff) | ||
522 | tm->tm_min = -1; | ||
523 | if (tm->tm_sec >= 0xff) | ||
524 | tm->tm_sec = -1; | ||
525 | |||
526 | if (tm->tm_year > 9999 || | ||
527 | tm->tm_mon >= 12 || | ||
528 | tm->tm_mday == 0 || tm->tm_mday >= 32 || | ||
529 | tm->tm_wday >= 7 || | ||
530 | tm->tm_hour >= 24 || | ||
531 | tm->tm_min >= 60 || | ||
532 | tm->tm_sec >= 60) | ||
533 | return -EINVAL; | ||
534 | |||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | 502 | static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) |
539 | { | 503 | { |
540 | struct platform_device *pdev = to_platform_device(dev); | 504 | struct platform_device *pdev = to_platform_device(dev); |
541 | struct sh_rtc *rtc = platform_get_drvdata(pdev); | 505 | struct sh_rtc *rtc = platform_get_drvdata(pdev); |
542 | unsigned int rcr1; | 506 | unsigned int rcr1; |
543 | struct rtc_time *tm = &wkalrm->time; | 507 | struct rtc_time *tm = &wkalrm->time; |
544 | int mon, err; | 508 | int mon; |
545 | |||
546 | err = sh_rtc_check_alarm(tm); | ||
547 | if (unlikely(err < 0)) | ||
548 | return err; | ||
549 | 509 | ||
550 | spin_lock_irq(&rtc->lock); | 510 | spin_lock_irq(&rtc->lock); |
551 | 511 | ||
diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c index 60232bd366ef..15ac597d54da 100644 --- a/drivers/rtc/rtc-tegra.c +++ b/drivers/rtc/rtc-tegra.c | |||
@@ -179,12 +179,6 @@ static int tegra_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
179 | if (sec == 0) { | 179 | if (sec == 0) { |
180 | /* alarm is disabled. */ | 180 | /* alarm is disabled. */ |
181 | alarm->enabled = 0; | 181 | alarm->enabled = 0; |
182 | alarm->time.tm_mon = -1; | ||
183 | alarm->time.tm_mday = -1; | ||
184 | alarm->time.tm_year = -1; | ||
185 | alarm->time.tm_hour = -1; | ||
186 | alarm->time.tm_min = -1; | ||
187 | alarm->time.tm_sec = -1; | ||
188 | } else { | 182 | } else { |
189 | /* alarm is enabled. */ | 183 | /* alarm is enabled. */ |
190 | alarm->enabled = 1; | 184 | alarm->enabled = 1; |
diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c index 7a0436329d6c..1f3117b5a83c 100644 --- a/drivers/rtc/rtc-v3020.c +++ b/drivers/rtc/rtc-v3020.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/rtc.h> | 25 | #include <linux/rtc.h> |
26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
27 | #include <linux/bcd.h> | 27 | #include <linux/bcd.h> |
28 | #include <linux/rtc-v3020.h> | 28 | #include <linux/platform_data/rtc-v3020.h> |
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/gpio.h> | 30 | #include <linux/gpio.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
diff --git a/include/linux/ds17287rtc.h b/include/linux/ds17287rtc.h deleted file mode 100644 index d85d3f497b96..000000000000 --- a/include/linux/ds17287rtc.h +++ /dev/null | |||
@@ -1,66 +0,0 @@ | |||
1 | /* | ||
2 | * ds17287rtc.h - register definitions for the ds1728[57] RTC / CMOS RAM | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * (C) 2003 Guido Guenther <agx@sigxcpu.org> | ||
9 | */ | ||
10 | #ifndef __LINUX_DS17287RTC_H | ||
11 | #define __LINUX_DS17287RTC_H | ||
12 | |||
13 | #include <linux/rtc.h> /* get the user-level API */ | ||
14 | #include <linux/mc146818rtc.h> | ||
15 | |||
16 | /* Register A */ | ||
17 | #define DS_REGA_DV2 0x40 /* countdown chain */ | ||
18 | #define DS_REGA_DV1 0x20 /* oscillator enable */ | ||
19 | #define DS_REGA_DV0 0x10 /* bank select */ | ||
20 | |||
21 | /* bank 1 registers */ | ||
22 | #define DS_B1_MODEL 0x40 /* model number byte */ | ||
23 | #define DS_B1_SN1 0x41 /* serial number byte 1 */ | ||
24 | #define DS_B1_SN2 0x42 /* serial number byte 2 */ | ||
25 | #define DS_B1_SN3 0x43 /* serial number byte 3 */ | ||
26 | #define DS_B1_SN4 0x44 /* serial number byte 4 */ | ||
27 | #define DS_B1_SN5 0x45 /* serial number byte 5 */ | ||
28 | #define DS_B1_SN6 0x46 /* serial number byte 6 */ | ||
29 | #define DS_B1_CRC 0x47 /* CRC byte */ | ||
30 | #define DS_B1_CENTURY 0x48 /* Century byte */ | ||
31 | #define DS_B1_DALARM 0x49 /* date alarm */ | ||
32 | #define DS_B1_XCTRL4A 0x4a /* extendec control register 4a */ | ||
33 | #define DS_B1_XCTRL4B 0x4b /* extendec control register 4b */ | ||
34 | #define DS_B1_RTCADDR2 0x4e /* rtc address 2 */ | ||
35 | #define DS_B1_RTCADDR3 0x4f /* rtc address 3 */ | ||
36 | #define DS_B1_RAMLSB 0x50 /* extended ram LSB */ | ||
37 | #define DS_B1_RAMMSB 0x51 /* extended ram MSB */ | ||
38 | #define DS_B1_RAMDPORT 0x53 /* extended ram data port */ | ||
39 | |||
40 | /* register details */ | ||
41 | /* extended control register 4a */ | ||
42 | #define DS_XCTRL4A_VRT2 0x80 /* valid ram and time */ | ||
43 | #define DS_XCTRL4A_INCR 0x40 /* increment progress status */ | ||
44 | #define DS_XCTRL4A_BME 0x20 /* burst mode enable */ | ||
45 | #define DS_XCTRL4A_PAB 0x08 /* power active bar ctrl */ | ||
46 | #define DS_XCTRL4A_RF 0x04 /* ram clear flag */ | ||
47 | #define DS_XCTRL4A_WF 0x02 /* wake up alarm flag */ | ||
48 | #define DS_XCTRL4A_KF 0x01 /* kickstart flag */ | ||
49 | |||
50 | /* interrupt causes */ | ||
51 | #define DS_XCTRL4A_IFS (DS_XCTRL4A_RF|DS_XCTRL4A_WF|DS_XCTRL4A_KF) | ||
52 | |||
53 | /* extended control register 4b */ | ||
54 | #define DS_XCTRL4B_ABE 0x80 /* auxiliary battery enable */ | ||
55 | #define DS_XCTRL4B_E32K 0x40 /* enable 32.768 kHz Output */ | ||
56 | #define DS_XCTRL4B_CS 0x20 /* crystal select */ | ||
57 | #define DS_XCTRL4B_RCE 0x10 /* ram clear enable */ | ||
58 | #define DS_XCTRL4B_PRS 0x08 /* PAB resec select */ | ||
59 | #define DS_XCTRL4B_RIE 0x04 /* ram clear interrupt enable */ | ||
60 | #define DS_XCTRL4B_WFE 0x02 /* wake up alarm interrupt enable */ | ||
61 | #define DS_XCTRL4B_KFE 0x01 /* kickstart interrupt enable */ | ||
62 | |||
63 | /* interrupt enable bits */ | ||
64 | #define DS_XCTRL4B_IFES (DS_XCTRL4B_RIE|DS_XCTRL4B_WFE|DS_XCTRL4B_KFE) | ||
65 | |||
66 | #endif /* __LINUX_DS17287RTC_H */ | ||
diff --git a/include/linux/mc146818rtc.h b/include/linux/mc146818rtc.h index 433e0c74d643..a585b4b5fa0e 100644 --- a/include/linux/mc146818rtc.h +++ b/include/linux/mc146818rtc.h | |||
@@ -14,6 +14,8 @@ | |||
14 | #include <asm/io.h> | 14 | #include <asm/io.h> |
15 | #include <linux/rtc.h> /* get the user-level API */ | 15 | #include <linux/rtc.h> /* get the user-level API */ |
16 | #include <asm/mc146818rtc.h> /* register access macros */ | 16 | #include <asm/mc146818rtc.h> /* register access macros */ |
17 | #include <linux/bcd.h> | ||
18 | #include <linux/delay.h> | ||
17 | 19 | ||
18 | #ifdef __KERNEL__ | 20 | #ifdef __KERNEL__ |
19 | #include <linux/spinlock.h> /* spinlock_t */ | 21 | #include <linux/spinlock.h> /* spinlock_t */ |
@@ -120,4 +122,7 @@ struct cmos_rtc_board_info { | |||
120 | #define RTC_IO_EXTENT_USED RTC_IO_EXTENT | 122 | #define RTC_IO_EXTENT_USED RTC_IO_EXTENT |
121 | #endif /* ARCH_RTC_LOCATION */ | 123 | #endif /* ARCH_RTC_LOCATION */ |
122 | 124 | ||
125 | unsigned int mc146818_get_time(struct rtc_time *time); | ||
126 | int mc146818_set_time(struct rtc_time *time); | ||
127 | |||
123 | #endif /* _MC146818RTC_H */ | 128 | #endif /* _MC146818RTC_H */ |
diff --git a/include/linux/rtc-ds2404.h b/include/linux/platform_data/rtc-ds2404.h index 22c53825528f..22c53825528f 100644 --- a/include/linux/rtc-ds2404.h +++ b/include/linux/platform_data/rtc-ds2404.h | |||
diff --git a/include/linux/m48t86.h b/include/linux/platform_data/rtc-m48t86.h index 915d6b4f0f89..915d6b4f0f89 100644 --- a/include/linux/m48t86.h +++ b/include/linux/platform_data/rtc-m48t86.h | |||
diff --git a/include/linux/rtc-v3020.h b/include/linux/platform_data/rtc-v3020.h index e55d82cebf80..e55d82cebf80 100644 --- a/include/linux/rtc-v3020.h +++ b/include/linux/platform_data/rtc-v3020.h | |||
diff --git a/include/linux/ds1286.h b/include/linux/rtc/ds1286.h index 45ea0aa0aeb9..45ea0aa0aeb9 100644 --- a/include/linux/ds1286.h +++ b/include/linux/rtc/ds1286.h | |||
diff --git a/tools/testing/selftests/timers/rtctest.c b/tools/testing/selftests/timers/rtctest.c index 624bce51b27d..4230d3052e5d 100644 --- a/tools/testing/selftests/timers/rtctest.c +++ b/tools/testing/selftests/timers/rtctest.c | |||
@@ -144,11 +144,12 @@ test_READ: | |||
144 | 144 | ||
145 | retval = ioctl(fd, RTC_ALM_SET, &rtc_tm); | 145 | retval = ioctl(fd, RTC_ALM_SET, &rtc_tm); |
146 | if (retval == -1) { | 146 | if (retval == -1) { |
147 | if (errno == ENOTTY) { | 147 | if (errno == EINVAL) { |
148 | fprintf(stderr, | 148 | fprintf(stderr, |
149 | "\n...Alarm IRQs not supported.\n"); | 149 | "\n...Alarm IRQs not supported.\n"); |
150 | goto test_PIE; | 150 | goto test_PIE; |
151 | } | 151 | } |
152 | |||
152 | perror("RTC_ALM_SET ioctl"); | 153 | perror("RTC_ALM_SET ioctl"); |
153 | exit(errno); | 154 | exit(errno); |
154 | } | 155 | } |
@@ -166,6 +167,12 @@ test_READ: | |||
166 | /* Enable alarm interrupts */ | 167 | /* Enable alarm interrupts */ |
167 | retval = ioctl(fd, RTC_AIE_ON, 0); | 168 | retval = ioctl(fd, RTC_AIE_ON, 0); |
168 | if (retval == -1) { | 169 | if (retval == -1) { |
170 | if (errno == EINVAL) { | ||
171 | fprintf(stderr, | ||
172 | "\n...Alarm IRQs not supported.\n"); | ||
173 | goto test_PIE; | ||
174 | } | ||
175 | |||
169 | perror("RTC_AIE_ON ioctl"); | 176 | perror("RTC_AIE_ON ioctl"); |
170 | exit(errno); | 177 | exit(errno); |
171 | } | 178 | } |
@@ -193,7 +200,7 @@ test_PIE: | |||
193 | retval = ioctl(fd, RTC_IRQP_READ, &tmp); | 200 | retval = ioctl(fd, RTC_IRQP_READ, &tmp); |
194 | if (retval == -1) { | 201 | if (retval == -1) { |
195 | /* not all RTCs support periodic IRQs */ | 202 | /* not all RTCs support periodic IRQs */ |
196 | if (errno == ENOTTY) { | 203 | if (errno == EINVAL) { |
197 | fprintf(stderr, "\nNo periodic IRQ support\n"); | 204 | fprintf(stderr, "\nNo periodic IRQ support\n"); |
198 | goto done; | 205 | goto done; |
199 | } | 206 | } |
@@ -211,7 +218,7 @@ test_PIE: | |||
211 | retval = ioctl(fd, RTC_IRQP_SET, tmp); | 218 | retval = ioctl(fd, RTC_IRQP_SET, tmp); |
212 | if (retval == -1) { | 219 | if (retval == -1) { |
213 | /* not all RTCs can change their periodic IRQ rate */ | 220 | /* not all RTCs can change their periodic IRQ rate */ |
214 | if (errno == ENOTTY) { | 221 | if (errno == EINVAL) { |
215 | fprintf(stderr, | 222 | fprintf(stderr, |
216 | "\n...Periodic IRQ rate is fixed\n"); | 223 | "\n...Periodic IRQ rate is fixed\n"); |
217 | goto done; | 224 | goto done; |