diff options
Diffstat (limited to 'include/linux/interrupt.h')
| -rw-r--r-- | include/linux/interrupt.h | 108 |
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 | */ | ||
| 68 | enum { | ||
| 69 | IRQTF_RUNTHREAD, | ||
| 70 | IRQTF_DIED, | ||
| 71 | IRQTF_WARNED, | ||
| 72 | }; | ||
| 73 | |||
| 62 | typedef irqreturn_t (*irq_handler_t)(int, void *); | 74 | typedef 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 | */ | ||
| 64 | struct irqaction { | 90 | struct 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 | ||
| 75 | extern irqreturn_t no_action(int cpl, void *dev_id); | 104 | extern irqreturn_t no_action(int cpl, void *dev_id); |
| 76 | extern int __must_check request_irq(unsigned int, irq_handler_t handler, | 105 | |
| 77 | unsigned long, const char *, void *); | 106 | #ifdef CONFIG_GENERIC_HARDIRQS |
| 107 | extern int __must_check | ||
| 108 | request_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 | |||
| 112 | static inline int __must_check | ||
| 113 | request_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 | |||
| 119 | extern void exit_irq_thread(void); | ||
| 120 | #else | ||
| 121 | |||
| 122 | extern int __must_check | ||
| 123 | request_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 | */ | ||
| 132 | static inline int __must_check | ||
| 133 | request_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 | |||
| 140 | static inline void exit_irq_thread(void) { } | ||
| 141 | #endif | ||
| 142 | |||
| 78 | extern void free_irq(unsigned int, void *); | 143 | extern void free_irq(unsigned int, void *); |
| 79 | 144 | ||
| 80 | struct device; | 145 | struct device; |
| 81 | 146 | ||
| 82 | extern int __must_check devm_request_irq(struct device *dev, unsigned int irq, | 147 | extern int __must_check |
| 83 | irq_handler_t handler, unsigned long irqflags, | 148 | devm_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 | |||
| 153 | static inline int __must_check | ||
| 154 | devm_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 | |||
| 85 | extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id); | 161 | extern 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); | |||
| 106 | extern void disable_irq(unsigned int irq); | 182 | extern void disable_irq(unsigned int irq); |
| 107 | extern void enable_irq(unsigned int irq); | 183 | extern void enable_irq(unsigned int irq); |
| 108 | 184 | ||
| 185 | /* The following three functions are for the core kernel use only. */ | ||
| 186 | extern void suspend_device_irqs(void); | ||
| 187 | extern void resume_device_irqs(void); | ||
| 188 | #ifdef CONFIG_PM_SLEEP | ||
| 189 | extern int check_wakeup_irqs(void); | ||
| 190 | #else | ||
| 191 | static 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 | ||
| 111 | extern cpumask_var_t irq_default_affinity; | 196 | extern 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 | */ | ||
| 349 | extern 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) |
| 275 | extern void raise_softirq_irqoff(unsigned int nr); | 365 | extern void raise_softirq_irqoff(unsigned int nr); |
| 276 | extern void raise_softirq(unsigned int nr); | 366 | extern void raise_softirq(unsigned int nr); |
| 367 | extern 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) | ||
| 557 | extern void debug_poll_all_shared_irqs(void); | ||
| 558 | #else | ||
| 559 | static inline void debug_poll_all_shared_irqs(void) { } | ||
| 560 | #endif | ||
| 561 | |||
| 465 | int show_interrupts(struct seq_file *p, void *v); | 562 | int show_interrupts(struct seq_file *p, void *v); |
| 466 | 563 | ||
| 467 | struct irq_desc; | 564 | struct irq_desc; |
| 468 | 565 | ||
| 469 | extern int early_irq_init(void); | 566 | extern int early_irq_init(void); |
| 567 | extern int arch_probe_nr_irqs(void); | ||
| 470 | extern int arch_early_irq_init(void); | 568 | extern int arch_early_irq_init(void); |
| 471 | extern int arch_init_chip_data(struct irq_desc *desc, int cpu); | 569 | extern int arch_init_chip_data(struct irq_desc *desc, int cpu); |
| 472 | 570 | ||
