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 SERIAL_BH,
33 NET_BH,
34 IMMEDIATE_BH,
35 KEYBOARD_BH,
36 CYCLADES_BH,
37 CM206_BH 38 };
39
40 externinlinevoidinit_bh(intnr, void (*routine)(void))
/* */ 41 { 42 bh_base[nr] = routine;
43 bh_mask_count[nr] = 0;
44 bh_mask |= 1 << nr;
45 } 46
47 externinlinevoidmark_bh(intnr)
/* */ 48 { 49 set_bit(nr, &bh_active);
50 } 51
52 /* 53 * These use a mask count to correctly handle 54 * nested disable/enable calls 55 */ 56 externinlinevoiddisable_bh(intnr)
/* */ 57 { 58 bh_mask &= ~(1 << nr);
59 bh_mask_count[nr]++;
60 } 61
62 externinlinevoidenable_bh(intnr)
/* */ 63 { 64 if (!--bh_mask_count[nr])
65 bh_mask |= 1 << nr;
66 } 67
68 /* 69 * start_bh_atomic/end_bh_atomic also nest 70 * naturally by using a counter 71 */ 72 externinlinevoidstart_bh_atomic(void)
/* */ 73 { 74 intr_count++;
75 barrier();
76 } 77
78 externinlinevoidend_bh_atomic(void)
/* */ 79 { 80 barrier();
81 intr_count--;
82 } 83
84 /* 85 * Autoprobing for irqs: 86 * 87 * probe_irq_on() and probe_irq_off() provide robust primitives 88 * for accurate IRQ probing during kernel initialization. They are 89 * reasonably simple to use, are not "fooled" by spurious interrupts, 90 * and, unlike other attempts at IRQ probing, they do not get hung on 91 * stuck interrupts (such as unused PS2 mouse interfaces on ASUS boards). 92 * 93 * For reasonably foolproof probing, use them as follows: 94 * 95 * 1. clear and/or mask the device's internal interrupt. 96 * 2. sti(); 97 * 3. irqs = probe_irq_on(); // "take over" all unassigned idle IRQs 98 * 4. enable the device and cause it to trigger an interrupt. 99 * 5. wait for the device to interrupt, using non-intrusive polling or a delay. 100 * 6. irq = probe_irq_off(irqs); // get IRQ number, 0=none, negative=multiple 101 * 7. service the device to clear its pending interrupt. 102 * 8. loop again if paranoia is required. 103 * 104 * probe_irq_on() returns a mask of allocated irq's. 105 * 106 * probe_irq_off() takes the mask as a parameter, 107 * and returns the irq number which occurred, 108 * or zero if none occurred, or a negative irq number 109 * if more than one irq occurred. 110 */ 111 externunsignedlongprobe_irq_on(void); /* returns 0 on failure */ 112 externintprobe_irq_off(unsignedlong); /* returns 0 or negative on failure */ 113
114 #endif