diff options
Diffstat (limited to 'arch/sparc64/kernel/time.c')
-rw-r--r-- | arch/sparc64/kernel/time.c | 83 |
1 files changed, 8 insertions, 75 deletions
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 | ||
427 | static u32 hypervisor_get_time(void) | ||
428 | { | ||
429 | unsigned long ret, time; | ||
430 | int retries = 10000; | ||
431 | |||
432 | retry: | ||
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 | |||
448 | static int hypervisor_set_time(u32 secs) | ||
449 | { | ||
450 | unsigned long ret; | ||
451 | int retries = 10000; | ||
452 | |||
453 | retry: | ||
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 | |||
469 | unsigned long cmos_regs; | 427 | unsigned long cmos_regs; |
470 | EXPORT_SYMBOL(cmos_regs); | 428 | EXPORT_SYMBOL(cmos_regs); |
471 | 429 | ||
@@ -644,6 +602,11 @@ static struct of_platform_driver mostek_driver = { | |||
644 | }, | 602 | }, |
645 | }; | 603 | }; |
646 | 604 | ||
605 | static struct platform_device rtc_sun4v_device = { | ||
606 | .name = "rtc-sun4v", | ||
607 | .id = -1, | ||
608 | }; | ||
609 | |||
647 | static int __init clock_init(void) | 610 | static 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 | ||
1040 | static 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 | |||
1049 | static 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 | |||
1058 | struct mini_rtc_ops { | 998 | struct 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 | ||
1068 | static 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 | |||
1073 | static struct mini_rtc_ops *mini_rtc_ops; | 1008 | static struct mini_rtc_ops *mini_rtc_ops; |
1074 | 1009 | ||
1075 | static inline void mini_get_rtc_time(struct rtc_time *time) | 1010 | static 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; |