X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=include%2Fasm-arm%2Fmach%2Firq.h;h=d4d420ecf3a826c37293fad7406a8cf9354bb5c8;hb=9464c7cf61b9433057924c36e6e02f303a00e768;hp=131f33733d25597167f4d67462a032455920f5d4;hpb=41689045f6a3cbe0550e1d34e9cc20d2e8c432ba;p=linux-2.6.git diff --git a/include/asm-arm/mach/irq.h b/include/asm-arm/mach/irq.h index 131f33733..d4d420ecf 100644 --- a/include/asm-arm/mach/irq.h +++ b/include/asm-arm/mach/irq.h @@ -10,32 +10,114 @@ #ifndef __ASM_ARM_MACH_IRQ_H #define __ASM_ARM_MACH_IRQ_H -#include - +struct irqdesc; +struct pt_regs; struct seq_file; +typedef void (*irq_handler_t)(unsigned int, struct irqdesc *, struct pt_regs *); +typedef void (*irq_control_t)(unsigned int); + +struct irqchip { + /* + * Acknowledge the IRQ. + * If this is a level-based IRQ, then it is expected to mask the IRQ + * as well. + */ + void (*ack)(unsigned int); + /* + * Mask the IRQ in hardware. + */ + void (*mask)(unsigned int); + /* + * Unmask the IRQ in hardware. + */ + void (*unmask)(unsigned int); + /* + * Ask the hardware to re-trigger the IRQ. + * Note: This method _must_ _not_ call the interrupt handler. + * If you are unable to retrigger the interrupt, do not + * provide a function, or if you do, return non-zero. + */ + int (*retrigger)(unsigned int); + /* + * Set the type of the IRQ. + */ + int (*set_type)(unsigned int, unsigned int); + /* + * Set wakeup-enable on the selected IRQ + */ + int (*set_wake)(unsigned int, unsigned int); + +#ifdef CONFIG_SMP + /* + * Route an interrupt to a CPU + */ + void (*set_cpu)(struct irqdesc *desc, unsigned int irq, unsigned int cpu); +#endif +}; + +struct irqdesc { + irq_handler_t handle; + struct irqchip *chip; + struct irqaction *action; + struct list_head pend; + void __iomem *base; + void *data; + unsigned int disable_depth; + + unsigned int triggered: 1; /* IRQ has occurred */ + unsigned int running : 1; /* IRQ is running */ + unsigned int pending : 1; /* IRQ is pending */ + unsigned int probing : 1; /* IRQ in use for a probe */ + unsigned int probe_ok : 1; /* IRQ can be used for probe */ + unsigned int valid : 1; /* IRQ claimable */ + unsigned int noautoenable : 1; /* don't automatically enable IRQ */ + unsigned int unused :25; + + unsigned int irqs_unhandled; + struct proc_dir_entry *procdir; + +#ifdef CONFIG_SMP + cpumask_t affinity; + unsigned int cpu; +#endif + + /* + * IRQ lock detection + */ + unsigned int lck_cnt; + unsigned int lck_pc; + unsigned int lck_jif; +}; + +extern struct irqdesc irq_desc[]; + +/* + * Helpful inline function for calling irq descriptor handlers. + */ +static inline void desc_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) +{ + desc->handle(irq, desc, regs); +} + /* * This is internal. Do not use it. */ extern void (*init_arch_irq)(void); extern void init_FIQ(void); extern int show_fiq_list(struct seq_file *, void *); +void __set_irq_handler(unsigned int irq, irq_handler_t, int); /* - * Function wrappers - */ -#define set_irq_chipdata(irq, d) set_irq_chip_data(irq, d) -#define get_irq_chipdata(irq) get_irq_chip_data(irq) - -/* - * Obsolete inline function for calling irq descriptor handlers. + * External stuff. */ -static inline void desc_handle_irq(unsigned int irq, struct irq_desc *desc, - struct pt_regs *regs) -{ - desc->handle_irq(irq, desc, regs); -} +#define set_irq_handler(irq,handler) __set_irq_handler(irq,handler,0) +#define set_irq_chained_handler(irq,handler) __set_irq_handler(irq,handler,1) +#define set_irq_data(irq,d) do { irq_desc[irq].data = d; } while (0) +#define set_irq_chipdata(irq,d) do { irq_desc[irq].base = d; } while (0) +#define get_irq_chipdata(irq) (irq_desc[irq].base) +void set_irq_chip(unsigned int irq, struct irqchip *); void set_irq_flags(unsigned int irq, unsigned int flags); #define IRQF_VALID (1 << 0) @@ -43,25 +125,12 @@ void set_irq_flags(unsigned int irq, unsigned int flags); #define IRQF_NOAUTOEN (1 << 2) /* - * This is for easy migration, but should be changed in the source + * Built-in IRQ handlers. */ -#define do_level_IRQ handle_level_irq -#define do_edge_IRQ handle_edge_irq -#define do_simple_IRQ handle_simple_irq -#define irqdesc irq_desc -#define irqchip irq_chip - -#define do_bad_IRQ(irq,desc,regs) \ -do { \ - spin_lock(&desc->lock); \ - handle_bad_irq(irq, desc, regs); \ - spin_unlock(&desc->lock); \ -} while(0) - -extern unsigned long irq_err_count; -static inline void ack_bad_irq(int irq) -{ - irq_err_count++; -} +void do_level_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs); +void do_edge_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs); +void do_simple_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs); +void do_bad_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs); +void dummy_mask_unmask_irq(unsigned int irq); #endif