diff options
-rw-r--r-- | arch/x86_64/kernel/smpboot.c | 2 | ||||
-rw-r--r-- | arch/x86_64/kernel/time.c | 47 | ||||
-rw-r--r-- | include/asm-x86_64/proto.h | 1 |
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); | |||
49 | extern void i8254_timer_resume(void); | 51 | extern void i8254_timer_resume(void); |
50 | extern int using_apic_timer; | 52 | extern int using_apic_timer; |
51 | 53 | ||
52 | static char *time_init_gtod(void); | 54 | static char *timename = NULL; |
53 | 55 | ||
54 | DEFINE_SPINLOCK(rtc_lock); | 56 | DEFINE_SPINLOCK(rtc_lock); |
55 | EXPORT_SYMBOL(rtc_lock); | 57 | EXPORT_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 | ||
896 | void __init time_init(void) | 898 | static int __cpuinit |
899 | time_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 | ||
911 | void __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) | 989 | void 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; | |||
51 | extern int sysctl_vsyscall; | 51 | extern int sysctl_vsyscall; |
52 | extern int nohpet; | 52 | extern int nohpet; |
53 | extern unsigned long vxtime_hz; | 53 | extern unsigned long vxtime_hz; |
54 | extern void time_init_gtod(void); | ||
54 | 55 | ||
55 | extern int numa_setup(char *opt); | 56 | extern int numa_setup(char *opt); |
56 | 57 | ||