aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/Kconfig9
-rw-r--r--drivers/rtc/rtc-s3c.c44
2 files changed, 50 insertions, 3 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 4301a6c7ed3b..9238c8f40f03 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -645,9 +645,16 @@ config RTC_DRV_OMAP
645 DA8xx/OMAP-L13x chips. This driver can also be built as a 645 DA8xx/OMAP-L13x chips. This driver can also be built as a
646 module called rtc-omap. 646 module called rtc-omap.
647 647
648config HAVE_S3C_RTC
649 bool
650 help
651 This will include RTC support for Samsung SoCs. If
652 you want to include RTC support for any machine, kindly
653 select this in the respective mach-XXXX/Kconfig file.
654
648config RTC_DRV_S3C 655config RTC_DRV_S3C
649 tristate "Samsung S3C series SoC RTC" 656 tristate "Samsung S3C series SoC RTC"
650 depends on ARCH_S3C2410 || ARCH_S3C64XX 657 depends on ARCH_S3C2410 || ARCH_S3C64XX || HAVE_S3C_RTC
651 help 658 help
652 RTC (Realtime Clock) driver for the clock inbuilt into the 659 RTC (Realtime Clock) driver for the clock inbuilt into the
653 Samsung S3C24XX series of SoCs. This can provide periodic 660 Samsung S3C24XX series of SoCs. This can provide periodic
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index 70b68d35f969..a0d3ec89d412 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -1,5 +1,8 @@
1/* drivers/rtc/rtc-s3c.c 1/* drivers/rtc/rtc-s3c.c
2 * 2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
3 * Copyright (c) 2004,2006 Simtec Electronics 6 * Copyright (c) 2004,2006 Simtec Electronics
4 * Ben Dooks, <ben@simtec.co.uk> 7 * Ben Dooks, <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/ 8 * http://armlinux.simtec.co.uk/
@@ -39,6 +42,7 @@ enum s3c_cpu_type {
39 42
40static struct resource *s3c_rtc_mem; 43static struct resource *s3c_rtc_mem;
41 44
45static struct clk *rtc_clk;
42static void __iomem *s3c_rtc_base; 46static void __iomem *s3c_rtc_base;
43static int s3c_rtc_alarmno = NO_IRQ; 47static int s3c_rtc_alarmno = NO_IRQ;
44static int s3c_rtc_tickno = NO_IRQ; 48static int s3c_rtc_tickno = NO_IRQ;
@@ -53,6 +57,10 @@ static irqreturn_t s3c_rtc_alarmirq(int irq, void *id)
53 struct rtc_device *rdev = id; 57 struct rtc_device *rdev = id;
54 58
55 rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF); 59 rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF);
60
61 if (s3c_rtc_cpu_type == TYPE_S3C64XX)
62 writeb(S3C2410_INTP_ALM, s3c_rtc_base + S3C2410_INTP);
63
56 return IRQ_HANDLED; 64 return IRQ_HANDLED;
57} 65}
58 66
@@ -61,6 +69,10 @@ static irqreturn_t s3c_rtc_tickirq(int irq, void *id)
61 struct rtc_device *rdev = id; 69 struct rtc_device *rdev = id;
62 70
63 rtc_update_irq(rdev, 1, RTC_PF | RTC_IRQF); 71 rtc_update_irq(rdev, 1, RTC_PF | RTC_IRQF);
72
73 if (s3c_rtc_cpu_type == TYPE_S3C64XX)
74 writeb(S3C2410_INTP_TIC, s3c_rtc_base + S3C2410_INTP);
75
64 return IRQ_HANDLED; 76 return IRQ_HANDLED;
65} 77}
66 78
@@ -94,7 +106,7 @@ static int s3c_rtc_setpie(struct device *dev, int enabled)
94 if (enabled) 106 if (enabled)
95 tmp |= S3C64XX_RTCCON_TICEN; 107 tmp |= S3C64XX_RTCCON_TICEN;
96 108
97 writeb(tmp, s3c_rtc_base + S3C2410_RTCCON); 109 writew(tmp, s3c_rtc_base + S3C2410_RTCCON);
98 } else { 110 } else {
99 tmp = readb(s3c_rtc_base + S3C2410_TICNT); 111 tmp = readb(s3c_rtc_base + S3C2410_TICNT);
100 tmp &= ~S3C2410_TICNT_ENABLE; 112 tmp &= ~S3C2410_TICNT_ENABLE;
@@ -128,7 +140,7 @@ static int s3c_rtc_setfreq(struct device *dev, int freq)
128 140
129 tmp |= (rtc_dev->max_user_freq / freq)-1; 141 tmp |= (rtc_dev->max_user_freq / freq)-1;
130 142
131 writeb(tmp, s3c_rtc_base + S3C2410_TICNT); 143 writel(tmp, s3c_rtc_base + S3C2410_TICNT);
132 spin_unlock_irq(&s3c_rtc_pie_lock); 144 spin_unlock_irq(&s3c_rtc_pie_lock);
133 145
134 return 0; 146 return 0;
@@ -431,6 +443,10 @@ static int __devexit s3c_rtc_remove(struct platform_device *dev)
431 s3c_rtc_setpie(&dev->dev, 0); 443 s3c_rtc_setpie(&dev->dev, 0);
432 s3c_rtc_setaie(0); 444 s3c_rtc_setaie(0);
433 445
446 clk_disable(rtc_clk);
447 clk_put(rtc_clk);
448 rtc_clk = NULL;
449
434 iounmap(s3c_rtc_base); 450 iounmap(s3c_rtc_base);
435 release_resource(s3c_rtc_mem); 451 release_resource(s3c_rtc_mem);
436 kfree(s3c_rtc_mem); 452 kfree(s3c_rtc_mem);
@@ -442,6 +458,7 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
442{ 458{
443 struct rtc_device *rtc; 459 struct rtc_device *rtc;
444 struct resource *res; 460 struct resource *res;
461 unsigned int tmp, i;
445 int ret; 462 int ret;
446 463
447 pr_debug("%s: probe=%p\n", __func__, pdev); 464 pr_debug("%s: probe=%p\n", __func__, pdev);
@@ -488,6 +505,16 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
488 goto err_nomap; 505 goto err_nomap;
489 } 506 }
490 507
508 rtc_clk = clk_get(&pdev->dev, "rtc");
509 if (IS_ERR(rtc_clk)) {
510 dev_err(&pdev->dev, "failed to find rtc clock source\n");
511 ret = PTR_ERR(rtc_clk);
512 rtc_clk = NULL;
513 goto err_clk;
514 }
515
516 clk_enable(rtc_clk);
517
491 /* check to see if everything is setup correctly */ 518 /* check to see if everything is setup correctly */
492 519
493 s3c_rtc_enable(pdev, 1); 520 s3c_rtc_enable(pdev, 1);
@@ -510,6 +537,15 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
510 537
511 s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data; 538 s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data;
512 539
540 /* Check RTC Time */
541
542 for (i = S3C2410_RTCSEC; i <= S3C2410_RTCYEAR; i += 0x4) {
543 tmp = readb(s3c_rtc_base + i);
544
545 if ((tmp & 0xf) > 0x9 || ((tmp >> 4) & 0xf) > 0x9)
546 writeb(0, s3c_rtc_base + i);
547 }
548
513 if (s3c_rtc_cpu_type == TYPE_S3C64XX) 549 if (s3c_rtc_cpu_type == TYPE_S3C64XX)
514 rtc->max_user_freq = 32768; 550 rtc->max_user_freq = 32768;
515 else 551 else
@@ -523,6 +559,10 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
523 559
524 err_nortc: 560 err_nortc:
525 s3c_rtc_enable(pdev, 0); 561 s3c_rtc_enable(pdev, 0);
562 clk_disable(rtc_clk);
563 clk_put(rtc_clk);
564
565 err_clk:
526 iounmap(s3c_rtc_base); 566 iounmap(s3c_rtc_base);
527 567
528 err_nomap: 568 err_nomap: