diff options
Diffstat (limited to 'arch/x86_64/kernel/apic.c')
-rw-r--r-- | arch/x86_64/kernel/apic.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c index bd3e45d47c37..d198f7d82e5a 100644 --- a/arch/x86_64/kernel/apic.c +++ b/arch/x86_64/kernel/apic.c | |||
@@ -68,6 +68,28 @@ int using_apic_timer __read_mostly = 0; | |||
68 | 68 | ||
69 | static void apic_pm_activate(void); | 69 | static void apic_pm_activate(void); |
70 | 70 | ||
71 | void apic_wait_icr_idle(void) | ||
72 | { | ||
73 | while (apic_read(APIC_ICR) & APIC_ICR_BUSY) | ||
74 | cpu_relax(); | ||
75 | } | ||
76 | |||
77 | unsigned int safe_apic_wait_icr_idle(void) | ||
78 | { | ||
79 | unsigned int send_status; | ||
80 | int timeout; | ||
81 | |||
82 | timeout = 0; | ||
83 | do { | ||
84 | send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; | ||
85 | if (!send_status) | ||
86 | break; | ||
87 | udelay(100); | ||
88 | } while (timeout++ < 1000); | ||
89 | |||
90 | return send_status; | ||
91 | } | ||
92 | |||
71 | void enable_NMI_through_LVT0 (void * dummy) | 93 | void enable_NMI_through_LVT0 (void * dummy) |
72 | { | 94 | { |
73 | unsigned int v; | 95 | unsigned int v; |
@@ -817,14 +839,15 @@ static void setup_APIC_timer(unsigned int clocks) | |||
817 | 839 | ||
818 | static int __init calibrate_APIC_clock(void) | 840 | static int __init calibrate_APIC_clock(void) |
819 | { | 841 | { |
820 | int apic, apic_start, tsc, tsc_start; | 842 | unsigned apic, apic_start; |
843 | unsigned long tsc, tsc_start; | ||
821 | int result; | 844 | int result; |
822 | /* | 845 | /* |
823 | * Put whatever arbitrary (but long enough) timeout | 846 | * Put whatever arbitrary (but long enough) timeout |
824 | * value into the APIC clock, we just want to get the | 847 | * value into the APIC clock, we just want to get the |
825 | * counter running for calibration. | 848 | * counter running for calibration. |
826 | */ | 849 | */ |
827 | __setup_APIC_LVTT(1000000000); | 850 | __setup_APIC_LVTT(4000000000); |
828 | 851 | ||
829 | apic_start = apic_read(APIC_TMCCT); | 852 | apic_start = apic_read(APIC_TMCCT); |
830 | #ifdef CONFIG_X86_PM_TIMER | 853 | #ifdef CONFIG_X86_PM_TIMER |
@@ -835,15 +858,15 @@ static int __init calibrate_APIC_clock(void) | |||
835 | } else | 858 | } else |
836 | #endif | 859 | #endif |
837 | { | 860 | { |
838 | rdtscl(tsc_start); | 861 | rdtscll(tsc_start); |
839 | 862 | ||
840 | do { | 863 | do { |
841 | apic = apic_read(APIC_TMCCT); | 864 | apic = apic_read(APIC_TMCCT); |
842 | rdtscl(tsc); | 865 | rdtscll(tsc); |
843 | } while ((tsc - tsc_start) < TICK_COUNT && | 866 | } while ((tsc - tsc_start) < TICK_COUNT && |
844 | (apic - apic_start) < TICK_COUNT); | 867 | (apic_start - apic) < TICK_COUNT); |
845 | 868 | ||
846 | result = (apic_start - apic) * 1000L * cpu_khz / | 869 | result = (apic_start - apic) * 1000L * tsc_khz / |
847 | (tsc - tsc_start); | 870 | (tsc - tsc_start); |
848 | } | 871 | } |
849 | printk("result %d\n", result); | 872 | printk("result %d\n", result); |