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