summaryrefslogtreecommitdiffstats
path: root/include/linux/interrupt.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/interrupt.h')
-rw-r--r--include/linux/interrupt.h53
1 files changed, 40 insertions, 13 deletions
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 4c4edc82c..77cd07c8f 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -2,17 +2,24 @@
#ifndef _LINUX_INTERRUPT_H
#define _LINUX_INTERRUPT_H
-#include <linux/linkage.h>
+#include <linux/kernel.h>
#include <asm/bitops.h>
-struct bh_struct {
- void (*routine)(void *);
- void *data;
+struct irqaction {
+ void (*handler)(int, void *, struct pt_regs *);
+ unsigned long flags;
+ unsigned long mask;
+ const char *name;
+ void *dev_id;
+ struct irqaction *next;
};
+extern unsigned long intr_count;
+
+extern int bh_mask_count[32];
extern unsigned long bh_active;
extern unsigned long bh_mask;
-extern struct bh_struct bh_base[32];
+extern void (*bh_base[32])(void);
asmlinkage void do_bottom_half(void);
@@ -23,37 +30,57 @@ enum {
TIMER_BH = 0,
CONSOLE_BH,
TQUEUE_BH,
+ DIGI_BH,
SERIAL_BH,
+ RISCOM8_BH,
NET_BH,
IMMEDIATE_BH,
KEYBOARD_BH,
- CYCLADES_BH
+ CYCLADES_BH,
+ CM206_BH
};
+extern inline void init_bh(int nr, void (*routine)(void))
+{
+ bh_base[nr] = routine;
+ bh_mask_count[nr] = 0;
+ bh_mask |= 1 << nr;
+}
+
extern inline void mark_bh(int nr)
{
set_bit(nr, &bh_active);
}
+/*
+ * These use a mask count to correctly handle
+ * nested disable/enable calls
+ */
extern inline void disable_bh(int nr)
{
- clear_bit(nr, &bh_mask);
+ bh_mask &= ~(1 << nr);
+ bh_mask_count[nr]++;
}
extern inline void enable_bh(int nr)
{
- set_bit(nr, &bh_mask);
+ if (!--bh_mask_count[nr])
+ bh_mask |= 1 << nr;
}
+/*
+ * start_bh_atomic/end_bh_atomic also nest
+ * naturally by using a counter
+ */
extern inline void start_bh_atomic(void)
{
intr_count++;
+ barrier();
}
extern inline void end_bh_atomic(void)
{
- if (intr_count == 1 && (bh_active & bh_mask))
- do_bottom_half();
+ barrier();
intr_count--;
}
@@ -77,14 +104,14 @@ extern inline void end_bh_atomic(void)
* 7. service the device to clear its pending interrupt.
* 8. loop again if paranoia is required.
*
- * probe_irq_on() returns a mask of snarfed irq's.
+ * probe_irq_on() returns a mask of allocated irq's.
*
* probe_irq_off() takes the mask as a parameter,
* and returns the irq number which occurred,
* or zero if none occurred, or a negative irq number
* if more than one irq occurred.
*/
-extern unsigned int probe_irq_on(void); /* returns 0 on failure */
-extern int probe_irq_off(unsigned int); /* returns 0 or negative on failure */
+extern unsigned long probe_irq_on(void); /* returns 0 on failure */
+extern int probe_irq_off(unsigned long); /* returns 0 or negative on failure */
#endif