diff options
-rw-r--r-- | arch/sparc64/kernel/time.c | 58 |
1 files changed, 50 insertions, 8 deletions
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index a22930d62adf..24681b9b4426 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c | |||
@@ -683,6 +683,48 @@ static void __init set_system_time(void) | |||
683 | } | 683 | } |
684 | } | 684 | } |
685 | 685 | ||
686 | /* davem suggests we keep this within the 4M locked kernel image */ | ||
687 | static u32 starfire_get_time(void) | ||
688 | { | ||
689 | static char obp_gettod[32]; | ||
690 | static u32 unix_tod; | ||
691 | |||
692 | sprintf(obp_gettod, "h# %08x unix-gettod", | ||
693 | (unsigned int) (long) &unix_tod); | ||
694 | prom_feval(obp_gettod); | ||
695 | |||
696 | return unix_tod; | ||
697 | } | ||
698 | |||
699 | static u32 hypervisor_get_time(void) | ||
700 | { | ||
701 | register unsigned long func asm("%o5"); | ||
702 | register unsigned long arg0 asm("%o0"); | ||
703 | register unsigned long arg1 asm("%o1"); | ||
704 | int retries = 10000; | ||
705 | |||
706 | retry: | ||
707 | func = HV_FAST_TOD_GET; | ||
708 | arg0 = 0; | ||
709 | arg1 = 0; | ||
710 | __asm__ __volatile__("ta %6" | ||
711 | : "=&r" (func), "=&r" (arg0), "=&r" (arg1) | ||
712 | : "0" (func), "1" (arg0), "2" (arg1), | ||
713 | "i" (HV_FAST_TRAP)); | ||
714 | if (arg0 == HV_EOK) | ||
715 | return arg1; | ||
716 | if (arg0 == HV_EWOULDBLOCK) { | ||
717 | if (--retries > 0) { | ||
718 | udelay(100); | ||
719 | goto retry; | ||
720 | } | ||
721 | printk(KERN_WARNING "SUN4V: tod_get() timed out.\n"); | ||
722 | return 0; | ||
723 | } | ||
724 | printk(KERN_WARNING "SUN4V: tod_get() not supported.\n"); | ||
725 | return 0; | ||
726 | } | ||
727 | |||
686 | void __init clock_probe(void) | 728 | void __init clock_probe(void) |
687 | { | 729 | { |
688 | struct linux_prom_registers clk_reg[2]; | 730 | struct linux_prom_registers clk_reg[2]; |
@@ -702,14 +744,14 @@ void __init clock_probe(void) | |||
702 | 744 | ||
703 | 745 | ||
704 | if (this_is_starfire) { | 746 | if (this_is_starfire) { |
705 | /* davem suggests we keep this within the 4M locked kernel image */ | 747 | xtime.tv_sec = starfire_get_time(); |
706 | static char obp_gettod[256]; | 748 | xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); |
707 | static u32 unix_tod; | 749 | set_normalized_timespec(&wall_to_monotonic, |
708 | 750 | -xtime.tv_sec, -xtime.tv_nsec); | |
709 | sprintf(obp_gettod, "h# %08x unix-gettod", | 751 | return; |
710 | (unsigned int) (long) &unix_tod); | 752 | } |
711 | prom_feval(obp_gettod); | 753 | if (tlb_type == hypervisor) { |
712 | xtime.tv_sec = unix_tod; | 754 | xtime.tv_sec = hypervisor_get_time(); |
713 | xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); | 755 | xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); |
714 | set_normalized_timespec(&wall_to_monotonic, | 756 | set_normalized_timespec(&wall_to_monotonic, |
715 | -xtime.tv_sec, -xtime.tv_nsec); | 757 | -xtime.tv_sec, -xtime.tv_nsec); |