#ifndef ASM_X86__HYPERVISOR_H
 #define ASM_X86__HYPERVISOR_H
 
-extern unsigned long get_hypervisor_tsc_freq(void);
 extern void init_hypervisor(struct cpuinfo_x86 *c);
+extern void init_hypervisor_platform(void);
 
 #endif
 
 {
        return PVOP_CALL0(unsigned long long, pv_time_ops.sched_clock);
 }
-#define calibrate_tsc() (pv_time_ops.get_tsc_khz())
 
 static inline unsigned long long paravirt_read_pmc(int counter)
 {
 
 #define TICK_SIZE (tick_nsec / 1000)
 
 unsigned long long native_sched_clock(void);
-unsigned long native_calibrate_tsc(void);
 extern int recalibrate_cpu_khz(void);
 
 #if defined(CONFIG_X86_32) && defined(CONFIG_X86_IO_APIC)
 
 extern int no_timer_check;
 
-#ifndef CONFIG_PARAVIRT
-#define calibrate_tsc() native_calibrate_tsc()
-#endif
-
 /* Accelerators for sched_clock()
  * convert from cycles(64bits) => nanoseconds (64bits)
  *  basic equation:
 
 extern void tsc_init(void);
 extern void mark_tsc_unstable(char *reason);
 extern int unsynchronized_tsc(void);
-int check_tsc_unstable(void);
+extern int check_tsc_unstable(void);
+extern unsigned long native_calibrate_tsc(void);
 
 /*
  * Boot-time check whether the TSCs are synchronized across
 
 #ifndef ASM_X86__VMWARE_H
 #define ASM_X86__VMWARE_H
 
-extern unsigned long vmware_get_tsc_khz(void);
+extern void vmware_platform_setup(void);
 extern int vmware_platform(void);
 extern void vmware_set_feature_bits(struct cpuinfo_x86 *c);
 
 
        void (*setup_percpu_clockev)(void);
 };
 
+/**
+ * struct x86_platform_ops - platform specific runtime functions
+ * @calibrate_tsc:             calibrate TSC
+ */
+struct x86_platform_ops {
+       unsigned long (*calibrate_tsc)(void);
+};
+
 extern struct x86_init_ops x86_init;
 extern struct x86_cpuinit_ops x86_cpuinit;
+extern struct x86_platform_ops x86_platform;
 
 extern void x86_init_noop(void);
 extern void x86_init_uint_noop(unsigned int unused);
 
                c->x86_hyper_vendor = X86_HYPER_VENDOR_NONE;
 }
 
-unsigned long get_hypervisor_tsc_freq(void)
-{
-       if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE)
-               return vmware_get_tsc_khz();
-       return 0;
-}
-
 static inline void __cpuinit
 hypervisor_set_feature_bits(struct cpuinfo_x86 *c)
 {
        detect_hypervisor_vendor(c);
        hypervisor_set_feature_bits(c);
 }
+
+void __init init_hypervisor_platform(void)
+{
+       init_hypervisor(&boot_cpu_data);
+       if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE)
+               vmware_platform_setup();
+}
 
 #include <linux/dmi.h>
 #include <asm/div64.h>
 #include <asm/vmware.h>
+#include <asm/x86_init.h>
 
 #define CPUID_VMWARE_INFO_LEAF 0x40000000
 #define VMWARE_HYPERVISOR_MAGIC        0x564D5868
        return eax != (uint32_t)-1 && ebx == VMWARE_HYPERVISOR_MAGIC;
 }
 
-static unsigned long __vmware_get_tsc_khz(void)
+static unsigned long vmware_get_tsc_khz(void)
 {
        uint64_t tsc_hz;
        uint32_t eax, ebx, ecx, edx;
 
        VMWARE_PORT(GETHZ, eax, ebx, ecx, edx);
 
-       if (ebx == UINT_MAX)
-               return 0;
        tsc_hz = eax | (((uint64_t)ebx) << 32);
        do_div(tsc_hz, 1000);
        BUG_ON(tsc_hz >> 32);
        return tsc_hz;
 }
 
+void __init vmware_platform_setup(void)
+{
+       uint32_t eax, ebx, ecx, edx;
+
+       VMWARE_PORT(GETHZ, eax, ebx, ecx, edx);
+
+       if (ebx != UINT_MAX)
+               x86_platform.calibrate_tsc = vmware_get_tsc_khz;
+}
+
 /*
  * While checking the dmi string infomation, just checking the product
  * serial key should be enough, as this will always have a VMware
        return 0;
 }
 
-unsigned long vmware_get_tsc_khz(void)
-{
-       BUG_ON(!vmware_platform());
-       return __vmware_get_tsc_khz();
-}
-
 /*
  * VMware hypervisor takes care of exporting a reliable TSC to the guest.
  * Still, due to timing difference when running on virtual cpus, the TSC can
 
                pv_time_ops.get_wallclock = kvm_get_wallclock;
                pv_time_ops.set_wallclock = kvm_set_wallclock;
                pv_time_ops.sched_clock = kvm_clock_read;
-               pv_time_ops.get_tsc_khz = kvm_get_tsc_khz;
+               x86_platform.calibrate_tsc = kvm_get_tsc_khz;
 #ifdef CONFIG_X86_LOCAL_APIC
                x86_cpuinit.setup_percpu_clockev =
                        kvm_setup_secondary_clock;
 
        .get_wallclock = native_get_wallclock,
        .set_wallclock = native_set_wallclock,
        .sched_clock = native_sched_clock,
-       .get_tsc_khz = native_calibrate_tsc,
 };
 
 struct pv_irq_ops pv_irq_ops = {
 
         * VMware detection requires dmi to be available, so this
         * needs to be done after dmi_scan_machine, for the BP.
         */
-       init_hypervisor(&boot_cpu_data);
+       init_hypervisor_platform();
 
        x86_init.resources.probe_roms();
 
 
 #include <asm/delay.h>
 #include <asm/hypervisor.h>
 #include <asm/nmi.h>
+#include <asm/x86_init.h>
 
 unsigned int __read_mostly cpu_khz;    /* TSC clocks / usec, not used here */
 EXPORT_SYMBOL(cpu_khz);
 {
        u64 tsc1, tsc2, delta, ref1, ref2;
        unsigned long tsc_pit_min = ULONG_MAX, tsc_ref_min = ULONG_MAX;
-       unsigned long flags, latch, ms, fast_calibrate, hv_tsc_khz;
+       unsigned long flags, latch, ms, fast_calibrate;
        int hpet = is_hpet_enabled(), i, loopmin;
 
-       hv_tsc_khz = get_hypervisor_tsc_freq();
-       if (hv_tsc_khz) {
-               printk(KERN_INFO "TSC: Frequency read from the hypervisor\n");
-               return hv_tsc_khz;
-       }
-
        local_irq_save(flags);
        fast_calibrate = quick_pit_calibrate();
        local_irq_restore(flags);
        unsigned long cpu_khz_old = cpu_khz;
 
        if (cpu_has_tsc) {
-               tsc_khz = calibrate_tsc();
+               tsc_khz = x86_platform.calibrate_tsc();
                cpu_khz = tsc_khz;
                cpu_data(0).loops_per_jiffy =
                        cpufreq_scale(cpu_data(0).loops_per_jiffy,
        if (!cpu_has_tsc)
                return;
 
-       tsc_khz = calibrate_tsc();
+       tsc_khz = x86_platform.calibrate_tsc();
        cpu_khz = tsc_khz;
 
        if (!tsc_khz) {
 
                x86_cpuinit.setup_percpu_clockev = vmi_time_ap_init;
 #endif
                pv_time_ops.sched_clock = vmi_sched_clock;
-               pv_time_ops.get_tsc_khz = vmi_tsc_khz;
+               x86_platform.calibrate_tsc = vmi_tsc_khz;
 
                /* We have true wallclock functions; disable CMOS clock sync */
                no_sync_cmos_clock = 1;
 
        return cycles_2_ns(vmi_timer_ops.get_cycle_counter(VMI_CYCLES_AVAILABLE));
 }
 
-/* paravirt_ops.get_tsc_khz = vmi_tsc_khz */
+/* x86_platform.calibrate_tsc = vmi_tsc_khz */
 unsigned long vmi_tsc_khz(void)
 {
        unsigned long long khz;
 
 #include <asm/e820.h>
 #include <asm/time.h>
 #include <asm/irq.h>
+#include <asm/tsc.h>
 
 void __cpuinit x86_init_noop(void) { }
 void __init x86_init_uint_noop(unsigned int unused) { }
 __cpuinitdata struct x86_cpuinit_ops x86_cpuinit = {
        .setup_percpu_clockev           = setup_secondary_APIC_clock,
 };
+
+struct x86_platform_ops x86_platform = {
+       .calibrate_tsc                  = native_calibrate_tsc,
+};
 
 
        /* Time operations */
        pv_time_ops.get_wallclock = lguest_get_wallclock;
-       pv_time_ops.get_tsc_khz = lguest_tsc_khz;
 
        x86_init.resources.memory_setup = lguest_memory_setup;
        x86_init.irqs.intr_init = lguest_init_IRQ;
        x86_init.timers.timer_init = lguest_time_init;
+       x86_platform.calibrate_tsc = lguest_tsc_khz;
 
        /*
         * Now is a good time to look at the implementations of these functions
 
 static const struct pv_time_ops xen_time_ops __initdata = {
        .set_wallclock = xen_set_wallclock,
        .get_wallclock = xen_get_wallclock,
-       .get_tsc_khz = xen_tsc_khz,
        .sched_clock = xen_sched_clock,
 };
 
        x86_init.timers.setup_percpu_clockev = x86_init_noop;
        x86_cpuinit.setup_percpu_clockev = x86_init_noop;
 
+       x86_platform.calibrate_tsc = xen_tsc_khz;
+
 #ifdef CONFIG_X86_64
        /*
         * Setup percpu state.  We only need to do this for 64-bit