diff options
Diffstat (limited to 'arch/x86/kernel/apic/apic.c')
-rw-r--r-- | arch/x86/kernel/apic/apic.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 20abd912f0e4..50c95af0f017 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -313,7 +313,7 @@ int lapic_get_maxlvt(void) | |||
313 | 313 | ||
314 | /* Clock divisor */ | 314 | /* Clock divisor */ |
315 | #define APIC_DIVISOR 16 | 315 | #define APIC_DIVISOR 16 |
316 | #define TSC_DIVISOR 32 | 316 | #define TSC_DIVISOR 8 |
317 | 317 | ||
318 | /* | 318 | /* |
319 | * This function sets up the local APIC timer, with a timeout of | 319 | * This function sets up the local APIC timer, with a timeout of |
@@ -565,13 +565,37 @@ static void setup_APIC_timer(void) | |||
565 | CLOCK_EVT_FEAT_DUMMY); | 565 | CLOCK_EVT_FEAT_DUMMY); |
566 | levt->set_next_event = lapic_next_deadline; | 566 | levt->set_next_event = lapic_next_deadline; |
567 | clockevents_config_and_register(levt, | 567 | clockevents_config_and_register(levt, |
568 | (tsc_khz / TSC_DIVISOR) * 1000, | 568 | tsc_khz * (1000 / TSC_DIVISOR), |
569 | 0xF, ~0UL); | 569 | 0xF, ~0UL); |
570 | } else | 570 | } else |
571 | clockevents_register_device(levt); | 571 | clockevents_register_device(levt); |
572 | } | 572 | } |
573 | 573 | ||
574 | /* | 574 | /* |
575 | * Install the updated TSC frequency from recalibration at the TSC | ||
576 | * deadline clockevent devices. | ||
577 | */ | ||
578 | static void __lapic_update_tsc_freq(void *info) | ||
579 | { | ||
580 | struct clock_event_device *levt = this_cpu_ptr(&lapic_events); | ||
581 | |||
582 | if (!this_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) | ||
583 | return; | ||
584 | |||
585 | clockevents_update_freq(levt, tsc_khz * (1000 / TSC_DIVISOR)); | ||
586 | } | ||
587 | |||
588 | void lapic_update_tsc_freq(void) | ||
589 | { | ||
590 | /* | ||
591 | * The clockevent device's ->mult and ->shift can both be | ||
592 | * changed. In order to avoid races, schedule the frequency | ||
593 | * update code on each CPU. | ||
594 | */ | ||
595 | on_each_cpu(__lapic_update_tsc_freq, NULL, 0); | ||
596 | } | ||
597 | |||
598 | /* | ||
575 | * In this functions we calibrate APIC bus clocks to the external timer. | 599 | * In this functions we calibrate APIC bus clocks to the external timer. |
576 | * | 600 | * |
577 | * We want to do the calibration only once since we want to have local timer | 601 | * We want to do the calibration only once since we want to have local timer |
@@ -1599,6 +1623,9 @@ void __init enable_IR_x2apic(void) | |||
1599 | unsigned long flags; | 1623 | unsigned long flags; |
1600 | int ret, ir_stat; | 1624 | int ret, ir_stat; |
1601 | 1625 | ||
1626 | if (skip_ioapic_setup) | ||
1627 | return; | ||
1628 | |||
1602 | ir_stat = irq_remapping_prepare(); | 1629 | ir_stat = irq_remapping_prepare(); |
1603 | if (ir_stat < 0 && !x2apic_supported()) | 1630 | if (ir_stat < 0 && !x2apic_supported()) |
1604 | return; | 1631 | return; |