summaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/time.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2019-06-28 15:23:07 +0800
committerThomas Gleixner <tglx@linutronix.de>2019-06-29 11:35:35 +0200
commitc8c4076723daca08bf35ccd68f22ea1c6219e207 (patch)
treeabfdc9f6fc6a02b11f11c85454aaa32d7ff5d977 /arch/x86/kernel/time.c
parentdde3626f815e38bbf96fddd5185038c4b4d395a8 (diff)
downloadlinux-c8c4076723daca08bf35ccd68f22ea1c6219e207.tar.gz
linux-c8c4076723daca08bf35ccd68f22ea1c6219e207.tar.bz2
linux-c8c4076723daca08bf35ccd68f22ea1c6219e207.zip
x86/timer: Skip PIT initialization on modern chipsets
Recent Intel chipsets including Skylake and ApolloLake have a special ITSSPRC register which allows the 8254 PIT to be gated. When gated, the 8254 registers can still be programmed as normal, but there are no IRQ0 timer interrupts. Some products such as the Connex L1430 and exone go Rugged E11 use this register to ship with the PIT gated by default. This causes Linux to fail to boot: Kernel panic - not syncing: IO-APIC + timer doesn't work! Boot with apic=debug and send a report. The panic happens before the framebuffer is initialized, so to the user, it appears as an early boot hang on a black screen. Affected products typically have a BIOS option that can be used to enable the 8254 and make Linux work (Chipset -> South Cluster Configuration -> Miscellaneous Configuration -> 8254 Clock Gating), however it would be best to make Linux support the no-8254 case. Modern sytems allow to discover the TSC and local APIC timer frequencies, so the calibration against the PIT is not required. These systems have always running timers and the local APIC timer works also in deep power states. So the setup of the PIT including the IO-APIC timer interrupt delivery checks are a pointless exercise. Skip the PIT setup and the IO-APIC timer interrupt checks on these systems, which avoids the panic caused by non ticking PITs and also speeds up the boot process. Thanks to Daniel for providing the changelog, initial analysis of the problem and testing against a variety of machines. Reported-by: Daniel Drake <drake@endlessm.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Tested-by: Daniel Drake <drake@endlessm.com> Cc: bp@alien8.de Cc: hpa@zytor.com Cc: linux@endlessm.com Cc: rafael.j.wysocki@intel.com Cc: hdegoede@redhat.com Link: https://lkml.kernel.org/r/20190628072307.24678-1-drake@endlessm.com
Diffstat (limited to 'arch/x86/kernel/time.c')
-rw-r--r--arch/x86/kernel/time.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/arch/x86/kernel/time.c b/arch/x86/kernel/time.c
index 0e14f6c0d35e..07c0e960b3f3 100644
--- a/arch/x86/kernel/time.c
+++ b/arch/x86/kernel/time.c
@@ -82,8 +82,11 @@ static void __init setup_default_timer_irq(void)
/* Default timer init function */
void __init hpet_time_init(void)
{
- if (!hpet_enable())
- setup_pit_timer();
+ if (!hpet_enable()) {
+ if (!pit_timer_init())
+ return;
+ }
+
setup_default_timer_irq();
}