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 #ifdef CONFIG_KGDB 29 int kgdb_early_setup; 30 #endif 31 32 static unsigned long irq_map[NR_IRQS / BITS_PER_LONG]; 33 34 int allocate_irqno(void) 35 { 36 int irq; 37 38 again: 39 irq = find_first_zero_bit(irq_map, NR_IRQS); 40 41 if (irq >= NR_IRQS) 42 return -ENOSPC; 43 44 if (test_and_set_bit(irq, irq_map)) 45 goto again; 46 47 return irq; 48 } 49 50 /* 51 * Allocate the 16 legacy interrupts for i8259 devices. This happens early 52 * in the kernel initialization so treating allocation failure as BUG() is 53 * ok. 54 */ 55 void __init alloc_legacy_irqno(void) 56 { 57 int i; 58 59 for (i = 0; i <= 16; i++) 60 BUG_ON(test_and_set_bit(i, irq_map)); 61 } 62 63 void free_irqno(unsigned int irq) 64 { 65 smp_mb__before_atomic(); 66 clear_bit(irq, irq_map); 67 smp_mb__after_atomic(); 68 } 69 70 /* 71 * 'what should we do if we get a hw irq event on an illegal vector'. 72 * each architecture has to answer this themselves. 73 */ 74 void ack_bad_irq(unsigned int irq) 75 { 76 printk("unexpected IRQ # %d\n", irq); 77 } 78 79 atomic_t irq_err_count; 80 81 int arch_show_interrupts(struct seq_file *p, int prec) 82 { 83 seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count)); 84 return 0; 85 } 86 87 asmlinkage void spurious_interrupt(void) 88 { 89 atomic_inc(&irq_err_count); 90 } 91 92 void __init init_IRQ(void) 93 { 94 int i; 95 96 #ifdef CONFIG_KGDB 97 if (kgdb_early_setup) 98 return; 99 #endif 100 101 for (i = 0; i < NR_IRQS; i++) 102 irq_set_noprobe(i); 103 104 arch_init_irq(); 105 106 #ifdef CONFIG_KGDB 107 if (!kgdb_early_setup) 108 kgdb_early_setup = 1; 109 #endif 110 } 111 112 #ifdef DEBUG_STACKOVERFLOW 113 static inline void check_stack_overflow(void) 114 { 115 unsigned long sp; 116 117 __asm__ __volatile__("move %0, $sp" : "=r" (sp)); 118 sp &= THREAD_MASK; 119 120 /* 121 * Check for stack overflow: is there less than STACK_WARN free? 122 * STACK_WARN is defined as 1/8 of THREAD_SIZE by default. 123 */ 124 if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) { 125 printk("do_IRQ: stack overflow: %ld\n", 126 sp - sizeof(struct thread_info)); 127 dump_stack(); 128 } 129 } 130 #else 131 static inline void check_stack_overflow(void) {} 132 #endif 133 134 135 /* 136 * do_IRQ handles all normal device IRQ's (the special 137 * SMP cross-CPU interrupts have their own specific 138 * handlers). 139 */ 140 void __irq_entry do_IRQ(unsigned int irq) 141 { 142 irq_enter(); 143 check_stack_overflow(); 144 generic_handle_irq(irq); 145 irq_exit(); 146 } 147 148