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/module.h> 17 #include <linux/proc_fs.h> 18 #include <linux/slab.h> 19 #include <linux/mm.h> 20 #include <linux/random.h> 21 #include <linux/sched.h> 22 #include <linux/seq_file.h> 23 #include <linux/kallsyms.h> 24 #include <linux/kgdb.h> 25 26 #include <asm/atomic.h> 27 #include <asm/system.h> 28 #include <asm/uaccess.h> 29 30 #ifdef CONFIG_KGDB 31 int kgdb_early_setup; 32 #endif 33 34 static unsigned long irq_map[NR_IRQS / BITS_PER_LONG]; 35 36 int allocate_irqno(void) 37 { 38 int irq; 39 40 again: 41 irq = find_first_zero_bit(irq_map, NR_IRQS); 42 43 if (irq >= NR_IRQS) 44 return -ENOSPC; 45 46 if (test_and_set_bit(irq, irq_map)) 47 goto again; 48 49 return irq; 50 } 51 52 /* 53 * Allocate the 16 legacy interrupts for i8259 devices. This happens early 54 * in the kernel initialization so treating allocation failure as BUG() is 55 * ok. 56 */ 57 void __init alloc_legacy_irqno(void) 58 { 59 int i; 60 61 for (i = 0; i <= 16; i++) 62 BUG_ON(test_and_set_bit(i, irq_map)); 63 } 64 65 void free_irqno(unsigned int irq) 66 { 67 smp_mb__before_clear_bit(); 68 clear_bit(irq, irq_map); 69 smp_mb__after_clear_bit(); 70 } 71 72 /* 73 * 'what should we do if we get a hw irq event on an illegal vector'. 74 * each architecture has to answer this themselves. 75 */ 76 void ack_bad_irq(unsigned int irq) 77 { 78 smtc_im_ack_irq(irq); 79 printk("unexpected IRQ # %d\n", irq); 80 } 81 82 atomic_t irq_err_count; 83 84 /* 85 * Generic, controller-independent functions: 86 */ 87 88 int show_interrupts(struct seq_file *p, void *v) 89 { 90 int i = *(loff_t *) v, j; 91 struct irqaction * action; 92 unsigned long flags; 93 94 if (i == 0) { 95 seq_printf(p, " "); 96 for_each_online_cpu(j) 97 seq_printf(p, "CPU%d ", j); 98 seq_putc(p, '\n'); 99 } 100 101 if (i < NR_IRQS) { 102 spin_lock_irqsave(&irq_desc[i].lock, flags); 103 action = irq_desc[i].action; 104 if (!action) 105 goto skip; 106 seq_printf(p, "%3d: ", i); 107 #ifndef CONFIG_SMP 108 seq_printf(p, "%10u ", kstat_irqs(i)); 109 #else 110 for_each_online_cpu(j) 111 seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); 112 #endif 113 seq_printf(p, " %14s", irq_desc[i].chip->name); 114 seq_printf(p, " %s", action->name); 115 116 for (action=action->next; action; action = action->next) 117 seq_printf(p, ", %s", action->name); 118 119 seq_putc(p, '\n'); 120 skip: 121 spin_unlock_irqrestore(&irq_desc[i].lock, flags); 122 } else if (i == NR_IRQS) { 123 seq_putc(p, '\n'); 124 seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); 125 } 126 return 0; 127 } 128 129 asmlinkage void spurious_interrupt(void) 130 { 131 atomic_inc(&irq_err_count); 132 } 133 134 void __init init_IRQ(void) 135 { 136 int i; 137 138 #ifdef CONFIG_KGDB 139 if (kgdb_early_setup) 140 return; 141 #endif 142 143 for (i = 0; i < NR_IRQS; i++) 144 set_irq_noprobe(i); 145 146 arch_init_irq(); 147 148 #ifdef CONFIG_KGDB 149 if (!kgdb_early_setup) 150 kgdb_early_setup = 1; 151 #endif 152 } 153