1 /* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Code to handle x86 style IRQs plus some generic interrupt stuff. 7 * 8 * Copyright (C) 1992 Linus Torvalds 9 * Copyright (C) 1994 - 2000 Ralf Baechle 10 */ 11 #include <linux/kernel.h> 12 #include <linux/delay.h> 13 #include <linux/init.h> 14 #include <linux/interrupt.h> 15 #include <linux/kernel_stat.h> 16 #include <linux/proc_fs.h> 17 #include <linux/mm.h> 18 #include <linux/random.h> 19 #include <linux/sched.h> 20 #include <linux/seq_file.h> 21 #include <linux/kallsyms.h> 22 #include <linux/kgdb.h> 23 #include <linux/ftrace.h> 24 25 #include <linux/atomic.h> 26 #include <asm/uaccess.h> 27 28 /* 29 * 'what should we do if we get a hw irq event on an illegal vector'. 30 * each architecture has to answer this themselves. 31 */ 32 void ack_bad_irq(unsigned int irq) 33 { 34 printk("unexpected IRQ # %d\n", irq); 35 } 36 37 atomic_t irq_err_count; 38 39 int arch_show_interrupts(struct seq_file *p, int prec) 40 { 41 seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count)); 42 return 0; 43 } 44 45 asmlinkage void spurious_interrupt(void) 46 { 47 atomic_inc(&irq_err_count); 48 } 49 50 void __init init_IRQ(void) 51 { 52 int i; 53 54 for (i = 0; i < NR_IRQS; i++) 55 irq_set_noprobe(i); 56 57 if (cpu_has_veic) 58 clear_c0_status(ST0_IM); 59 60 arch_init_irq(); 61 } 62 63 #ifdef CONFIG_DEBUG_STACKOVERFLOW 64 static inline void check_stack_overflow(void) 65 { 66 unsigned long sp; 67 68 __asm__ __volatile__("move %0, $sp" : "=r" (sp)); 69 sp &= THREAD_MASK; 70 71 /* 72 * Check for stack overflow: is there less than STACK_WARN free? 73 * STACK_WARN is defined as 1/8 of THREAD_SIZE by default. 74 */ 75 if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) { 76 printk("do_IRQ: stack overflow: %ld\n", 77 sp - sizeof(struct thread_info)); 78 dump_stack(); 79 } 80 } 81 #else 82 static inline void check_stack_overflow(void) {} 83 #endif 84 85 86 /* 87 * do_IRQ handles all normal device IRQ's (the special 88 * SMP cross-CPU interrupts have their own specific 89 * handlers). 90 */ 91 void __irq_entry do_IRQ(unsigned int irq) 92 { 93 irq_enter(); 94 check_stack_overflow(); 95 generic_handle_irq(irq); 96 irq_exit(); 97 } 98 99