1 // SPDX-License-Identifier: GPL-2.0 1 // SPDX-License-Identifier: GPL-2.0 2 /* 2 /* 3 * 8253/PIT functions !! 3 * i8253.c 8253/PIT functions 4 * 4 * 5 */ 5 */ 6 #include <linux/clockchips.h> 6 #include <linux/clockchips.h> 7 #include <linux/init.h> << 8 #include <linux/timex.h> << 9 #include <linux/i8253.h> 7 #include <linux/i8253.h> >> 8 #include <linux/export.h> >> 9 #include <linux/smp.h> >> 10 #include <linux/irq.h> 10 11 11 #include <asm/hypervisor.h> << 12 #include <asm/apic.h> << 13 #include <asm/hpet.h> << 14 #include <asm/time.h> 12 #include <asm/time.h> 15 #include <asm/smp.h> << 16 13 17 /* !! 14 static irqreturn_t timer_interrupt(int irq, void *dev_id) 18 * HPET replaces the PIT, when enabled. So we << 19 * the two timers is used << 20 */ << 21 struct clock_event_device *global_clock_event; << 22 << 23 /* << 24 * Modern chipsets can disable the PIT clock w << 25 * would be possible to enable the clock but t << 26 * specific and not discoverable. Avoid the wh << 27 * << 28 * These platforms have discoverable TSC/CPU f << 29 * requires to know the local APIC timer frequ << 30 * calibrated against the PIT interrupt. << 31 */ << 32 static bool __init use_pit(void) << 33 { 15 { 34 if (!IS_ENABLED(CONFIG_X86_TSC) || !bo !! 16 i8253_clockevent.event_handler(&i8253_clockevent); 35 return true; << 36 17 37 /* This also returns true when APIC is !! 18 return IRQ_HANDLED; 38 return apic_needs_pit(); << 39 } 19 } 40 20 41 bool __init pit_timer_init(void) !! 21 void __init setup_pit_timer(void) 42 { 22 { 43 if (!use_pit()) { !! 23 unsigned long flags = IRQF_NOBALANCING | IRQF_TIMER; 44 /* !! 24 45 * Don't just ignore the PIT. << 46 * VMMs otherwise steal CPU ti << 47 * the (masked) IRQ. << 48 */ << 49 clockevent_i8253_disable(); << 50 return false; << 51 } << 52 clockevent_i8253_init(true); 25 clockevent_i8253_init(true); 53 global_clock_event = &i8253_clockevent !! 26 if (request_irq(0, timer_interrupt, flags, "timer", NULL)) 54 return true; !! 27 pr_err("Failed to request irq 0 (timer)\n"); 55 } 28 } 56 29 57 #ifndef CONFIG_X86_64 << 58 static int __init init_pit_clocksource(void) 30 static int __init init_pit_clocksource(void) 59 { 31 { 60 /* !! 32 if (num_possible_cpus() > 1 || /* PIT does not scale! */ 61 * Several reasons not to register PI << 62 * << 63 * - On SMP PIT does not scale due to << 64 * - when HPET is enabled << 65 * - when local APIC timer is active << 66 */ << 67 if (num_possible_cpus() > 1 || is_hpet << 68 !clockevent_state_periodic(&i8253_ 33 !clockevent_state_periodic(&i8253_clockevent)) 69 return 0; 34 return 0; 70 35 71 return clocksource_i8253_init(); 36 return clocksource_i8253_init(); 72 } 37 } 73 arch_initcall(init_pit_clocksource); 38 arch_initcall(init_pit_clocksource); 74 #endif /* !CONFIG_X86_64 */ << 75 39
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.