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 struct irqaction {
9 void (*handler)(int, void *, struct pt_regs *);
10 unsigned long flags;
11 unsigned long mask;
12 const char *name;
13 void *dev_id;
14 struct irqaction *next;
15 };
16
17
18 extern int bh_mask_count[32];
19 extern unsigned long bh_active;
20 extern unsigned long bh_mask;
21 extern void (*bh_base[32])(void);
22
23 asmlinkage void do_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 extern inline void init_bh(int nr, void (*routine)(void))
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
41 {
42 bh_base[nr] = routine;
43 bh_mask_count[nr] = 0;
44 bh_mask |= 1 << nr;
45 }
46
47 extern inline void mark_bh(int nr)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
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 extern inline void disable_bh(int nr)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
57 {
58 bh_mask &= ~(1 << nr);
59 bh_mask_count[nr]++;
60 }
61
62 extern inline void enable_bh(int nr)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
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 extern inline void start_bh_atomic(void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
73 {
74 intr_count++;
75 barrier();
76 }
77
78 extern inline void end_bh_atomic(void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
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 extern unsigned long probe_irq_on(void); /* returns 0 on failure */
112 extern int probe_irq_off(unsigned long); /* returns 0 or negative on failure */
113
114 #endif