diff options
Diffstat (limited to 'arch/x86_64/kernel/time.c')
-rw-r--r-- | arch/x86_64/kernel/time.c | 36 |
1 files changed, 19 insertions, 17 deletions
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index 8cb2b2d35f5d..76857add2f51 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c | |||
@@ -67,6 +67,7 @@ static int notsc __initdata = 0; | |||
67 | 67 | ||
68 | unsigned int cpu_khz; /* TSC clocks / usec, not used here */ | 68 | unsigned int cpu_khz; /* TSC clocks / usec, not used here */ |
69 | EXPORT_SYMBOL(cpu_khz); | 69 | EXPORT_SYMBOL(cpu_khz); |
70 | unsigned long hpet_address; | ||
70 | static unsigned long hpet_period; /* fsecs / HPET clock */ | 71 | static unsigned long hpet_period; /* fsecs / HPET clock */ |
71 | unsigned long hpet_tick; /* HPET clocks / interrupt */ | 72 | unsigned long hpet_tick; /* HPET clocks / interrupt */ |
72 | int hpet_use_timer; /* Use counter of hpet for time keeping, otherwise PIT */ | 73 | int hpet_use_timer; /* Use counter of hpet for time keeping, otherwise PIT */ |
@@ -316,7 +317,7 @@ static noinline void handle_lost_ticks(int lost) | |||
316 | KERN_WARNING "Your time source seems to be instable or " | 317 | KERN_WARNING "Your time source seems to be instable or " |
317 | "some driver is hogging interupts\n"); | 318 | "some driver is hogging interupts\n"); |
318 | print_symbol("rip %s\n", get_irq_regs()->rip); | 319 | print_symbol("rip %s\n", get_irq_regs()->rip); |
319 | if (vxtime.mode == VXTIME_TSC && vxtime.hpet_address) { | 320 | if (vxtime.mode == VXTIME_TSC && hpet_address) { |
320 | printk(KERN_WARNING "Falling back to HPET\n"); | 321 | printk(KERN_WARNING "Falling back to HPET\n"); |
321 | if (hpet_use_timer) | 322 | if (hpet_use_timer) |
322 | vxtime.last = hpet_readl(HPET_T0_CMP) - | 323 | vxtime.last = hpet_readl(HPET_T0_CMP) - |
@@ -324,6 +325,7 @@ static noinline void handle_lost_ticks(int lost) | |||
324 | else | 325 | else |
325 | vxtime.last = hpet_readl(HPET_COUNTER); | 326 | vxtime.last = hpet_readl(HPET_COUNTER); |
326 | vxtime.mode = VXTIME_HPET; | 327 | vxtime.mode = VXTIME_HPET; |
328 | vxtime.hpet_address = hpet_address; | ||
327 | do_gettimeoffset = do_gettimeoffset_hpet; | 329 | do_gettimeoffset = do_gettimeoffset_hpet; |
328 | } | 330 | } |
329 | /* else should fall back to PIT, but code missing. */ | 331 | /* else should fall back to PIT, but code missing. */ |
@@ -354,7 +356,7 @@ void main_timer_handler(void) | |||
354 | 356 | ||
355 | write_seqlock(&xtime_lock); | 357 | write_seqlock(&xtime_lock); |
356 | 358 | ||
357 | if (vxtime.hpet_address) | 359 | if (hpet_address) |
358 | offset = hpet_readl(HPET_COUNTER); | 360 | offset = hpet_readl(HPET_COUNTER); |
359 | 361 | ||
360 | if (hpet_use_timer) { | 362 | if (hpet_use_timer) { |
@@ -739,7 +741,7 @@ static __init int late_hpet_init(void) | |||
739 | struct hpet_data hd; | 741 | struct hpet_data hd; |
740 | unsigned int ntimer; | 742 | unsigned int ntimer; |
741 | 743 | ||
742 | if (!vxtime.hpet_address) | 744 | if (!hpet_address) |
743 | return 0; | 745 | return 0; |
744 | 746 | ||
745 | memset(&hd, 0, sizeof (hd)); | 747 | memset(&hd, 0, sizeof (hd)); |
@@ -752,7 +754,7 @@ static __init int late_hpet_init(void) | |||
752 | * Register with driver. | 754 | * Register with driver. |
753 | * Timer0 and Timer1 is used by platform. | 755 | * Timer0 and Timer1 is used by platform. |
754 | */ | 756 | */ |
755 | hd.hd_phys_address = vxtime.hpet_address; | 757 | hd.hd_phys_address = hpet_address; |
756 | hd.hd_address = (void __iomem *)fix_to_virt(FIX_HPET_BASE); | 758 | hd.hd_address = (void __iomem *)fix_to_virt(FIX_HPET_BASE); |
757 | hd.hd_nirqs = ntimer; | 759 | hd.hd_nirqs = ntimer; |
758 | hd.hd_flags = HPET_DATA_PLATFORM; | 760 | hd.hd_flags = HPET_DATA_PLATFORM; |
@@ -821,10 +823,10 @@ static int hpet_init(void) | |||
821 | { | 823 | { |
822 | unsigned int id; | 824 | unsigned int id; |
823 | 825 | ||
824 | if (!vxtime.hpet_address) | 826 | if (!hpet_address) |
825 | return -1; | 827 | return -1; |
826 | set_fixmap_nocache(FIX_HPET_BASE, vxtime.hpet_address); | 828 | set_fixmap_nocache(FIX_HPET_BASE, hpet_address); |
827 | __set_fixmap(VSYSCALL_HPET, vxtime.hpet_address, PAGE_KERNEL_VSYSCALL_NOCACHE); | 829 | __set_fixmap(VSYSCALL_HPET, hpet_address, PAGE_KERNEL_VSYSCALL_NOCACHE); |
828 | 830 | ||
829 | /* | 831 | /* |
830 | * Read the period, compute tick and quotient. | 832 | * Read the period, compute tick and quotient. |
@@ -878,7 +880,7 @@ void __init pit_stop_interrupt(void) | |||
878 | void __init stop_timer_interrupt(void) | 880 | void __init stop_timer_interrupt(void) |
879 | { | 881 | { |
880 | char *name; | 882 | char *name; |
881 | if (vxtime.hpet_address) { | 883 | if (hpet_address) { |
882 | name = "HPET"; | 884 | name = "HPET"; |
883 | hpet_timer_stop_set_go(0); | 885 | hpet_timer_stop_set_go(0); |
884 | } else { | 886 | } else { |
@@ -901,8 +903,7 @@ static struct irqaction irq0 = { | |||
901 | void __init time_init(void) | 903 | void __init time_init(void) |
902 | { | 904 | { |
903 | if (nohpet) | 905 | if (nohpet) |
904 | vxtime.hpet_address = 0; | 906 | hpet_address = 0; |
905 | |||
906 | xtime.tv_sec = get_cmos_time(); | 907 | xtime.tv_sec = get_cmos_time(); |
907 | xtime.tv_nsec = 0; | 908 | xtime.tv_nsec = 0; |
908 | 909 | ||
@@ -912,7 +913,7 @@ void __init time_init(void) | |||
912 | if (!hpet_init()) | 913 | if (!hpet_init()) |
913 | vxtime_hz = (FSEC_PER_SEC + hpet_period / 2) / hpet_period; | 914 | vxtime_hz = (FSEC_PER_SEC + hpet_period / 2) / hpet_period; |
914 | else | 915 | else |
915 | vxtime.hpet_address = 0; | 916 | hpet_address = 0; |
916 | 917 | ||
917 | if (hpet_use_timer) { | 918 | if (hpet_use_timer) { |
918 | /* set tick_nsec to use the proper rate for HPET */ | 919 | /* set tick_nsec to use the proper rate for HPET */ |
@@ -920,7 +921,7 @@ void __init time_init(void) | |||
920 | cpu_khz = hpet_calibrate_tsc(); | 921 | cpu_khz = hpet_calibrate_tsc(); |
921 | timename = "HPET"; | 922 | timename = "HPET"; |
922 | #ifdef CONFIG_X86_PM_TIMER | 923 | #ifdef CONFIG_X86_PM_TIMER |
923 | } else if (pmtmr_ioport && !vxtime.hpet_address) { | 924 | } else if (pmtmr_ioport && !hpet_address) { |
924 | vxtime_hz = PM_TIMER_FREQUENCY; | 925 | vxtime_hz = PM_TIMER_FREQUENCY; |
925 | timename = "PM"; | 926 | timename = "PM"; |
926 | pit_init(); | 927 | pit_init(); |
@@ -990,23 +991,24 @@ void time_init_gtod(void) | |||
990 | if (unsynchronized_tsc()) | 991 | if (unsynchronized_tsc()) |
991 | notsc = 1; | 992 | notsc = 1; |
992 | 993 | ||
993 | if (cpu_has(&boot_cpu_data, X86_FEATURE_RDTSCP)) | 994 | if (cpu_has(&boot_cpu_data, X86_FEATURE_RDTSCP)) |
994 | vgetcpu_mode = VGETCPU_RDTSCP; | 995 | vgetcpu_mode = VGETCPU_RDTSCP; |
995 | else | 996 | else |
996 | vgetcpu_mode = VGETCPU_LSL; | 997 | vgetcpu_mode = VGETCPU_LSL; |
997 | 998 | ||
998 | if (vxtime.hpet_address && notsc) { | 999 | if (hpet_address && notsc) { |
999 | timetype = hpet_use_timer ? "HPET" : "PIT/HPET"; | 1000 | timetype = hpet_use_timer ? "HPET" : "PIT/HPET"; |
1000 | if (hpet_use_timer) | 1001 | if (hpet_use_timer) |
1001 | vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick; | 1002 | vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick; |
1002 | else | 1003 | else |
1003 | vxtime.last = hpet_readl(HPET_COUNTER); | 1004 | vxtime.last = hpet_readl(HPET_COUNTER); |
1004 | vxtime.mode = VXTIME_HPET; | 1005 | vxtime.mode = VXTIME_HPET; |
1006 | vxtime.hpet_address = hpet_address; | ||
1005 | do_gettimeoffset = do_gettimeoffset_hpet; | 1007 | do_gettimeoffset = do_gettimeoffset_hpet; |
1006 | #ifdef CONFIG_X86_PM_TIMER | 1008 | #ifdef CONFIG_X86_PM_TIMER |
1007 | /* Using PM for gettimeofday is quite slow, but we have no other | 1009 | /* Using PM for gettimeofday is quite slow, but we have no other |
1008 | choice because the TSC is too unreliable on some systems. */ | 1010 | choice because the TSC is too unreliable on some systems. */ |
1009 | } else if (pmtmr_ioport && !vxtime.hpet_address && notsc) { | 1011 | } else if (pmtmr_ioport && !hpet_address && notsc) { |
1010 | timetype = "PM"; | 1012 | timetype = "PM"; |
1011 | do_gettimeoffset = do_gettimeoffset_pm; | 1013 | do_gettimeoffset = do_gettimeoffset_pm; |
1012 | vxtime.mode = VXTIME_PMTMR; | 1014 | vxtime.mode = VXTIME_PMTMR; |
@@ -1066,7 +1068,7 @@ static int timer_resume(struct sys_device *dev) | |||
1066 | sleep_length = 0; | 1068 | sleep_length = 0; |
1067 | ctime = sleep_start; | 1069 | ctime = sleep_start; |
1068 | } | 1070 | } |
1069 | if (vxtime.hpet_address) | 1071 | if (hpet_address) |
1070 | hpet_reenable(); | 1072 | hpet_reenable(); |
1071 | else | 1073 | else |
1072 | i8254_timer_resume(); | 1074 | i8254_timer_resume(); |
@@ -1150,7 +1152,7 @@ static unsigned int hpet_t1_cmp; /* cached comparator register */ | |||
1150 | 1152 | ||
1151 | int is_hpet_enabled(void) | 1153 | int is_hpet_enabled(void) |
1152 | { | 1154 | { |
1153 | return vxtime.hpet_address != 0; | 1155 | return hpet_address != 0; |
1154 | } | 1156 | } |
1155 | 1157 | ||
1156 | /* | 1158 | /* |