diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-26 10:44:09 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-26 10:44:09 -0400 |
commit | 1f6e05171bb5cc32a4d6437ab2269fc21d169ca7 (patch) | |
tree | cf8a99623fe30fde6c5a729f329aa3a4e282886a /include | |
parent | 19b4a8d520a6e0176dd52aaa429261ad4fcaa545 (diff) | |
parent | 9bab0b7fbaceec47d32db51cd9e59c82fb071f5a (diff) |
Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
* 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
genirq: Add IRQF_RESUME_EARLY and resume such IRQs earlier
genirq: Fix fatfinered fixup really
genirq: percpu: allow interrupt type to be set at enable time
genirq: Add support for per-cpu dev_id interrupts
genirq: Add IRQCHIP_SKIP_SET_WAKE flag
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/interrupt.h | 41 | ||||
-rw-r--r-- | include/linux/irq.h | 18 | ||||
-rw-r--r-- | include/linux/irqdesc.h | 1 |
3 files changed, 48 insertions, 12 deletions
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index a103732b7588..a64b00e286f5 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h | |||
@@ -59,6 +59,8 @@ | |||
59 | * IRQF_NO_SUSPEND - Do not disable this IRQ during suspend | 59 | * IRQF_NO_SUSPEND - Do not disable this IRQ during suspend |
60 | * IRQF_FORCE_RESUME - Force enable it on resume even if IRQF_NO_SUSPEND is set | 60 | * IRQF_FORCE_RESUME - Force enable it on resume even if IRQF_NO_SUSPEND is set |
61 | * IRQF_NO_THREAD - Interrupt cannot be threaded | 61 | * IRQF_NO_THREAD - Interrupt cannot be threaded |
62 | * IRQF_EARLY_RESUME - Resume IRQ early during syscore instead of at device | ||
63 | * resume time. | ||
62 | */ | 64 | */ |
63 | #define IRQF_DISABLED 0x00000020 | 65 | #define IRQF_DISABLED 0x00000020 |
64 | #define IRQF_SAMPLE_RANDOM 0x00000040 | 66 | #define IRQF_SAMPLE_RANDOM 0x00000040 |
@@ -72,6 +74,7 @@ | |||
72 | #define IRQF_NO_SUSPEND 0x00004000 | 74 | #define IRQF_NO_SUSPEND 0x00004000 |
73 | #define IRQF_FORCE_RESUME 0x00008000 | 75 | #define IRQF_FORCE_RESUME 0x00008000 |
74 | #define IRQF_NO_THREAD 0x00010000 | 76 | #define IRQF_NO_THREAD 0x00010000 |
77 | #define IRQF_EARLY_RESUME 0x00020000 | ||
75 | 78 | ||
76 | #define IRQF_TIMER (__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD) | 79 | #define IRQF_TIMER (__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD) |
77 | 80 | ||
@@ -95,6 +98,7 @@ typedef irqreturn_t (*irq_handler_t)(int, void *); | |||
95 | * @flags: flags (see IRQF_* above) | 98 | * @flags: flags (see IRQF_* above) |
96 | * @name: name of the device | 99 | * @name: name of the device |
97 | * @dev_id: cookie to identify the device | 100 | * @dev_id: cookie to identify the device |
101 | * @percpu_dev_id: cookie to identify the device | ||
98 | * @next: pointer to the next irqaction for shared interrupts | 102 | * @next: pointer to the next irqaction for shared interrupts |
99 | * @irq: interrupt number | 103 | * @irq: interrupt number |
100 | * @dir: pointer to the proc/irq/NN/name entry | 104 | * @dir: pointer to the proc/irq/NN/name entry |
@@ -104,17 +108,18 @@ typedef irqreturn_t (*irq_handler_t)(int, void *); | |||
104 | * @thread_mask: bitmask for keeping track of @thread activity | 108 | * @thread_mask: bitmask for keeping track of @thread activity |
105 | */ | 109 | */ |
106 | struct irqaction { | 110 | struct irqaction { |
107 | irq_handler_t handler; | 111 | irq_handler_t handler; |
108 | unsigned long flags; | 112 | unsigned long flags; |
109 | void *dev_id; | 113 | void *dev_id; |
110 | struct irqaction *next; | 114 | void __percpu *percpu_dev_id; |
111 | int irq; | 115 | struct irqaction *next; |
112 | irq_handler_t thread_fn; | 116 | int irq; |
113 | struct task_struct *thread; | 117 | irq_handler_t thread_fn; |
114 | unsigned long thread_flags; | 118 | struct task_struct *thread; |
115 | unsigned long thread_mask; | 119 | unsigned long thread_flags; |
116 | const char *name; | 120 | unsigned long thread_mask; |
117 | struct proc_dir_entry *dir; | 121 | const char *name; |
122 | struct proc_dir_entry *dir; | ||
118 | } ____cacheline_internodealigned_in_smp; | 123 | } ____cacheline_internodealigned_in_smp; |
119 | 124 | ||
120 | extern irqreturn_t no_action(int cpl, void *dev_id); | 125 | extern irqreturn_t no_action(int cpl, void *dev_id); |
@@ -136,6 +141,10 @@ extern int __must_check | |||
136 | request_any_context_irq(unsigned int irq, irq_handler_t handler, | 141 | request_any_context_irq(unsigned int irq, irq_handler_t handler, |
137 | unsigned long flags, const char *name, void *dev_id); | 142 | unsigned long flags, const char *name, void *dev_id); |
138 | 143 | ||
144 | extern int __must_check | ||
145 | request_percpu_irq(unsigned int irq, irq_handler_t handler, | ||
146 | const char *devname, void __percpu *percpu_dev_id); | ||
147 | |||
139 | extern void exit_irq_thread(void); | 148 | extern void exit_irq_thread(void); |
140 | #else | 149 | #else |
141 | 150 | ||
@@ -164,10 +173,18 @@ request_any_context_irq(unsigned int irq, irq_handler_t handler, | |||
164 | return request_irq(irq, handler, flags, name, dev_id); | 173 | return request_irq(irq, handler, flags, name, dev_id); |
165 | } | 174 | } |
166 | 175 | ||
176 | static inline int __must_check | ||
177 | request_percpu_irq(unsigned int irq, irq_handler_t handler, | ||
178 | const char *devname, void __percpu *percpu_dev_id) | ||
179 | { | ||
180 | return request_irq(irq, handler, 0, devname, percpu_dev_id); | ||
181 | } | ||
182 | |||
167 | static inline void exit_irq_thread(void) { } | 183 | static inline void exit_irq_thread(void) { } |
168 | #endif | 184 | #endif |
169 | 185 | ||
170 | extern void free_irq(unsigned int, void *); | 186 | extern void free_irq(unsigned int, void *); |
187 | extern void free_percpu_irq(unsigned int, void __percpu *); | ||
171 | 188 | ||
172 | struct device; | 189 | struct device; |
173 | 190 | ||
@@ -207,7 +224,9 @@ extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id); | |||
207 | 224 | ||
208 | extern void disable_irq_nosync(unsigned int irq); | 225 | extern void disable_irq_nosync(unsigned int irq); |
209 | extern void disable_irq(unsigned int irq); | 226 | extern void disable_irq(unsigned int irq); |
227 | extern void disable_percpu_irq(unsigned int irq); | ||
210 | extern void enable_irq(unsigned int irq); | 228 | extern void enable_irq(unsigned int irq); |
229 | extern void enable_percpu_irq(unsigned int irq, unsigned int type); | ||
211 | 230 | ||
212 | /* The following three functions are for the core kernel use only. */ | 231 | /* The following three functions are for the core kernel use only. */ |
213 | #ifdef CONFIG_GENERIC_HARDIRQS | 232 | #ifdef CONFIG_GENERIC_HARDIRQS |
diff --git a/include/linux/irq.h b/include/linux/irq.h index 59517300a315..59e49c80cc2c 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
@@ -66,6 +66,7 @@ typedef void (*irq_preflow_handler_t)(struct irq_data *data); | |||
66 | * IRQ_NO_BALANCING - Interrupt cannot be balanced (affinity set) | 66 | * IRQ_NO_BALANCING - Interrupt cannot be balanced (affinity set) |
67 | * IRQ_MOVE_PCNTXT - Interrupt can be migrated from process context | 67 | * IRQ_MOVE_PCNTXT - Interrupt can be migrated from process context |
68 | * IRQ_NESTED_TRHEAD - Interrupt nests into another thread | 68 | * IRQ_NESTED_TRHEAD - Interrupt nests into another thread |
69 | * IRQ_PER_CPU_DEVID - Dev_id is a per-cpu variable | ||
69 | */ | 70 | */ |
70 | enum { | 71 | enum { |
71 | IRQ_TYPE_NONE = 0x00000000, | 72 | IRQ_TYPE_NONE = 0x00000000, |
@@ -88,12 +89,13 @@ enum { | |||
88 | IRQ_MOVE_PCNTXT = (1 << 14), | 89 | IRQ_MOVE_PCNTXT = (1 << 14), |
89 | IRQ_NESTED_THREAD = (1 << 15), | 90 | IRQ_NESTED_THREAD = (1 << 15), |
90 | IRQ_NOTHREAD = (1 << 16), | 91 | IRQ_NOTHREAD = (1 << 16), |
92 | IRQ_PER_CPU_DEVID = (1 << 17), | ||
91 | }; | 93 | }; |
92 | 94 | ||
93 | #define IRQF_MODIFY_MASK \ | 95 | #define IRQF_MODIFY_MASK \ |
94 | (IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \ | 96 | (IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \ |
95 | IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL | IRQ_NO_BALANCING | \ | 97 | IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL | IRQ_NO_BALANCING | \ |
96 | IRQ_PER_CPU | IRQ_NESTED_THREAD) | 98 | IRQ_PER_CPU | IRQ_NESTED_THREAD | IRQ_NOTHREAD | IRQ_PER_CPU_DEVID) |
97 | 99 | ||
98 | #define IRQ_NO_BALANCING_MASK (IRQ_PER_CPU | IRQ_NO_BALANCING) | 100 | #define IRQ_NO_BALANCING_MASK (IRQ_PER_CPU | IRQ_NO_BALANCING) |
99 | 101 | ||
@@ -336,12 +338,14 @@ struct irq_chip { | |||
336 | * IRQCHIP_MASK_ON_SUSPEND: Mask non wake irqs in the suspend path | 338 | * IRQCHIP_MASK_ON_SUSPEND: Mask non wake irqs in the suspend path |
337 | * IRQCHIP_ONOFFLINE_ENABLED: Only call irq_on/off_line callbacks | 339 | * IRQCHIP_ONOFFLINE_ENABLED: Only call irq_on/off_line callbacks |
338 | * when irq enabled | 340 | * when irq enabled |
341 | * IRQCHIP_SKIP_SET_WAKE: Skip chip.irq_set_wake(), for this irq chip | ||
339 | */ | 342 | */ |
340 | enum { | 343 | enum { |
341 | IRQCHIP_SET_TYPE_MASKED = (1 << 0), | 344 | IRQCHIP_SET_TYPE_MASKED = (1 << 0), |
342 | IRQCHIP_EOI_IF_HANDLED = (1 << 1), | 345 | IRQCHIP_EOI_IF_HANDLED = (1 << 1), |
343 | IRQCHIP_MASK_ON_SUSPEND = (1 << 2), | 346 | IRQCHIP_MASK_ON_SUSPEND = (1 << 2), |
344 | IRQCHIP_ONOFFLINE_ENABLED = (1 << 3), | 347 | IRQCHIP_ONOFFLINE_ENABLED = (1 << 3), |
348 | IRQCHIP_SKIP_SET_WAKE = (1 << 4), | ||
345 | }; | 349 | }; |
346 | 350 | ||
347 | /* This include will go away once we isolated irq_desc usage to core code */ | 351 | /* This include will go away once we isolated irq_desc usage to core code */ |
@@ -365,6 +369,8 @@ enum { | |||
365 | struct irqaction; | 369 | struct irqaction; |
366 | extern int setup_irq(unsigned int irq, struct irqaction *new); | 370 | extern int setup_irq(unsigned int irq, struct irqaction *new); |
367 | extern void remove_irq(unsigned int irq, struct irqaction *act); | 371 | extern void remove_irq(unsigned int irq, struct irqaction *act); |
372 | extern int setup_percpu_irq(unsigned int irq, struct irqaction *new); | ||
373 | extern void remove_percpu_irq(unsigned int irq, struct irqaction *act); | ||
368 | 374 | ||
369 | extern void irq_cpu_online(void); | 375 | extern void irq_cpu_online(void); |
370 | extern void irq_cpu_offline(void); | 376 | extern void irq_cpu_offline(void); |
@@ -392,6 +398,7 @@ extern void handle_edge_irq(unsigned int irq, struct irq_desc *desc); | |||
392 | extern void handle_edge_eoi_irq(unsigned int irq, struct irq_desc *desc); | 398 | extern void handle_edge_eoi_irq(unsigned int irq, struct irq_desc *desc); |
393 | extern void handle_simple_irq(unsigned int irq, struct irq_desc *desc); | 399 | extern void handle_simple_irq(unsigned int irq, struct irq_desc *desc); |
394 | extern void handle_percpu_irq(unsigned int irq, struct irq_desc *desc); | 400 | extern void handle_percpu_irq(unsigned int irq, struct irq_desc *desc); |
401 | extern void handle_percpu_devid_irq(unsigned int irq, struct irq_desc *desc); | ||
395 | extern void handle_bad_irq(unsigned int irq, struct irq_desc *desc); | 402 | extern void handle_bad_irq(unsigned int irq, struct irq_desc *desc); |
396 | extern void handle_nested_irq(unsigned int irq); | 403 | extern void handle_nested_irq(unsigned int irq); |
397 | 404 | ||
@@ -420,6 +427,8 @@ static inline void irq_set_chip_and_handler(unsigned int irq, struct irq_chip *c | |||
420 | irq_set_chip_and_handler_name(irq, chip, handle, NULL); | 427 | irq_set_chip_and_handler_name(irq, chip, handle, NULL); |
421 | } | 428 | } |
422 | 429 | ||
430 | extern int irq_set_percpu_devid(unsigned int irq); | ||
431 | |||
423 | extern void | 432 | extern void |
424 | __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, | 433 | __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, |
425 | const char *name); | 434 | const char *name); |
@@ -481,6 +490,13 @@ static inline void irq_set_nested_thread(unsigned int irq, bool nest) | |||
481 | irq_clear_status_flags(irq, IRQ_NESTED_THREAD); | 490 | irq_clear_status_flags(irq, IRQ_NESTED_THREAD); |
482 | } | 491 | } |
483 | 492 | ||
493 | static inline void irq_set_percpu_devid_flags(unsigned int irq) | ||
494 | { | ||
495 | irq_set_status_flags(irq, | ||
496 | IRQ_NOAUTOEN | IRQ_PER_CPU | IRQ_NOTHREAD | | ||
497 | IRQ_NOPROBE | IRQ_PER_CPU_DEVID); | ||
498 | } | ||
499 | |||
484 | /* Handle dynamic irq creation and destruction */ | 500 | /* Handle dynamic irq creation and destruction */ |
485 | extern unsigned int create_irq_nr(unsigned int irq_want, int node); | 501 | extern unsigned int create_irq_nr(unsigned int irq_want, int node); |
486 | extern int create_irq(void); | 502 | extern int create_irq(void); |
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h index 150134ac709a..6b69c2c9dff1 100644 --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h | |||
@@ -53,6 +53,7 @@ struct irq_desc { | |||
53 | unsigned long last_unhandled; /* Aging timer for unhandled count */ | 53 | unsigned long last_unhandled; /* Aging timer for unhandled count */ |
54 | unsigned int irqs_unhandled; | 54 | unsigned int irqs_unhandled; |
55 | raw_spinlock_t lock; | 55 | raw_spinlock_t lock; |
56 | struct cpumask *percpu_enabled; | ||
56 | #ifdef CONFIG_SMP | 57 | #ifdef CONFIG_SMP |
57 | const struct cpumask *affinity_hint; | 58 | const struct cpumask *affinity_hint; |
58 | struct irq_affinity_notify *affinity_notify; | 59 | struct irq_affinity_notify *affinity_notify; |