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 |
