aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sparc64/kernel/time.c58
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 */
687static 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
699static 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
706retry:
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
686void __init clock_probe(void) 728void __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);