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 15555879ce..582896f7d4 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 7a9b182241..97b9e46d19 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 038fe1f47e..3b1c602479 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 | ||
