diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-07 14:07:52 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-07 14:07:52 -0700 | 
| commit | c61b79b6ef266890954213a701d8f6021d8c1289 (patch) | |
| tree | 9b000a7dae5a782a0d667137ab43e4f1bea70d58 /include/linux/interrupt.h | |
| parent | 2b2ec7554cf7ec5e4412f89a5af6abe8ce950700 (diff) | |
| parent | 9efe21cb82b5dbe3b0b2ae4de4eccc64ecb94e95 (diff) | |
Merge branch 'irq/threaded' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'irq/threaded' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  genirq: fix devres.o build for GENERIC_HARDIRQS=n
  genirq: provide old request_irq() for CONFIG_GENERIC_HARDIRQ=n
  genirq: threaded irq handlers review fixups
  genirq: add support for threaded interrupts to devres
  genirq: add threaded interrupt handler support
Diffstat (limited to 'include/linux/interrupt.h')
| -rw-r--r-- | include/linux/interrupt.h | 75 | 
1 files changed, 70 insertions, 5 deletions
| diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 8a9613d0c674..91bb76f44f14 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -59,6 +59,18 @@  #define IRQF_NOBALANCING	0x00000800  #define IRQF_IRQPOLL		0x00001000 +/* + * Bits used by threaded handlers: + * IRQTF_RUNTHREAD - signals that the interrupt handler thread should run + * IRQTF_DIED      - handler thread died + * IRQTF_WARNED    - warning "IRQ_WAKE_THREAD w/o thread_fn" has been printed + */ +enum { +	IRQTF_RUNTHREAD, +	IRQTF_DIED, +	IRQTF_WARNED, +}; +  typedef irqreturn_t (*irq_handler_t)(int, void *);  /** @@ -71,6 +83,9 @@ typedef irqreturn_t (*irq_handler_t)(int, void *);   * @next:	pointer to the next irqaction for shared interrupts   * @irq:	interrupt number   * @dir:	pointer to the proc/irq/NN/name entry + * @thread_fn:	interupt handler function for threaded interrupts + * @thread:	thread pointer for threaded interrupts + * @thread_flags:	flags related to @thread   */  struct irqaction {  	irq_handler_t handler; @@ -81,18 +96,68 @@ struct irqaction {  	struct irqaction *next;  	int irq;  	struct proc_dir_entry *dir; +	irq_handler_t thread_fn; +	struct task_struct *thread; +	unsigned long thread_flags;  };  extern irqreturn_t no_action(int cpl, void *dev_id); -extern int __must_check request_irq(unsigned int, irq_handler_t handler, -		       unsigned long, const char *, void *); + +#ifdef CONFIG_GENERIC_HARDIRQS +extern int __must_check +request_threaded_irq(unsigned int irq, irq_handler_t handler, +		     irq_handler_t thread_fn, +		     unsigned long flags, const char *name, void *dev); + +static inline int __must_check +request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, +	    const char *name, void *dev) +{ +	return request_threaded_irq(irq, handler, NULL, flags, name, dev); +} + +extern void exit_irq_thread(void); +#else + +extern int __must_check +request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, +	    const char *name, void *dev); + +/* + * Special function to avoid ifdeffery in kernel/irq/devres.c which + * gets magically built by GENERIC_HARDIRQS=n architectures (sparc, + * m68k). I really love these $@%#!* obvious Makefile references: + * ../../../kernel/irq/devres.o + */ +static inline int __must_check +request_threaded_irq(unsigned int irq, irq_handler_t handler, +		     irq_handler_t thread_fn, +		     unsigned long flags, const char *name, void *dev) +{ +	return request_irq(irq, handler, flags, name, dev); +} + +static inline void exit_irq_thread(void) { } +#endif +  extern void free_irq(unsigned int, void *);  struct device; -extern int __must_check devm_request_irq(struct device *dev, unsigned int irq, -			    irq_handler_t handler, unsigned long irqflags, -			    const char *devname, void *dev_id); +extern int __must_check +devm_request_threaded_irq(struct device *dev, unsigned int irq, +			  irq_handler_t handler, irq_handler_t thread_fn, +			  unsigned long irqflags, const char *devname, +			  void *dev_id); + +static inline int __must_check +devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler, +		 unsigned long irqflags, const char *devname, void *dev_id) +{ +	return devm_request_threaded_irq(dev, irq, handler, NULL, irqflags, +					 devname, dev_id); +} +  extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id);  /* | 
