diff options
Diffstat (limited to 'include/linux/interrupt.h')
-rw-r--r-- | include/linux/interrupt.h | 81 |
1 files changed, 59 insertions, 22 deletions
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 55e0d4253e49..bea0ac750712 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h | |||
@@ -14,6 +14,8 @@ | |||
14 | #include <linux/smp.h> | 14 | #include <linux/smp.h> |
15 | #include <linux/percpu.h> | 15 | #include <linux/percpu.h> |
16 | #include <linux/hrtimer.h> | 16 | #include <linux/hrtimer.h> |
17 | #include <linux/kref.h> | ||
18 | #include <linux/workqueue.h> | ||
17 | 19 | ||
18 | #include <asm/atomic.h> | 20 | #include <asm/atomic.h> |
19 | #include <asm/ptrace.h> | 21 | #include <asm/ptrace.h> |
@@ -55,7 +57,8 @@ | |||
55 | * Used by threaded interrupts which need to keep the | 57 | * Used by threaded interrupts which need to keep the |
56 | * irq line disabled until the threaded handler has been run. | 58 | * irq line disabled until the threaded handler has been run. |
57 | * IRQF_NO_SUSPEND - Do not disable this IRQ during suspend | 59 | * IRQF_NO_SUSPEND - Do not disable this IRQ during suspend |
58 | * | 60 | * IRQF_FORCE_RESUME - Force enable it on resume even if IRQF_NO_SUSPEND is set |
61 | * IRQF_NO_THREAD - Interrupt cannot be threaded | ||
59 | */ | 62 | */ |
60 | #define IRQF_DISABLED 0x00000020 | 63 | #define IRQF_DISABLED 0x00000020 |
61 | #define IRQF_SAMPLE_RANDOM 0x00000040 | 64 | #define IRQF_SAMPLE_RANDOM 0x00000040 |
@@ -67,22 +70,10 @@ | |||
67 | #define IRQF_IRQPOLL 0x00001000 | 70 | #define IRQF_IRQPOLL 0x00001000 |
68 | #define IRQF_ONESHOT 0x00002000 | 71 | #define IRQF_ONESHOT 0x00002000 |
69 | #define IRQF_NO_SUSPEND 0x00004000 | 72 | #define IRQF_NO_SUSPEND 0x00004000 |
73 | #define IRQF_FORCE_RESUME 0x00008000 | ||
74 | #define IRQF_NO_THREAD 0x00010000 | ||
70 | 75 | ||
71 | #define IRQF_TIMER (__IRQF_TIMER | IRQF_NO_SUSPEND) | 76 | #define IRQF_TIMER (__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD) |
72 | |||
73 | /* | ||
74 | * Bits used by threaded handlers: | ||
75 | * IRQTF_RUNTHREAD - signals that the interrupt handler thread should run | ||
76 | * IRQTF_DIED - handler thread died | ||
77 | * IRQTF_WARNED - warning "IRQ_WAKE_THREAD w/o thread_fn" has been printed | ||
78 | * IRQTF_AFFINITY - irq thread is requested to adjust affinity | ||
79 | */ | ||
80 | enum { | ||
81 | IRQTF_RUNTHREAD, | ||
82 | IRQTF_DIED, | ||
83 | IRQTF_WARNED, | ||
84 | IRQTF_AFFINITY, | ||
85 | }; | ||
86 | 77 | ||
87 | /* | 78 | /* |
88 | * These values can be returned by request_any_context_irq() and | 79 | * These values can be returned by request_any_context_irq() and |
@@ -107,9 +98,10 @@ typedef irqreturn_t (*irq_handler_t)(int, void *); | |||
107 | * @next: pointer to the next irqaction for shared interrupts | 98 | * @next: pointer to the next irqaction for shared interrupts |
108 | * @irq: interrupt number | 99 | * @irq: interrupt number |
109 | * @dir: pointer to the proc/irq/NN/name entry | 100 | * @dir: pointer to the proc/irq/NN/name entry |
110 | * @thread_fn: interupt handler function for threaded interrupts | 101 | * @thread_fn: interrupt handler function for threaded interrupts |
111 | * @thread: thread pointer for threaded interrupts | 102 | * @thread: thread pointer for threaded interrupts |
112 | * @thread_flags: flags related to @thread | 103 | * @thread_flags: flags related to @thread |
104 | * @thread_mask: bitmask for keeping track of @thread activity | ||
113 | */ | 105 | */ |
114 | struct irqaction { | 106 | struct irqaction { |
115 | irq_handler_t handler; | 107 | irq_handler_t handler; |
@@ -120,6 +112,7 @@ struct irqaction { | |||
120 | irq_handler_t thread_fn; | 112 | irq_handler_t thread_fn; |
121 | struct task_struct *thread; | 113 | struct task_struct *thread; |
122 | unsigned long thread_flags; | 114 | unsigned long thread_flags; |
115 | unsigned long thread_mask; | ||
123 | const char *name; | 116 | const char *name; |
124 | struct proc_dir_entry *dir; | 117 | struct proc_dir_entry *dir; |
125 | } ____cacheline_internodealigned_in_smp; | 118 | } ____cacheline_internodealigned_in_smp; |
@@ -240,6 +233,35 @@ extern int irq_can_set_affinity(unsigned int irq); | |||
240 | extern int irq_select_affinity(unsigned int irq); | 233 | extern int irq_select_affinity(unsigned int irq); |
241 | 234 | ||
242 | extern int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m); | 235 | extern int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m); |
236 | |||
237 | /** | ||
238 | * struct irq_affinity_notify - context for notification of IRQ affinity changes | ||
239 | * @irq: Interrupt to which notification applies | ||
240 | * @kref: Reference count, for internal use | ||
241 | * @work: Work item, for internal use | ||
242 | * @notify: Function to be called on change. This will be | ||
243 | * called in process context. | ||
244 | * @release: Function to be called on release. This will be | ||
245 | * called in process context. Once registered, the | ||
246 | * structure must only be freed when this function is | ||
247 | * called or later. | ||
248 | */ | ||
249 | struct irq_affinity_notify { | ||
250 | unsigned int irq; | ||
251 | struct kref kref; | ||
252 | struct work_struct work; | ||
253 | void (*notify)(struct irq_affinity_notify *, const cpumask_t *mask); | ||
254 | void (*release)(struct kref *ref); | ||
255 | }; | ||
256 | |||
257 | extern int | ||
258 | irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify); | ||
259 | |||
260 | static inline void irq_run_affinity_notifiers(void) | ||
261 | { | ||
262 | flush_scheduled_work(); | ||
263 | } | ||
264 | |||
243 | #else /* CONFIG_SMP */ | 265 | #else /* CONFIG_SMP */ |
244 | 266 | ||
245 | static inline int irq_set_affinity(unsigned int irq, const struct cpumask *m) | 267 | static inline int irq_set_affinity(unsigned int irq, const struct cpumask *m) |
@@ -255,7 +277,7 @@ static inline int irq_can_set_affinity(unsigned int irq) | |||
255 | static inline int irq_select_affinity(unsigned int irq) { return 0; } | 277 | static inline int irq_select_affinity(unsigned int irq) { return 0; } |
256 | 278 | ||
257 | static inline int irq_set_affinity_hint(unsigned int irq, | 279 | static inline int irq_set_affinity_hint(unsigned int irq, |
258 | const struct cpumask *m) | 280 | const struct cpumask *m) |
259 | { | 281 | { |
260 | return -EINVAL; | 282 | return -EINVAL; |
261 | } | 283 | } |
@@ -314,16 +336,16 @@ static inline void enable_irq_lockdep_irqrestore(unsigned int irq, unsigned long | |||
314 | } | 336 | } |
315 | 337 | ||
316 | /* IRQ wakeup (PM) control: */ | 338 | /* IRQ wakeup (PM) control: */ |
317 | extern int set_irq_wake(unsigned int irq, unsigned int on); | 339 | extern int irq_set_irq_wake(unsigned int irq, unsigned int on); |
318 | 340 | ||
319 | static inline int enable_irq_wake(unsigned int irq) | 341 | static inline int enable_irq_wake(unsigned int irq) |
320 | { | 342 | { |
321 | return set_irq_wake(irq, 1); | 343 | return irq_set_irq_wake(irq, 1); |
322 | } | 344 | } |
323 | 345 | ||
324 | static inline int disable_irq_wake(unsigned int irq) | 346 | static inline int disable_irq_wake(unsigned int irq) |
325 | { | 347 | { |
326 | return set_irq_wake(irq, 0); | 348 | return irq_set_irq_wake(irq, 0); |
327 | } | 349 | } |
328 | 350 | ||
329 | #else /* !CONFIG_GENERIC_HARDIRQS */ | 351 | #else /* !CONFIG_GENERIC_HARDIRQS */ |
@@ -353,6 +375,13 @@ static inline int disable_irq_wake(unsigned int irq) | |||
353 | } | 375 | } |
354 | #endif /* CONFIG_GENERIC_HARDIRQS */ | 376 | #endif /* CONFIG_GENERIC_HARDIRQS */ |
355 | 377 | ||
378 | |||
379 | #ifdef CONFIG_IRQ_FORCED_THREADING | ||
380 | extern bool force_irqthreads; | ||
381 | #else | ||
382 | #define force_irqthreads (0) | ||
383 | #endif | ||
384 | |||
356 | #ifndef __ARCH_SET_SOFTIRQ_PENDING | 385 | #ifndef __ARCH_SET_SOFTIRQ_PENDING |
357 | #define set_softirq_pending(x) (local_softirq_pending() = (x)) | 386 | #define set_softirq_pending(x) (local_softirq_pending() = (x)) |
358 | #define or_softirq_pending(x) (local_softirq_pending() |= (x)) | 387 | #define or_softirq_pending(x) (local_softirq_pending() |= (x)) |
@@ -426,6 +455,13 @@ extern void raise_softirq(unsigned int nr); | |||
426 | */ | 455 | */ |
427 | DECLARE_PER_CPU(struct list_head [NR_SOFTIRQS], softirq_work_list); | 456 | DECLARE_PER_CPU(struct list_head [NR_SOFTIRQS], softirq_work_list); |
428 | 457 | ||
458 | DECLARE_PER_CPU(struct task_struct *, ksoftirqd); | ||
459 | |||
460 | static inline struct task_struct *this_cpu_ksoftirqd(void) | ||
461 | { | ||
462 | return this_cpu_read(ksoftirqd); | ||
463 | } | ||
464 | |||
429 | /* Try to send a softirq to a remote cpu. If this cannot be done, the | 465 | /* Try to send a softirq to a remote cpu. If this cannot be done, the |
430 | * work will be queued to the local cpu. | 466 | * work will be queued to the local cpu. |
431 | */ | 467 | */ |
@@ -448,7 +484,7 @@ extern void __send_remote_softirq(struct call_single_data *cp, int cpu, | |||
448 | Properties: | 484 | Properties: |
449 | * If tasklet_schedule() is called, then tasklet is guaranteed | 485 | * If tasklet_schedule() is called, then tasklet is guaranteed |
450 | to be executed on some cpu at least once after this. | 486 | to be executed on some cpu at least once after this. |
451 | * If the tasklet is already scheduled, but its excecution is still not | 487 | * If the tasklet is already scheduled, but its execution is still not |
452 | started, it will be executed only once. | 488 | started, it will be executed only once. |
453 | * If this tasklet is already running on another CPU (or schedule is called | 489 | * If this tasklet is already running on another CPU (or schedule is called |
454 | from tasklet itself), it is rescheduled for later. | 490 | from tasklet itself), it is rescheduled for later. |
@@ -645,6 +681,7 @@ static inline void init_irq_proc(void) | |||
645 | 681 | ||
646 | struct seq_file; | 682 | struct seq_file; |
647 | int show_interrupts(struct seq_file *p, void *v); | 683 | int show_interrupts(struct seq_file *p, void *v); |
684 | int arch_show_interrupts(struct seq_file *p, int prec); | ||
648 | 685 | ||
649 | extern int early_irq_init(void); | 686 | extern int early_irq_init(void); |
650 | extern int arch_probe_nr_irqs(void); | 687 | extern int arch_probe_nr_irqs(void); |