diff options
Diffstat (limited to 'include/linux/irq.h')
-rw-r--r-- | include/linux/irq.h | 191 |
1 files changed, 59 insertions, 132 deletions
diff --git a/include/linux/irq.h b/include/linux/irq.h index 1d3577f30d45..09a308072f56 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <asm/ptrace.h> | 28 | #include <asm/ptrace.h> |
29 | #include <asm/irq_regs.h> | 29 | #include <asm/irq_regs.h> |
30 | 30 | ||
31 | struct seq_file; | ||
31 | struct irq_desc; | 32 | struct irq_desc; |
32 | struct irq_data; | 33 | struct irq_data; |
33 | typedef void (*irq_flow_handler_t)(unsigned int irq, | 34 | typedef void (*irq_flow_handler_t)(unsigned int irq, |
@@ -63,13 +64,6 @@ typedef void (*irq_preflow_handler_t)(struct irq_data *data); | |||
63 | * IRQ_NO_BALANCING - Interrupt cannot be balanced (affinity set) | 64 | * IRQ_NO_BALANCING - Interrupt cannot be balanced (affinity set) |
64 | * IRQ_MOVE_PCNTXT - Interrupt can be migrated from process context | 65 | * IRQ_MOVE_PCNTXT - Interrupt can be migrated from process context |
65 | * IRQ_NESTED_TRHEAD - Interrupt nests into another thread | 66 | * IRQ_NESTED_TRHEAD - Interrupt nests into another thread |
66 | * | ||
67 | * Deprecated bits. They are kept updated as long as | ||
68 | * CONFIG_GENERIC_HARDIRQS_NO_COMPAT is not set. Will go away soon. These bits | ||
69 | * are internal state of the core code and if you really need to acces | ||
70 | * them then talk to the genirq maintainer instead of hacking | ||
71 | * something weird. | ||
72 | * | ||
73 | */ | 67 | */ |
74 | enum { | 68 | enum { |
75 | IRQ_TYPE_NONE = 0x00000000, | 69 | IRQ_TYPE_NONE = 0x00000000, |
@@ -91,18 +85,6 @@ enum { | |||
91 | IRQ_NO_BALANCING = (1 << 13), | 85 | IRQ_NO_BALANCING = (1 << 13), |
92 | IRQ_MOVE_PCNTXT = (1 << 14), | 86 | IRQ_MOVE_PCNTXT = (1 << 14), |
93 | IRQ_NESTED_THREAD = (1 << 15), | 87 | IRQ_NESTED_THREAD = (1 << 15), |
94 | |||
95 | #ifndef CONFIG_GENERIC_HARDIRQS_NO_COMPAT | ||
96 | IRQ_INPROGRESS = (1 << 16), | ||
97 | IRQ_REPLAY = (1 << 17), | ||
98 | IRQ_WAITING = (1 << 18), | ||
99 | IRQ_DISABLED = (1 << 19), | ||
100 | IRQ_PENDING = (1 << 20), | ||
101 | IRQ_MASKED = (1 << 21), | ||
102 | IRQ_MOVE_PENDING = (1 << 22), | ||
103 | IRQ_AFFINITY_SET = (1 << 23), | ||
104 | IRQ_WAKEUP = (1 << 24), | ||
105 | #endif | ||
106 | }; | 88 | }; |
107 | 89 | ||
108 | #define IRQF_MODIFY_MASK \ | 90 | #define IRQF_MODIFY_MASK \ |
@@ -134,7 +116,7 @@ struct msi_desc; | |||
134 | * struct irq_data - per irq and irq chip data passed down to chip functions | 116 | * struct irq_data - per irq and irq chip data passed down to chip functions |
135 | * @irq: interrupt number | 117 | * @irq: interrupt number |
136 | * @node: node index useful for balancing | 118 | * @node: node index useful for balancing |
137 | * @state_use_accessor: status information for irq chip functions. | 119 | * @state_use_accessors: status information for irq chip functions. |
138 | * Use accessor functions to deal with it | 120 | * Use accessor functions to deal with it |
139 | * @chip: low level interrupt hardware access | 121 | * @chip: low level interrupt hardware access |
140 | * @handler_data: per-IRQ data for the irq_chip methods | 122 | * @handler_data: per-IRQ data for the irq_chip methods |
@@ -173,6 +155,9 @@ struct irq_data { | |||
173 | * from suspend | 155 | * from suspend |
174 | * IRDQ_MOVE_PCNTXT - Interrupt can be moved in process | 156 | * IRDQ_MOVE_PCNTXT - Interrupt can be moved in process |
175 | * context | 157 | * context |
158 | * IRQD_IRQ_DISABLED - Disabled state of the interrupt | ||
159 | * IRQD_IRQ_MASKED - Masked state of the interrupt | ||
160 | * IRQD_IRQ_INPROGRESS - In progress state of the interrupt | ||
176 | */ | 161 | */ |
177 | enum { | 162 | enum { |
178 | IRQD_TRIGGER_MASK = 0xf, | 163 | IRQD_TRIGGER_MASK = 0xf, |
@@ -183,6 +168,9 @@ enum { | |||
183 | IRQD_LEVEL = (1 << 13), | 168 | IRQD_LEVEL = (1 << 13), |
184 | IRQD_WAKEUP_STATE = (1 << 14), | 169 | IRQD_WAKEUP_STATE = (1 << 14), |
185 | IRQD_MOVE_PCNTXT = (1 << 15), | 170 | IRQD_MOVE_PCNTXT = (1 << 15), |
171 | IRQD_IRQ_DISABLED = (1 << 16), | ||
172 | IRQD_IRQ_MASKED = (1 << 17), | ||
173 | IRQD_IRQ_INPROGRESS = (1 << 18), | ||
186 | }; | 174 | }; |
187 | 175 | ||
188 | static inline bool irqd_is_setaffinity_pending(struct irq_data *d) | 176 | static inline bool irqd_is_setaffinity_pending(struct irq_data *d) |
@@ -205,6 +193,11 @@ static inline bool irqd_affinity_was_set(struct irq_data *d) | |||
205 | return d->state_use_accessors & IRQD_AFFINITY_SET; | 193 | return d->state_use_accessors & IRQD_AFFINITY_SET; |
206 | } | 194 | } |
207 | 195 | ||
196 | static inline void irqd_mark_affinity_was_set(struct irq_data *d) | ||
197 | { | ||
198 | d->state_use_accessors |= IRQD_AFFINITY_SET; | ||
199 | } | ||
200 | |||
208 | static inline u32 irqd_get_trigger_type(struct irq_data *d) | 201 | static inline u32 irqd_get_trigger_type(struct irq_data *d) |
209 | { | 202 | { |
210 | return d->state_use_accessors & IRQD_TRIGGER_MASK; | 203 | return d->state_use_accessors & IRQD_TRIGGER_MASK; |
@@ -234,6 +227,36 @@ static inline bool irqd_can_move_in_process_context(struct irq_data *d) | |||
234 | return d->state_use_accessors & IRQD_MOVE_PCNTXT; | 227 | return d->state_use_accessors & IRQD_MOVE_PCNTXT; |
235 | } | 228 | } |
236 | 229 | ||
230 | static inline bool irqd_irq_disabled(struct irq_data *d) | ||
231 | { | ||
232 | return d->state_use_accessors & IRQD_IRQ_DISABLED; | ||
233 | } | ||
234 | |||
235 | static inline bool irqd_irq_masked(struct irq_data *d) | ||
236 | { | ||
237 | return d->state_use_accessors & IRQD_IRQ_MASKED; | ||
238 | } | ||
239 | |||
240 | static inline bool irqd_irq_inprogress(struct irq_data *d) | ||
241 | { | ||
242 | return d->state_use_accessors & IRQD_IRQ_INPROGRESS; | ||
243 | } | ||
244 | |||
245 | /* | ||
246 | * Functions for chained handlers which can be enabled/disabled by the | ||
247 | * standard disable_irq/enable_irq calls. Must be called with | ||
248 | * irq_desc->lock held. | ||
249 | */ | ||
250 | static inline void irqd_set_chained_irq_inprogress(struct irq_data *d) | ||
251 | { | ||
252 | d->state_use_accessors |= IRQD_IRQ_INPROGRESS; | ||
253 | } | ||
254 | |||
255 | static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d) | ||
256 | { | ||
257 | d->state_use_accessors &= ~IRQD_IRQ_INPROGRESS; | ||
258 | } | ||
259 | |||
237 | /** | 260 | /** |
238 | * struct irq_chip - hardware interrupt chip descriptor | 261 | * struct irq_chip - hardware interrupt chip descriptor |
239 | * | 262 | * |
@@ -270,34 +293,15 @@ static inline bool irqd_can_move_in_process_context(struct irq_data *d) | |||
270 | * @irq_set_wake: enable/disable power-management wake-on of an IRQ | 293 | * @irq_set_wake: enable/disable power-management wake-on of an IRQ |
271 | * @irq_bus_lock: function to lock access to slow bus (i2c) chips | 294 | * @irq_bus_lock: function to lock access to slow bus (i2c) chips |
272 | * @irq_bus_sync_unlock:function to sync and unlock slow bus (i2c) chips | 295 | * @irq_bus_sync_unlock:function to sync and unlock slow bus (i2c) chips |
296 | * @irq_cpu_online: configure an interrupt source for a secondary CPU | ||
297 | * @irq_cpu_offline: un-configure an interrupt source for a secondary CPU | ||
298 | * @irq_print_chip: optional to print special chip info in show_interrupts | ||
273 | * @flags: chip specific flags | 299 | * @flags: chip specific flags |
274 | * | 300 | * |
275 | * @release: release function solely used by UML | 301 | * @release: release function solely used by UML |
276 | */ | 302 | */ |
277 | struct irq_chip { | 303 | struct irq_chip { |
278 | const char *name; | 304 | const char *name; |
279 | #ifndef CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED | ||
280 | unsigned int (*startup)(unsigned int irq); | ||
281 | void (*shutdown)(unsigned int irq); | ||
282 | void (*enable)(unsigned int irq); | ||
283 | void (*disable)(unsigned int irq); | ||
284 | |||
285 | void (*ack)(unsigned int irq); | ||
286 | void (*mask)(unsigned int irq); | ||
287 | void (*mask_ack)(unsigned int irq); | ||
288 | void (*unmask)(unsigned int irq); | ||
289 | void (*eoi)(unsigned int irq); | ||
290 | |||
291 | void (*end)(unsigned int irq); | ||
292 | int (*set_affinity)(unsigned int irq, | ||
293 | const struct cpumask *dest); | ||
294 | int (*retrigger)(unsigned int irq); | ||
295 | int (*set_type)(unsigned int irq, unsigned int flow_type); | ||
296 | int (*set_wake)(unsigned int irq, unsigned int on); | ||
297 | |||
298 | void (*bus_lock)(unsigned int irq); | ||
299 | void (*bus_sync_unlock)(unsigned int irq); | ||
300 | #endif | ||
301 | unsigned int (*irq_startup)(struct irq_data *data); | 305 | unsigned int (*irq_startup)(struct irq_data *data); |
302 | void (*irq_shutdown)(struct irq_data *data); | 306 | void (*irq_shutdown)(struct irq_data *data); |
303 | void (*irq_enable)(struct irq_data *data); | 307 | void (*irq_enable)(struct irq_data *data); |
@@ -317,6 +321,11 @@ struct irq_chip { | |||
317 | void (*irq_bus_lock)(struct irq_data *data); | 321 | void (*irq_bus_lock)(struct irq_data *data); |
318 | void (*irq_bus_sync_unlock)(struct irq_data *data); | 322 | void (*irq_bus_sync_unlock)(struct irq_data *data); |
319 | 323 | ||
324 | void (*irq_cpu_online)(struct irq_data *data); | ||
325 | void (*irq_cpu_offline)(struct irq_data *data); | ||
326 | |||
327 | void (*irq_print_chip)(struct irq_data *data, struct seq_file *p); | ||
328 | |||
320 | unsigned long flags; | 329 | unsigned long flags; |
321 | 330 | ||
322 | /* Currently used only by UML, might disappear one day.*/ | 331 | /* Currently used only by UML, might disappear one day.*/ |
@@ -331,11 +340,14 @@ struct irq_chip { | |||
331 | * IRQCHIP_SET_TYPE_MASKED: Mask before calling chip.irq_set_type() | 340 | * IRQCHIP_SET_TYPE_MASKED: Mask before calling chip.irq_set_type() |
332 | * IRQCHIP_EOI_IF_HANDLED: Only issue irq_eoi() when irq was handled | 341 | * IRQCHIP_EOI_IF_HANDLED: Only issue irq_eoi() when irq was handled |
333 | * IRQCHIP_MASK_ON_SUSPEND: Mask non wake irqs in the suspend path | 342 | * IRQCHIP_MASK_ON_SUSPEND: Mask non wake irqs in the suspend path |
343 | * IRQCHIP_ONOFFLINE_ENABLED: Only call irq_on/off_line callbacks | ||
344 | * when irq enabled | ||
334 | */ | 345 | */ |
335 | enum { | 346 | enum { |
336 | IRQCHIP_SET_TYPE_MASKED = (1 << 0), | 347 | IRQCHIP_SET_TYPE_MASKED = (1 << 0), |
337 | IRQCHIP_EOI_IF_HANDLED = (1 << 1), | 348 | IRQCHIP_EOI_IF_HANDLED = (1 << 1), |
338 | IRQCHIP_MASK_ON_SUSPEND = (1 << 2), | 349 | IRQCHIP_MASK_ON_SUSPEND = (1 << 2), |
350 | IRQCHIP_ONOFFLINE_ENABLED = (1 << 3), | ||
339 | }; | 351 | }; |
340 | 352 | ||
341 | /* This include will go away once we isolated irq_desc usage to core code */ | 353 | /* This include will go away once we isolated irq_desc usage to core code */ |
@@ -360,25 +372,22 @@ struct irqaction; | |||
360 | extern int setup_irq(unsigned int irq, struct irqaction *new); | 372 | extern int setup_irq(unsigned int irq, struct irqaction *new); |
361 | extern void remove_irq(unsigned int irq, struct irqaction *act); | 373 | extern void remove_irq(unsigned int irq, struct irqaction *act); |
362 | 374 | ||
375 | extern void irq_cpu_online(void); | ||
376 | extern void irq_cpu_offline(void); | ||
377 | extern int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *cpumask); | ||
378 | |||
363 | #ifdef CONFIG_GENERIC_HARDIRQS | 379 | #ifdef CONFIG_GENERIC_HARDIRQS |
364 | 380 | ||
365 | #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ) | 381 | #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ) |
366 | void move_native_irq(int irq); | ||
367 | void move_masked_irq(int irq); | ||
368 | void irq_move_irq(struct irq_data *data); | 382 | void irq_move_irq(struct irq_data *data); |
369 | void irq_move_masked_irq(struct irq_data *data); | 383 | void irq_move_masked_irq(struct irq_data *data); |
370 | #else | 384 | #else |
371 | static inline void move_native_irq(int irq) { } | ||
372 | static inline void move_masked_irq(int irq) { } | ||
373 | static inline void irq_move_irq(struct irq_data *data) { } | 385 | static inline void irq_move_irq(struct irq_data *data) { } |
374 | static inline void irq_move_masked_irq(struct irq_data *data) { } | 386 | static inline void irq_move_masked_irq(struct irq_data *data) { } |
375 | #endif | 387 | #endif |
376 | 388 | ||
377 | extern int no_irq_affinity; | 389 | extern int no_irq_affinity; |
378 | 390 | ||
379 | /* Handle irq action chains: */ | ||
380 | extern irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action); | ||
381 | |||
382 | /* | 391 | /* |
383 | * Built-in IRQ handlers for various IRQ types, | 392 | * Built-in IRQ handlers for various IRQ types, |
384 | * callable via desc->handle_irq() | 393 | * callable via desc->handle_irq() |
@@ -386,6 +395,7 @@ extern irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action); | |||
386 | extern void handle_level_irq(unsigned int irq, struct irq_desc *desc); | 395 | extern void handle_level_irq(unsigned int irq, struct irq_desc *desc); |
387 | extern void handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc); | 396 | extern void handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc); |
388 | extern void handle_edge_irq(unsigned int irq, struct irq_desc *desc); | 397 | extern void handle_edge_irq(unsigned int irq, struct irq_desc *desc); |
398 | extern void handle_edge_eoi_irq(unsigned int irq, struct irq_desc *desc); | ||
389 | 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); |
390 | 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); |
391 | extern void handle_bad_irq(unsigned int irq, struct irq_desc *desc); | 401 | extern void handle_bad_irq(unsigned int irq, struct irq_desc *desc); |
@@ -534,89 +544,6 @@ static inline struct msi_desc *irq_data_get_msi(struct irq_data *d) | |||
534 | return d->msi_desc; | 544 | return d->msi_desc; |
535 | } | 545 | } |
536 | 546 | ||
537 | #ifndef CONFIG_GENERIC_HARDIRQS_NO_COMPAT | ||
538 | /* Please do not use: Use the replacement functions instead */ | ||
539 | static inline int set_irq_chip(unsigned int irq, struct irq_chip *chip) | ||
540 | { | ||
541 | return irq_set_chip(irq, chip); | ||
542 | } | ||
543 | static inline int set_irq_data(unsigned int irq, void *data) | ||
544 | { | ||
545 | return irq_set_handler_data(irq, data); | ||
546 | } | ||
547 | static inline int set_irq_chip_data(unsigned int irq, void *data) | ||
548 | { | ||
549 | return irq_set_chip_data(irq, data); | ||
550 | } | ||
551 | static inline int set_irq_type(unsigned int irq, unsigned int type) | ||
552 | { | ||
553 | return irq_set_irq_type(irq, type); | ||
554 | } | ||
555 | static inline int set_irq_msi(unsigned int irq, struct msi_desc *entry) | ||
556 | { | ||
557 | return irq_set_msi_desc(irq, entry); | ||
558 | } | ||
559 | static inline struct irq_chip *get_irq_chip(unsigned int irq) | ||
560 | { | ||
561 | return irq_get_chip(irq); | ||
562 | } | ||
563 | static inline void *get_irq_chip_data(unsigned int irq) | ||
564 | { | ||
565 | return irq_get_chip_data(irq); | ||
566 | } | ||
567 | static inline void *get_irq_data(unsigned int irq) | ||
568 | { | ||
569 | return irq_get_handler_data(irq); | ||
570 | } | ||
571 | static inline void *irq_data_get_irq_data(struct irq_data *d) | ||
572 | { | ||
573 | return irq_data_get_irq_handler_data(d); | ||
574 | } | ||
575 | static inline struct msi_desc *get_irq_msi(unsigned int irq) | ||
576 | { | ||
577 | return irq_get_msi_desc(irq); | ||
578 | } | ||
579 | static inline void set_irq_noprobe(unsigned int irq) | ||
580 | { | ||
581 | irq_set_noprobe(irq); | ||
582 | } | ||
583 | static inline void set_irq_probe(unsigned int irq) | ||
584 | { | ||
585 | irq_set_probe(irq); | ||
586 | } | ||
587 | static inline void set_irq_nested_thread(unsigned int irq, int nest) | ||
588 | { | ||
589 | irq_set_nested_thread(irq, nest); | ||
590 | } | ||
591 | static inline void | ||
592 | set_irq_chip_and_handler_name(unsigned int irq, struct irq_chip *chip, | ||
593 | irq_flow_handler_t handle, const char *name) | ||
594 | { | ||
595 | irq_set_chip_and_handler_name(irq, chip, handle, name); | ||
596 | } | ||
597 | static inline void | ||
598 | set_irq_chip_and_handler(unsigned int irq, struct irq_chip *chip, | ||
599 | irq_flow_handler_t handle) | ||
600 | { | ||
601 | irq_set_chip_and_handler(irq, chip, handle); | ||
602 | } | ||
603 | static inline void | ||
604 | __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, | ||
605 | const char *name) | ||
606 | { | ||
607 | __irq_set_handler(irq, handle, is_chained, name); | ||
608 | } | ||
609 | static inline void set_irq_handler(unsigned int irq, irq_flow_handler_t handle) | ||
610 | { | ||
611 | irq_set_handler(irq, handle); | ||
612 | } | ||
613 | static inline void | ||
614 | set_irq_chained_handler(unsigned int irq, irq_flow_handler_t handle) | ||
615 | { | ||
616 | irq_set_chained_handler(irq, handle); | ||
617 | } | ||
618 | #endif | ||
619 | |||
620 | int irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node); | 547 | int irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node); |
621 | void irq_free_descs(unsigned int irq, unsigned int cnt); | 548 | void irq_free_descs(unsigned int irq, unsigned int cnt); |
622 | int irq_reserve_irqs(unsigned int from, unsigned int cnt); | 549 | int irq_reserve_irqs(unsigned int from, unsigned int cnt); |