aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/time.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/kernel/time.c')
-rw-r--r--arch/x86_64/kernel/time.c36
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
68unsigned int cpu_khz; /* TSC clocks / usec, not used here */ 68unsigned int cpu_khz; /* TSC clocks / usec, not used here */
69EXPORT_SYMBOL(cpu_khz); 69EXPORT_SYMBOL(cpu_khz);
70unsigned long hpet_address;
70static unsigned long hpet_period; /* fsecs / HPET clock */ 71static unsigned long hpet_period; /* fsecs / HPET clock */
71unsigned long hpet_tick; /* HPET clocks / interrupt */ 72unsigned long hpet_tick; /* HPET clocks / interrupt */
72int hpet_use_timer; /* Use counter of hpet for time keeping, otherwise PIT */ 73int 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)
878void __init stop_timer_interrupt(void) 880void __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 = {
901void __init time_init(void) 903void __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
1151int is_hpet_enabled(void) 1153int is_hpet_enabled(void)
1152{ 1154{
1153 return vxtime.hpet_address != 0; 1155 return hpet_address != 0;
1154} 1156}
1155 1157
1156/* 1158/*