aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2012-02-13 01:01:37 -0500
committerArnd Bergmann <arnd@arndb.de>2012-02-13 01:01:37 -0500
commit7dae8c5209147ad06d424928a5f1ec45caa87691 (patch)
tree9d62ca389dde613cf6eba66710eb06d513f202a5 /drivers
parentac819a86a76dc29d18306f5c998c38af1ebb58cd (diff)
parentb2994d318dc78c9a4a43605629f00217335ada28 (diff)
Merge branch 'v3.4-next/devel-samsung-rtc' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung into next/drivers
* 'v3.4-next/devel-samsung-rtc' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung: ARM: S3C2443/S3C2416: add s3c_rtc_setname and rename rtc devices rtc-s3c: add variants for S3C2443 and S3C2416 rtc-s3c: make room for more variants in devicetree block ARM: SAMSUNG: cleanup of rtc register definitions
Diffstat (limited to 'drivers')
-rw-r--r--drivers/rtc/rtc-s3c.c71
1 files changed, 58 insertions, 13 deletions
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index aef40bd2957b..78951866f8ab 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -35,6 +35,8 @@
35 35
36enum s3c_cpu_type { 36enum s3c_cpu_type {
37 TYPE_S3C2410, 37 TYPE_S3C2410,
38 TYPE_S3C2416,
39 TYPE_S3C2443,
38 TYPE_S3C64XX, 40 TYPE_S3C64XX,
39}; 41};
40 42
@@ -132,6 +134,7 @@ static int s3c_rtc_setfreq(struct device *dev, int freq)
132 struct platform_device *pdev = to_platform_device(dev); 134 struct platform_device *pdev = to_platform_device(dev);
133 struct rtc_device *rtc_dev = platform_get_drvdata(pdev); 135 struct rtc_device *rtc_dev = platform_get_drvdata(pdev);
134 unsigned int tmp = 0; 136 unsigned int tmp = 0;
137 int val;
135 138
136 if (!is_power_of_2(freq)) 139 if (!is_power_of_2(freq))
137 return -EINVAL; 140 return -EINVAL;
@@ -139,12 +142,22 @@ static int s3c_rtc_setfreq(struct device *dev, int freq)
139 clk_enable(rtc_clk); 142 clk_enable(rtc_clk);
140 spin_lock_irq(&s3c_rtc_pie_lock); 143 spin_lock_irq(&s3c_rtc_pie_lock);
141 144
142 if (s3c_rtc_cpu_type == TYPE_S3C2410) { 145 if (s3c_rtc_cpu_type != TYPE_S3C64XX) {
143 tmp = readb(s3c_rtc_base + S3C2410_TICNT); 146 tmp = readb(s3c_rtc_base + S3C2410_TICNT);
144 tmp &= S3C2410_TICNT_ENABLE; 147 tmp &= S3C2410_TICNT_ENABLE;
145 } 148 }
146 149
147 tmp |= (rtc_dev->max_user_freq / freq)-1; 150 val = (rtc_dev->max_user_freq / freq) - 1;
151
152 if (s3c_rtc_cpu_type == TYPE_S3C2416 || s3c_rtc_cpu_type == TYPE_S3C2443) {
153 tmp |= S3C2443_TICNT_PART(val);
154 writel(S3C2443_TICNT1_PART(val), s3c_rtc_base + S3C2443_TICNT1);
155
156 if (s3c_rtc_cpu_type == TYPE_S3C2416)
157 writel(S3C2416_TICNT2_PART(val), s3c_rtc_base + S3C2416_TICNT2);
158 } else {
159 tmp |= val;
160 }
148 161
149 writel(tmp, s3c_rtc_base + S3C2410_TICNT); 162 writel(tmp, s3c_rtc_base + S3C2410_TICNT);
150 spin_unlock_irq(&s3c_rtc_pie_lock); 163 spin_unlock_irq(&s3c_rtc_pie_lock);
@@ -371,7 +384,7 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en)
371 tmp &= ~S3C2410_RTCCON_RTCEN; 384 tmp &= ~S3C2410_RTCCON_RTCEN;
372 writew(tmp, base + S3C2410_RTCCON); 385 writew(tmp, base + S3C2410_RTCCON);
373 386
374 if (s3c_rtc_cpu_type == TYPE_S3C2410) { 387 if (s3c_rtc_cpu_type != TYPE_S3C64XX) {
375 tmp = readb(base + S3C2410_TICNT); 388 tmp = readb(base + S3C2410_TICNT);
376 tmp &= ~S3C2410_TICNT_ENABLE; 389 tmp &= ~S3C2410_TICNT_ENABLE;
377 writeb(tmp, base + S3C2410_TICNT); 390 writeb(tmp, base + S3C2410_TICNT);
@@ -428,12 +441,27 @@ static int __devexit s3c_rtc_remove(struct platform_device *dev)
428 return 0; 441 return 0;
429} 442}
430 443
444static const struct of_device_id s3c_rtc_dt_match[];
445
446static inline int s3c_rtc_get_driver_data(struct platform_device *pdev)
447{
448#ifdef CONFIG_OF
449 if (pdev->dev.of_node) {
450 const struct of_device_id *match;
451 match = of_match_node(s3c_rtc_dt_match, pdev->dev.of_node);
452 return match->data;
453 }
454#endif
455 return platform_get_device_id(pdev)->driver_data;
456}
457
431static int __devinit s3c_rtc_probe(struct platform_device *pdev) 458static int __devinit s3c_rtc_probe(struct platform_device *pdev)
432{ 459{
433 struct rtc_device *rtc; 460 struct rtc_device *rtc;
434 struct rtc_time rtc_tm; 461 struct rtc_time rtc_tm;
435 struct resource *res; 462 struct resource *res;
436 int ret; 463 int ret;
464 int tmp;
437 465
438 pr_debug("%s: probe=%p\n", __func__, pdev); 466 pr_debug("%s: probe=%p\n", __func__, pdev);
439 467
@@ -508,13 +536,7 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
508 goto err_nortc; 536 goto err_nortc;
509 } 537 }
510 538
511#ifdef CONFIG_OF 539 s3c_rtc_cpu_type = s3c_rtc_get_driver_data(pdev);
512 if (pdev->dev.of_node)
513 s3c_rtc_cpu_type = of_device_is_compatible(pdev->dev.of_node,
514 "samsung,s3c6410-rtc") ? TYPE_S3C64XX : TYPE_S3C2410;
515 else
516#endif
517 s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data;
518 540
519 /* Check RTC Time */ 541 /* Check RTC Time */
520 542
@@ -533,11 +555,17 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
533 dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n"); 555 dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n");
534 } 556 }
535 557
536 if (s3c_rtc_cpu_type == TYPE_S3C64XX) 558 if (s3c_rtc_cpu_type != TYPE_S3C2410)
537 rtc->max_user_freq = 32768; 559 rtc->max_user_freq = 32768;
538 else 560 else
539 rtc->max_user_freq = 128; 561 rtc->max_user_freq = 128;
540 562
563 if (s3c_rtc_cpu_type == TYPE_S3C2416 || s3c_rtc_cpu_type == TYPE_S3C2443) {
564 tmp = readw(s3c_rtc_base + S3C2410_RTCCON);
565 tmp |= S3C2443_RTCCON_TICSEL;
566 writew(tmp, s3c_rtc_base + S3C2410_RTCCON);
567 }
568
541 platform_set_drvdata(pdev, rtc); 569 platform_set_drvdata(pdev, rtc);
542 570
543 s3c_rtc_setfreq(&pdev->dev, 1); 571 s3c_rtc_setfreq(&pdev->dev, 1);
@@ -638,8 +666,19 @@ static int s3c_rtc_resume(struct platform_device *pdev)
638 666
639#ifdef CONFIG_OF 667#ifdef CONFIG_OF
640static const struct of_device_id s3c_rtc_dt_match[] = { 668static const struct of_device_id s3c_rtc_dt_match[] = {
641 { .compatible = "samsung,s3c2410-rtc" }, 669 {
642 { .compatible = "samsung,s3c6410-rtc" }, 670 .compatible = "samsung,s3c2410-rtc"
671 .data = TYPE_S3C2410,
672 }, {
673 .compatible = "samsung,s3c2416-rtc"
674 .data = TYPE_S3C2416,
675 }, {
676 .compatible = "samsung,s3c2443-rtc"
677 .data = TYPE_S3C2443,
678 }, {
679 .compatible = "samsung,s3c6410-rtc"
680 .data = TYPE_S3C64XX,
681 },
643 {}, 682 {},
644}; 683};
645MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match); 684MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match);
@@ -652,6 +691,12 @@ static struct platform_device_id s3c_rtc_driver_ids[] = {
652 .name = "s3c2410-rtc", 691 .name = "s3c2410-rtc",
653 .driver_data = TYPE_S3C2410, 692 .driver_data = TYPE_S3C2410,
654 }, { 693 }, {
694 .name = "s3c2416-rtc",
695 .driver_data = TYPE_S3C2416,
696 }, {
697 .name = "s3c2443-rtc",
698 .driver_data = TYPE_S3C2443,
699 }, {
655 .name = "s3c64xx-rtc", 700 .name = "s3c64xx-rtc",
656 .driver_data = TYPE_S3C64XX, 701 .driver_data = TYPE_S3C64XX,
657 }, 702 },