aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-08-29 04:34:27 -0400
committerDavid S. Miller <davem@davemloft.net>2008-08-29 17:16:51 -0400
commit84d6bd5ef79a6ccc21af97b870f6ef94fbc9b11e (patch)
tree4f6739d7dda05c18eb2dccd26d521fecd6dd37cc
parent7a138ede551c5282c1b81d191bdd4aa989b119a8 (diff)
sparc64: Use generic sun4v RTC driver.
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/sparc64/Kconfig1
-rw-r--r--arch/sparc64/kernel/time.c83
2 files changed, 9 insertions, 75 deletions
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index a4ec899faa42..16149ce8a416 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -23,6 +23,7 @@ config SPARC64
23 select RTC_DRV_M48T59 23 select RTC_DRV_M48T59
24 select RTC_DRV_CMOS 24 select RTC_DRV_CMOS
25 select RTC_DRV_BQ4802 25 select RTC_DRV_BQ4802
26 select RTC_DRV_SUN4V
26 27
27config GENERIC_TIME 28config GENERIC_TIME
28 bool 29 bool
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index 5e199a0e4378..15d16dbca1db 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -424,48 +424,6 @@ static int starfire_set_time(u32 val)
424 return 0; 424 return 0;
425} 425}
426 426
427static u32 hypervisor_get_time(void)
428{
429 unsigned long ret, time;
430 int retries = 10000;
431
432retry:
433 ret = sun4v_tod_get(&time);
434 if (ret == HV_EOK)
435 return time;
436 if (ret == HV_EWOULDBLOCK) {
437 if (--retries > 0) {
438 udelay(100);
439 goto retry;
440 }
441 printk(KERN_WARNING "SUN4V: tod_get() timed out.\n");
442 return 0;
443 }
444 printk(KERN_WARNING "SUN4V: tod_get() not supported.\n");
445 return 0;
446}
447
448static int hypervisor_set_time(u32 secs)
449{
450 unsigned long ret;
451 int retries = 10000;
452
453retry:
454 ret = sun4v_tod_set(secs);
455 if (ret == HV_EOK)
456 return 0;
457 if (ret == HV_EWOULDBLOCK) {
458 if (--retries > 0) {
459 udelay(100);
460 goto retry;
461 }
462 printk(KERN_WARNING "SUN4V: tod_set() timed out.\n");
463 return -EAGAIN;
464 }
465 printk(KERN_WARNING "SUN4V: tod_set() not supported.\n");
466 return -EOPNOTSUPP;
467}
468
469unsigned long cmos_regs; 427unsigned long cmos_regs;
470EXPORT_SYMBOL(cmos_regs); 428EXPORT_SYMBOL(cmos_regs);
471 429
@@ -644,6 +602,11 @@ static struct of_platform_driver mostek_driver = {
644 }, 602 },
645}; 603};
646 604
605static struct platform_device rtc_sun4v_device = {
606 .name = "rtc-sun4v",
607 .id = -1,
608};
609
647static int __init clock_init(void) 610static int __init clock_init(void)
648{ 611{
649 if (this_is_starfire) { 612 if (this_is_starfire) {
@@ -653,13 +616,8 @@ static int __init clock_init(void)
653 -xtime.tv_sec, -xtime.tv_nsec); 616 -xtime.tv_sec, -xtime.tv_nsec);
654 return 0; 617 return 0;
655 } 618 }
656 if (tlb_type == hypervisor) { 619 if (tlb_type == hypervisor)
657 xtime.tv_sec = hypervisor_get_time(); 620 return platform_device_register(&rtc_sun4v_device);
658 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
659 set_normalized_timespec(&wall_to_monotonic,
660 -xtime.tv_sec, -xtime.tv_nsec);
661 return 0;
662 }
663 621
664 (void) of_register_driver(&rtc_driver, &of_platform_bus_type); 622 (void) of_register_driver(&rtc_driver, &of_platform_bus_type);
665 (void) of_register_driver(&mostek_driver, &of_platform_bus_type); 623 (void) of_register_driver(&mostek_driver, &of_platform_bus_type);
@@ -1037,24 +995,6 @@ static int starfire_set_rtc_time(struct rtc_time *time)
1037 return starfire_set_time(seconds); 995 return starfire_set_time(seconds);
1038} 996}
1039 997
1040static void hypervisor_get_rtc_time(struct rtc_time *time)
1041{
1042 u32 seconds = hypervisor_get_time();
1043
1044 to_tm(seconds, time);
1045 time->tm_year -= 1900;
1046 time->tm_mon -= 1;
1047}
1048
1049static int hypervisor_set_rtc_time(struct rtc_time *time)
1050{
1051 u32 seconds = mktime(time->tm_year + 1900, time->tm_mon + 1,
1052 time->tm_mday, time->tm_hour,
1053 time->tm_min, time->tm_sec);
1054
1055 return hypervisor_set_time(seconds);
1056}
1057
1058struct mini_rtc_ops { 998struct mini_rtc_ops {
1059 void (*get_rtc_time)(struct rtc_time *); 999 void (*get_rtc_time)(struct rtc_time *);
1060 int (*set_rtc_time)(struct rtc_time *); 1000 int (*set_rtc_time)(struct rtc_time *);
@@ -1065,11 +1005,6 @@ static struct mini_rtc_ops starfire_rtc_ops = {
1065 .set_rtc_time = starfire_set_rtc_time, 1005 .set_rtc_time = starfire_set_rtc_time,
1066}; 1006};
1067 1007
1068static struct mini_rtc_ops hypervisor_rtc_ops = {
1069 .get_rtc_time = hypervisor_get_rtc_time,
1070 .set_rtc_time = hypervisor_set_rtc_time,
1071};
1072
1073static struct mini_rtc_ops *mini_rtc_ops; 1008static struct mini_rtc_ops *mini_rtc_ops;
1074 1009
1075static inline void mini_get_rtc_time(struct rtc_time *time) 1010static inline void mini_get_rtc_time(struct rtc_time *time)
@@ -1192,9 +1127,7 @@ static int __init rtc_mini_init(void)
1192{ 1127{
1193 int retval; 1128 int retval;
1194 1129
1195 if (tlb_type == hypervisor) 1130 if (this_is_starfire)
1196 mini_rtc_ops = &hypervisor_rtc_ops;
1197 else if (this_is_starfire)
1198 mini_rtc_ops = &starfire_rtc_ops; 1131 mini_rtc_ops = &starfire_rtc_ops;
1199 else 1132 else
1200 return -ENODEV; 1133 return -ENODEV;