diff options
Diffstat (limited to 'drivers/rtc/rtc-s3c.c')
| -rw-r--r-- | drivers/rtc/rtc-s3c.c | 44 |
1 files changed, 42 insertions, 2 deletions
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 | ||
| 40 | static struct resource *s3c_rtc_mem; | 43 | static struct resource *s3c_rtc_mem; |
| 41 | 44 | ||
| 45 | static struct clk *rtc_clk; | ||
| 42 | static void __iomem *s3c_rtc_base; | 46 | static void __iomem *s3c_rtc_base; |
| 43 | static int s3c_rtc_alarmno = NO_IRQ; | 47 | static int s3c_rtc_alarmno = NO_IRQ; |
| 44 | static int s3c_rtc_tickno = NO_IRQ; | 48 | static 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: |
