diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/rtc/rtc-s3c.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 16512ecae31a..53c99b1a3c92 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
| @@ -57,11 +57,13 @@ static irqreturn_t s3c_rtc_alarmirq(int irq, void *id) | |||
| 57 | { | 57 | { |
| 58 | struct rtc_device *rdev = id; | 58 | struct rtc_device *rdev = id; |
| 59 | 59 | ||
| 60 | clk_enable(rtc_clk); | ||
| 60 | rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF); | 61 | rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF); |
| 61 | 62 | ||
| 62 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) | 63 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) |
| 63 | writeb(S3C2410_INTP_ALM, s3c_rtc_base + S3C2410_INTP); | 64 | writeb(S3C2410_INTP_ALM, s3c_rtc_base + S3C2410_INTP); |
| 64 | 65 | ||
| 66 | clk_disable(rtc_clk); | ||
| 65 | return IRQ_HANDLED; | 67 | return IRQ_HANDLED; |
| 66 | } | 68 | } |
| 67 | 69 | ||
| @@ -69,11 +71,13 @@ static irqreturn_t s3c_rtc_tickirq(int irq, void *id) | |||
| 69 | { | 71 | { |
| 70 | struct rtc_device *rdev = id; | 72 | struct rtc_device *rdev = id; |
| 71 | 73 | ||
| 74 | clk_enable(rtc_clk); | ||
| 72 | rtc_update_irq(rdev, 1, RTC_PF | RTC_IRQF); | 75 | rtc_update_irq(rdev, 1, RTC_PF | RTC_IRQF); |
| 73 | 76 | ||
| 74 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) | 77 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) |
| 75 | writeb(S3C2410_INTP_TIC, s3c_rtc_base + S3C2410_INTP); | 78 | writeb(S3C2410_INTP_TIC, s3c_rtc_base + S3C2410_INTP); |
| 76 | 79 | ||
| 80 | clk_disable(rtc_clk); | ||
| 77 | return IRQ_HANDLED; | 81 | return IRQ_HANDLED; |
| 78 | } | 82 | } |
| 79 | 83 | ||
| @@ -84,12 +88,14 @@ static int s3c_rtc_setaie(struct device *dev, unsigned int enabled) | |||
| 84 | 88 | ||
| 85 | pr_debug("%s: aie=%d\n", __func__, enabled); | 89 | pr_debug("%s: aie=%d\n", __func__, enabled); |
| 86 | 90 | ||
| 91 | clk_enable(rtc_clk); | ||
| 87 | tmp = readb(s3c_rtc_base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; | 92 | tmp = readb(s3c_rtc_base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; |
| 88 | 93 | ||
| 89 | if (enabled) | 94 | if (enabled) |
| 90 | tmp |= S3C2410_RTCALM_ALMEN; | 95 | tmp |= S3C2410_RTCALM_ALMEN; |
| 91 | 96 | ||
| 92 | writeb(tmp, s3c_rtc_base + S3C2410_RTCALM); | 97 | writeb(tmp, s3c_rtc_base + S3C2410_RTCALM); |
| 98 | clk_disable(rtc_clk); | ||
| 93 | 99 | ||
| 94 | return 0; | 100 | return 0; |
| 95 | } | 101 | } |
| @@ -103,6 +109,7 @@ static int s3c_rtc_setfreq(struct device *dev, int freq) | |||
| 103 | if (!is_power_of_2(freq)) | 109 | if (!is_power_of_2(freq)) |
| 104 | return -EINVAL; | 110 | return -EINVAL; |
| 105 | 111 | ||
| 112 | clk_enable(rtc_clk); | ||
| 106 | spin_lock_irq(&s3c_rtc_pie_lock); | 113 | spin_lock_irq(&s3c_rtc_pie_lock); |
| 107 | 114 | ||
| 108 | if (s3c_rtc_cpu_type == TYPE_S3C2410) { | 115 | if (s3c_rtc_cpu_type == TYPE_S3C2410) { |
| @@ -114,6 +121,7 @@ static int s3c_rtc_setfreq(struct device *dev, int freq) | |||
| 114 | 121 | ||
| 115 | writel(tmp, s3c_rtc_base + S3C2410_TICNT); | 122 | writel(tmp, s3c_rtc_base + S3C2410_TICNT); |
| 116 | spin_unlock_irq(&s3c_rtc_pie_lock); | 123 | spin_unlock_irq(&s3c_rtc_pie_lock); |
| 124 | clk_disable(rtc_clk); | ||
| 117 | 125 | ||
| 118 | return 0; | 126 | return 0; |
| 119 | } | 127 | } |
| @@ -125,6 +133,7 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) | |||
| 125 | unsigned int have_retried = 0; | 133 | unsigned int have_retried = 0; |
| 126 | void __iomem *base = s3c_rtc_base; | 134 | void __iomem *base = s3c_rtc_base; |
| 127 | 135 | ||
| 136 | clk_enable(rtc_clk); | ||
| 128 | retry_get_time: | 137 | retry_get_time: |
| 129 | rtc_tm->tm_min = readb(base + S3C2410_RTCMIN); | 138 | rtc_tm->tm_min = readb(base + S3C2410_RTCMIN); |
| 130 | rtc_tm->tm_hour = readb(base + S3C2410_RTCHOUR); | 139 | rtc_tm->tm_hour = readb(base + S3C2410_RTCHOUR); |
| @@ -157,6 +166,7 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) | |||
| 157 | rtc_tm->tm_year += 100; | 166 | rtc_tm->tm_year += 100; |
| 158 | rtc_tm->tm_mon -= 1; | 167 | rtc_tm->tm_mon -= 1; |
| 159 | 168 | ||
| 169 | clk_disable(rtc_clk); | ||
| 160 | return rtc_valid_tm(rtc_tm); | 170 | return rtc_valid_tm(rtc_tm); |
| 161 | } | 171 | } |
| 162 | 172 | ||
| @@ -165,6 +175,7 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) | |||
| 165 | void __iomem *base = s3c_rtc_base; | 175 | void __iomem *base = s3c_rtc_base; |
| 166 | int year = tm->tm_year - 100; | 176 | int year = tm->tm_year - 100; |
| 167 | 177 | ||
| 178 | clk_enable(rtc_clk); | ||
| 168 | pr_debug("set time %04d.%02d.%02d %02d:%02d:%02d\n", | 179 | pr_debug("set time %04d.%02d.%02d %02d:%02d:%02d\n", |
| 169 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | 180 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, |
| 170 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 181 | tm->tm_hour, tm->tm_min, tm->tm_sec); |
| @@ -182,6 +193,7 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) | |||
| 182 | writeb(bin2bcd(tm->tm_mday), base + S3C2410_RTCDATE); | 193 | writeb(bin2bcd(tm->tm_mday), base + S3C2410_RTCDATE); |
| 183 | writeb(bin2bcd(tm->tm_mon + 1), base + S3C2410_RTCMON); | 194 | writeb(bin2bcd(tm->tm_mon + 1), base + S3C2410_RTCMON); |
| 184 | writeb(bin2bcd(year), base + S3C2410_RTCYEAR); | 195 | writeb(bin2bcd(year), base + S3C2410_RTCYEAR); |
| 196 | clk_disable(rtc_clk); | ||
| 185 | 197 | ||
| 186 | return 0; | 198 | return 0; |
| 187 | } | 199 | } |
| @@ -192,6 +204,7 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 192 | void __iomem *base = s3c_rtc_base; | 204 | void __iomem *base = s3c_rtc_base; |
| 193 | unsigned int alm_en; | 205 | unsigned int alm_en; |
| 194 | 206 | ||
| 207 | clk_enable(rtc_clk); | ||
| 195 | alm_tm->tm_sec = readb(base + S3C2410_ALMSEC); | 208 | alm_tm->tm_sec = readb(base + S3C2410_ALMSEC); |
| 196 | alm_tm->tm_min = readb(base + S3C2410_ALMMIN); | 209 | alm_tm->tm_min = readb(base + S3C2410_ALMMIN); |
| 197 | alm_tm->tm_hour = readb(base + S3C2410_ALMHOUR); | 210 | alm_tm->tm_hour = readb(base + S3C2410_ALMHOUR); |
| @@ -243,6 +256,7 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 243 | else | 256 | else |
| 244 | alm_tm->tm_year = -1; | 257 | alm_tm->tm_year = -1; |
| 245 | 258 | ||
| 259 | clk_disable(rtc_clk); | ||
| 246 | return 0; | 260 | return 0; |
| 247 | } | 261 | } |
| 248 | 262 | ||
| @@ -252,6 +266,7 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 252 | void __iomem *base = s3c_rtc_base; | 266 | void __iomem *base = s3c_rtc_base; |
| 253 | unsigned int alrm_en; | 267 | unsigned int alrm_en; |
| 254 | 268 | ||
| 269 | clk_enable(rtc_clk); | ||
| 255 | pr_debug("s3c_rtc_setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n", | 270 | pr_debug("s3c_rtc_setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n", |
| 256 | alrm->enabled, | 271 | alrm->enabled, |
| 257 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | 272 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, |
| @@ -282,6 +297,7 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 282 | 297 | ||
| 283 | s3c_rtc_setaie(dev, alrm->enabled); | 298 | s3c_rtc_setaie(dev, alrm->enabled); |
| 284 | 299 | ||
| 300 | clk_disable(rtc_clk); | ||
| 285 | return 0; | 301 | return 0; |
| 286 | } | 302 | } |
| 287 | 303 | ||
| @@ -289,6 +305,7 @@ static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) | |||
| 289 | { | 305 | { |
| 290 | unsigned int ticnt; | 306 | unsigned int ticnt; |
| 291 | 307 | ||
| 308 | clk_enable(rtc_clk); | ||
| 292 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { | 309 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { |
| 293 | ticnt = readw(s3c_rtc_base + S3C2410_RTCCON); | 310 | ticnt = readw(s3c_rtc_base + S3C2410_RTCCON); |
| 294 | ticnt &= S3C64XX_RTCCON_TICEN; | 311 | ticnt &= S3C64XX_RTCCON_TICEN; |
| @@ -298,6 +315,7 @@ static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) | |||
| 298 | } | 315 | } |
| 299 | 316 | ||
| 300 | seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt ? "yes" : "no"); | 317 | seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt ? "yes" : "no"); |
| 318 | clk_disable(rtc_clk); | ||
| 301 | return 0; | 319 | return 0; |
| 302 | } | 320 | } |
| 303 | 321 | ||
| @@ -360,6 +378,7 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en) | |||
| 360 | if (s3c_rtc_base == NULL) | 378 | if (s3c_rtc_base == NULL) |
| 361 | return; | 379 | return; |
| 362 | 380 | ||
| 381 | clk_enable(rtc_clk); | ||
| 363 | if (!en) { | 382 | if (!en) { |
| 364 | tmp = readw(base + S3C2410_RTCCON); | 383 | tmp = readw(base + S3C2410_RTCCON); |
| 365 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) | 384 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) |
| @@ -399,6 +418,7 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en) | |||
| 399 | base + S3C2410_RTCCON); | 418 | base + S3C2410_RTCCON); |
| 400 | } | 419 | } |
| 401 | } | 420 | } |
| 421 | clk_disable(rtc_clk); | ||
| 402 | } | 422 | } |
| 403 | 423 | ||
| 404 | static int __devexit s3c_rtc_remove(struct platform_device *dev) | 424 | static int __devexit s3c_rtc_remove(struct platform_device *dev) |
| @@ -410,7 +430,6 @@ static int __devexit s3c_rtc_remove(struct platform_device *dev) | |||
| 410 | 430 | ||
| 411 | s3c_rtc_setaie(&dev->dev, 0); | 431 | s3c_rtc_setaie(&dev->dev, 0); |
| 412 | 432 | ||
| 413 | clk_disable(rtc_clk); | ||
| 414 | clk_put(rtc_clk); | 433 | clk_put(rtc_clk); |
| 415 | rtc_clk = NULL; | 434 | rtc_clk = NULL; |
| 416 | 435 | ||
| @@ -530,6 +549,8 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) | |||
| 530 | 549 | ||
| 531 | s3c_rtc_setfreq(&pdev->dev, 1); | 550 | s3c_rtc_setfreq(&pdev->dev, 1); |
| 532 | 551 | ||
| 552 | clk_disable(rtc_clk); | ||
| 553 | |||
| 533 | return 0; | 554 | return 0; |
| 534 | 555 | ||
| 535 | err_nortc: | 556 | err_nortc: |
| @@ -555,6 +576,7 @@ static int ticnt_save, ticnt_en_save; | |||
| 555 | 576 | ||
| 556 | static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) | 577 | static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) |
| 557 | { | 578 | { |
| 579 | clk_enable(rtc_clk); | ||
| 558 | /* save TICNT for anyone using periodic interrupts */ | 580 | /* save TICNT for anyone using periodic interrupts */ |
| 559 | ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); | 581 | ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); |
| 560 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { | 582 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { |
| @@ -569,6 +591,7 @@ static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) | |||
| 569 | else | 591 | else |
| 570 | dev_err(&pdev->dev, "enable_irq_wake failed\n"); | 592 | dev_err(&pdev->dev, "enable_irq_wake failed\n"); |
| 571 | } | 593 | } |
| 594 | clk_disable(rtc_clk); | ||
| 572 | 595 | ||
| 573 | return 0; | 596 | return 0; |
| 574 | } | 597 | } |
| @@ -577,6 +600,7 @@ static int s3c_rtc_resume(struct platform_device *pdev) | |||
| 577 | { | 600 | { |
| 578 | unsigned int tmp; | 601 | unsigned int tmp; |
| 579 | 602 | ||
| 603 | clk_enable(rtc_clk); | ||
| 580 | s3c_rtc_enable(pdev, 1); | 604 | s3c_rtc_enable(pdev, 1); |
| 581 | writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); | 605 | writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); |
| 582 | if (s3c_rtc_cpu_type == TYPE_S3C64XX && ticnt_en_save) { | 606 | if (s3c_rtc_cpu_type == TYPE_S3C64XX && ticnt_en_save) { |
| @@ -588,6 +612,7 @@ static int s3c_rtc_resume(struct platform_device *pdev) | |||
| 588 | disable_irq_wake(s3c_rtc_alarmno); | 612 | disable_irq_wake(s3c_rtc_alarmno); |
| 589 | wake_en = false; | 613 | wake_en = false; |
| 590 | } | 614 | } |
| 615 | clk_disable(rtc_clk); | ||
| 591 | 616 | ||
| 592 | return 0; | 617 | return 0; |
| 593 | } | 618 | } |
