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
This commit is contained in:
@ -116,7 +116,7 @@
|
||||
# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#if defined(CONFIG_SMP) || defined(CONFIG_GENERIC_HARDIRQS)
|
||||
extern void synchronize_irq(unsigned int irq);
|
||||
#else
|
||||
# define synchronize_irq(irq) barrier()
|
||||
|
@ -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);
|
||||
|
||||
/*
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <linux/irqnr.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/topology.h>
|
||||
#include <linux/wait.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/ptrace.h>
|
||||
@ -158,6 +159,8 @@ struct irq_2_iommu;
|
||||
* @affinity: IRQ affinity on SMP
|
||||
* @cpu: cpu index useful for balancing
|
||||
* @pending_mask: pending rebalanced interrupts
|
||||
* @threads_active: number of irqaction threads currently running
|
||||
* @wait_for_threads: wait queue for sync_irq to wait for threaded handlers
|
||||
* @dir: /proc/irq/ procfs entry
|
||||
* @name: flow handler name for /proc/interrupts output
|
||||
*/
|
||||
@ -189,6 +192,8 @@ struct irq_desc {
|
||||
cpumask_var_t pending_mask;
|
||||
#endif
|
||||
#endif
|
||||
atomic_t threads_active;
|
||||
wait_queue_head_t wait_for_threads;
|
||||
#ifdef CONFIG_PROC_FS
|
||||
struct proc_dir_entry *dir;
|
||||
#endif
|
||||
|
@ -5,10 +5,12 @@
|
||||
* enum irqreturn
|
||||
* @IRQ_NONE interrupt was not from this device
|
||||
* @IRQ_HANDLED interrupt was handled by this device
|
||||
* @IRQ_WAKE_THREAD handler requests to wake the handler thread
|
||||
*/
|
||||
enum irqreturn {
|
||||
IRQ_NONE,
|
||||
IRQ_HANDLED,
|
||||
IRQ_WAKE_THREAD,
|
||||
};
|
||||
|
||||
typedef enum irqreturn irqreturn_t;
|
||||
|
@ -1294,6 +1294,11 @@ struct task_struct {
|
||||
/* Protection of (de-)allocation: mm, files, fs, tty, keyrings */
|
||||
spinlock_t alloc_lock;
|
||||
|
||||
#ifdef CONFIG_GENERIC_HARDIRQS
|
||||
/* IRQ handler threads */
|
||||
struct irqaction *irqaction;
|
||||
#endif
|
||||
|
||||
/* Protection of the PI data structures: */
|
||||
spinlock_t pi_lock;
|
||||
|
||||
|
Reference in New Issue
Block a user