| .. | .. |
|---|
| 8 | 8 | #include <linux/timex.h> |
|---|
| 9 | 9 | #include <linux/i8253.h> |
|---|
| 10 | 10 | |
|---|
| 11 | +#include <asm/apic.h> |
|---|
| 11 | 12 | #include <asm/hpet.h> |
|---|
| 12 | 13 | #include <asm/time.h> |
|---|
| 13 | 14 | #include <asm/smp.h> |
|---|
| .. | .. |
|---|
| 18 | 19 | */ |
|---|
| 19 | 20 | struct clock_event_device *global_clock_event; |
|---|
| 20 | 21 | |
|---|
| 21 | | -void __init setup_pit_timer(void) |
|---|
| 22 | +/* |
|---|
| 23 | + * Modern chipsets can disable the PIT clock which makes it unusable. It |
|---|
| 24 | + * would be possible to enable the clock but the registers are chipset |
|---|
| 25 | + * specific and not discoverable. Avoid the whack a mole game. |
|---|
| 26 | + * |
|---|
| 27 | + * These platforms have discoverable TSC/CPU frequencies but this also |
|---|
| 28 | + * requires to know the local APIC timer frequency as it normally is |
|---|
| 29 | + * calibrated against the PIT interrupt. |
|---|
| 30 | + */ |
|---|
| 31 | +static bool __init use_pit(void) |
|---|
| 22 | 32 | { |
|---|
| 33 | + if (!IS_ENABLED(CONFIG_X86_TSC) || !boot_cpu_has(X86_FEATURE_TSC)) |
|---|
| 34 | + return true; |
|---|
| 35 | + |
|---|
| 36 | + /* This also returns true when APIC is disabled */ |
|---|
| 37 | + return apic_needs_pit(); |
|---|
| 38 | +} |
|---|
| 39 | + |
|---|
| 40 | +bool __init pit_timer_init(void) |
|---|
| 41 | +{ |
|---|
| 42 | + if (!use_pit()) |
|---|
| 43 | + return false; |
|---|
| 44 | + |
|---|
| 23 | 45 | clockevent_i8253_init(true); |
|---|
| 24 | 46 | global_clock_event = &i8253_clockevent; |
|---|
| 47 | + return true; |
|---|
| 25 | 48 | } |
|---|
| 26 | 49 | |
|---|
| 27 | 50 | #ifndef CONFIG_X86_64 |
|---|