.. | .. |
---|
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 |
---|