diff options
Diffstat (limited to 'arch/x86_64/kernel/time.c')
-rw-r--r-- | arch/x86_64/kernel/time.c | 37 |
1 files changed, 21 insertions, 16 deletions
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index dba7237be5c1..3080f84bf7b7 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c | |||
@@ -48,6 +48,8 @@ static void cpufreq_delayed_get(void); | |||
48 | extern void i8254_timer_resume(void); | 48 | extern void i8254_timer_resume(void); |
49 | extern int using_apic_timer; | 49 | extern int using_apic_timer; |
50 | 50 | ||
51 | static char *time_init_gtod(void); | ||
52 | |||
51 | DEFINE_SPINLOCK(rtc_lock); | 53 | DEFINE_SPINLOCK(rtc_lock); |
52 | DEFINE_SPINLOCK(i8253_lock); | 54 | DEFINE_SPINLOCK(i8253_lock); |
53 | 55 | ||
@@ -59,7 +61,7 @@ static int notsc __initdata = 0; | |||
59 | unsigned int cpu_khz; /* TSC clocks / usec, not used here */ | 61 | unsigned int cpu_khz; /* TSC clocks / usec, not used here */ |
60 | static unsigned long hpet_period; /* fsecs / HPET clock */ | 62 | static unsigned long hpet_period; /* fsecs / HPET clock */ |
61 | unsigned long hpet_tick; /* HPET clocks / interrupt */ | 63 | unsigned long hpet_tick; /* HPET clocks / interrupt */ |
62 | static int hpet_use_timer; /* Use counter of hpet for time keeping, otherwise PIT */ | 64 | int hpet_use_timer; /* Use counter of hpet for time keeping, otherwise PIT */ |
63 | unsigned long vxtime_hz = PIT_TICK_RATE; | 65 | unsigned long vxtime_hz = PIT_TICK_RATE; |
64 | int report_lost_ticks; /* command line option */ | 66 | int report_lost_ticks; /* command line option */ |
65 | unsigned long long monotonic_base; | 67 | unsigned long long monotonic_base; |
@@ -326,7 +328,10 @@ static noinline void handle_lost_ticks(int lost, struct pt_regs *regs) | |||
326 | print_symbol("rip %s\n", regs->rip); | 328 | print_symbol("rip %s\n", regs->rip); |
327 | if (vxtime.mode == VXTIME_TSC && vxtime.hpet_address) { | 329 | if (vxtime.mode == VXTIME_TSC && vxtime.hpet_address) { |
328 | printk(KERN_WARNING "Falling back to HPET\n"); | 330 | printk(KERN_WARNING "Falling back to HPET\n"); |
329 | vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick; | 331 | if (hpet_use_timer) |
332 | vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick; | ||
333 | else | ||
334 | vxtime.last = hpet_readl(HPET_COUNTER); | ||
330 | vxtime.mode = VXTIME_HPET; | 335 | vxtime.mode = VXTIME_HPET; |
331 | do_gettimeoffset = do_gettimeoffset_hpet; | 336 | do_gettimeoffset = do_gettimeoffset_hpet; |
332 | } | 337 | } |
@@ -898,6 +903,7 @@ static struct irqaction irq0 = { | |||
898 | void __init time_init(void) | 903 | void __init time_init(void) |
899 | { | 904 | { |
900 | char *timename; | 905 | char *timename; |
906 | char *gtod; | ||
901 | 907 | ||
902 | #ifdef HPET_HACK_ENABLE_DANGEROUS | 908 | #ifdef HPET_HACK_ENABLE_DANGEROUS |
903 | if (!vxtime.hpet_address) { | 909 | if (!vxtime.hpet_address) { |
@@ -942,21 +948,19 @@ void __init time_init(void) | |||
942 | timename = "PIT"; | 948 | timename = "PIT"; |
943 | } | 949 | } |
944 | 950 | ||
945 | printk(KERN_INFO "time.c: Using %ld.%06ld MHz %s timer.\n", | 951 | vxtime.mode = VXTIME_TSC; |
946 | vxtime_hz / 1000000, vxtime_hz % 1000000, timename); | 952 | gtod = time_init_gtod(); |
953 | |||
954 | printk(KERN_INFO "time.c: Using %ld.%06ld MHz WALL %s GTOD %s timer.\n", | ||
955 | vxtime_hz / 1000000, vxtime_hz % 1000000, timename, gtod); | ||
947 | printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n", | 956 | printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n", |
948 | cpu_khz / 1000, cpu_khz % 1000); | 957 | cpu_khz / 1000, cpu_khz % 1000); |
949 | vxtime.mode = VXTIME_TSC; | ||
950 | vxtime.quot = (1000000L << 32) / vxtime_hz; | 958 | vxtime.quot = (1000000L << 32) / vxtime_hz; |
951 | vxtime.tsc_quot = (1000L << 32) / cpu_khz; | 959 | vxtime.tsc_quot = (1000L << 32) / cpu_khz; |
952 | vxtime.last_tsc = get_cycles_sync(); | 960 | vxtime.last_tsc = get_cycles_sync(); |
953 | setup_irq(0, &irq0); | 961 | setup_irq(0, &irq0); |
954 | 962 | ||
955 | set_cyc2ns_scale(cpu_khz); | 963 | set_cyc2ns_scale(cpu_khz); |
956 | |||
957 | #ifndef CONFIG_SMP | ||
958 | time_init_gtod(); | ||
959 | #endif | ||
960 | } | 964 | } |
961 | 965 | ||
962 | /* | 966 | /* |
@@ -978,9 +982,9 @@ __cpuinit int unsynchronized_tsc(void) | |||
978 | } | 982 | } |
979 | 983 | ||
980 | /* | 984 | /* |
981 | * Decide after all CPUs are booted what mode gettimeofday should use. | 985 | * Decide what mode gettimeofday should use. |
982 | */ | 986 | */ |
983 | void __init time_init_gtod(void) | 987 | __init static char *time_init_gtod(void) |
984 | { | 988 | { |
985 | char *timetype; | 989 | char *timetype; |
986 | 990 | ||
@@ -988,7 +992,10 @@ void __init time_init_gtod(void) | |||
988 | notsc = 1; | 992 | notsc = 1; |
989 | if (vxtime.hpet_address && notsc) { | 993 | if (vxtime.hpet_address && notsc) { |
990 | timetype = hpet_use_timer ? "HPET" : "PIT/HPET"; | 994 | timetype = hpet_use_timer ? "HPET" : "PIT/HPET"; |
991 | vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick; | 995 | if (hpet_use_timer) |
996 | vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick; | ||
997 | else | ||
998 | vxtime.last = hpet_readl(HPET_COUNTER); | ||
992 | vxtime.mode = VXTIME_HPET; | 999 | vxtime.mode = VXTIME_HPET; |
993 | do_gettimeoffset = do_gettimeoffset_hpet; | 1000 | do_gettimeoffset = do_gettimeoffset_hpet; |
994 | #ifdef CONFIG_X86_PM_TIMER | 1001 | #ifdef CONFIG_X86_PM_TIMER |
@@ -1005,8 +1012,7 @@ void __init time_init_gtod(void) | |||
1005 | timetype = hpet_use_timer ? "HPET/TSC" : "PIT/TSC"; | 1012 | timetype = hpet_use_timer ? "HPET/TSC" : "PIT/TSC"; |
1006 | vxtime.mode = VXTIME_TSC; | 1013 | vxtime.mode = VXTIME_TSC; |
1007 | } | 1014 | } |
1008 | 1015 | return timetype; | |
1009 | printk(KERN_INFO "time.c: Using %s based timekeeping.\n", timetype); | ||
1010 | } | 1016 | } |
1011 | 1017 | ||
1012 | __setup("report_lost_ticks", time_setup); | 1018 | __setup("report_lost_ticks", time_setup); |
@@ -1321,8 +1327,7 @@ static int __init nohpet_setup(char *s) | |||
1321 | 1327 | ||
1322 | __setup("nohpet", nohpet_setup); | 1328 | __setup("nohpet", nohpet_setup); |
1323 | 1329 | ||
1324 | 1330 | int __init notsc_setup(char *s) | |
1325 | static int __init notsc_setup(char *s) | ||
1326 | { | 1331 | { |
1327 | notsc = 1; | 1332 | notsc = 1; |
1328 | return 0; | 1333 | return 0; |