147926214SThomas Gleixner /* 247926214SThomas Gleixner * Copyright (c) 1991,1992,1995 Linus Torvalds 347926214SThomas Gleixner * Copyright (c) 1994 Alan Modra 447926214SThomas Gleixner * Copyright (c) 1995 Markus Kuhn 547926214SThomas Gleixner * Copyright (c) 1996 Ingo Molnar 647926214SThomas Gleixner * Copyright (c) 1998 Andrea Arcangeli 747926214SThomas Gleixner * Copyright (c) 2002,2006 Vojtech Pavlik 847926214SThomas Gleixner * Copyright (c) 2003 Andi Kleen 947926214SThomas Gleixner * 1047926214SThomas Gleixner */ 1147926214SThomas Gleixner 1247926214SThomas Gleixner #include <linux/clockchips.h> 1347926214SThomas Gleixner #include <linux/interrupt.h> 1447926214SThomas Gleixner #include <linux/time.h> 1547926214SThomas Gleixner #include <linux/mca.h> 1647926214SThomas Gleixner 1747926214SThomas Gleixner #include <asm/vsyscall.h> 1847926214SThomas Gleixner #include <asm/x86_init.h> 1947926214SThomas Gleixner #include <asm/i8259.h> 2047926214SThomas Gleixner #include <asm/i8253.h> 2147926214SThomas Gleixner #include <asm/timer.h> 2247926214SThomas Gleixner #include <asm/hpet.h> 2347926214SThomas Gleixner #include <asm/time.h> 2447926214SThomas Gleixner 2547926214SThomas Gleixner #if defined(CONFIG_X86_32) && defined(CONFIG_X86_IO_APIC) 2647926214SThomas Gleixner int timer_ack; 2747926214SThomas Gleixner #endif 2847926214SThomas Gleixner 2947926214SThomas Gleixner #ifdef CONFIG_X86_64 3047926214SThomas Gleixner volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES; 3147926214SThomas Gleixner #endif 3247926214SThomas Gleixner 3347926214SThomas Gleixner unsigned long profile_pc(struct pt_regs *regs) 3447926214SThomas Gleixner { 3547926214SThomas Gleixner unsigned long pc = instruction_pointer(regs); 3647926214SThomas Gleixner 3747926214SThomas Gleixner if (!user_mode_vm(regs) && in_lock_functions(pc)) { 3847926214SThomas Gleixner #ifdef CONFIG_FRAME_POINTER 3947926214SThomas Gleixner return *(unsigned long *)(regs->bp + sizeof(long)); 4047926214SThomas Gleixner #else 4147926214SThomas Gleixner unsigned long *sp = (unsigned long *)regs->sp; 4247926214SThomas Gleixner /* 4347926214SThomas Gleixner * Return address is either directly at stack pointer 4447926214SThomas Gleixner * or above a saved flags. Eflags has bits 22-31 zero, 4547926214SThomas Gleixner * kernel addresses don't. 4647926214SThomas Gleixner */ 4747926214SThomas Gleixner if (sp[0] >> 22) 4847926214SThomas Gleixner return sp[0]; 4947926214SThomas Gleixner if (sp[1] >> 22) 5047926214SThomas Gleixner return sp[1]; 5147926214SThomas Gleixner #endif 5247926214SThomas Gleixner } 5347926214SThomas Gleixner return pc; 5447926214SThomas Gleixner } 5547926214SThomas Gleixner EXPORT_SYMBOL(profile_pc); 5647926214SThomas Gleixner 5747926214SThomas Gleixner /* 5847926214SThomas Gleixner * Default timer interrupt handler for PIT/HPET 5947926214SThomas Gleixner */ 6047926214SThomas Gleixner static irqreturn_t timer_interrupt(int irq, void *dev_id) 6147926214SThomas Gleixner { 6247926214SThomas Gleixner /* Keep nmi watchdog up to date */ 6347926214SThomas Gleixner inc_irq_stat(irq0_irqs); 6447926214SThomas Gleixner 6547926214SThomas Gleixner /* Optimized out for !IO_APIC and x86_64 */ 6647926214SThomas Gleixner if (timer_ack) { 6747926214SThomas Gleixner /* 6847926214SThomas Gleixner * Subtle, when I/O APICs are used we have to ack timer IRQ 6947926214SThomas Gleixner * manually to deassert NMI lines for the watchdog if run 7047926214SThomas Gleixner * on an 82489DX-based system. 7147926214SThomas Gleixner */ 7247926214SThomas Gleixner spin_lock(&i8259A_lock); 7347926214SThomas Gleixner outb(0x0c, PIC_MASTER_OCW3); 7447926214SThomas Gleixner /* Ack the IRQ; AEOI will end it automatically. */ 7547926214SThomas Gleixner inb(PIC_MASTER_POLL); 7647926214SThomas Gleixner spin_unlock(&i8259A_lock); 7747926214SThomas Gleixner } 7847926214SThomas Gleixner 7947926214SThomas Gleixner global_clock_event->event_handler(global_clock_event); 8047926214SThomas Gleixner 8147926214SThomas Gleixner /* MCA bus quirk: Acknowledge irq0 by setting bit 7 in port 0x61 */ 8247926214SThomas Gleixner if (MCA_bus) 8347926214SThomas Gleixner outb_p(inb_p(0x61)| 0x80, 0x61); 8447926214SThomas Gleixner 8547926214SThomas Gleixner return IRQ_HANDLED; 8647926214SThomas Gleixner } 8747926214SThomas Gleixner 8847926214SThomas Gleixner static struct irqaction irq0 = { 8947926214SThomas Gleixner .handler = timer_interrupt, 9047926214SThomas Gleixner .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER, 9147926214SThomas Gleixner .name = "timer" 9247926214SThomas Gleixner }; 9347926214SThomas Gleixner 9447926214SThomas Gleixner void __init setup_default_timer_irq(void) 9547926214SThomas Gleixner { 9647926214SThomas Gleixner irq0.mask = cpumask_of_cpu(0); 9747926214SThomas Gleixner setup_irq(0, &irq0); 9847926214SThomas Gleixner } 9947926214SThomas Gleixner 10047926214SThomas Gleixner /* Default timer init function */ 10147926214SThomas Gleixner void __init hpet_time_init(void) 10247926214SThomas Gleixner { 10347926214SThomas Gleixner if (!hpet_enable()) 10447926214SThomas Gleixner setup_pit_timer(); 10547926214SThomas Gleixner setup_default_timer_irq(); 10647926214SThomas Gleixner } 10747926214SThomas Gleixner 10847926214SThomas Gleixner static void x86_late_time_init(void) 10947926214SThomas Gleixner { 11047926214SThomas Gleixner x86_init.timers.timer_init(); 111dd0a70c8SThomas Gleixner tsc_init(); 11247926214SThomas Gleixner } 11347926214SThomas Gleixner 11447926214SThomas Gleixner /* 11547926214SThomas Gleixner * Initialize TSC and delay the periodic timer init to 11647926214SThomas Gleixner * late x86_late_time_init() so ioremap works. 11747926214SThomas Gleixner */ 11847926214SThomas Gleixner void __init time_init(void) 11947926214SThomas Gleixner { 12047926214SThomas Gleixner late_time_init = x86_late_time_init; 12147926214SThomas Gleixner } 122