diff options
Diffstat (limited to 'drivers/rtc/rtc-s3c.c')
-rw-r--r-- | drivers/rtc/rtc-s3c.c | 124 |
1 files changed, 69 insertions, 55 deletions
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index d6d1bff52b8e..2c7de79c83b9 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -69,12 +69,12 @@ static void s3c_rtc_setaie(int to) | |||
69 | 69 | ||
70 | pr_debug("%s: aie=%d\n", __FUNCTION__, to); | 70 | pr_debug("%s: aie=%d\n", __FUNCTION__, to); |
71 | 71 | ||
72 | tmp = readb(S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; | 72 | tmp = readb(s3c_rtc_base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; |
73 | 73 | ||
74 | if (to) | 74 | if (to) |
75 | tmp |= S3C2410_RTCALM_ALMEN; | 75 | tmp |= S3C2410_RTCALM_ALMEN; |
76 | 76 | ||
77 | writeb(tmp, S3C2410_RTCALM); | 77 | writeb(tmp, s3c_rtc_base + S3C2410_RTCALM); |
78 | } | 78 | } |
79 | 79 | ||
80 | static void s3c_rtc_setpie(int to) | 80 | static void s3c_rtc_setpie(int to) |
@@ -84,12 +84,12 @@ static void s3c_rtc_setpie(int to) | |||
84 | pr_debug("%s: pie=%d\n", __FUNCTION__, to); | 84 | pr_debug("%s: pie=%d\n", __FUNCTION__, to); |
85 | 85 | ||
86 | spin_lock_irq(&s3c_rtc_pie_lock); | 86 | spin_lock_irq(&s3c_rtc_pie_lock); |
87 | tmp = readb(S3C2410_TICNT) & ~S3C2410_TICNT_ENABLE; | 87 | tmp = readb(s3c_rtc_base + S3C2410_TICNT) & ~S3C2410_TICNT_ENABLE; |
88 | 88 | ||
89 | if (to) | 89 | if (to) |
90 | tmp |= S3C2410_TICNT_ENABLE; | 90 | tmp |= S3C2410_TICNT_ENABLE; |
91 | 91 | ||
92 | writeb(tmp, S3C2410_TICNT); | 92 | writeb(tmp, s3c_rtc_base + S3C2410_TICNT); |
93 | spin_unlock_irq(&s3c_rtc_pie_lock); | 93 | spin_unlock_irq(&s3c_rtc_pie_lock); |
94 | } | 94 | } |
95 | 95 | ||
@@ -98,13 +98,13 @@ static void s3c_rtc_setfreq(int freq) | |||
98 | unsigned int tmp; | 98 | unsigned int tmp; |
99 | 99 | ||
100 | spin_lock_irq(&s3c_rtc_pie_lock); | 100 | spin_lock_irq(&s3c_rtc_pie_lock); |
101 | tmp = readb(S3C2410_TICNT) & S3C2410_TICNT_ENABLE; | 101 | tmp = readb(s3c_rtc_base + S3C2410_TICNT) & S3C2410_TICNT_ENABLE; |
102 | 102 | ||
103 | s3c_rtc_freq = freq; | 103 | s3c_rtc_freq = freq; |
104 | 104 | ||
105 | tmp |= (128 / freq)-1; | 105 | tmp |= (128 / freq)-1; |
106 | 106 | ||
107 | writeb(tmp, S3C2410_TICNT); | 107 | writeb(tmp, s3c_rtc_base + S3C2410_TICNT); |
108 | spin_unlock_irq(&s3c_rtc_pie_lock); | 108 | spin_unlock_irq(&s3c_rtc_pie_lock); |
109 | } | 109 | } |
110 | 110 | ||
@@ -113,14 +113,15 @@ static void s3c_rtc_setfreq(int freq) | |||
113 | static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) | 113 | static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) |
114 | { | 114 | { |
115 | unsigned int have_retried = 0; | 115 | unsigned int have_retried = 0; |
116 | void __iomem *base = s3c_rtc_base; | ||
116 | 117 | ||
117 | retry_get_time: | 118 | retry_get_time: |
118 | rtc_tm->tm_min = readb(S3C2410_RTCMIN); | 119 | rtc_tm->tm_min = readb(base + S3C2410_RTCMIN); |
119 | rtc_tm->tm_hour = readb(S3C2410_RTCHOUR); | 120 | rtc_tm->tm_hour = readb(base + S3C2410_RTCHOUR); |
120 | rtc_tm->tm_mday = readb(S3C2410_RTCDATE); | 121 | rtc_tm->tm_mday = readb(base + S3C2410_RTCDATE); |
121 | rtc_tm->tm_mon = readb(S3C2410_RTCMON); | 122 | rtc_tm->tm_mon = readb(base + S3C2410_RTCMON); |
122 | rtc_tm->tm_year = readb(S3C2410_RTCYEAR); | 123 | rtc_tm->tm_year = readb(base + S3C2410_RTCYEAR); |
123 | rtc_tm->tm_sec = readb(S3C2410_RTCSEC); | 124 | rtc_tm->tm_sec = readb(base + S3C2410_RTCSEC); |
124 | 125 | ||
125 | /* the only way to work out wether the system was mid-update | 126 | /* the only way to work out wether the system was mid-update |
126 | * when we read it is to check the second counter, and if it | 127 | * when we read it is to check the second counter, and if it |
@@ -151,17 +152,26 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) | |||
151 | 152 | ||
152 | static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) | 153 | static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) |
153 | { | 154 | { |
154 | /* the rtc gets round the y2k problem by just not supporting it */ | 155 | void __iomem *base = s3c_rtc_base; |
156 | int year = tm->tm_year - 100; | ||
155 | 157 | ||
156 | if (tm->tm_year < 100) | 158 | pr_debug("set time %02d.%02d.%02d %02d/%02d/%02d\n", |
159 | tm->tm_year, tm->tm_mon, tm->tm_mday, | ||
160 | tm->tm_hour, tm->tm_min, tm->tm_sec); | ||
161 | |||
162 | /* we get around y2k by simply not supporting it */ | ||
163 | |||
164 | if (year < 0 || year >= 100) { | ||
165 | dev_err(dev, "rtc only supports 100 years\n"); | ||
157 | return -EINVAL; | 166 | return -EINVAL; |
167 | } | ||
158 | 168 | ||
159 | writeb(BIN2BCD(tm->tm_sec), S3C2410_RTCSEC); | 169 | writeb(BIN2BCD(tm->tm_sec), base + S3C2410_RTCSEC); |
160 | writeb(BIN2BCD(tm->tm_min), S3C2410_RTCMIN); | 170 | writeb(BIN2BCD(tm->tm_min), base + S3C2410_RTCMIN); |
161 | writeb(BIN2BCD(tm->tm_hour), S3C2410_RTCHOUR); | 171 | writeb(BIN2BCD(tm->tm_hour), base + S3C2410_RTCHOUR); |
162 | writeb(BIN2BCD(tm->tm_mday), S3C2410_RTCDATE); | 172 | writeb(BIN2BCD(tm->tm_mday), base + S3C2410_RTCDATE); |
163 | writeb(BIN2BCD(tm->tm_mon + 1), S3C2410_RTCMON); | 173 | writeb(BIN2BCD(tm->tm_mon + 1), base + S3C2410_RTCMON); |
164 | writeb(BIN2BCD(tm->tm_year - 100), S3C2410_RTCYEAR); | 174 | writeb(BIN2BCD(year), base + S3C2410_RTCYEAR); |
165 | 175 | ||
166 | return 0; | 176 | return 0; |
167 | } | 177 | } |
@@ -169,16 +179,17 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) | |||
169 | static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) | 179 | static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) |
170 | { | 180 | { |
171 | struct rtc_time *alm_tm = &alrm->time; | 181 | struct rtc_time *alm_tm = &alrm->time; |
182 | void __iomem *base = s3c_rtc_base; | ||
172 | unsigned int alm_en; | 183 | unsigned int alm_en; |
173 | 184 | ||
174 | alm_tm->tm_sec = readb(S3C2410_ALMSEC); | 185 | alm_tm->tm_sec = readb(base + S3C2410_ALMSEC); |
175 | alm_tm->tm_min = readb(S3C2410_ALMMIN); | 186 | alm_tm->tm_min = readb(base + S3C2410_ALMMIN); |
176 | alm_tm->tm_hour = readb(S3C2410_ALMHOUR); | 187 | alm_tm->tm_hour = readb(base + S3C2410_ALMHOUR); |
177 | alm_tm->tm_mon = readb(S3C2410_ALMMON); | 188 | alm_tm->tm_mon = readb(base + S3C2410_ALMMON); |
178 | alm_tm->tm_mday = readb(S3C2410_ALMDATE); | 189 | alm_tm->tm_mday = readb(base + S3C2410_ALMDATE); |
179 | alm_tm->tm_year = readb(S3C2410_ALMYEAR); | 190 | alm_tm->tm_year = readb(base + S3C2410_ALMYEAR); |
180 | 191 | ||
181 | alm_en = readb(S3C2410_RTCALM); | 192 | alm_en = readb(base + S3C2410_RTCALM); |
182 | 193 | ||
183 | pr_debug("read alarm %02x %02x.%02x.%02x %02x/%02x/%02x\n", | 194 | pr_debug("read alarm %02x %02x.%02x.%02x %02x/%02x/%02x\n", |
184 | alm_en, | 195 | alm_en, |
@@ -226,6 +237,7 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
226 | static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | 237 | static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) |
227 | { | 238 | { |
228 | struct rtc_time *tm = &alrm->time; | 239 | struct rtc_time *tm = &alrm->time; |
240 | void __iomem *base = s3c_rtc_base; | ||
229 | unsigned int alrm_en; | 241 | unsigned int alrm_en; |
230 | 242 | ||
231 | pr_debug("s3c_rtc_setalarm: %d, %02x/%02x/%02x %02x.%02x.%02x\n", | 243 | pr_debug("s3c_rtc_setalarm: %d, %02x/%02x/%02x %02x.%02x.%02x\n", |
@@ -234,32 +246,32 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
234 | tm->tm_hour & 0xff, tm->tm_min & 0xff, tm->tm_sec); | 246 | tm->tm_hour & 0xff, tm->tm_min & 0xff, tm->tm_sec); |
235 | 247 | ||
236 | 248 | ||
237 | alrm_en = readb(S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN; | 249 | alrm_en = readb(base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN; |
238 | writeb(0x00, S3C2410_RTCALM); | 250 | writeb(0x00, base + S3C2410_RTCALM); |
239 | 251 | ||
240 | if (tm->tm_sec < 60 && tm->tm_sec >= 0) { | 252 | if (tm->tm_sec < 60 && tm->tm_sec >= 0) { |
241 | alrm_en |= S3C2410_RTCALM_SECEN; | 253 | alrm_en |= S3C2410_RTCALM_SECEN; |
242 | writeb(BIN2BCD(tm->tm_sec), S3C2410_ALMSEC); | 254 | writeb(BIN2BCD(tm->tm_sec), base + S3C2410_ALMSEC); |
243 | } | 255 | } |
244 | 256 | ||
245 | if (tm->tm_min < 60 && tm->tm_min >= 0) { | 257 | if (tm->tm_min < 60 && tm->tm_min >= 0) { |
246 | alrm_en |= S3C2410_RTCALM_MINEN; | 258 | alrm_en |= S3C2410_RTCALM_MINEN; |
247 | writeb(BIN2BCD(tm->tm_min), S3C2410_ALMMIN); | 259 | writeb(BIN2BCD(tm->tm_min), base + S3C2410_ALMMIN); |
248 | } | 260 | } |
249 | 261 | ||
250 | if (tm->tm_hour < 24 && tm->tm_hour >= 0) { | 262 | if (tm->tm_hour < 24 && tm->tm_hour >= 0) { |
251 | alrm_en |= S3C2410_RTCALM_HOUREN; | 263 | alrm_en |= S3C2410_RTCALM_HOUREN; |
252 | writeb(BIN2BCD(tm->tm_hour), S3C2410_ALMHOUR); | 264 | writeb(BIN2BCD(tm->tm_hour), base + S3C2410_ALMHOUR); |
253 | } | 265 | } |
254 | 266 | ||
255 | pr_debug("setting S3C2410_RTCALM to %08x\n", alrm_en); | 267 | pr_debug("setting S3C2410_RTCALM to %08x\n", alrm_en); |
256 | 268 | ||
257 | writeb(alrm_en, S3C2410_RTCALM); | 269 | writeb(alrm_en, base + S3C2410_RTCALM); |
258 | 270 | ||
259 | if (0) { | 271 | if (0) { |
260 | alrm_en = readb(S3C2410_RTCALM); | 272 | alrm_en = readb(base + S3C2410_RTCALM); |
261 | alrm_en &= ~S3C2410_RTCALM_ALMEN; | 273 | alrm_en &= ~S3C2410_RTCALM_ALMEN; |
262 | writeb(alrm_en, S3C2410_RTCALM); | 274 | writeb(alrm_en, base + S3C2410_RTCALM); |
263 | disable_irq_wake(s3c_rtc_alarmno); | 275 | disable_irq_wake(s3c_rtc_alarmno); |
264 | } | 276 | } |
265 | 277 | ||
@@ -319,8 +331,8 @@ static int s3c_rtc_ioctl(struct device *dev, | |||
319 | 331 | ||
320 | static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) | 332 | static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) |
321 | { | 333 | { |
322 | unsigned int rtcalm = readb(S3C2410_RTCALM); | 334 | unsigned int rtcalm = readb(s3c_rtc_base + S3C2410_RTCALM); |
323 | unsigned int ticnt = readb (S3C2410_TICNT); | 335 | unsigned int ticnt = readb(s3c_rtc_base + S3C2410_TICNT); |
324 | 336 | ||
325 | seq_printf(seq, "alarm_IRQ\t: %s\n", | 337 | seq_printf(seq, "alarm_IRQ\t: %s\n", |
326 | (rtcalm & S3C2410_RTCALM_ALMEN) ? "yes" : "no" ); | 338 | (rtcalm & S3C2410_RTCALM_ALMEN) ? "yes" : "no" ); |
@@ -387,39 +399,40 @@ static struct rtc_class_ops s3c_rtcops = { | |||
387 | 399 | ||
388 | static void s3c_rtc_enable(struct platform_device *pdev, int en) | 400 | static void s3c_rtc_enable(struct platform_device *pdev, int en) |
389 | { | 401 | { |
402 | void __iomem *base = s3c_rtc_base; | ||
390 | unsigned int tmp; | 403 | unsigned int tmp; |
391 | 404 | ||
392 | if (s3c_rtc_base == NULL) | 405 | if (s3c_rtc_base == NULL) |
393 | return; | 406 | return; |
394 | 407 | ||
395 | if (!en) { | 408 | if (!en) { |
396 | tmp = readb(S3C2410_RTCCON); | 409 | tmp = readb(base + S3C2410_RTCCON); |
397 | writeb(tmp & ~S3C2410_RTCCON_RTCEN, S3C2410_RTCCON); | 410 | writeb(tmp & ~S3C2410_RTCCON_RTCEN, base + S3C2410_RTCCON); |
398 | 411 | ||
399 | tmp = readb(S3C2410_TICNT); | 412 | tmp = readb(base + S3C2410_TICNT); |
400 | writeb(tmp & ~S3C2410_TICNT_ENABLE, S3C2410_TICNT); | 413 | writeb(tmp & ~S3C2410_TICNT_ENABLE, base + S3C2410_TICNT); |
401 | } else { | 414 | } else { |
402 | /* re-enable the device, and check it is ok */ | 415 | /* re-enable the device, and check it is ok */ |
403 | 416 | ||
404 | if ((readb(S3C2410_RTCCON) & S3C2410_RTCCON_RTCEN) == 0){ | 417 | if ((readb(base+S3C2410_RTCCON) & S3C2410_RTCCON_RTCEN) == 0){ |
405 | dev_info(&pdev->dev, "rtc disabled, re-enabling\n"); | 418 | dev_info(&pdev->dev, "rtc disabled, re-enabling\n"); |
406 | 419 | ||
407 | tmp = readb(S3C2410_RTCCON); | 420 | tmp = readb(base + S3C2410_RTCCON); |
408 | writeb(tmp | S3C2410_RTCCON_RTCEN , S3C2410_RTCCON); | 421 | writeb(tmp|S3C2410_RTCCON_RTCEN, base+S3C2410_RTCCON); |
409 | } | 422 | } |
410 | 423 | ||
411 | if ((readb(S3C2410_RTCCON) & S3C2410_RTCCON_CNTSEL)){ | 424 | if ((readb(base + S3C2410_RTCCON) & S3C2410_RTCCON_CNTSEL)){ |
412 | dev_info(&pdev->dev, "removing RTCCON_CNTSEL\n"); | 425 | dev_info(&pdev->dev, "removing RTCCON_CNTSEL\n"); |
413 | 426 | ||
414 | tmp = readb(S3C2410_RTCCON); | 427 | tmp = readb(base + S3C2410_RTCCON); |
415 | writeb(tmp& ~S3C2410_RTCCON_CNTSEL , S3C2410_RTCCON); | 428 | writeb(tmp& ~S3C2410_RTCCON_CNTSEL, base+S3C2410_RTCCON); |
416 | } | 429 | } |
417 | 430 | ||
418 | if ((readb(S3C2410_RTCCON) & S3C2410_RTCCON_CLKRST)){ | 431 | if ((readb(base + S3C2410_RTCCON) & S3C2410_RTCCON_CLKRST)){ |
419 | dev_info(&pdev->dev, "removing RTCCON_CLKRST\n"); | 432 | dev_info(&pdev->dev, "removing RTCCON_CLKRST\n"); |
420 | 433 | ||
421 | tmp = readb(S3C2410_RTCCON); | 434 | tmp = readb(base + S3C2410_RTCCON); |
422 | writeb(tmp & ~S3C2410_RTCCON_CLKRST, S3C2410_RTCCON); | 435 | writeb(tmp & ~S3C2410_RTCCON_CLKRST, base+S3C2410_RTCCON); |
423 | } | 436 | } |
424 | } | 437 | } |
425 | } | 438 | } |
@@ -475,8 +488,8 @@ static int s3c_rtc_probe(struct platform_device *pdev) | |||
475 | } | 488 | } |
476 | 489 | ||
477 | s3c_rtc_mem = request_mem_region(res->start, | 490 | s3c_rtc_mem = request_mem_region(res->start, |
478 | res->end-res->start+1, | 491 | res->end-res->start+1, |
479 | pdev->name); | 492 | pdev->name); |
480 | 493 | ||
481 | if (s3c_rtc_mem == NULL) { | 494 | if (s3c_rtc_mem == NULL) { |
482 | dev_err(&pdev->dev, "failed to reserve memory region\n"); | 495 | dev_err(&pdev->dev, "failed to reserve memory region\n"); |
@@ -495,7 +508,8 @@ static int s3c_rtc_probe(struct platform_device *pdev) | |||
495 | 508 | ||
496 | s3c_rtc_enable(pdev, 1); | 509 | s3c_rtc_enable(pdev, 1); |
497 | 510 | ||
498 | pr_debug("s3c2410_rtc: RTCCON=%02x\n", readb(S3C2410_RTCCON)); | 511 | pr_debug("s3c2410_rtc: RTCCON=%02x\n", |
512 | readb(s3c_rtc_base + S3C2410_RTCCON)); | ||
499 | 513 | ||
500 | s3c_rtc_setfreq(s3c_rtc_freq); | 514 | s3c_rtc_setfreq(s3c_rtc_freq); |
501 | 515 | ||
@@ -543,7 +557,7 @@ static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) | |||
543 | 557 | ||
544 | /* save TICNT for anyone using periodic interrupts */ | 558 | /* save TICNT for anyone using periodic interrupts */ |
545 | 559 | ||
546 | ticnt_save = readb(S3C2410_TICNT); | 560 | ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); |
547 | 561 | ||
548 | /* calculate time delta for suspend */ | 562 | /* calculate time delta for suspend */ |
549 | 563 | ||
@@ -567,7 +581,7 @@ static int s3c_rtc_resume(struct platform_device *pdev) | |||
567 | rtc_tm_to_time(&tm, &time.tv_sec); | 581 | rtc_tm_to_time(&tm, &time.tv_sec); |
568 | restore_time_delta(&s3c_rtc_delta, &time); | 582 | restore_time_delta(&s3c_rtc_delta, &time); |
569 | 583 | ||
570 | writeb(ticnt_save, S3C2410_TICNT); | 584 | writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); |
571 | return 0; | 585 | return 0; |
572 | } | 586 | } |
573 | #else | 587 | #else |