diff options
author | Jiri Kosina <jkosina@suse.cz> | 2010-06-16 12:08:13 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2010-06-16 12:08:13 -0400 |
commit | f1bbbb6912662b9f6070c5bfc4ca9eb1f06a9d5b (patch) | |
tree | c2c130a74be25b0b2dff992e1a195e2728bdaadd /drivers/rtc | |
parent | fd0961ff67727482bb20ca7e8ea97b83e9de2ddb (diff) | |
parent | 7e27d6e778cd87b6f2415515d7127eba53fe5d02 (diff) |
Merge branch 'master' into for-next
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/Kconfig | 9 | ||||
-rw-r--r-- | drivers/rtc/Makefile | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-ab3100.c | 41 | ||||
-rw-r--r-- | drivers/rtc/rtc-ab8500.c | 363 | ||||
-rw-r--r-- | drivers/rtc/rtc-cmos.c | 88 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1302.c | 85 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1374.c | 2 | ||||
-rw-r--r-- | drivers/rtc/rtc-isl1208.c | 45 | ||||
-rw-r--r-- | drivers/rtc/rtc-m41t80.c | 22 | ||||
-rw-r--r-- | drivers/rtc/rtc-mpc5121.c | 14 | ||||
-rw-r--r-- | drivers/rtc/rtc-mxc.c | 25 | ||||
-rw-r--r-- | drivers/rtc/rtc-rx8025.c | 2 | ||||
-rw-r--r-- | drivers/rtc/rtc-s35390a.c | 2 | ||||
-rw-r--r-- | drivers/rtc/rtc-s3c.c | 112 | ||||
-rw-r--r-- | drivers/rtc/rtc-wm831x.c | 16 |
15 files changed, 639 insertions, 188 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 50ac047cd136..10ba12c8c5e0 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -611,6 +611,13 @@ config RTC_DRV_AB3100 | |||
611 | Select this to enable the ST-Ericsson AB3100 Mixed Signal IC RTC | 611 | Select this to enable the ST-Ericsson AB3100 Mixed Signal IC RTC |
612 | support. This chip contains a battery- and capacitor-backed RTC. | 612 | support. This chip contains a battery- and capacitor-backed RTC. |
613 | 613 | ||
614 | config RTC_DRV_AB8500 | ||
615 | tristate "ST-Ericsson AB8500 RTC" | ||
616 | depends on AB8500_CORE | ||
617 | help | ||
618 | Select this to enable the ST-Ericsson AB8500 power management IC RTC | ||
619 | support. This chip contains a battery- and capacitor-backed RTC. | ||
620 | |||
614 | config RTC_DRV_NUC900 | 621 | config RTC_DRV_NUC900 |
615 | tristate "NUC910/NUC920 RTC driver" | 622 | tristate "NUC910/NUC920 RTC driver" |
616 | depends on RTC_CLASS && ARCH_W90X900 | 623 | depends on RTC_CLASS && ARCH_W90X900 |
@@ -640,7 +647,7 @@ config RTC_DRV_OMAP | |||
640 | 647 | ||
641 | config RTC_DRV_S3C | 648 | config RTC_DRV_S3C |
642 | tristate "Samsung S3C series SoC RTC" | 649 | tristate "Samsung S3C series SoC RTC" |
643 | depends on ARCH_S3C2410 | 650 | depends on ARCH_S3C2410 || ARCH_S3C64XX |
644 | help | 651 | help |
645 | RTC (Realtime Clock) driver for the clock inbuilt into the | 652 | RTC (Realtime Clock) driver for the clock inbuilt into the |
646 | Samsung S3C24XX series of SoCs. This can provide periodic | 653 | Samsung S3C24XX series of SoCs. This can provide periodic |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 245311a1348f..5adbba7cf89c 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -18,6 +18,7 @@ rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o | |||
18 | # Keep the list ordered. | 18 | # Keep the list ordered. |
19 | 19 | ||
20 | obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o | 20 | obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o |
21 | obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o | ||
21 | obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o | 22 | obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o |
22 | obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o | 23 | obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o |
23 | obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o | 24 | obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o |
diff --git a/drivers/rtc/rtc-ab3100.c b/drivers/rtc/rtc-ab3100.c index 4704aac2b5af..d26780ea254b 100644 --- a/drivers/rtc/rtc-ab3100.c +++ b/drivers/rtc/rtc-ab3100.c | |||
@@ -9,7 +9,7 @@ | |||
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/platform_device.h> | 10 | #include <linux/platform_device.h> |
11 | #include <linux/rtc.h> | 11 | #include <linux/rtc.h> |
12 | #include <linux/mfd/ab3100.h> | 12 | #include <linux/mfd/abx500.h> |
13 | 13 | ||
14 | /* Clock rate in Hz */ | 14 | /* Clock rate in Hz */ |
15 | #define AB3100_RTC_CLOCK_RATE 32768 | 15 | #define AB3100_RTC_CLOCK_RATE 32768 |
@@ -45,7 +45,6 @@ | |||
45 | */ | 45 | */ |
46 | static int ab3100_rtc_set_mmss(struct device *dev, unsigned long secs) | 46 | static int ab3100_rtc_set_mmss(struct device *dev, unsigned long secs) |
47 | { | 47 | { |
48 | struct ab3100 *ab3100_data = dev_get_drvdata(dev); | ||
49 | u8 regs[] = {AB3100_TI0, AB3100_TI1, AB3100_TI2, | 48 | u8 regs[] = {AB3100_TI0, AB3100_TI1, AB3100_TI2, |
50 | AB3100_TI3, AB3100_TI4, AB3100_TI5}; | 49 | AB3100_TI3, AB3100_TI4, AB3100_TI5}; |
51 | unsigned char buf[6]; | 50 | unsigned char buf[6]; |
@@ -61,27 +60,26 @@ static int ab3100_rtc_set_mmss(struct device *dev, unsigned long secs) | |||
61 | buf[5] = (fat_time >> 40) & 0xFF; | 60 | buf[5] = (fat_time >> 40) & 0xFF; |
62 | 61 | ||
63 | for (i = 0; i < 6; i++) { | 62 | for (i = 0; i < 6; i++) { |
64 | err = ab3100_set_register_interruptible(ab3100_data, | 63 | err = abx500_set_register_interruptible(dev, 0, |
65 | regs[i], buf[i]); | 64 | regs[i], buf[i]); |
66 | if (err) | 65 | if (err) |
67 | return err; | 66 | return err; |
68 | } | 67 | } |
69 | 68 | ||
70 | /* Set the flag to mark that the clock is now set */ | 69 | /* Set the flag to mark that the clock is now set */ |
71 | return ab3100_mask_and_set_register_interruptible(ab3100_data, | 70 | return abx500_mask_and_set_register_interruptible(dev, 0, |
72 | AB3100_RTC, | 71 | AB3100_RTC, |
73 | 0xFE, 0x01); | 72 | 0x01, 0x01); |
74 | 73 | ||
75 | } | 74 | } |
76 | 75 | ||
77 | static int ab3100_rtc_read_time(struct device *dev, struct rtc_time *tm) | 76 | static int ab3100_rtc_read_time(struct device *dev, struct rtc_time *tm) |
78 | { | 77 | { |
79 | struct ab3100 *ab3100_data = dev_get_drvdata(dev); | ||
80 | unsigned long time; | 78 | unsigned long time; |
81 | u8 rtcval; | 79 | u8 rtcval; |
82 | int err; | 80 | int err; |
83 | 81 | ||
84 | err = ab3100_get_register_interruptible(ab3100_data, | 82 | err = abx500_get_register_interruptible(dev, 0, |
85 | AB3100_RTC, &rtcval); | 83 | AB3100_RTC, &rtcval); |
86 | if (err) | 84 | if (err) |
87 | return err; | 85 | return err; |
@@ -94,7 +92,7 @@ static int ab3100_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
94 | u8 buf[6]; | 92 | u8 buf[6]; |
95 | 93 | ||
96 | /* Read out time registers */ | 94 | /* Read out time registers */ |
97 | err = ab3100_get_register_page_interruptible(ab3100_data, | 95 | err = abx500_get_register_page_interruptible(dev, 0, |
98 | AB3100_TI0, | 96 | AB3100_TI0, |
99 | buf, 6); | 97 | buf, 6); |
100 | if (err != 0) | 98 | if (err != 0) |
@@ -114,7 +112,6 @@ static int ab3100_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
114 | 112 | ||
115 | static int ab3100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | 113 | static int ab3100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) |
116 | { | 114 | { |
117 | struct ab3100 *ab3100_data = dev_get_drvdata(dev); | ||
118 | unsigned long time; | 115 | unsigned long time; |
119 | u64 fat_time; | 116 | u64 fat_time; |
120 | u8 buf[6]; | 117 | u8 buf[6]; |
@@ -122,7 +119,7 @@ static int ab3100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
122 | int err; | 119 | int err; |
123 | 120 | ||
124 | /* Figure out if alarm is enabled or not */ | 121 | /* Figure out if alarm is enabled or not */ |
125 | err = ab3100_get_register_interruptible(ab3100_data, | 122 | err = abx500_get_register_interruptible(dev, 0, |
126 | AB3100_RTC, &rtcval); | 123 | AB3100_RTC, &rtcval); |
127 | if (err) | 124 | if (err) |
128 | return err; | 125 | return err; |
@@ -133,7 +130,7 @@ static int ab3100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
133 | /* No idea how this could be represented */ | 130 | /* No idea how this could be represented */ |
134 | alarm->pending = 0; | 131 | alarm->pending = 0; |
135 | /* Read out alarm registers, only 4 bytes */ | 132 | /* Read out alarm registers, only 4 bytes */ |
136 | err = ab3100_get_register_page_interruptible(ab3100_data, | 133 | err = abx500_get_register_page_interruptible(dev, 0, |
137 | AB3100_AL0, buf, 4); | 134 | AB3100_AL0, buf, 4); |
138 | if (err) | 135 | if (err) |
139 | return err; | 136 | return err; |
@@ -148,7 +145,6 @@ static int ab3100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
148 | 145 | ||
149 | static int ab3100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) | 146 | static int ab3100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) |
150 | { | 147 | { |
151 | struct ab3100 *ab3100_data = dev_get_drvdata(dev); | ||
152 | u8 regs[] = {AB3100_AL0, AB3100_AL1, AB3100_AL2, AB3100_AL3}; | 148 | u8 regs[] = {AB3100_AL0, AB3100_AL1, AB3100_AL2, AB3100_AL3}; |
153 | unsigned char buf[4]; | 149 | unsigned char buf[4]; |
154 | unsigned long secs; | 150 | unsigned long secs; |
@@ -165,21 +161,19 @@ static int ab3100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
165 | 161 | ||
166 | /* Set the alarm */ | 162 | /* Set the alarm */ |
167 | for (i = 0; i < 4; i++) { | 163 | for (i = 0; i < 4; i++) { |
168 | err = ab3100_set_register_interruptible(ab3100_data, | 164 | err = abx500_set_register_interruptible(dev, 0, |
169 | regs[i], buf[i]); | 165 | regs[i], buf[i]); |
170 | if (err) | 166 | if (err) |
171 | return err; | 167 | return err; |
172 | } | 168 | } |
173 | /* Then enable the alarm */ | 169 | /* Then enable the alarm */ |
174 | return ab3100_mask_and_set_register_interruptible(ab3100_data, | 170 | return abx500_mask_and_set_register_interruptible(dev, 0, |
175 | AB3100_RTC, ~(1 << 2), | 171 | AB3100_RTC, (1 << 2), |
176 | alarm->enabled << 2); | 172 | alarm->enabled << 2); |
177 | } | 173 | } |
178 | 174 | ||
179 | static int ab3100_rtc_irq_enable(struct device *dev, unsigned int enabled) | 175 | static int ab3100_rtc_irq_enable(struct device *dev, unsigned int enabled) |
180 | { | 176 | { |
181 | struct ab3100 *ab3100_data = dev_get_drvdata(dev); | ||
182 | |||
183 | /* | 177 | /* |
184 | * It's not possible to enable/disable the alarm IRQ for this RTC. | 178 | * It's not possible to enable/disable the alarm IRQ for this RTC. |
185 | * It does not actually trigger any IRQ: instead its only function is | 179 | * It does not actually trigger any IRQ: instead its only function is |
@@ -188,12 +182,12 @@ static int ab3100_rtc_irq_enable(struct device *dev, unsigned int enabled) | |||
188 | * and need to be handled there instead. | 182 | * and need to be handled there instead. |
189 | */ | 183 | */ |
190 | if (enabled) | 184 | if (enabled) |
191 | return ab3100_mask_and_set_register_interruptible(ab3100_data, | 185 | return abx500_mask_and_set_register_interruptible(dev, 0, |
192 | AB3100_RTC, ~(1 << 2), | 186 | AB3100_RTC, (1 << 2), |
193 | 1 << 2); | 187 | 1 << 2); |
194 | else | 188 | else |
195 | return ab3100_mask_and_set_register_interruptible(ab3100_data, | 189 | return abx500_mask_and_set_register_interruptible(dev, 0, |
196 | AB3100_RTC, ~(1 << 2), | 190 | AB3100_RTC, (1 << 2), |
197 | 0); | 191 | 0); |
198 | } | 192 | } |
199 | 193 | ||
@@ -210,10 +204,9 @@ static int __init ab3100_rtc_probe(struct platform_device *pdev) | |||
210 | int err; | 204 | int err; |
211 | u8 regval; | 205 | u8 regval; |
212 | struct rtc_device *rtc; | 206 | struct rtc_device *rtc; |
213 | struct ab3100 *ab3100_data = platform_get_drvdata(pdev); | ||
214 | 207 | ||
215 | /* The first RTC register needs special treatment */ | 208 | /* The first RTC register needs special treatment */ |
216 | err = ab3100_get_register_interruptible(ab3100_data, | 209 | err = abx500_get_register_interruptible(&pdev->dev, 0, |
217 | AB3100_RTC, ®val); | 210 | AB3100_RTC, ®val); |
218 | if (err) { | 211 | if (err) { |
219 | dev_err(&pdev->dev, "unable to read RTC register\n"); | 212 | dev_err(&pdev->dev, "unable to read RTC register\n"); |
@@ -231,7 +224,7 @@ static int __init ab3100_rtc_probe(struct platform_device *pdev) | |||
231 | * This bit remains until RTC power is lost. | 224 | * This bit remains until RTC power is lost. |
232 | */ | 225 | */ |
233 | regval = 1 | RTC_SETTING; | 226 | regval = 1 | RTC_SETTING; |
234 | err = ab3100_set_register_interruptible(ab3100_data, | 227 | err = abx500_set_register_interruptible(&pdev->dev, 0, |
235 | AB3100_RTC, regval); | 228 | AB3100_RTC, regval); |
236 | /* Ignore any error on this write */ | 229 | /* Ignore any error on this write */ |
237 | } | 230 | } |
diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c new file mode 100644 index 000000000000..2fda03125e55 --- /dev/null +++ b/drivers/rtc/rtc-ab8500.c | |||
@@ -0,0 +1,363 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * License terms: GNU General Public License (GPL) version 2 | ||
5 | * Author: Virupax Sadashivpetimath <virupax.sadashivpetimath@stericsson.com> | ||
6 | * | ||
7 | * RTC clock driver for the RTC part of the AB8500 Power management chip. | ||
8 | * Based on RTC clock driver for the AB3100 Analog Baseband Chip by | ||
9 | * Linus Walleij <linus.walleij@stericsson.com> | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/rtc.h> | ||
17 | #include <linux/mfd/ab8500.h> | ||
18 | #include <linux/delay.h> | ||
19 | |||
20 | #define AB8500_RTC_SOFF_STAT_REG 0x0F00 | ||
21 | #define AB8500_RTC_CC_CONF_REG 0x0F01 | ||
22 | #define AB8500_RTC_READ_REQ_REG 0x0F02 | ||
23 | #define AB8500_RTC_WATCH_TSECMID_REG 0x0F03 | ||
24 | #define AB8500_RTC_WATCH_TSECHI_REG 0x0F04 | ||
25 | #define AB8500_RTC_WATCH_TMIN_LOW_REG 0x0F05 | ||
26 | #define AB8500_RTC_WATCH_TMIN_MID_REG 0x0F06 | ||
27 | #define AB8500_RTC_WATCH_TMIN_HI_REG 0x0F07 | ||
28 | #define AB8500_RTC_ALRM_MIN_LOW_REG 0x0F08 | ||
29 | #define AB8500_RTC_ALRM_MIN_MID_REG 0x0F09 | ||
30 | #define AB8500_RTC_ALRM_MIN_HI_REG 0x0F0A | ||
31 | #define AB8500_RTC_STAT_REG 0x0F0B | ||
32 | #define AB8500_RTC_BKUP_CHG_REG 0x0F0C | ||
33 | #define AB8500_RTC_FORCE_BKUP_REG 0x0F0D | ||
34 | #define AB8500_RTC_CALIB_REG 0x0F0E | ||
35 | #define AB8500_RTC_SWITCH_STAT_REG 0x0F0F | ||
36 | #define AB8500_REV_REG 0x1080 | ||
37 | |||
38 | /* RtcReadRequest bits */ | ||
39 | #define RTC_READ_REQUEST 0x01 | ||
40 | #define RTC_WRITE_REQUEST 0x02 | ||
41 | |||
42 | /* RtcCtrl bits */ | ||
43 | #define RTC_ALARM_ENA 0x04 | ||
44 | #define RTC_STATUS_DATA 0x01 | ||
45 | |||
46 | #define COUNTS_PER_SEC (0xF000 / 60) | ||
47 | #define AB8500_RTC_EPOCH 2000 | ||
48 | |||
49 | static const unsigned long ab8500_rtc_time_regs[] = { | ||
50 | AB8500_RTC_WATCH_TMIN_HI_REG, AB8500_RTC_WATCH_TMIN_MID_REG, | ||
51 | AB8500_RTC_WATCH_TMIN_LOW_REG, AB8500_RTC_WATCH_TSECHI_REG, | ||
52 | AB8500_RTC_WATCH_TSECMID_REG | ||
53 | }; | ||
54 | |||
55 | static const unsigned long ab8500_rtc_alarm_regs[] = { | ||
56 | AB8500_RTC_ALRM_MIN_HI_REG, AB8500_RTC_ALRM_MIN_MID_REG, | ||
57 | AB8500_RTC_ALRM_MIN_LOW_REG | ||
58 | }; | ||
59 | |||
60 | /* Calculate the seconds from 1970 to 01-01-2000 00:00:00 */ | ||
61 | static unsigned long get_elapsed_seconds(int year) | ||
62 | { | ||
63 | unsigned long secs; | ||
64 | struct rtc_time tm = { | ||
65 | .tm_year = year - 1900, | ||
66 | .tm_mday = 1, | ||
67 | }; | ||
68 | |||
69 | /* | ||
70 | * This function calculates secs from 1970 and not from | ||
71 | * 1900, even if we supply the offset from year 1900. | ||
72 | */ | ||
73 | rtc_tm_to_time(&tm, &secs); | ||
74 | return secs; | ||
75 | } | ||
76 | |||
77 | static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
78 | { | ||
79 | struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); | ||
80 | unsigned long timeout = jiffies + HZ; | ||
81 | int retval, i; | ||
82 | unsigned long mins, secs; | ||
83 | unsigned char buf[ARRAY_SIZE(ab8500_rtc_time_regs)]; | ||
84 | |||
85 | /* Request a data read */ | ||
86 | retval = ab8500_write(ab8500, AB8500_RTC_READ_REQ_REG, | ||
87 | RTC_READ_REQUEST); | ||
88 | if (retval < 0) | ||
89 | return retval; | ||
90 | |||
91 | /* Early AB8500 chips will not clear the rtc read request bit */ | ||
92 | if (ab8500->revision == 0) { | ||
93 | msleep(1); | ||
94 | } else { | ||
95 | /* Wait for some cycles after enabling the rtc read in ab8500 */ | ||
96 | while (time_before(jiffies, timeout)) { | ||
97 | retval = ab8500_read(ab8500, AB8500_RTC_READ_REQ_REG); | ||
98 | if (retval < 0) | ||
99 | return retval; | ||
100 | |||
101 | if (!(retval & RTC_READ_REQUEST)) | ||
102 | break; | ||
103 | |||
104 | msleep(1); | ||
105 | } | ||
106 | } | ||
107 | |||
108 | /* Read the Watchtime registers */ | ||
109 | for (i = 0; i < ARRAY_SIZE(ab8500_rtc_time_regs); i++) { | ||
110 | retval = ab8500_read(ab8500, ab8500_rtc_time_regs[i]); | ||
111 | if (retval < 0) | ||
112 | return retval; | ||
113 | buf[i] = retval; | ||
114 | } | ||
115 | |||
116 | mins = (buf[0] << 16) | (buf[1] << 8) | buf[2]; | ||
117 | |||
118 | secs = (buf[3] << 8) | buf[4]; | ||
119 | secs = secs / COUNTS_PER_SEC; | ||
120 | secs = secs + (mins * 60); | ||
121 | |||
122 | /* Add back the initially subtracted number of seconds */ | ||
123 | secs += get_elapsed_seconds(AB8500_RTC_EPOCH); | ||
124 | |||
125 | rtc_time_to_tm(secs, tm); | ||
126 | return rtc_valid_tm(tm); | ||
127 | } | ||
128 | |||
129 | static int ab8500_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
130 | { | ||
131 | struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); | ||
132 | int retval, i; | ||
133 | unsigned char buf[ARRAY_SIZE(ab8500_rtc_time_regs)]; | ||
134 | unsigned long no_secs, no_mins, secs = 0; | ||
135 | |||
136 | if (tm->tm_year < (AB8500_RTC_EPOCH - 1900)) { | ||
137 | dev_dbg(dev, "year should be equal to or greater than %d\n", | ||
138 | AB8500_RTC_EPOCH); | ||
139 | return -EINVAL; | ||
140 | } | ||
141 | |||
142 | /* Get the number of seconds since 1970 */ | ||
143 | rtc_tm_to_time(tm, &secs); | ||
144 | |||
145 | /* | ||
146 | * Convert it to the number of seconds since 01-01-2000 00:00:00, since | ||
147 | * we only have a small counter in the RTC. | ||
148 | */ | ||
149 | secs -= get_elapsed_seconds(AB8500_RTC_EPOCH); | ||
150 | |||
151 | no_mins = secs / 60; | ||
152 | |||
153 | no_secs = secs % 60; | ||
154 | /* Make the seconds count as per the RTC resolution */ | ||
155 | no_secs = no_secs * COUNTS_PER_SEC; | ||
156 | |||
157 | buf[4] = no_secs & 0xFF; | ||
158 | buf[3] = (no_secs >> 8) & 0xFF; | ||
159 | |||
160 | buf[2] = no_mins & 0xFF; | ||
161 | buf[1] = (no_mins >> 8) & 0xFF; | ||
162 | buf[0] = (no_mins >> 16) & 0xFF; | ||
163 | |||
164 | for (i = 0; i < ARRAY_SIZE(ab8500_rtc_time_regs); i++) { | ||
165 | retval = ab8500_write(ab8500, ab8500_rtc_time_regs[i], buf[i]); | ||
166 | if (retval < 0) | ||
167 | return retval; | ||
168 | } | ||
169 | |||
170 | /* Request a data write */ | ||
171 | return ab8500_write(ab8500, AB8500_RTC_READ_REQ_REG, RTC_WRITE_REQUEST); | ||
172 | } | ||
173 | |||
174 | static int ab8500_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | ||
175 | { | ||
176 | struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); | ||
177 | int retval, i; | ||
178 | int rtc_ctrl; | ||
179 | unsigned char buf[ARRAY_SIZE(ab8500_rtc_alarm_regs)]; | ||
180 | unsigned long secs, mins; | ||
181 | |||
182 | /* Check if the alarm is enabled or not */ | ||
183 | rtc_ctrl = ab8500_read(ab8500, AB8500_RTC_STAT_REG); | ||
184 | if (rtc_ctrl < 0) | ||
185 | return rtc_ctrl; | ||
186 | |||
187 | if (rtc_ctrl & RTC_ALARM_ENA) | ||
188 | alarm->enabled = 1; | ||
189 | else | ||
190 | alarm->enabled = 0; | ||
191 | |||
192 | alarm->pending = 0; | ||
193 | |||
194 | for (i = 0; i < ARRAY_SIZE(ab8500_rtc_alarm_regs); i++) { | ||
195 | retval = ab8500_read(ab8500, ab8500_rtc_alarm_regs[i]); | ||
196 | if (retval < 0) | ||
197 | return retval; | ||
198 | buf[i] = retval; | ||
199 | } | ||
200 | |||
201 | mins = (buf[0] << 16) | (buf[1] << 8) | (buf[2]); | ||
202 | secs = mins * 60; | ||
203 | |||
204 | /* Add back the initially subtracted number of seconds */ | ||
205 | secs += get_elapsed_seconds(AB8500_RTC_EPOCH); | ||
206 | |||
207 | rtc_time_to_tm(secs, &alarm->time); | ||
208 | |||
209 | return rtc_valid_tm(&alarm->time); | ||
210 | } | ||
211 | |||
212 | static int ab8500_rtc_irq_enable(struct device *dev, unsigned int enabled) | ||
213 | { | ||
214 | struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); | ||
215 | |||
216 | return ab8500_set_bits(ab8500, AB8500_RTC_STAT_REG, RTC_ALARM_ENA, | ||
217 | enabled ? RTC_ALARM_ENA : 0); | ||
218 | } | ||
219 | |||
220 | static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) | ||
221 | { | ||
222 | struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); | ||
223 | int retval, i; | ||
224 | unsigned char buf[ARRAY_SIZE(ab8500_rtc_alarm_regs)]; | ||
225 | unsigned long mins, secs = 0; | ||
226 | |||
227 | if (alarm->time.tm_year < (AB8500_RTC_EPOCH - 1900)) { | ||
228 | dev_dbg(dev, "year should be equal to or greater than %d\n", | ||
229 | AB8500_RTC_EPOCH); | ||
230 | return -EINVAL; | ||
231 | } | ||
232 | |||
233 | /* Get the number of seconds since 1970 */ | ||
234 | rtc_tm_to_time(&alarm->time, &secs); | ||
235 | |||
236 | /* | ||
237 | * Convert it to the number of seconds since 01-01-2000 00:00:00, since | ||
238 | * we only have a small counter in the RTC. | ||
239 | */ | ||
240 | secs -= get_elapsed_seconds(AB8500_RTC_EPOCH); | ||
241 | |||
242 | mins = secs / 60; | ||
243 | |||
244 | buf[2] = mins & 0xFF; | ||
245 | buf[1] = (mins >> 8) & 0xFF; | ||
246 | buf[0] = (mins >> 16) & 0xFF; | ||
247 | |||
248 | /* Set the alarm time */ | ||
249 | for (i = 0; i < ARRAY_SIZE(ab8500_rtc_alarm_regs); i++) { | ||
250 | retval = ab8500_write(ab8500, ab8500_rtc_alarm_regs[i], buf[i]); | ||
251 | if (retval < 0) | ||
252 | return retval; | ||
253 | } | ||
254 | |||
255 | return ab8500_rtc_irq_enable(dev, alarm->enabled); | ||
256 | } | ||
257 | |||
258 | static irqreturn_t rtc_alarm_handler(int irq, void *data) | ||
259 | { | ||
260 | struct rtc_device *rtc = data; | ||
261 | unsigned long events = RTC_IRQF | RTC_AF; | ||
262 | |||
263 | dev_dbg(&rtc->dev, "%s\n", __func__); | ||
264 | rtc_update_irq(rtc, 1, events); | ||
265 | |||
266 | return IRQ_HANDLED; | ||
267 | } | ||
268 | |||
269 | static const struct rtc_class_ops ab8500_rtc_ops = { | ||
270 | .read_time = ab8500_rtc_read_time, | ||
271 | .set_time = ab8500_rtc_set_time, | ||
272 | .read_alarm = ab8500_rtc_read_alarm, | ||
273 | .set_alarm = ab8500_rtc_set_alarm, | ||
274 | .alarm_irq_enable = ab8500_rtc_irq_enable, | ||
275 | }; | ||
276 | |||
277 | static int __devinit ab8500_rtc_probe(struct platform_device *pdev) | ||
278 | { | ||
279 | struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); | ||
280 | int err; | ||
281 | struct rtc_device *rtc; | ||
282 | int rtc_ctrl; | ||
283 | int irq; | ||
284 | |||
285 | irq = platform_get_irq_byname(pdev, "ALARM"); | ||
286 | if (irq < 0) | ||
287 | return irq; | ||
288 | |||
289 | /* For RTC supply test */ | ||
290 | err = ab8500_set_bits(ab8500, AB8500_RTC_STAT_REG, RTC_STATUS_DATA, | ||
291 | RTC_STATUS_DATA); | ||
292 | if (err < 0) | ||
293 | return err; | ||
294 | |||
295 | /* Wait for reset by the PorRtc */ | ||
296 | msleep(1); | ||
297 | |||
298 | rtc_ctrl = ab8500_read(ab8500, AB8500_RTC_STAT_REG); | ||
299 | if (rtc_ctrl < 0) | ||
300 | return rtc_ctrl; | ||
301 | |||
302 | /* Check if the RTC Supply fails */ | ||
303 | if (!(rtc_ctrl & RTC_STATUS_DATA)) { | ||
304 | dev_err(&pdev->dev, "RTC supply failure\n"); | ||
305 | return -ENODEV; | ||
306 | } | ||
307 | |||
308 | rtc = rtc_device_register("ab8500-rtc", &pdev->dev, &ab8500_rtc_ops, | ||
309 | THIS_MODULE); | ||
310 | if (IS_ERR(rtc)) { | ||
311 | dev_err(&pdev->dev, "Registration failed\n"); | ||
312 | err = PTR_ERR(rtc); | ||
313 | return err; | ||
314 | } | ||
315 | |||
316 | err = request_threaded_irq(irq, NULL, rtc_alarm_handler, 0, | ||
317 | "ab8500-rtc", rtc); | ||
318 | if (err < 0) { | ||
319 | rtc_device_unregister(rtc); | ||
320 | return err; | ||
321 | } | ||
322 | |||
323 | platform_set_drvdata(pdev, rtc); | ||
324 | |||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | static int __devexit ab8500_rtc_remove(struct platform_device *pdev) | ||
329 | { | ||
330 | struct rtc_device *rtc = platform_get_drvdata(pdev); | ||
331 | int irq = platform_get_irq_byname(pdev, "ALARM"); | ||
332 | |||
333 | free_irq(irq, rtc); | ||
334 | rtc_device_unregister(rtc); | ||
335 | platform_set_drvdata(pdev, NULL); | ||
336 | |||
337 | return 0; | ||
338 | } | ||
339 | |||
340 | static struct platform_driver ab8500_rtc_driver = { | ||
341 | .driver = { | ||
342 | .name = "ab8500-rtc", | ||
343 | .owner = THIS_MODULE, | ||
344 | }, | ||
345 | .probe = ab8500_rtc_probe, | ||
346 | .remove = __devexit_p(ab8500_rtc_remove), | ||
347 | }; | ||
348 | |||
349 | static int __init ab8500_rtc_init(void) | ||
350 | { | ||
351 | return platform_driver_register(&ab8500_rtc_driver); | ||
352 | } | ||
353 | |||
354 | static void __exit ab8500_rtc_exit(void) | ||
355 | { | ||
356 | platform_driver_unregister(&ab8500_rtc_driver); | ||
357 | } | ||
358 | |||
359 | module_init(ab8500_rtc_init); | ||
360 | module_exit(ab8500_rtc_exit); | ||
361 | MODULE_AUTHOR("Virupax Sadashivpetimath <virupax.sadashivpetimath@stericsson.com>"); | ||
362 | MODULE_DESCRIPTION("AB8500 RTC Driver"); | ||
363 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index ece4dbddc0ea..11b8ea29d2b7 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -238,31 +238,32 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
238 | rtc_control = CMOS_READ(RTC_CONTROL); | 238 | rtc_control = CMOS_READ(RTC_CONTROL); |
239 | spin_unlock_irq(&rtc_lock); | 239 | spin_unlock_irq(&rtc_lock); |
240 | 240 | ||
241 | /* REVISIT this assumes PC style usage: always BCD */ | 241 | if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { |
242 | 242 | if (((unsigned)t->time.tm_sec) < 0x60) | |
243 | if (((unsigned)t->time.tm_sec) < 0x60) | 243 | t->time.tm_sec = bcd2bin(t->time.tm_sec); |
244 | t->time.tm_sec = bcd2bin(t->time.tm_sec); | ||
245 | else | ||
246 | t->time.tm_sec = -1; | ||
247 | if (((unsigned)t->time.tm_min) < 0x60) | ||
248 | t->time.tm_min = bcd2bin(t->time.tm_min); | ||
249 | else | ||
250 | t->time.tm_min = -1; | ||
251 | if (((unsigned)t->time.tm_hour) < 0x24) | ||
252 | t->time.tm_hour = bcd2bin(t->time.tm_hour); | ||
253 | else | ||
254 | t->time.tm_hour = -1; | ||
255 | |||
256 | if (cmos->day_alrm) { | ||
257 | if (((unsigned)t->time.tm_mday) <= 0x31) | ||
258 | t->time.tm_mday = bcd2bin(t->time.tm_mday); | ||
259 | else | 244 | else |
260 | t->time.tm_mday = -1; | 245 | t->time.tm_sec = -1; |
261 | if (cmos->mon_alrm) { | 246 | if (((unsigned)t->time.tm_min) < 0x60) |
262 | if (((unsigned)t->time.tm_mon) <= 0x12) | 247 | t->time.tm_min = bcd2bin(t->time.tm_min); |
263 | t->time.tm_mon = bcd2bin(t->time.tm_mon) - 1; | 248 | else |
249 | t->time.tm_min = -1; | ||
250 | if (((unsigned)t->time.tm_hour) < 0x24) | ||
251 | t->time.tm_hour = bcd2bin(t->time.tm_hour); | ||
252 | else | ||
253 | t->time.tm_hour = -1; | ||
254 | |||
255 | if (cmos->day_alrm) { | ||
256 | if (((unsigned)t->time.tm_mday) <= 0x31) | ||
257 | t->time.tm_mday = bcd2bin(t->time.tm_mday); | ||
264 | else | 258 | else |
265 | t->time.tm_mon = -1; | 259 | t->time.tm_mday = -1; |
260 | |||
261 | if (cmos->mon_alrm) { | ||
262 | if (((unsigned)t->time.tm_mon) <= 0x12) | ||
263 | t->time.tm_mon = bcd2bin(t->time.tm_mon)-1; | ||
264 | else | ||
265 | t->time.tm_mon = -1; | ||
266 | } | ||
266 | } | 267 | } |
267 | } | 268 | } |
268 | t->time.tm_year = -1; | 269 | t->time.tm_year = -1; |
@@ -322,29 +323,26 @@ static void cmos_irq_disable(struct cmos_rtc *cmos, unsigned char mask) | |||
322 | static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) | 323 | static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) |
323 | { | 324 | { |
324 | struct cmos_rtc *cmos = dev_get_drvdata(dev); | 325 | struct cmos_rtc *cmos = dev_get_drvdata(dev); |
325 | unsigned char mon, mday, hrs, min, sec; | 326 | unsigned char mon, mday, hrs, min, sec, rtc_control; |
326 | 327 | ||
327 | if (!is_valid_irq(cmos->irq)) | 328 | if (!is_valid_irq(cmos->irq)) |
328 | return -EIO; | 329 | return -EIO; |
329 | 330 | ||
330 | /* REVISIT this assumes PC style usage: always BCD */ | ||
331 | |||
332 | /* Writing 0xff means "don't care" or "match all". */ | ||
333 | |||
334 | mon = t->time.tm_mon + 1; | 331 | mon = t->time.tm_mon + 1; |
335 | mon = (mon <= 12) ? bin2bcd(mon) : 0xff; | ||
336 | |||
337 | mday = t->time.tm_mday; | 332 | mday = t->time.tm_mday; |
338 | mday = (mday >= 1 && mday <= 31) ? bin2bcd(mday) : 0xff; | ||
339 | |||
340 | hrs = t->time.tm_hour; | 333 | hrs = t->time.tm_hour; |
341 | hrs = (hrs < 24) ? bin2bcd(hrs) : 0xff; | ||
342 | |||
343 | min = t->time.tm_min; | 334 | min = t->time.tm_min; |
344 | min = (min < 60) ? bin2bcd(min) : 0xff; | ||
345 | |||
346 | sec = t->time.tm_sec; | 335 | sec = t->time.tm_sec; |
347 | sec = (sec < 60) ? bin2bcd(sec) : 0xff; | 336 | |
337 | rtc_control = CMOS_READ(RTC_CONTROL); | ||
338 | if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { | ||
339 | /* Writing 0xff means "don't care" or "match all". */ | ||
340 | mon = (mon <= 12) ? bin2bcd(mon) : 0xff; | ||
341 | mday = (mday >= 1 && mday <= 31) ? bin2bcd(mday) : 0xff; | ||
342 | hrs = (hrs < 24) ? bin2bcd(hrs) : 0xff; | ||
343 | min = (min < 60) ? bin2bcd(min) : 0xff; | ||
344 | sec = (sec < 60) ? bin2bcd(sec) : 0xff; | ||
345 | } | ||
348 | 346 | ||
349 | spin_lock_irq(&rtc_lock); | 347 | spin_lock_irq(&rtc_lock); |
350 | 348 | ||
@@ -478,7 +476,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq) | |||
478 | "update_IRQ\t: %s\n" | 476 | "update_IRQ\t: %s\n" |
479 | "HPET_emulated\t: %s\n" | 477 | "HPET_emulated\t: %s\n" |
480 | // "square_wave\t: %s\n" | 478 | // "square_wave\t: %s\n" |
481 | // "BCD\t\t: %s\n" | 479 | "BCD\t\t: %s\n" |
482 | "DST_enable\t: %s\n" | 480 | "DST_enable\t: %s\n" |
483 | "periodic_freq\t: %d\n" | 481 | "periodic_freq\t: %d\n" |
484 | "batt_status\t: %s\n", | 482 | "batt_status\t: %s\n", |
@@ -486,7 +484,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq) | |||
486 | (rtc_control & RTC_UIE) ? "yes" : "no", | 484 | (rtc_control & RTC_UIE) ? "yes" : "no", |
487 | is_hpet_enabled() ? "yes" : "no", | 485 | is_hpet_enabled() ? "yes" : "no", |
488 | // (rtc_control & RTC_SQWE) ? "yes" : "no", | 486 | // (rtc_control & RTC_SQWE) ? "yes" : "no", |
489 | // (rtc_control & RTC_DM_BINARY) ? "no" : "yes", | 487 | (rtc_control & RTC_DM_BINARY) ? "no" : "yes", |
490 | (rtc_control & RTC_DST_EN) ? "yes" : "no", | 488 | (rtc_control & RTC_DST_EN) ? "yes" : "no", |
491 | cmos->rtc->irq_freq, | 489 | cmos->rtc->irq_freq, |
492 | (valid & RTC_VRT) ? "okay" : "dead"); | 490 | (valid & RTC_VRT) ? "okay" : "dead"); |
@@ -721,6 +719,9 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
721 | } | 719 | } |
722 | } | 720 | } |
723 | 721 | ||
722 | cmos_rtc.dev = dev; | ||
723 | dev_set_drvdata(dev, &cmos_rtc); | ||
724 | |||
724 | cmos_rtc.rtc = rtc_device_register(driver_name, dev, | 725 | cmos_rtc.rtc = rtc_device_register(driver_name, dev, |
725 | &cmos_rtc_ops, THIS_MODULE); | 726 | &cmos_rtc_ops, THIS_MODULE); |
726 | if (IS_ERR(cmos_rtc.rtc)) { | 727 | if (IS_ERR(cmos_rtc.rtc)) { |
@@ -728,8 +729,6 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
728 | goto cleanup0; | 729 | goto cleanup0; |
729 | } | 730 | } |
730 | 731 | ||
731 | cmos_rtc.dev = dev; | ||
732 | dev_set_drvdata(dev, &cmos_rtc); | ||
733 | rename_region(ports, dev_name(&cmos_rtc.rtc->dev)); | 732 | rename_region(ports, dev_name(&cmos_rtc.rtc->dev)); |
734 | 733 | ||
735 | spin_lock_irq(&rtc_lock); | 734 | spin_lock_irq(&rtc_lock); |
@@ -751,12 +750,11 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
751 | 750 | ||
752 | spin_unlock_irq(&rtc_lock); | 751 | spin_unlock_irq(&rtc_lock); |
753 | 752 | ||
754 | /* FIXME teach the alarm code how to handle binary mode; | 753 | /* FIXME: |
755 | * <asm-generic/rtc.h> doesn't know 12-hour mode either. | 754 | * <asm-generic/rtc.h> doesn't know 12-hour mode either. |
756 | */ | 755 | */ |
757 | if (is_valid_irq(rtc_irq) && | 756 | if (is_valid_irq(rtc_irq) && !(rtc_control & RTC_24H)) { |
758 | (!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY)))) { | 757 | dev_warn(dev, "only 24-hr supported\n"); |
759 | dev_dbg(dev, "only 24-hr BCD mode supported\n"); | ||
760 | retval = -ENXIO; | 758 | retval = -ENXIO; |
761 | goto cleanup1; | 759 | goto cleanup1; |
762 | } | 760 | } |
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c index 532acf9b05d8..359d1e04626c 100644 --- a/drivers/rtc/rtc-ds1302.c +++ b/drivers/rtc/rtc-ds1302.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/rtc.h> | 16 | #include <linux/rtc.h> |
17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
18 | #include <linux/bcd.h> | 18 | #include <linux/bcd.h> |
19 | #include <asm/rtc.h> | ||
20 | 19 | ||
21 | #define DRV_NAME "rtc-ds1302" | 20 | #define DRV_NAME "rtc-ds1302" |
22 | #define DRV_VERSION "0.1.1" | 21 | #define DRV_VERSION "0.1.1" |
@@ -34,14 +33,55 @@ | |||
34 | #define RTC_ADDR_MIN 0x01 /* Address of minute register */ | 33 | #define RTC_ADDR_MIN 0x01 /* Address of minute register */ |
35 | #define RTC_ADDR_SEC 0x00 /* Address of second register */ | 34 | #define RTC_ADDR_SEC 0x00 /* Address of second register */ |
36 | 35 | ||
36 | #ifdef CONFIG_SH_SECUREEDGE5410 | ||
37 | #include <asm/rtc.h> | ||
38 | #include <mach/snapgear.h> | ||
39 | |||
37 | #define RTC_RESET 0x1000 | 40 | #define RTC_RESET 0x1000 |
38 | #define RTC_IODATA 0x0800 | 41 | #define RTC_IODATA 0x0800 |
39 | #define RTC_SCLK 0x0400 | 42 | #define RTC_SCLK 0x0400 |
40 | 43 | ||
41 | #ifdef CONFIG_SH_SECUREEDGE5410 | ||
42 | #include <mach/snapgear.h> | ||
43 | #define set_dp(x) SECUREEDGE_WRITE_IOPORT(x, 0x1c00) | 44 | #define set_dp(x) SECUREEDGE_WRITE_IOPORT(x, 0x1c00) |
44 | #define get_dp() SECUREEDGE_READ_IOPORT() | 45 | #define get_dp() SECUREEDGE_READ_IOPORT() |
46 | #define ds1302_set_tx() | ||
47 | #define ds1302_set_rx() | ||
48 | |||
49 | static inline int ds1302_hw_init(void) | ||
50 | { | ||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | static inline void ds1302_reset(void) | ||
55 | { | ||
56 | set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); | ||
57 | } | ||
58 | |||
59 | static inline void ds1302_clock(void) | ||
60 | { | ||
61 | set_dp(get_dp() | RTC_SCLK); /* clock high */ | ||
62 | set_dp(get_dp() & ~RTC_SCLK); /* clock low */ | ||
63 | } | ||
64 | |||
65 | static inline void ds1302_start(void) | ||
66 | { | ||
67 | set_dp(get_dp() | RTC_RESET); | ||
68 | } | ||
69 | |||
70 | static inline void ds1302_stop(void) | ||
71 | { | ||
72 | set_dp(get_dp() & ~RTC_RESET); | ||
73 | } | ||
74 | |||
75 | static inline void ds1302_txbit(int bit) | ||
76 | { | ||
77 | set_dp((get_dp() & ~RTC_IODATA) | (bit ? RTC_IODATA : 0)); | ||
78 | } | ||
79 | |||
80 | static inline int ds1302_rxbit(void) | ||
81 | { | ||
82 | return !!(get_dp() & RTC_IODATA); | ||
83 | } | ||
84 | |||
45 | #else | 85 | #else |
46 | #error "Add support for your platform" | 86 | #error "Add support for your platform" |
47 | #endif | 87 | #endif |
@@ -50,11 +90,11 @@ static void ds1302_sendbits(unsigned int val) | |||
50 | { | 90 | { |
51 | int i; | 91 | int i; |
52 | 92 | ||
93 | ds1302_set_tx(); | ||
94 | |||
53 | for (i = 8; (i); i--, val >>= 1) { | 95 | for (i = 8; (i); i--, val >>= 1) { |
54 | set_dp((get_dp() & ~RTC_IODATA) | ((val & 0x1) ? | 96 | ds1302_txbit(val & 0x1); |
55 | RTC_IODATA : 0)); | 97 | ds1302_clock(); |
56 | set_dp(get_dp() | RTC_SCLK); /* clock high */ | ||
57 | set_dp(get_dp() & ~RTC_SCLK); /* clock low */ | ||
58 | } | 98 | } |
59 | } | 99 | } |
60 | 100 | ||
@@ -63,10 +103,11 @@ static unsigned int ds1302_recvbits(void) | |||
63 | unsigned int val; | 103 | unsigned int val; |
64 | int i; | 104 | int i; |
65 | 105 | ||
106 | ds1302_set_rx(); | ||
107 | |||
66 | for (i = 0, val = 0; (i < 8); i++) { | 108 | for (i = 0, val = 0; (i < 8); i++) { |
67 | val |= (((get_dp() & RTC_IODATA) ? 1 : 0) << i); | 109 | val |= (ds1302_rxbit() << i); |
68 | set_dp(get_dp() | RTC_SCLK); /* clock high */ | 110 | ds1302_clock(); |
69 | set_dp(get_dp() & ~RTC_SCLK); /* clock low */ | ||
70 | } | 111 | } |
71 | 112 | ||
72 | return val; | 113 | return val; |
@@ -76,23 +117,24 @@ static unsigned int ds1302_readbyte(unsigned int addr) | |||
76 | { | 117 | { |
77 | unsigned int val; | 118 | unsigned int val; |
78 | 119 | ||
79 | set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); | 120 | ds1302_reset(); |
80 | 121 | ||
81 | set_dp(get_dp() | RTC_RESET); | 122 | ds1302_start(); |
82 | ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_READ); | 123 | ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_READ); |
83 | val = ds1302_recvbits(); | 124 | val = ds1302_recvbits(); |
84 | set_dp(get_dp() & ~RTC_RESET); | 125 | ds1302_stop(); |
85 | 126 | ||
86 | return val; | 127 | return val; |
87 | } | 128 | } |
88 | 129 | ||
89 | static void ds1302_writebyte(unsigned int addr, unsigned int val) | 130 | static void ds1302_writebyte(unsigned int addr, unsigned int val) |
90 | { | 131 | { |
91 | set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); | 132 | ds1302_reset(); |
92 | set_dp(get_dp() | RTC_RESET); | 133 | |
134 | ds1302_start(); | ||
93 | ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_WRITE); | 135 | ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_WRITE); |
94 | ds1302_sendbits(val); | 136 | ds1302_sendbits(val); |
95 | set_dp(get_dp() & ~RTC_RESET); | 137 | ds1302_stop(); |
96 | } | 138 | } |
97 | 139 | ||
98 | static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm) | 140 | static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm) |
@@ -167,13 +209,20 @@ static int __init ds1302_rtc_probe(struct platform_device *pdev) | |||
167 | { | 209 | { |
168 | struct rtc_device *rtc; | 210 | struct rtc_device *rtc; |
169 | 211 | ||
212 | if (ds1302_hw_init()) { | ||
213 | dev_err(&pdev->dev, "Failed to init communication channel"); | ||
214 | return -EINVAL; | ||
215 | } | ||
216 | |||
170 | /* Reset */ | 217 | /* Reset */ |
171 | set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); | 218 | ds1302_reset(); |
172 | 219 | ||
173 | /* Write a magic value to the DS1302 RAM, and see if it sticks. */ | 220 | /* Write a magic value to the DS1302 RAM, and see if it sticks. */ |
174 | ds1302_writebyte(RTC_ADDR_RAM0, 0x42); | 221 | ds1302_writebyte(RTC_ADDR_RAM0, 0x42); |
175 | if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42) | 222 | if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42) { |
223 | dev_err(&pdev->dev, "Failed to probe"); | ||
176 | return -ENODEV; | 224 | return -ENODEV; |
225 | } | ||
177 | 226 | ||
178 | rtc = rtc_device_register("ds1302", &pdev->dev, | 227 | rtc = rtc_device_register("ds1302", &pdev->dev, |
179 | &ds1302_rtc_ops, THIS_MODULE); | 228 | &ds1302_rtc_ops, THIS_MODULE); |
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index 61945734ad00..1f0007fd4431 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c | |||
@@ -403,7 +403,6 @@ out_irq: | |||
403 | free_irq(client->irq, client); | 403 | free_irq(client->irq, client); |
404 | 404 | ||
405 | out_free: | 405 | out_free: |
406 | i2c_set_clientdata(client, NULL); | ||
407 | kfree(ds1374); | 406 | kfree(ds1374); |
408 | return ret; | 407 | return ret; |
409 | } | 408 | } |
@@ -422,7 +421,6 @@ static int __devexit ds1374_remove(struct i2c_client *client) | |||
422 | } | 421 | } |
423 | 422 | ||
424 | rtc_device_unregister(ds1374->rtc); | 423 | rtc_device_unregister(ds1374->rtc); |
425 | i2c_set_clientdata(client, NULL); | ||
426 | kfree(ds1374); | 424 | kfree(ds1374); |
427 | return 0; | 425 | return 0; |
428 | } | 426 | } |
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index 054e05294af8..468200c38ecb 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c | |||
@@ -462,39 +462,16 @@ isl1208_sysfs_store_usr(struct device *dev, | |||
462 | static DEVICE_ATTR(usr, S_IRUGO | S_IWUSR, isl1208_sysfs_show_usr, | 462 | static DEVICE_ATTR(usr, S_IRUGO | S_IWUSR, isl1208_sysfs_show_usr, |
463 | isl1208_sysfs_store_usr); | 463 | isl1208_sysfs_store_usr); |
464 | 464 | ||
465 | static int | 465 | static struct attribute *isl1208_rtc_attrs[] = { |
466 | isl1208_sysfs_register(struct device *dev) | 466 | &dev_attr_atrim.attr, |
467 | { | 467 | &dev_attr_dtrim.attr, |
468 | int err; | 468 | &dev_attr_usr.attr, |
469 | 469 | NULL | |
470 | err = device_create_file(dev, &dev_attr_atrim); | 470 | }; |
471 | if (err) | ||
472 | return err; | ||
473 | |||
474 | err = device_create_file(dev, &dev_attr_dtrim); | ||
475 | if (err) { | ||
476 | device_remove_file(dev, &dev_attr_atrim); | ||
477 | return err; | ||
478 | } | ||
479 | |||
480 | err = device_create_file(dev, &dev_attr_usr); | ||
481 | if (err) { | ||
482 | device_remove_file(dev, &dev_attr_atrim); | ||
483 | device_remove_file(dev, &dev_attr_dtrim); | ||
484 | } | ||
485 | |||
486 | return 0; | ||
487 | } | ||
488 | |||
489 | static int | ||
490 | isl1208_sysfs_unregister(struct device *dev) | ||
491 | { | ||
492 | device_remove_file(dev, &dev_attr_dtrim); | ||
493 | device_remove_file(dev, &dev_attr_atrim); | ||
494 | device_remove_file(dev, &dev_attr_usr); | ||
495 | 471 | ||
496 | return 0; | 472 | static const struct attribute_group isl1208_rtc_sysfs_files = { |
497 | } | 473 | .attrs = isl1208_rtc_attrs, |
474 | }; | ||
498 | 475 | ||
499 | static int | 476 | static int |
500 | isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) | 477 | isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) |
@@ -529,7 +506,7 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
529 | dev_warn(&client->dev, "rtc power failure detected, " | 506 | dev_warn(&client->dev, "rtc power failure detected, " |
530 | "please set clock.\n"); | 507 | "please set clock.\n"); |
531 | 508 | ||
532 | rc = isl1208_sysfs_register(&client->dev); | 509 | rc = sysfs_create_group(&client->dev.kobj, &isl1208_rtc_sysfs_files); |
533 | if (rc) | 510 | if (rc) |
534 | goto exit_unregister; | 511 | goto exit_unregister; |
535 | 512 | ||
@@ -546,7 +523,7 @@ isl1208_remove(struct i2c_client *client) | |||
546 | { | 523 | { |
547 | struct rtc_device *rtc = i2c_get_clientdata(client); | 524 | struct rtc_device *rtc = i2c_get_clientdata(client); |
548 | 525 | ||
549 | isl1208_sysfs_unregister(&client->dev); | 526 | sysfs_remove_group(&client->dev.kobj, &isl1208_rtc_sysfs_files); |
550 | rtc_device_unregister(rtc); | 527 | rtc_device_unregister(rtc); |
551 | 528 | ||
552 | return 0; | 529 | return 0; |
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 60fe266f0f49..6dc4e6241418 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c | |||
@@ -595,10 +595,6 @@ static void wdt_disable(void) | |||
595 | static ssize_t wdt_write(struct file *file, const char __user *buf, | 595 | static ssize_t wdt_write(struct file *file, const char __user *buf, |
596 | size_t count, loff_t *ppos) | 596 | size_t count, loff_t *ppos) |
597 | { | 597 | { |
598 | /* Can't seek (pwrite) on this device | ||
599 | if (ppos != &file->f_pos) | ||
600 | return -ESPIPE; | ||
601 | */ | ||
602 | if (count) { | 598 | if (count) { |
603 | wdt_ping(); | 599 | wdt_ping(); |
604 | return 1; | 600 | return 1; |
@@ -623,7 +619,7 @@ static ssize_t wdt_read(struct file *file, char __user *buf, | |||
623 | * according to their available features. We only actually usefully support | 619 | * according to their available features. We only actually usefully support |
624 | * querying capabilities and current status. | 620 | * querying capabilities and current status. |
625 | */ | 621 | */ |
626 | static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 622 | static int wdt_ioctl(struct file *file, unsigned int cmd, |
627 | unsigned long arg) | 623 | unsigned long arg) |
628 | { | 624 | { |
629 | int new_margin, rv; | 625 | int new_margin, rv; |
@@ -676,6 +672,18 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
676 | return -ENOTTY; | 672 | return -ENOTTY; |
677 | } | 673 | } |
678 | 674 | ||
675 | static long wdt_unlocked_ioctl(struct file *file, unsigned int cmd, | ||
676 | unsigned long arg) | ||
677 | { | ||
678 | int ret; | ||
679 | |||
680 | lock_kernel(); | ||
681 | ret = wdt_ioctl(file, cmd, arg); | ||
682 | unlock_kernel(); | ||
683 | |||
684 | return ret; | ||
685 | } | ||
686 | |||
679 | /** | 687 | /** |
680 | * wdt_open: | 688 | * wdt_open: |
681 | * @inode: inode of device | 689 | * @inode: inode of device |
@@ -695,7 +703,7 @@ static int wdt_open(struct inode *inode, struct file *file) | |||
695 | */ | 703 | */ |
696 | wdt_is_open = 1; | 704 | wdt_is_open = 1; |
697 | unlock_kernel(); | 705 | unlock_kernel(); |
698 | return 0; | 706 | return nonseekable_open(inode, file); |
699 | } | 707 | } |
700 | return -ENODEV; | 708 | return -ENODEV; |
701 | } | 709 | } |
@@ -736,7 +744,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, | |||
736 | static const struct file_operations wdt_fops = { | 744 | static const struct file_operations wdt_fops = { |
737 | .owner = THIS_MODULE, | 745 | .owner = THIS_MODULE, |
738 | .read = wdt_read, | 746 | .read = wdt_read, |
739 | .ioctl = wdt_ioctl, | 747 | .unlocked_ioctl = wdt_unlocked_ioctl, |
740 | .write = wdt_write, | 748 | .write = wdt_write, |
741 | .open = wdt_open, | 749 | .open = wdt_open, |
742 | .release = wdt_release, | 750 | .release = wdt_release, |
diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index f0dbf9cb8f9c..db5d8c416d26 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c | |||
@@ -279,7 +279,7 @@ static int __devinit mpc5121_rtc_probe(struct of_device *op, | |||
279 | if (!rtc) | 279 | if (!rtc) |
280 | return -ENOMEM; | 280 | return -ENOMEM; |
281 | 281 | ||
282 | rtc->regs = of_iomap(op->node, 0); | 282 | rtc->regs = of_iomap(op->dev.of_node, 0); |
283 | if (!rtc->regs) { | 283 | if (!rtc->regs) { |
284 | dev_err(&op->dev, "%s: couldn't map io space\n", __func__); | 284 | dev_err(&op->dev, "%s: couldn't map io space\n", __func__); |
285 | err = -ENOSYS; | 285 | err = -ENOSYS; |
@@ -290,7 +290,7 @@ static int __devinit mpc5121_rtc_probe(struct of_device *op, | |||
290 | 290 | ||
291 | dev_set_drvdata(&op->dev, rtc); | 291 | dev_set_drvdata(&op->dev, rtc); |
292 | 292 | ||
293 | rtc->irq = irq_of_parse_and_map(op->node, 1); | 293 | rtc->irq = irq_of_parse_and_map(op->dev.of_node, 1); |
294 | err = request_irq(rtc->irq, mpc5121_rtc_handler, IRQF_DISABLED, | 294 | err = request_irq(rtc->irq, mpc5121_rtc_handler, IRQF_DISABLED, |
295 | "mpc5121-rtc", &op->dev); | 295 | "mpc5121-rtc", &op->dev); |
296 | if (err) { | 296 | if (err) { |
@@ -299,7 +299,7 @@ static int __devinit mpc5121_rtc_probe(struct of_device *op, | |||
299 | goto out_dispose; | 299 | goto out_dispose; |
300 | } | 300 | } |
301 | 301 | ||
302 | rtc->irq_periodic = irq_of_parse_and_map(op->node, 0); | 302 | rtc->irq_periodic = irq_of_parse_and_map(op->dev.of_node, 0); |
303 | err = request_irq(rtc->irq_periodic, mpc5121_rtc_handler_upd, | 303 | err = request_irq(rtc->irq_periodic, mpc5121_rtc_handler_upd, |
304 | IRQF_DISABLED, "mpc5121-rtc_upd", &op->dev); | 304 | IRQF_DISABLED, "mpc5121-rtc_upd", &op->dev); |
305 | if (err) { | 305 | if (err) { |
@@ -365,9 +365,11 @@ static struct of_device_id mpc5121_rtc_match[] __devinitdata = { | |||
365 | }; | 365 | }; |
366 | 366 | ||
367 | static struct of_platform_driver mpc5121_rtc_driver = { | 367 | static struct of_platform_driver mpc5121_rtc_driver = { |
368 | .owner = THIS_MODULE, | 368 | .driver = { |
369 | .name = "mpc5121-rtc", | 369 | .name = "mpc5121-rtc", |
370 | .match_table = mpc5121_rtc_match, | 370 | .owner = THIS_MODULE, |
371 | .of_match_table = mpc5121_rtc_match, | ||
372 | }, | ||
371 | .probe = mpc5121_rtc_probe, | 373 | .probe = mpc5121_rtc_probe, |
372 | .remove = __devexit_p(mpc5121_rtc_remove), | 374 | .remove = __devexit_p(mpc5121_rtc_remove), |
373 | }; | 375 | }; |
diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index d71fe61db1d6..25ec921db07c 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c | |||
@@ -379,7 +379,6 @@ static struct rtc_class_ops mxc_rtc_ops = { | |||
379 | 379 | ||
380 | static int __init mxc_rtc_probe(struct platform_device *pdev) | 380 | static int __init mxc_rtc_probe(struct platform_device *pdev) |
381 | { | 381 | { |
382 | struct clk *clk; | ||
383 | struct resource *res; | 382 | struct resource *res; |
384 | struct rtc_device *rtc; | 383 | struct rtc_device *rtc; |
385 | struct rtc_plat_data *pdata = NULL; | 384 | struct rtc_plat_data *pdata = NULL; |
@@ -402,14 +401,15 @@ static int __init mxc_rtc_probe(struct platform_device *pdev) | |||
402 | pdata->ioaddr = devm_ioremap(&pdev->dev, res->start, | 401 | pdata->ioaddr = devm_ioremap(&pdev->dev, res->start, |
403 | resource_size(res)); | 402 | resource_size(res)); |
404 | 403 | ||
405 | clk = clk_get(&pdev->dev, "ckil"); | 404 | pdata->clk = clk_get(&pdev->dev, "rtc"); |
406 | if (IS_ERR(clk)) { | 405 | if (IS_ERR(pdata->clk)) { |
407 | ret = PTR_ERR(clk); | 406 | dev_err(&pdev->dev, "unable to get clock!\n"); |
407 | ret = PTR_ERR(pdata->clk); | ||
408 | goto exit_free_pdata; | 408 | goto exit_free_pdata; |
409 | } | 409 | } |
410 | 410 | ||
411 | rate = clk_get_rate(clk); | 411 | clk_enable(pdata->clk); |
412 | clk_put(clk); | 412 | rate = clk_get_rate(pdata->clk); |
413 | 413 | ||
414 | if (rate == 32768) | 414 | if (rate == 32768) |
415 | reg = RTC_INPUT_CLK_32768HZ; | 415 | reg = RTC_INPUT_CLK_32768HZ; |
@@ -420,7 +420,7 @@ static int __init mxc_rtc_probe(struct platform_device *pdev) | |||
420 | else { | 420 | else { |
421 | dev_err(&pdev->dev, "rtc clock is not valid (%lu)\n", rate); | 421 | dev_err(&pdev->dev, "rtc clock is not valid (%lu)\n", rate); |
422 | ret = -EINVAL; | 422 | ret = -EINVAL; |
423 | goto exit_free_pdata; | 423 | goto exit_put_clk; |
424 | } | 424 | } |
425 | 425 | ||
426 | reg |= RTC_ENABLE_BIT; | 426 | reg |= RTC_ENABLE_BIT; |
@@ -428,18 +428,9 @@ static int __init mxc_rtc_probe(struct platform_device *pdev) | |||
428 | if (((readw(pdata->ioaddr + RTC_RTCCTL)) & RTC_ENABLE_BIT) == 0) { | 428 | if (((readw(pdata->ioaddr + RTC_RTCCTL)) & RTC_ENABLE_BIT) == 0) { |
429 | dev_err(&pdev->dev, "hardware module can't be enabled!\n"); | 429 | dev_err(&pdev->dev, "hardware module can't be enabled!\n"); |
430 | ret = -EIO; | 430 | ret = -EIO; |
431 | goto exit_free_pdata; | 431 | goto exit_put_clk; |
432 | } | ||
433 | |||
434 | pdata->clk = clk_get(&pdev->dev, "rtc"); | ||
435 | if (IS_ERR(pdata->clk)) { | ||
436 | dev_err(&pdev->dev, "unable to get clock!\n"); | ||
437 | ret = PTR_ERR(pdata->clk); | ||
438 | goto exit_free_pdata; | ||
439 | } | 432 | } |
440 | 433 | ||
441 | clk_enable(pdata->clk); | ||
442 | |||
443 | rtc = rtc_device_register(pdev->name, &pdev->dev, &mxc_rtc_ops, | 434 | rtc = rtc_device_register(pdev->name, &pdev->dev, &mxc_rtc_ops, |
444 | THIS_MODULE); | 435 | THIS_MODULE); |
445 | if (IS_ERR(rtc)) { | 436 | if (IS_ERR(rtc)) { |
diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c index b65c82f792d9..789f62f9b47d 100644 --- a/drivers/rtc/rtc-rx8025.c +++ b/drivers/rtc/rtc-rx8025.c | |||
@@ -632,7 +632,6 @@ errout_reg: | |||
632 | rtc_device_unregister(rx8025->rtc); | 632 | rtc_device_unregister(rx8025->rtc); |
633 | 633 | ||
634 | errout_free: | 634 | errout_free: |
635 | i2c_set_clientdata(client, NULL); | ||
636 | kfree(rx8025); | 635 | kfree(rx8025); |
637 | 636 | ||
638 | errout: | 637 | errout: |
@@ -656,7 +655,6 @@ static int __devexit rx8025_remove(struct i2c_client *client) | |||
656 | 655 | ||
657 | rx8025_sysfs_unregister(&client->dev); | 656 | rx8025_sysfs_unregister(&client->dev); |
658 | rtc_device_unregister(rx8025->rtc); | 657 | rtc_device_unregister(rx8025->rtc); |
659 | i2c_set_clientdata(client, NULL); | ||
660 | kfree(rx8025); | 658 | kfree(rx8025); |
661 | return 0; | 659 | return 0; |
662 | } | 660 | } |
diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index def4d396d0b0..f789e002c9b0 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c | |||
@@ -275,7 +275,6 @@ exit_dummy: | |||
275 | if (s35390a->client[i]) | 275 | if (s35390a->client[i]) |
276 | i2c_unregister_device(s35390a->client[i]); | 276 | i2c_unregister_device(s35390a->client[i]); |
277 | kfree(s35390a); | 277 | kfree(s35390a); |
278 | i2c_set_clientdata(client, NULL); | ||
279 | 278 | ||
280 | exit: | 279 | exit: |
281 | return err; | 280 | return err; |
@@ -292,7 +291,6 @@ static int s35390a_remove(struct i2c_client *client) | |||
292 | 291 | ||
293 | rtc_device_unregister(s35390a->rtc); | 292 | rtc_device_unregister(s35390a->rtc); |
294 | kfree(s35390a); | 293 | kfree(s35390a); |
295 | i2c_set_clientdata(client, NULL); | ||
296 | 294 | ||
297 | return 0; | 295 | return 0; |
298 | } | 296 | } |
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 4969b6059c89..70b68d35f969 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -29,6 +29,11 @@ | |||
29 | #include <asm/irq.h> | 29 | #include <asm/irq.h> |
30 | #include <plat/regs-rtc.h> | 30 | #include <plat/regs-rtc.h> |
31 | 31 | ||
32 | enum s3c_cpu_type { | ||
33 | TYPE_S3C2410, | ||
34 | TYPE_S3C64XX, | ||
35 | }; | ||
36 | |||
32 | /* I have yet to find an S3C implementation with more than one | 37 | /* I have yet to find an S3C implementation with more than one |
33 | * of these rtc blocks in */ | 38 | * of these rtc blocks in */ |
34 | 39 | ||
@@ -37,6 +42,7 @@ static struct resource *s3c_rtc_mem; | |||
37 | static void __iomem *s3c_rtc_base; | 42 | static void __iomem *s3c_rtc_base; |
38 | static int s3c_rtc_alarmno = NO_IRQ; | 43 | static int s3c_rtc_alarmno = NO_IRQ; |
39 | static int s3c_rtc_tickno = NO_IRQ; | 44 | static int s3c_rtc_tickno = NO_IRQ; |
45 | static enum s3c_cpu_type s3c_rtc_cpu_type; | ||
40 | 46 | ||
41 | static DEFINE_SPINLOCK(s3c_rtc_pie_lock); | 47 | static DEFINE_SPINLOCK(s3c_rtc_pie_lock); |
42 | 48 | ||
@@ -80,12 +86,25 @@ static int s3c_rtc_setpie(struct device *dev, int enabled) | |||
80 | pr_debug("%s: pie=%d\n", __func__, enabled); | 86 | pr_debug("%s: pie=%d\n", __func__, enabled); |
81 | 87 | ||
82 | spin_lock_irq(&s3c_rtc_pie_lock); | 88 | spin_lock_irq(&s3c_rtc_pie_lock); |
83 | tmp = readb(s3c_rtc_base + S3C2410_TICNT) & ~S3C2410_TICNT_ENABLE; | ||
84 | 89 | ||
85 | if (enabled) | 90 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { |
86 | tmp |= S3C2410_TICNT_ENABLE; | 91 | tmp = readb(s3c_rtc_base + S3C2410_RTCCON); |
92 | tmp &= ~S3C64XX_RTCCON_TICEN; | ||
93 | |||
94 | if (enabled) | ||
95 | tmp |= S3C64XX_RTCCON_TICEN; | ||
96 | |||
97 | writeb(tmp, s3c_rtc_base + S3C2410_RTCCON); | ||
98 | } else { | ||
99 | tmp = readb(s3c_rtc_base + S3C2410_TICNT); | ||
100 | tmp &= ~S3C2410_TICNT_ENABLE; | ||
101 | |||
102 | if (enabled) | ||
103 | tmp |= S3C2410_TICNT_ENABLE; | ||
104 | |||
105 | writeb(tmp, s3c_rtc_base + S3C2410_TICNT); | ||
106 | } | ||
87 | 107 | ||
88 | writeb(tmp, s3c_rtc_base + S3C2410_TICNT); | ||
89 | spin_unlock_irq(&s3c_rtc_pie_lock); | 108 | spin_unlock_irq(&s3c_rtc_pie_lock); |
90 | 109 | ||
91 | return 0; | 110 | return 0; |
@@ -93,15 +112,21 @@ static int s3c_rtc_setpie(struct device *dev, int enabled) | |||
93 | 112 | ||
94 | static int s3c_rtc_setfreq(struct device *dev, int freq) | 113 | static int s3c_rtc_setfreq(struct device *dev, int freq) |
95 | { | 114 | { |
96 | unsigned int tmp; | 115 | struct platform_device *pdev = to_platform_device(dev); |
116 | struct rtc_device *rtc_dev = platform_get_drvdata(pdev); | ||
117 | unsigned int tmp = 0; | ||
97 | 118 | ||
98 | if (!is_power_of_2(freq)) | 119 | if (!is_power_of_2(freq)) |
99 | return -EINVAL; | 120 | return -EINVAL; |
100 | 121 | ||
101 | spin_lock_irq(&s3c_rtc_pie_lock); | 122 | spin_lock_irq(&s3c_rtc_pie_lock); |
102 | 123 | ||
103 | tmp = readb(s3c_rtc_base + S3C2410_TICNT) & S3C2410_TICNT_ENABLE; | 124 | if (s3c_rtc_cpu_type == TYPE_S3C2410) { |
104 | tmp |= (128 / freq)-1; | 125 | tmp = readb(s3c_rtc_base + S3C2410_TICNT); |
126 | tmp &= S3C2410_TICNT_ENABLE; | ||
127 | } | ||
128 | |||
129 | tmp |= (rtc_dev->max_user_freq / freq)-1; | ||
105 | 130 | ||
106 | writeb(tmp, s3c_rtc_base + S3C2410_TICNT); | 131 | writeb(tmp, s3c_rtc_base + S3C2410_TICNT); |
107 | spin_unlock_irq(&s3c_rtc_pie_lock); | 132 | spin_unlock_irq(&s3c_rtc_pie_lock); |
@@ -283,10 +308,17 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
283 | 308 | ||
284 | static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) | 309 | static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) |
285 | { | 310 | { |
286 | unsigned int ticnt = readb(s3c_rtc_base + S3C2410_TICNT); | 311 | unsigned int ticnt; |
312 | |||
313 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { | ||
314 | ticnt = readb(s3c_rtc_base + S3C2410_RTCCON); | ||
315 | ticnt &= S3C64XX_RTCCON_TICEN; | ||
316 | } else { | ||
317 | ticnt = readb(s3c_rtc_base + S3C2410_TICNT); | ||
318 | ticnt &= S3C2410_TICNT_ENABLE; | ||
319 | } | ||
287 | 320 | ||
288 | seq_printf(seq, "periodic_IRQ\t: %s\n", | 321 | seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt ? "yes" : "no"); |
289 | (ticnt & S3C2410_TICNT_ENABLE) ? "yes" : "no" ); | ||
290 | return 0; | 322 | return 0; |
291 | } | 323 | } |
292 | 324 | ||
@@ -353,10 +385,16 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en) | |||
353 | 385 | ||
354 | if (!en) { | 386 | if (!en) { |
355 | tmp = readb(base + S3C2410_RTCCON); | 387 | tmp = readb(base + S3C2410_RTCCON); |
356 | writeb(tmp & ~S3C2410_RTCCON_RTCEN, base + S3C2410_RTCCON); | 388 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) |
357 | 389 | tmp &= ~S3C64XX_RTCCON_TICEN; | |
358 | tmp = readb(base + S3C2410_TICNT); | 390 | tmp &= ~S3C2410_RTCCON_RTCEN; |
359 | writeb(tmp & ~S3C2410_TICNT_ENABLE, base + S3C2410_TICNT); | 391 | writeb(tmp, base + S3C2410_RTCCON); |
392 | |||
393 | if (s3c_rtc_cpu_type == TYPE_S3C2410) { | ||
394 | tmp = readb(base + S3C2410_TICNT); | ||
395 | tmp &= ~S3C2410_TICNT_ENABLE; | ||
396 | writeb(tmp, base + S3C2410_TICNT); | ||
397 | } | ||
360 | } else { | 398 | } else { |
361 | /* re-enable the device, and check it is ok */ | 399 | /* re-enable the device, and check it is ok */ |
362 | 400 | ||
@@ -457,8 +495,6 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) | |||
457 | pr_debug("s3c2410_rtc: RTCCON=%02x\n", | 495 | pr_debug("s3c2410_rtc: RTCCON=%02x\n", |
458 | readb(s3c_rtc_base + S3C2410_RTCCON)); | 496 | readb(s3c_rtc_base + S3C2410_RTCCON)); |
459 | 497 | ||
460 | s3c_rtc_setfreq(&pdev->dev, 1); | ||
461 | |||
462 | device_init_wakeup(&pdev->dev, 1); | 498 | device_init_wakeup(&pdev->dev, 1); |
463 | 499 | ||
464 | /* register RTC and exit */ | 500 | /* register RTC and exit */ |
@@ -472,9 +508,17 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) | |||
472 | goto err_nortc; | 508 | goto err_nortc; |
473 | } | 509 | } |
474 | 510 | ||
475 | rtc->max_user_freq = 128; | 511 | s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data; |
512 | |||
513 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) | ||
514 | rtc->max_user_freq = 32768; | ||
515 | else | ||
516 | rtc->max_user_freq = 128; | ||
476 | 517 | ||
477 | platform_set_drvdata(pdev, rtc); | 518 | platform_set_drvdata(pdev, rtc); |
519 | |||
520 | s3c_rtc_setfreq(&pdev->dev, 1); | ||
521 | |||
478 | return 0; | 522 | return 0; |
479 | 523 | ||
480 | err_nortc: | 524 | err_nortc: |
@@ -492,20 +536,30 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) | |||
492 | 536 | ||
493 | /* RTC Power management control */ | 537 | /* RTC Power management control */ |
494 | 538 | ||
495 | static int ticnt_save; | 539 | static int ticnt_save, ticnt_en_save; |
496 | 540 | ||
497 | static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) | 541 | static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) |
498 | { | 542 | { |
499 | /* save TICNT for anyone using periodic interrupts */ | 543 | /* save TICNT for anyone using periodic interrupts */ |
500 | ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); | 544 | ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); |
545 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { | ||
546 | ticnt_en_save = readb(s3c_rtc_base + S3C2410_RTCCON); | ||
547 | ticnt_en_save &= S3C64XX_RTCCON_TICEN; | ||
548 | } | ||
501 | s3c_rtc_enable(pdev, 0); | 549 | s3c_rtc_enable(pdev, 0); |
502 | return 0; | 550 | return 0; |
503 | } | 551 | } |
504 | 552 | ||
505 | static int s3c_rtc_resume(struct platform_device *pdev) | 553 | static int s3c_rtc_resume(struct platform_device *pdev) |
506 | { | 554 | { |
555 | unsigned int tmp; | ||
556 | |||
507 | s3c_rtc_enable(pdev, 1); | 557 | s3c_rtc_enable(pdev, 1); |
508 | writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); | 558 | writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); |
559 | if (s3c_rtc_cpu_type == TYPE_S3C64XX && ticnt_en_save) { | ||
560 | tmp = readb(s3c_rtc_base + S3C2410_RTCCON); | ||
561 | writeb(tmp | ticnt_en_save, s3c_rtc_base + S3C2410_RTCCON); | ||
562 | } | ||
509 | return 0; | 563 | return 0; |
510 | } | 564 | } |
511 | #else | 565 | #else |
@@ -513,13 +567,27 @@ static int s3c_rtc_resume(struct platform_device *pdev) | |||
513 | #define s3c_rtc_resume NULL | 567 | #define s3c_rtc_resume NULL |
514 | #endif | 568 | #endif |
515 | 569 | ||
516 | static struct platform_driver s3c2410_rtc_driver = { | 570 | static struct platform_device_id s3c_rtc_driver_ids[] = { |
571 | { | ||
572 | .name = "s3c2410-rtc", | ||
573 | .driver_data = TYPE_S3C2410, | ||
574 | }, { | ||
575 | .name = "s3c64xx-rtc", | ||
576 | .driver_data = TYPE_S3C64XX, | ||
577 | }, | ||
578 | { } | ||
579 | }; | ||
580 | |||
581 | MODULE_DEVICE_TABLE(platform, s3c_rtc_driver_ids); | ||
582 | |||
583 | static struct platform_driver s3c_rtc_driver = { | ||
517 | .probe = s3c_rtc_probe, | 584 | .probe = s3c_rtc_probe, |
518 | .remove = __devexit_p(s3c_rtc_remove), | 585 | .remove = __devexit_p(s3c_rtc_remove), |
519 | .suspend = s3c_rtc_suspend, | 586 | .suspend = s3c_rtc_suspend, |
520 | .resume = s3c_rtc_resume, | 587 | .resume = s3c_rtc_resume, |
588 | .id_table = s3c_rtc_driver_ids, | ||
521 | .driver = { | 589 | .driver = { |
522 | .name = "s3c2410-rtc", | 590 | .name = "s3c-rtc", |
523 | .owner = THIS_MODULE, | 591 | .owner = THIS_MODULE, |
524 | }, | 592 | }, |
525 | }; | 593 | }; |
@@ -529,12 +597,12 @@ static char __initdata banner[] = "S3C24XX RTC, (c) 2004,2006 Simtec Electronics | |||
529 | static int __init s3c_rtc_init(void) | 597 | static int __init s3c_rtc_init(void) |
530 | { | 598 | { |
531 | printk(banner); | 599 | printk(banner); |
532 | return platform_driver_register(&s3c2410_rtc_driver); | 600 | return platform_driver_register(&s3c_rtc_driver); |
533 | } | 601 | } |
534 | 602 | ||
535 | static void __exit s3c_rtc_exit(void) | 603 | static void __exit s3c_rtc_exit(void) |
536 | { | 604 | { |
537 | platform_driver_unregister(&s3c2410_rtc_driver); | 605 | platform_driver_unregister(&s3c_rtc_driver); |
538 | } | 606 | } |
539 | 607 | ||
540 | module_init(s3c_rtc_init); | 608 | module_init(s3c_rtc_init); |
diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c index b16cfe57a484..82931dc65c0b 100644 --- a/drivers/rtc/rtc-wm831x.c +++ b/drivers/rtc/rtc-wm831x.c | |||
@@ -449,17 +449,17 @@ static int wm831x_rtc_probe(struct platform_device *pdev) | |||
449 | goto err; | 449 | goto err; |
450 | } | 450 | } |
451 | 451 | ||
452 | ret = wm831x_request_irq(wm831x, per_irq, wm831x_per_irq, | 452 | ret = request_threaded_irq(per_irq, NULL, wm831x_per_irq, |
453 | IRQF_TRIGGER_RISING, "wm831x_rtc_per", | 453 | IRQF_TRIGGER_RISING, "RTC period", |
454 | wm831x_rtc); | 454 | wm831x_rtc); |
455 | if (ret != 0) { | 455 | if (ret != 0) { |
456 | dev_err(&pdev->dev, "Failed to request periodic IRQ %d: %d\n", | 456 | dev_err(&pdev->dev, "Failed to request periodic IRQ %d: %d\n", |
457 | per_irq, ret); | 457 | per_irq, ret); |
458 | } | 458 | } |
459 | 459 | ||
460 | ret = wm831x_request_irq(wm831x, alm_irq, wm831x_alm_irq, | 460 | ret = request_threaded_irq(alm_irq, NULL, wm831x_alm_irq, |
461 | IRQF_TRIGGER_RISING, "wm831x_rtc_alm", | 461 | IRQF_TRIGGER_RISING, "RTC alarm", |
462 | wm831x_rtc); | 462 | wm831x_rtc); |
463 | if (ret != 0) { | 463 | if (ret != 0) { |
464 | dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n", | 464 | dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n", |
465 | alm_irq, ret); | 465 | alm_irq, ret); |
@@ -478,8 +478,8 @@ static int __devexit wm831x_rtc_remove(struct platform_device *pdev) | |||
478 | int per_irq = platform_get_irq_byname(pdev, "PER"); | 478 | int per_irq = platform_get_irq_byname(pdev, "PER"); |
479 | int alm_irq = platform_get_irq_byname(pdev, "ALM"); | 479 | int alm_irq = platform_get_irq_byname(pdev, "ALM"); |
480 | 480 | ||
481 | wm831x_free_irq(wm831x_rtc->wm831x, alm_irq, wm831x_rtc); | 481 | free_irq(alm_irq, wm831x_rtc); |
482 | wm831x_free_irq(wm831x_rtc->wm831x, per_irq, wm831x_rtc); | 482 | free_irq(per_irq, wm831x_rtc); |
483 | rtc_device_unregister(wm831x_rtc->rtc); | 483 | rtc_device_unregister(wm831x_rtc->rtc); |
484 | kfree(wm831x_rtc); | 484 | kfree(wm831x_rtc); |
485 | 485 | ||