diff options
Diffstat (limited to 'include/linux/irq.h')
-rw-r--r-- | include/linux/irq.h | 184 |
1 files changed, 59 insertions, 125 deletions
diff --git a/include/linux/irq.h b/include/linux/irq.h index 1d3577f30d45..2a375a72ce3c 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, |
@@ -91,18 +92,6 @@ enum { | |||
91 | IRQ_NO_BALANCING = (1 << 13), | 92 | IRQ_NO_BALANCING = (1 << 13), |
92 | IRQ_MOVE_PCNTXT = (1 << 14), | 93 | IRQ_MOVE_PCNTXT = (1 << 14), |
93 | IRQ_NESTED_THREAD = (1 << 15), | 94 | 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 | }; | 95 | }; |
107 | 96 | ||
108 | #define IRQF_MODIFY_MASK \ | 97 | #define IRQF_MODIFY_MASK \ |
@@ -134,7 +123,7 @@ struct msi_desc; | |||
134 | * struct irq_data - per irq and irq chip data passed down to chip functions | 123 | * struct irq_data - per irq and irq chip data passed down to chip functions |
135 | * @irq: interrupt number | 124 | * @irq: interrupt number |
136 | * @node: node index useful for balancing | 125 | * @node: node index useful for balancing |
137 | * @state_use_accessor: status information for irq chip functions. | 126 | * @state_use_accessors: status information for irq chip functions. |
138 | * Use accessor functions to deal with it | 127 | * Use accessor functions to deal with it |
139 | * @chip: low level interrupt hardware access | 128 | * @chip: low level interrupt hardware access |
140 | * @handler_data: per-IRQ data for the irq_chip methods | 129 | * @handler_data: per-IRQ data for the irq_chip methods |
@@ -173,6 +162,9 @@ struct irq_data { | |||
173 | * from suspend | 162 | * from suspend |
174 | * IRDQ_MOVE_PCNTXT - Interrupt can be moved in process | 163 | * IRDQ_MOVE_PCNTXT - Interrupt can be moved in process |
175 | * context | 164 | * context |
165 | * IRQD_IRQ_DISABLED - Disabled state of the interrupt | ||
166 | * IRQD_IRQ_MASKED - Masked state of the interrupt | ||
167 | * IRQD_IRQ_INPROGRESS - In progress state of the interrupt | ||
176 | */ | 168 | */ |
177 | enum { | 169 | enum { |
178 | IRQD_TRIGGER_MASK = 0xf, | 170 | IRQD_TRIGGER_MASK = 0xf, |
@@ -183,6 +175,9 @@ enum { | |||
183 | IRQD_LEVEL = (1 << 13), | 175 | IRQD_LEVEL = (1 << 13), |
184 | IRQD_WAKEUP_STATE = (1 << 14), | 176 | IRQD_WAKEUP_STATE = (1 << 14), |
185 | IRQD_MOVE_PCNTXT = (1 << 15), | 177 | IRQD_MOVE_PCNTXT = (1 << 15), |
178 | IRQD_IRQ_DISABLED = (1 << 16), | ||
179 | IRQD_IRQ_MASKED = (1 << 17), | ||
180 | IRQD_IRQ_INPROGRESS = (1 << 18), | ||
186 | }; | 181 | }; |
187 | 182 | ||
188 | static inline bool irqd_is_setaffinity_pending(struct irq_data *d) | 183 | static inline bool irqd_is_setaffinity_pending(struct irq_data *d) |
@@ -205,6 +200,11 @@ static inline bool irqd_affinity_was_set(struct irq_data *d) | |||
205 | return d->state_use_accessors & IRQD_AFFINITY_SET; | 200 | return d->state_use_accessors & IRQD_AFFINITY_SET; |
206 | } | 201 | } |
207 | 202 | ||
203 | static inline void irqd_mark_affinity_was_set(struct irq_data *d) | ||
204 | { | ||
205 | d->state_use_accessors |= IRQD_AFFINITY_SET; | ||
206 | } | ||
207 | |||
208 | static inline u32 irqd_get_trigger_type(struct irq_data *d) | 208 | static inline u32 irqd_get_trigger_type(struct irq_data *d) |
209 | { | 209 | { |
210 | return d->state_use_accessors & IRQD_TRIGGER_MASK; | 210 | return d->state_use_accessors & IRQD_TRIGGER_MASK; |
@@ -234,6 +234,36 @@ static inline bool irqd_can_move_in_process_context(struct irq_data *d) | |||
234 | return d->state_use_accessors & IRQD_MOVE_PCNTXT; | 234 | return d->state_use_accessors & IRQD_MOVE_PCNTXT; |
235 | } | 235 | } |
236 | 236 | ||
237 | static inline bool irqd_irq_disabled(struct irq_data *d) | ||
238 | { | ||
239 | return d->state_use_accessors & IRQD_IRQ_DISABLED; | ||
240 | } | ||
241 | |||
242 | static inline bool irqd_irq_masked(struct irq_data *d) | ||
243 | { | ||
244 | return d->state_use_accessors & IRQD_IRQ_MASKED; | ||
245 | } | ||
246 | |||
247 | static inline bool irqd_irq_inprogress(struct irq_data *d) | ||
248 | { | ||
249 | return d->state_use_accessors & IRQD_IRQ_INPROGRESS; | ||
250 | } | ||
251 | |||
252 | /* | ||
253 | * Functions for chained handlers which can be enabled/disabled by the | ||
254 | * standard disable_irq/enable_irq calls. Must be called with | ||
255 | * irq_desc->lock held. | ||
256 | */ | ||
257 | static inline void irqd_set_chained_irq_inprogress(struct irq_data *d) | ||
258 | { | ||
259 | d->state_use_accessors |= IRQD_IRQ_INPROGRESS; | ||
260 | } | ||
261 | |||
262 | static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d) | ||
263 | { | ||
264 | d->state_use_accessors &= ~IRQD_IRQ_INPROGRESS; | ||
265 | } | ||
266 | |||
237 | /** | 267 | /** |
238 | * struct irq_chip - hardware interrupt chip descriptor | 268 | * struct irq_chip - hardware interrupt chip descriptor |
239 | * | 269 | * |
@@ -270,34 +300,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 | 300 | * @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 | 301 | * @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 | 302 | * @irq_bus_sync_unlock:function to sync and unlock slow bus (i2c) chips |
303 | * @irq_cpu_online: configure an interrupt source for a secondary CPU | ||
304 | * @irq_cpu_offline: un-configure an interrupt source for a secondary CPU | ||
305 | * @irq_print_chip: optional to print special chip info in show_interrupts | ||
273 | * @flags: chip specific flags | 306 | * @flags: chip specific flags |
274 | * | 307 | * |
275 | * @release: release function solely used by UML | 308 | * @release: release function solely used by UML |
276 | */ | 309 | */ |
277 | struct irq_chip { | 310 | struct irq_chip { |
278 | const char *name; | 311 | 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); | 312 | unsigned int (*irq_startup)(struct irq_data *data); |
302 | void (*irq_shutdown)(struct irq_data *data); | 313 | void (*irq_shutdown)(struct irq_data *data); |
303 | void (*irq_enable)(struct irq_data *data); | 314 | void (*irq_enable)(struct irq_data *data); |
@@ -317,6 +328,11 @@ struct irq_chip { | |||
317 | void (*irq_bus_lock)(struct irq_data *data); | 328 | void (*irq_bus_lock)(struct irq_data *data); |
318 | void (*irq_bus_sync_unlock)(struct irq_data *data); | 329 | void (*irq_bus_sync_unlock)(struct irq_data *data); |
319 | 330 | ||
331 | void (*irq_cpu_online)(struct irq_data *data); | ||
332 | void (*irq_cpu_offline)(struct irq_data *data); | ||
333 | |||
334 | void (*irq_print_chip)(struct irq_data *data, struct seq_file *p); | ||
335 | |||
320 | unsigned long flags; | 336 | unsigned long flags; |
321 | 337 | ||
322 | /* Currently used only by UML, might disappear one day.*/ | 338 | /* Currently used only by UML, might disappear one day.*/ |
@@ -331,11 +347,14 @@ struct irq_chip { | |||
331 | * IRQCHIP_SET_TYPE_MASKED: Mask before calling chip.irq_set_type() | 347 | * IRQCHIP_SET_TYPE_MASKED: Mask before calling chip.irq_set_type() |
332 | * IRQCHIP_EOI_IF_HANDLED: Only issue irq_eoi() when irq was handled | 348 | * 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 | 349 | * IRQCHIP_MASK_ON_SUSPEND: Mask non wake irqs in the suspend path |
350 | * IRQCHIP_ONOFFLINE_ENABLED: Only call irq_on/off_line callbacks | ||
351 | * when irq enabled | ||
334 | */ | 352 | */ |
335 | enum { | 353 | enum { |
336 | IRQCHIP_SET_TYPE_MASKED = (1 << 0), | 354 | IRQCHIP_SET_TYPE_MASKED = (1 << 0), |
337 | IRQCHIP_EOI_IF_HANDLED = (1 << 1), | 355 | IRQCHIP_EOI_IF_HANDLED = (1 << 1), |
338 | IRQCHIP_MASK_ON_SUSPEND = (1 << 2), | 356 | IRQCHIP_MASK_ON_SUSPEND = (1 << 2), |
357 | IRQCHIP_ONOFFLINE_ENABLED = (1 << 3), | ||
339 | }; | 358 | }; |
340 | 359 | ||
341 | /* This include will go away once we isolated irq_desc usage to core code */ | 360 | /* This include will go away once we isolated irq_desc usage to core code */ |
@@ -360,25 +379,22 @@ struct irqaction; | |||
360 | extern int setup_irq(unsigned int irq, struct irqaction *new); | 379 | extern int setup_irq(unsigned int irq, struct irqaction *new); |
361 | extern void remove_irq(unsigned int irq, struct irqaction *act); | 380 | extern void remove_irq(unsigned int irq, struct irqaction *act); |
362 | 381 | ||
382 | extern void irq_cpu_online(void); | ||
383 | extern void irq_cpu_offline(void); | ||
384 | extern int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *cpumask); | ||
385 | |||
363 | #ifdef CONFIG_GENERIC_HARDIRQS | 386 | #ifdef CONFIG_GENERIC_HARDIRQS |
364 | 387 | ||
365 | #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ) | 388 | #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); | 389 | void irq_move_irq(struct irq_data *data); |
369 | void irq_move_masked_irq(struct irq_data *data); | 390 | void irq_move_masked_irq(struct irq_data *data); |
370 | #else | 391 | #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) { } | 392 | static inline void irq_move_irq(struct irq_data *data) { } |
374 | static inline void irq_move_masked_irq(struct irq_data *data) { } | 393 | static inline void irq_move_masked_irq(struct irq_data *data) { } |
375 | #endif | 394 | #endif |
376 | 395 | ||
377 | extern int no_irq_affinity; | 396 | extern int no_irq_affinity; |
378 | 397 | ||
379 | /* Handle irq action chains: */ | ||
380 | extern irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action); | ||
381 | |||
382 | /* | 398 | /* |
383 | * Built-in IRQ handlers for various IRQ types, | 399 | * Built-in IRQ handlers for various IRQ types, |
384 | * callable via desc->handle_irq() | 400 | * callable via desc->handle_irq() |
@@ -386,6 +402,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); | 402 | 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); | 403 | 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); | 404 | extern void handle_edge_irq(unsigned int irq, struct irq_desc *desc); |
405 | 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); | 406 | 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); | 407 | 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); | 408 | extern void handle_bad_irq(unsigned int irq, struct irq_desc *desc); |
@@ -534,89 +551,6 @@ static inline struct msi_desc *irq_data_get_msi(struct irq_data *d) | |||
534 | return d->msi_desc; | 551 | return d->msi_desc; |
535 | } | 552 | } |
536 | 553 | ||
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); | 554 | 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); | 555 | void irq_free_descs(unsigned int irq, unsigned int cnt); |
622 | int irq_reserve_irqs(unsigned int from, unsigned int cnt); | 556 | int irq_reserve_irqs(unsigned int from, unsigned int cnt); |