1 /* interrupt.h */ 2 #ifndef_LINUX_INTERRUPT_H 3 #define_LINUX_INTERRUPT_H 4
5 #include <linux/kernel.h>
6 #include <asm/bitops.h>
7
8 structirqaction{ 9 void (*handler)(int, void *, structpt_regs *);
10 unsignedlongflags;
11 unsignedlongmask;
12 constchar *name;
13 void *dev_id;
14 structirqaction *next;
15 };
16
17
18 externintbh_mask_count[32];
19 externunsignedlongbh_active;
20 externunsignedlongbh_mask;
21 externvoid (*bh_base[32])(void);
22
23 asmlinkagevoiddo_bottom_half(void);
24
25 /* Who gets which entry in bh_base. Things which will occur most often 26 should come first - in which case NET should be up the top with SERIAL/TQUEUE! */ 27
28 enum{ 29 TIMER_BH = 0,
30 CONSOLE_BH,
31 TQUEUE_BH,
32 DIGI_BH,
33 SERIAL_BH,
34 RISCOM8_BH,
35 NET_BH,
36 IMMEDIATE_BH,
37 KEYBOARD_BH,
38 CYCLADES_BH,
39 CM206_BH 40 };
41
42 externinlinevoidinit_bh(intnr, void (*routine)(void))
/* */ 43 { 44 bh_base[nr] = routine;
45 bh_mask_count[nr] = 0;
46 bh_mask |= 1 << nr;
47 } 48
49 externinlinevoidmark_bh(intnr)
/* */ 50 { 51 set_bit(nr, &bh_active);
52 } 53
54 /* 55 * These use a mask count to correctly handle 56 * nested disable/enable calls 57 */ 58 externinlinevoiddisable_bh(intnr)
/* */ 59 { 60 bh_mask &= ~(1 << nr);
61 bh_mask_count[nr]++;
62 } 63
64 externinlinevoidenable_bh(intnr)
/* */ 65 { 66 if (!--bh_mask_count[nr])
67 bh_mask |= 1 << nr;
68 } 69
70 /* 71 * start_bh_atomic/end_bh_atomic also nest 72 * naturally by using a counter 73 */ 74 externinlinevoidstart_bh_atomic(void)
/* */ 75 { 76 intr_count++;
77 barrier();
78 } 79
80 externinlinevoidend_bh_atomic(void)
/* */ 81 { 82 barrier();
83 intr_count--;
84 } 85
86 /* 87 * Autoprobing for irqs: 88 * 89 * probe_irq_on() and probe_irq_off() provide robust primitives 90 * for accurate IRQ probing during kernel initialization. They are 91 * reasonably simple to use, are not "fooled" by spurious interrupts, 92 * and, unlike other attempts at IRQ probing, they do not get hung on 93 * stuck interrupts (such as unused PS2 mouse interfaces on ASUS boards). 94 * 95 * For reasonably foolproof probing, use them as follows: 96 * 97 * 1. clear and/or mask the device's internal interrupt. 98 * 2. sti(); 99 * 3. irqs = probe_irq_on(); // "take over" all unassigned idle IRQs 100 * 4. enable the device and cause it to trigger an interrupt. 101 * 5. wait for the device to interrupt, using non-intrusive polling or a delay. 102 * 6. irq = probe_irq_off(irqs); // get IRQ number, 0=none, negative=multiple 103 * 7. service the device to clear its pending interrupt. 104 * 8. loop again if paranoia is required. 105 * 106 * probe_irq_on() returns a mask of allocated irq's. 107 * 108 * probe_irq_off() takes the mask as a parameter, 109 * and returns the irq number which occurred, 110 * or zero if none occurred, or a negative irq number 111 * if more than one irq occurred. 112 */ 113 externunsignedlongprobe_irq_on(void); /* returns 0 on failure */ 114 externintprobe_irq_off(unsignedlong); /* returns 0 or negative on failure */ 115
116 #endif