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 29int kgdb_early_setup; 30#endif 31 32static DECLARE_BITMAP(irq_map, NR_IRQS); 33 34int allocate_irqno(void) 35{ 36 int irq; 37 38again: 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 */ 55void __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 63void 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 */ 74void ack_bad_irq(unsigned int irq) 75{ 76 printk("unexpected IRQ # %d\n", irq); 77} 78 79atomic_t irq_err_count; 80 81int 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 87asmlinkage void spurious_interrupt(void) 88{ 89 atomic_inc(&irq_err_count); 90} 91 92void __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 CONFIG_DEBUG_STACKOVERFLOW 113static 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 131static 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 */ 140void __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