Blame view
arch/mips/kernel/irq.c
3.29 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 10 |
/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Code to handle x86 style IRQs plus some generic interrupt stuff. * * Copyright (C) 1992 Linus Torvalds * Copyright (C) 1994 - 2000 Ralf Baechle */ |
1da177e4c Linux-2.6.12-rc2 |
11 12 13 14 15 |
#include <linux/kernel.h> #include <linux/delay.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/kernel_stat.h> |
1da177e4c Linux-2.6.12-rc2 |
16 |
#include <linux/proc_fs.h> |
1da177e4c Linux-2.6.12-rc2 |
17 18 19 20 21 |
#include <linux/mm.h> #include <linux/random.h> #include <linux/sched.h> #include <linux/seq_file.h> #include <linux/kallsyms.h> |
885470011 [MIPS] kgdb: add ... |
22 |
#include <linux/kgdb.h> |
8f99a1626 MIPS: Tracing: Ad... |
23 |
#include <linux/ftrace.h> |
1da177e4c Linux-2.6.12-rc2 |
24 |
|
60063497a atomic: use <linu... |
25 |
#include <linux/atomic.h> |
1da177e4c Linux-2.6.12-rc2 |
26 27 |
#include <asm/system.h> #include <asm/uaccess.h> |
885470011 [MIPS] kgdb: add ... |
28 29 30 |
#ifdef CONFIG_KGDB int kgdb_early_setup; #endif |
4a4cf7792 [MIPS] Make irq n... |
31 |
static unsigned long irq_map[NR_IRQS / BITS_PER_LONG]; |
f543110da [MIPS] Drop __dev... |
32 |
int allocate_irqno(void) |
4a4cf7792 [MIPS] Make irq n... |
33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
{ int irq; again: irq = find_first_zero_bit(irq_map, NR_IRQS); if (irq >= NR_IRQS) return -ENOSPC; if (test_and_set_bit(irq, irq_map)) goto again; return irq; } |
4a4cf7792 [MIPS] Make irq n... |
47 48 49 50 51 52 53 54 55 56 57 58 |
/* * Allocate the 16 legacy interrupts for i8259 devices. This happens early * in the kernel initialization so treating allocation failure as BUG() is * ok. */ void __init alloc_legacy_irqno(void) { int i; for (i = 0; i <= 16; i++) BUG_ON(test_and_set_bit(i, irq_map)); } |
f543110da [MIPS] Drop __dev... |
59 |
void free_irqno(unsigned int irq) |
4a4cf7792 [MIPS] Make irq n... |
60 61 62 63 64 |
{ smp_mb__before_clear_bit(); clear_bit(irq, irq_map); smp_mb__after_clear_bit(); } |
1da177e4c Linux-2.6.12-rc2 |
65 66 67 68 69 70 |
/* * 'what should we do if we get a hw irq event on an illegal vector'. * each architecture has to answer this themselves. */ void ack_bad_irq(unsigned int irq) { |
1146fe305 [MIPS] SMTC: Make... |
71 |
smtc_im_ack_irq(irq); |
1da177e4c Linux-2.6.12-rc2 |
72 73 74 75 76 |
printk("unexpected IRQ # %d ", irq); } atomic_t irq_err_count; |
f8396c170 MIPS: Use generic... |
77 |
int arch_show_interrupts(struct seq_file *p, int prec) |
1da177e4c Linux-2.6.12-rc2 |
78 |
{ |
f8396c170 MIPS: Use generic... |
79 80 |
seq_printf(p, "%*s: %10u ", prec, "ERR", atomic_read(&irq_err_count)); |
1da177e4c Linux-2.6.12-rc2 |
81 82 |
return 0; } |
937a80157 [MIPS] Complete f... |
83 |
asmlinkage void spurious_interrupt(void) |
93373ed4d [MIPS] Rewrite sp... |
84 85 86 |
{ atomic_inc(&irq_err_count); } |
1da177e4c Linux-2.6.12-rc2 |
87 88 |
void __init init_IRQ(void) { |
24649c00c MIPS: Mark all bu... |
89 |
int i; |
885470011 [MIPS] kgdb: add ... |
90 91 92 93 |
#ifdef CONFIG_KGDB if (kgdb_early_setup) return; #endif |
24649c00c MIPS: Mark all bu... |
94 |
for (i = 0; i < NR_IRQS; i++) |
e4ec7989b MIPS: Convert the... |
95 |
irq_set_noprobe(i); |
24649c00c MIPS: Mark all bu... |
96 |
|
1da177e4c Linux-2.6.12-rc2 |
97 |
arch_init_irq(); |
885470011 [MIPS] kgdb: add ... |
98 99 100 101 102 |
#ifdef CONFIG_KGDB if (!kgdb_early_setup) kgdb_early_setup = 1; #endif |
1da177e4c Linux-2.6.12-rc2 |
103 |
} |
8f99a1626 MIPS: Tracing: Ad... |
104 |
|
334c86c49 MIPS: IRQ: Add st... |
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
#ifdef DEBUG_STACKOVERFLOW static inline void check_stack_overflow(void) { unsigned long sp; __asm__ __volatile__("move %0, $sp" : "=r" (sp)); sp &= THREAD_MASK; /* * Check for stack overflow: is there less than STACK_WARN free? * STACK_WARN is defined as 1/8 of THREAD_SIZE by default. */ if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) { printk("do_IRQ: stack overflow: %ld ", sp - sizeof(struct thread_info)); dump_stack(); } } #else static inline void check_stack_overflow(void) {} #endif |
8f99a1626 MIPS: Tracing: Ad... |
127 128 129 130 131 132 133 134 |
/* * do_IRQ handles all normal device IRQ's (the special * SMP cross-CPU interrupts have their own specific * handlers). */ void __irq_entry do_IRQ(unsigned int irq) { irq_enter(); |
334c86c49 MIPS: IRQ: Add st... |
135 |
check_stack_overflow(); |
930cd54b3 MIPS: SMTC: Clean... |
136 137 |
if (!smtc_handle_on_other_cpu(irq)) generic_handle_irq(irq); |
8f99a1626 MIPS: Tracing: Ad... |
138 139 140 141 142 143 144 145 146 147 148 149 |
irq_exit(); } #ifdef CONFIG_MIPS_MT_SMTC_IRQAFF /* * To avoid inefficient and in some cases pathological re-checking of * IRQ affinity, we have this variant that skips the affinity check. */ void __irq_entry do_IRQ_no_affinity(unsigned int irq) { irq_enter(); |
930cd54b3 MIPS: SMTC: Clean... |
150 |
smtc_im_backstop(irq); |
8f99a1626 MIPS: Tracing: Ad... |
151 152 153 154 155 |
generic_handle_irq(irq); irq_exit(); } #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ |