diff options
Diffstat (limited to 'include/linux/interrupt.h')
-rw-r--r-- | include/linux/interrupt.h | 53 |
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 |