aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86_64/kernel/smpboot.c2
-rw-r--r--arch/x86_64/kernel/time.c47
-rw-r--r--include/asm-x86_64/proto.h1
3 files changed, 38 insertions, 12 deletions
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 15555879ce95..582896f7d420 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -1181,6 +1181,8 @@ void __init smp_cpus_done(unsigned int max_cpus)
1181#endif 1181#endif
1182 1182
1183 check_nmi_watchdog(); 1183 check_nmi_watchdog();
1184
1185 time_init_gtod();
1184} 1186}
1185 1187
1186#ifdef CONFIG_HOTPLUG_CPU 1188#ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 7a9b18224182..97b9e46d1992 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -24,6 +24,8 @@
24#include <linux/device.h> 24#include <linux/device.h>
25#include <linux/sysdev.h> 25#include <linux/sysdev.h>
26#include <linux/bcd.h> 26#include <linux/bcd.h>
27#include <linux/notifier.h>
28#include <linux/cpu.h>
27#include <linux/kallsyms.h> 29#include <linux/kallsyms.h>
28#include <linux/acpi.h> 30#include <linux/acpi.h>
29#ifdef CONFIG_ACPI 31#ifdef CONFIG_ACPI
@@ -49,7 +51,7 @@ static void cpufreq_delayed_get(void);
49extern void i8254_timer_resume(void); 51extern void i8254_timer_resume(void);
50extern int using_apic_timer; 52extern int using_apic_timer;
51 53
52static char *time_init_gtod(void); 54static char *timename = NULL;
53 55
54DEFINE_SPINLOCK(rtc_lock); 56DEFINE_SPINLOCK(rtc_lock);
55EXPORT_SYMBOL(rtc_lock); 57EXPORT_SYMBOL(rtc_lock);
@@ -893,11 +895,21 @@ static struct irqaction irq0 = {
893 timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL 895 timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL
894}; 896};
895 897
896void __init time_init(void) 898static int __cpuinit
899time_cpu_notifier(struct notifier_block *nb, unsigned long action, void *hcpu)
897{ 900{
898 char *timename; 901 unsigned cpu = (unsigned long) hcpu;
899 char *gtod; 902 if (action == CPU_ONLINE &&
903 cpu_has(&cpu_data[cpu], X86_FEATURE_RDTSCP)) {
904 unsigned p;
905 p = smp_processor_id() | (cpu_to_node(smp_processor_id())<<12);
906 write_rdtscp_aux(p);
907 }
908 return NOTIFY_DONE;
909}
900 910
911void __init time_init(void)
912{
901 if (nohpet) 913 if (nohpet)
902 vxtime.hpet_address = 0; 914 vxtime.hpet_address = 0;
903 915
@@ -931,18 +943,19 @@ void __init time_init(void)
931 } 943 }
932 944
933 vxtime.mode = VXTIME_TSC; 945 vxtime.mode = VXTIME_TSC;
934 gtod = time_init_gtod();
935
936 printk(KERN_INFO "time.c: Using %ld.%06ld MHz WALL %s GTOD %s timer.\n",
937 vxtime_hz / 1000000, vxtime_hz % 1000000, timename, gtod);
938 printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n",
939 cpu_khz / 1000, cpu_khz % 1000);
940 vxtime.quot = (USEC_PER_SEC << US_SCALE) / vxtime_hz; 946 vxtime.quot = (USEC_PER_SEC << US_SCALE) / vxtime_hz;
941 vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz; 947 vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz;
942 vxtime.last_tsc = get_cycles_sync(); 948 vxtime.last_tsc = get_cycles_sync();
943 setup_irq(0, &irq0); 949 setup_irq(0, &irq0);
944 950
945 set_cyc2ns_scale(cpu_khz); 951 set_cyc2ns_scale(cpu_khz);
952
953 hotcpu_notifier(time_cpu_notifier, 0);
954 time_cpu_notifier(NULL, CPU_ONLINE, (void *)(long)smp_processor_id());
955
956#ifndef CONFIG_SMP
957 time_init_gtod();
958#endif
946} 959}
947 960
948/* 961/*
@@ -973,12 +986,13 @@ __cpuinit int unsynchronized_tsc(void)
973/* 986/*
974 * Decide what mode gettimeofday should use. 987 * Decide what mode gettimeofday should use.
975 */ 988 */
976__init static char *time_init_gtod(void) 989void time_init_gtod(void)
977{ 990{
978 char *timetype; 991 char *timetype;
979 992
980 if (unsynchronized_tsc()) 993 if (unsynchronized_tsc())
981 notsc = 1; 994 notsc = 1;
995
982 if (vxtime.hpet_address && notsc) { 996 if (vxtime.hpet_address && notsc) {
983 timetype = hpet_use_timer ? "HPET" : "PIT/HPET"; 997 timetype = hpet_use_timer ? "HPET" : "PIT/HPET";
984 if (hpet_use_timer) 998 if (hpet_use_timer)
@@ -1001,7 +1015,16 @@ __init static char *time_init_gtod(void)
1001 timetype = hpet_use_timer ? "HPET/TSC" : "PIT/TSC"; 1015 timetype = hpet_use_timer ? "HPET/TSC" : "PIT/TSC";
1002 vxtime.mode = VXTIME_TSC; 1016 vxtime.mode = VXTIME_TSC;
1003 } 1017 }
1004 return timetype; 1018
1019 printk(KERN_INFO "time.c: Using %ld.%06ld MHz WALL %s GTOD %s timer.\n",
1020 vxtime_hz / 1000000, vxtime_hz % 1000000, timename, timetype);
1021 printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n",
1022 cpu_khz / 1000, cpu_khz % 1000);
1023 vxtime.quot = (USEC_PER_SEC << US_SCALE) / vxtime_hz;
1024 vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz;
1025 vxtime.last_tsc = get_cycles_sync();
1026
1027 set_cyc2ns_scale(cpu_khz);
1005} 1028}
1006 1029
1007__setup("report_lost_ticks", time_setup); 1030__setup("report_lost_ticks", time_setup);
diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h
index 038fe1f47e6f..3b1c60247902 100644
--- a/include/asm-x86_64/proto.h
+++ b/include/asm-x86_64/proto.h
@@ -51,6 +51,7 @@ extern unsigned long long monotonic_base;
51extern int sysctl_vsyscall; 51extern int sysctl_vsyscall;
52extern int nohpet; 52extern int nohpet;
53extern unsigned long vxtime_hz; 53extern unsigned long vxtime_hz;
54extern void time_init_gtod(void);
54 55
55extern int numa_setup(char *opt); 56extern int numa_setup(char *opt);
56 57