diff options
-rw-r--r-- | arch/x86/kernel/apic_64.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c index 48206bb8de1f..ce2f8015d5ce 100644 --- a/arch/x86/kernel/apic_64.c +++ b/arch/x86/kernel/apic_64.c | |||
@@ -759,14 +759,14 @@ void __init init_apic_mappings(void) | |||
759 | 759 | ||
760 | #define APIC_DIVISOR 16 | 760 | #define APIC_DIVISOR 16 |
761 | 761 | ||
762 | static void __setup_APIC_LVTT(unsigned int clocks) | 762 | static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) |
763 | { | 763 | { |
764 | unsigned int lvtt_value, tmp_value; | 764 | unsigned int lvtt_value, tmp_value; |
765 | int cpu = smp_processor_id(); | ||
766 | |||
767 | lvtt_value = APIC_LVT_TIMER_PERIODIC | LOCAL_TIMER_VECTOR; | ||
768 | 765 | ||
769 | if (cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) | 766 | lvtt_value = LOCAL_TIMER_VECTOR; |
767 | if (!oneshot) | ||
768 | lvtt_value |= APIC_LVT_TIMER_PERIODIC; | ||
769 | if (!irqen) | ||
770 | lvtt_value |= APIC_LVT_MASKED; | 770 | lvtt_value |= APIC_LVT_MASKED; |
771 | 771 | ||
772 | apic_write(APIC_LVTT, lvtt_value); | 772 | apic_write(APIC_LVTT, lvtt_value); |
@@ -779,12 +779,14 @@ static void __setup_APIC_LVTT(unsigned int clocks) | |||
779 | & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE)) | 779 | & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE)) |
780 | | APIC_TDR_DIV_16); | 780 | | APIC_TDR_DIV_16); |
781 | 781 | ||
782 | apic_write(APIC_TMICT, clocks/APIC_DIVISOR); | 782 | if (!oneshot) |
783 | apic_write(APIC_TMICT, clocks/APIC_DIVISOR); | ||
783 | } | 784 | } |
784 | 785 | ||
785 | static void setup_APIC_timer(unsigned int clocks) | 786 | static void setup_APIC_timer(unsigned int clocks) |
786 | { | 787 | { |
787 | unsigned long flags; | 788 | unsigned long flags; |
789 | int irqen; | ||
788 | 790 | ||
789 | local_irq_save(flags); | 791 | local_irq_save(flags); |
790 | 792 | ||
@@ -805,7 +807,10 @@ static void setup_APIC_timer(unsigned int clocks) | |||
805 | c2 |= inb_p(0x40) << 8; | 807 | c2 |= inb_p(0x40) << 8; |
806 | } while (c2 - c1 < 300); | 808 | } while (c2 - c1 < 300); |
807 | } | 809 | } |
808 | __setup_APIC_LVTT(clocks); | 810 | |
811 | irqen = ! cpu_isset(smp_processor_id(), | ||
812 | timer_interrupt_broadcast_ipi_mask); | ||
813 | __setup_APIC_LVTT(clocks, 0, irqen); | ||
809 | /* Turn off PIT interrupt if we use APIC timer as main timer. | 814 | /* Turn off PIT interrupt if we use APIC timer as main timer. |
810 | Only works with the PM timer right now | 815 | Only works with the PM timer right now |
811 | TBD fix it for HPET too. */ | 816 | TBD fix it for HPET too. */ |
@@ -843,8 +848,10 @@ static int __init calibrate_APIC_clock(void) | |||
843 | * Put whatever arbitrary (but long enough) timeout | 848 | * Put whatever arbitrary (but long enough) timeout |
844 | * value into the APIC clock, we just want to get the | 849 | * value into the APIC clock, we just want to get the |
845 | * counter running for calibration. | 850 | * counter running for calibration. |
851 | * | ||
852 | * No interrupt enable ! | ||
846 | */ | 853 | */ |
847 | __setup_APIC_LVTT(4000000000); | 854 | __setup_APIC_LVTT(4000000000, 0, 0); |
848 | 855 | ||
849 | apic_start = apic_read(APIC_TMCCT); | 856 | apic_start = apic_read(APIC_TMCCT); |
850 | #ifdef CONFIG_X86_PM_TIMER | 857 | #ifdef CONFIG_X86_PM_TIMER |