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); |
