1 /* interrupt.h */
2 #ifndef _LINUX_INTERRUPT_H
3 #define _LINUX_INTERRUPT_H
4
5 #include <linux/linkage.h>
6 #include <asm/bitops.h>
7
8 struct bh_struct {
9 void (*routine)(void *);
10 void *data;
11 };
12
13 extern unsigned long bh_active;
14 extern unsigned long bh_mask;
15 extern struct bh_struct bh_base[32];
16
17 asmlinkage void do_bottom_half(void);
18
19 /* Who gets which entry in bh_base. Things which will occur most often
20 should come first - in which case NET should be up the top with SERIAL/TQUEUE! */
21
22 enum {
23 TIMER_BH = 0,
24 CONSOLE_BH,
25 TQUEUE_BH,
26 SERIAL_BH,
27 NET_BH,
28 IMMEDIATE_BH,
29 KEYBOARD_BH,
30 CYCLADES_BH,
31 CM206_BH
32 };
33
34 extern inline void mark_bh(int nr)
/* ![[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)
*/
35 {
36 set_bit(nr, &bh_active);
37 }
38
39 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)
*/
40 {
41 clear_bit(nr, &bh_mask);
42 }
43
44 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)
*/
45 {
46 set_bit(nr, &bh_mask);
47 }
48
49 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)
*/
50 {
51 intr_count++;
52 }
53
54 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)
*/
55 {
56 if (intr_count == 1 && (bh_active & bh_mask))
57 do_bottom_half();
58 intr_count--;
59 }
60
61 /*
62 * Autoprobing for irqs:
63 *
64 * probe_irq_on() and probe_irq_off() provide robust primitives
65 * for accurate IRQ probing during kernel initialization. They are
66 * reasonably simple to use, are not "fooled" by spurious interrupts,
67 * and, unlike other attempts at IRQ probing, they do not get hung on
68 * stuck interrupts (such as unused PS2 mouse interfaces on ASUS boards).
69 *
70 * For reasonably foolproof probing, use them as follows:
71 *
72 * 1. clear and/or mask the device's internal interrupt.
73 * 2. sti();
74 * 3. irqs = probe_irq_on(); // "take over" all unassigned idle IRQs
75 * 4. enable the device and cause it to trigger an interrupt.
76 * 5. wait for the device to interrupt, using non-intrusive polling or a delay.
77 * 6. irq = probe_irq_off(irqs); // get IRQ number, 0=none, negative=multiple
78 * 7. service the device to clear its pending interrupt.
79 * 8. loop again if paranoia is required.
80 *
81 * probe_irq_on() returns a mask of snarfed irq's.
82 *
83 * probe_irq_off() takes the mask as a parameter,
84 * and returns the irq number which occurred,
85 * or zero if none occurred, or a negative irq number
86 * if more than one irq occurred.
87 */
88 extern unsigned long probe_irq_on(void); /* returns 0 on failure */
89 extern int probe_irq_off(unsigned long); /* returns 0 or negative on failure */
90
91 #endif