aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/interrupt.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/interrupt.h')
-rw-r--r--include/linux/interrupt.h108
1 files changed, 103 insertions, 5 deletions
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 9127f6b51a39..91bb76f44f14 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -59,8 +59,34 @@
59#define IRQF_NOBALANCING 0x00000800 59#define IRQF_NOBALANCING 0x00000800
60#define IRQF_IRQPOLL 0x00001000 60#define IRQF_IRQPOLL 0x00001000
61 61
62/*
63 * Bits used by threaded handlers:
64 * IRQTF_RUNTHREAD - signals that the interrupt handler thread should run
65 * IRQTF_DIED - handler thread died
66 * IRQTF_WARNED - warning "IRQ_WAKE_THREAD w/o thread_fn" has been printed
67 */
68enum {
69 IRQTF_RUNTHREAD,
70 IRQTF_DIED,
71 IRQTF_WARNED,
72};
73
62typedef irqreturn_t (*irq_handler_t)(int, void *); 74typedef irqreturn_t (*irq_handler_t)(int, void *);
63 75
76/**
77 * struct irqaction - per interrupt action descriptor
78 * @handler: interrupt handler function
79 * @flags: flags (see IRQF_* above)
80 * @mask: no comment as it is useless and about to be removed
81 * @name: name of the device
82 * @dev_id: cookie to identify the device
83 * @next: pointer to the next irqaction for shared interrupts
84 * @irq: interrupt number
85 * @dir: pointer to the proc/irq/NN/name entry
86 * @thread_fn: interupt handler function for threaded interrupts
87 * @thread: thread pointer for threaded interrupts
88 * @thread_flags: flags related to @thread
89 */
64struct irqaction { 90struct irqaction {
65 irq_handler_t handler; 91 irq_handler_t handler;
66 unsigned long flags; 92 unsigned long flags;
@@ -70,18 +96,68 @@ struct irqaction {
70 struct irqaction *next; 96 struct irqaction *next;
71 int irq; 97 int irq;
72 struct proc_dir_entry *dir; 98 struct proc_dir_entry *dir;
99 irq_handler_t thread_fn;
100 struct task_struct *thread;
101 unsigned long thread_flags;
73}; 102};
74 103
75extern irqreturn_t no_action(int cpl, void *dev_id); 104extern irqreturn_t no_action(int cpl, void *dev_id);
76extern int __must_check request_irq(unsigned int, irq_handler_t handler, 105
77 unsigned long, const char *, void *); 106#ifdef CONFIG_GENERIC_HARDIRQS
107extern int __must_check
108request_threaded_irq(unsigned int irq, irq_handler_t handler,
109 irq_handler_t thread_fn,
110 unsigned long flags, const char *name, void *dev);
111
112static inline int __must_check
113request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
114 const char *name, void *dev)
115{
116 return request_threaded_irq(irq, handler, NULL, flags, name, dev);
117}
118
119extern void exit_irq_thread(void);
120#else
121
122extern int __must_check
123request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
124 const char *name, void *dev);
125
126/*
127 * Special function to avoid ifdeffery in kernel/irq/devres.c which
128 * gets magically built by GENERIC_HARDIRQS=n architectures (sparc,
129 * m68k). I really love these $@%#!* obvious Makefile references:
130 * ../../../kernel/irq/devres.o
131 */
132static inline int __must_check
133request_threaded_irq(unsigned int irq, irq_handler_t handler,
134 irq_handler_t thread_fn,
135 unsigned long flags, const char *name, void *dev)
136{
137 return request_irq(irq, handler, flags, name, dev);
138}
139
140static inline void exit_irq_thread(void) { }
141#endif
142
78extern void free_irq(unsigned int, void *); 143extern void free_irq(unsigned int, void *);
79 144
80struct device; 145struct device;
81 146
82extern int __must_check devm_request_irq(struct device *dev, unsigned int irq, 147extern int __must_check
83 irq_handler_t handler, unsigned long irqflags, 148devm_request_threaded_irq(struct device *dev, unsigned int irq,
84 const char *devname, void *dev_id); 149 irq_handler_t handler, irq_handler_t thread_fn,
150 unsigned long irqflags, const char *devname,
151 void *dev_id);
152
153static inline int __must_check
154devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler,
155 unsigned long irqflags, const char *devname, void *dev_id)
156{
157 return devm_request_threaded_irq(dev, irq, handler, NULL, irqflags,
158 devname, dev_id);
159}
160
85extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id); 161extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id);
86 162
87/* 163/*
@@ -106,6 +182,15 @@ extern void disable_irq_nosync(unsigned int irq);
106extern void disable_irq(unsigned int irq); 182extern void disable_irq(unsigned int irq);
107extern void enable_irq(unsigned int irq); 183extern void enable_irq(unsigned int irq);
108 184
185/* The following three functions are for the core kernel use only. */
186extern void suspend_device_irqs(void);
187extern void resume_device_irqs(void);
188#ifdef CONFIG_PM_SLEEP
189extern int check_wakeup_irqs(void);
190#else
191static inline int check_wakeup_irqs(void) { return 0; }
192#endif
193
109#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS) 194#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS)
110 195
111extern cpumask_var_t irq_default_affinity; 196extern cpumask_var_t irq_default_affinity;
@@ -258,6 +343,11 @@ enum
258 NR_SOFTIRQS 343 NR_SOFTIRQS
259}; 344};
260 345
346/* map softirq index to softirq name. update 'softirq_to_name' in
347 * kernel/softirq.c when adding a new softirq.
348 */
349extern char *softirq_to_name[NR_SOFTIRQS];
350
261/* softirq mask and active fields moved to irq_cpustat_t in 351/* softirq mask and active fields moved to irq_cpustat_t in
262 * asm/hardirq.h to get better cache usage. KAO 352 * asm/hardirq.h to get better cache usage. KAO
263 */ 353 */
@@ -274,6 +364,7 @@ extern void softirq_init(void);
274#define __raise_softirq_irqoff(nr) do { or_softirq_pending(1UL << (nr)); } while (0) 364#define __raise_softirq_irqoff(nr) do { or_softirq_pending(1UL << (nr)); } while (0)
275extern void raise_softirq_irqoff(unsigned int nr); 365extern void raise_softirq_irqoff(unsigned int nr);
276extern void raise_softirq(unsigned int nr); 366extern void raise_softirq(unsigned int nr);
367extern void wakeup_softirqd(void);
277 368
278/* This is the worklist that queues up per-cpu softirq work. 369/* This is the worklist that queues up per-cpu softirq work.
279 * 370 *
@@ -462,11 +553,18 @@ static inline void init_irq_proc(void)
462} 553}
463#endif 554#endif
464 555
556#if defined(CONFIG_GENERIC_HARDIRQS) && defined(CONFIG_DEBUG_SHIRQ)
557extern void debug_poll_all_shared_irqs(void);
558#else
559static inline void debug_poll_all_shared_irqs(void) { }
560#endif
561
465int show_interrupts(struct seq_file *p, void *v); 562int show_interrupts(struct seq_file *p, void *v);
466 563
467struct irq_desc; 564struct irq_desc;
468 565
469extern int early_irq_init(void); 566extern int early_irq_init(void);
567extern int arch_probe_nr_irqs(void);
470extern int arch_early_irq_init(void); 568extern int arch_early_irq_init(void);
471extern int arch_init_chip_data(struct irq_desc *desc, int cpu); 569extern int arch_init_chip_data(struct irq_desc *desc, int cpu);
472 570