diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-19 20:30:15 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-19 20:30:15 -0400 |
| commit | acd30250d7d0f495685d1c7c6184636a22fcdf7f (patch) | |
| tree | 40f4e7e092de434c49a5f67f27ff1d3bf71000f9 /include/linux | |
| parent | 6595b4a940c4c447b619ab5268378ed03e632694 (diff) | |
| parent | edf76f8307c350bcb81f0c760118a991b3e62956 (diff) | |
Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
irq: Export functions to allow modular irq drivers
genirq: Uninline and sanity check generic_handle_irq()
genirq: Remove pointless ifdefs
genirq: Make generic irq chip depend on CONFIG_GENERIC_IRQ_CHIP
genirq: Add chip suspend and resume callbacks
genirq: Implement a generic interrupt chip
genirq: Support per-IRQ thread disabling.
genirq: irq_desc: Document preflow_handler and affinity_hint
genirq: Update DocBook comments
genirq: Forgotten updates/deletions after removal of compat code
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/irq.h | 179 | ||||
| -rw-r--r-- | include/linux/irqdesc.h | 11 |
2 files changed, 165 insertions, 25 deletions
diff --git a/include/linux/irq.h b/include/linux/irq.h index 09a308072f56..8b4538446636 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
| @@ -53,12 +53,13 @@ typedef void (*irq_preflow_handler_t)(struct irq_data *data); | |||
| 53 | * Bits which can be modified via irq_set/clear/modify_status_flags() | 53 | * Bits which can be modified via irq_set/clear/modify_status_flags() |
| 54 | * IRQ_LEVEL - Interrupt is level type. Will be also | 54 | * IRQ_LEVEL - Interrupt is level type. Will be also |
| 55 | * updated in the code when the above trigger | 55 | * updated in the code when the above trigger |
| 56 | * bits are modified via set_irq_type() | 56 | * bits are modified via irq_set_irq_type() |
| 57 | * IRQ_PER_CPU - Mark an interrupt PER_CPU. Will protect | 57 | * IRQ_PER_CPU - Mark an interrupt PER_CPU. Will protect |
| 58 | * it from affinity setting | 58 | * it from affinity setting |
| 59 | * IRQ_NOPROBE - Interrupt cannot be probed by autoprobing | 59 | * IRQ_NOPROBE - Interrupt cannot be probed by autoprobing |
| 60 | * IRQ_NOREQUEST - Interrupt cannot be requested via | 60 | * IRQ_NOREQUEST - Interrupt cannot be requested via |
| 61 | * request_irq() | 61 | * request_irq() |
| 62 | * IRQ_NOTHREAD - Interrupt cannot be threaded | ||
| 62 | * IRQ_NOAUTOEN - Interrupt is not automatically enabled in | 63 | * IRQ_NOAUTOEN - Interrupt is not automatically enabled in |
| 63 | * request/setup_irq() | 64 | * request/setup_irq() |
| 64 | * IRQ_NO_BALANCING - Interrupt cannot be balanced (affinity set) | 65 | * IRQ_NO_BALANCING - Interrupt cannot be balanced (affinity set) |
| @@ -85,6 +86,7 @@ enum { | |||
| 85 | IRQ_NO_BALANCING = (1 << 13), | 86 | IRQ_NO_BALANCING = (1 << 13), |
| 86 | IRQ_MOVE_PCNTXT = (1 << 14), | 87 | IRQ_MOVE_PCNTXT = (1 << 14), |
| 87 | IRQ_NESTED_THREAD = (1 << 15), | 88 | IRQ_NESTED_THREAD = (1 << 15), |
| 89 | IRQ_NOTHREAD = (1 << 16), | ||
| 88 | }; | 90 | }; |
| 89 | 91 | ||
| 90 | #define IRQF_MODIFY_MASK \ | 92 | #define IRQF_MODIFY_MASK \ |
| @@ -261,23 +263,6 @@ static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d) | |||
| 261 | * struct irq_chip - hardware interrupt chip descriptor | 263 | * struct irq_chip - hardware interrupt chip descriptor |
| 262 | * | 264 | * |
| 263 | * @name: name for /proc/interrupts | 265 | * @name: name for /proc/interrupts |
| 264 | * @startup: deprecated, replaced by irq_startup | ||
| 265 | * @shutdown: deprecated, replaced by irq_shutdown | ||
| 266 | * @enable: deprecated, replaced by irq_enable | ||
| 267 | * @disable: deprecated, replaced by irq_disable | ||
| 268 | * @ack: deprecated, replaced by irq_ack | ||
| 269 | * @mask: deprecated, replaced by irq_mask | ||
| 270 | * @mask_ack: deprecated, replaced by irq_mask_ack | ||
| 271 | * @unmask: deprecated, replaced by irq_unmask | ||
| 272 | * @eoi: deprecated, replaced by irq_eoi | ||
| 273 | * @end: deprecated, will go away with __do_IRQ() | ||
| 274 | * @set_affinity: deprecated, replaced by irq_set_affinity | ||
| 275 | * @retrigger: deprecated, replaced by irq_retrigger | ||
| 276 | * @set_type: deprecated, replaced by irq_set_type | ||
| 277 | * @set_wake: deprecated, replaced by irq_wake | ||
| 278 | * @bus_lock: deprecated, replaced by irq_bus_lock | ||
| 279 | * @bus_sync_unlock: deprecated, replaced by irq_bus_sync_unlock | ||
| 280 | * | ||
| 281 | * @irq_startup: start up the interrupt (defaults to ->enable if NULL) | 266 | * @irq_startup: start up the interrupt (defaults to ->enable if NULL) |
| 282 | * @irq_shutdown: shut down the interrupt (defaults to ->disable if NULL) | 267 | * @irq_shutdown: shut down the interrupt (defaults to ->disable if NULL) |
| 283 | * @irq_enable: enable the interrupt (defaults to chip->unmask if NULL) | 268 | * @irq_enable: enable the interrupt (defaults to chip->unmask if NULL) |
| @@ -295,6 +280,9 @@ static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d) | |||
| 295 | * @irq_bus_sync_unlock:function to sync and unlock slow bus (i2c) chips | 280 | * @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 | 281 | * @irq_cpu_online: configure an interrupt source for a secondary CPU |
| 297 | * @irq_cpu_offline: un-configure an interrupt source for a secondary CPU | 282 | * @irq_cpu_offline: un-configure an interrupt source for a secondary CPU |
| 283 | * @irq_suspend: function called from core code on suspend once per chip | ||
| 284 | * @irq_resume: function called from core code on resume once per chip | ||
| 285 | * @irq_pm_shutdown: function called from core code on shutdown once per chip | ||
| 298 | * @irq_print_chip: optional to print special chip info in show_interrupts | 286 | * @irq_print_chip: optional to print special chip info in show_interrupts |
| 299 | * @flags: chip specific flags | 287 | * @flags: chip specific flags |
| 300 | * | 288 | * |
| @@ -324,6 +312,10 @@ struct irq_chip { | |||
| 324 | void (*irq_cpu_online)(struct irq_data *data); | 312 | void (*irq_cpu_online)(struct irq_data *data); |
| 325 | void (*irq_cpu_offline)(struct irq_data *data); | 313 | void (*irq_cpu_offline)(struct irq_data *data); |
| 326 | 314 | ||
| 315 | void (*irq_suspend)(struct irq_data *data); | ||
| 316 | void (*irq_resume)(struct irq_data *data); | ||
| 317 | void (*irq_pm_shutdown)(struct irq_data *data); | ||
| 318 | |||
| 327 | void (*irq_print_chip)(struct irq_data *data, struct seq_file *p); | 319 | void (*irq_print_chip)(struct irq_data *data, struct seq_file *p); |
| 328 | 320 | ||
| 329 | unsigned long flags; | 321 | unsigned long flags; |
| @@ -439,7 +431,7 @@ irq_set_handler(unsigned int irq, irq_flow_handler_t handle) | |||
| 439 | /* | 431 | /* |
| 440 | * Set a highlevel chained flow handler for a given IRQ. | 432 | * Set a highlevel chained flow handler for a given IRQ. |
| 441 | * (a chained handler is automatically enabled and set to | 433 | * (a chained handler is automatically enabled and set to |
| 442 | * IRQ_NOREQUEST and IRQ_NOPROBE) | 434 | * IRQ_NOREQUEST, IRQ_NOPROBE, and IRQ_NOTHREAD) |
| 443 | */ | 435 | */ |
| 444 | static inline void | 436 | static inline void |
| 445 | irq_set_chained_handler(unsigned int irq, irq_flow_handler_t handle) | 437 | irq_set_chained_handler(unsigned int irq, irq_flow_handler_t handle) |
| @@ -469,6 +461,16 @@ static inline void irq_set_probe(unsigned int irq) | |||
| 469 | irq_modify_status(irq, IRQ_NOPROBE, 0); | 461 | irq_modify_status(irq, IRQ_NOPROBE, 0); |
| 470 | } | 462 | } |
| 471 | 463 | ||
| 464 | static inline void irq_set_nothread(unsigned int irq) | ||
| 465 | { | ||
| 466 | irq_modify_status(irq, 0, IRQ_NOTHREAD); | ||
| 467 | } | ||
| 468 | |||
| 469 | static inline void irq_set_thread(unsigned int irq) | ||
| 470 | { | ||
| 471 | irq_modify_status(irq, IRQ_NOTHREAD, 0); | ||
| 472 | } | ||
| 473 | |||
| 472 | static inline void irq_set_nested_thread(unsigned int irq, bool nest) | 474 | static inline void irq_set_nested_thread(unsigned int irq, bool nest) |
| 473 | { | 475 | { |
| 474 | if (nest) | 476 | if (nest) |
| @@ -573,6 +575,145 @@ static inline int irq_reserve_irq(unsigned int irq) | |||
| 573 | return irq_reserve_irqs(irq, 1); | 575 | return irq_reserve_irqs(irq, 1); |
| 574 | } | 576 | } |
| 575 | 577 | ||
| 578 | #ifndef irq_reg_writel | ||
| 579 | # define irq_reg_writel(val, addr) writel(val, addr) | ||
| 580 | #endif | ||
| 581 | #ifndef irq_reg_readl | ||
| 582 | # define irq_reg_readl(addr) readl(addr) | ||
| 583 | #endif | ||
| 584 | |||
| 585 | /** | ||
| 586 | * struct irq_chip_regs - register offsets for struct irq_gci | ||
| 587 | * @enable: Enable register offset to reg_base | ||
| 588 | * @disable: Disable register offset to reg_base | ||
| 589 | * @mask: Mask register offset to reg_base | ||
| 590 | * @ack: Ack register offset to reg_base | ||
| 591 | * @eoi: Eoi register offset to reg_base | ||
| 592 | * @type: Type configuration register offset to reg_base | ||
| 593 | * @polarity: Polarity configuration register offset to reg_base | ||
| 594 | */ | ||
| 595 | struct irq_chip_regs { | ||
| 596 | unsigned long enable; | ||
| 597 | unsigned long disable; | ||
| 598 | unsigned long mask; | ||
| 599 | unsigned long ack; | ||
| 600 | unsigned long eoi; | ||
| 601 | unsigned long type; | ||
| 602 | unsigned long polarity; | ||
| 603 | }; | ||
| 604 | |||
| 605 | /** | ||
| 606 | * struct irq_chip_type - Generic interrupt chip instance for a flow type | ||
| 607 | * @chip: The real interrupt chip which provides the callbacks | ||
| 608 | * @regs: Register offsets for this chip | ||
| 609 | * @handler: Flow handler associated with this chip | ||
| 610 | * @type: Chip can handle these flow types | ||
| 611 | * | ||
| 612 | * A irq_generic_chip can have several instances of irq_chip_type when | ||
| 613 | * it requires different functions and register offsets for different | ||
| 614 | * flow types. | ||
| 615 | */ | ||
| 616 | struct irq_chip_type { | ||
| 617 | struct irq_chip chip; | ||
| 618 | struct irq_chip_regs regs; | ||
| 619 | irq_flow_handler_t handler; | ||
| 620 | u32 type; | ||
| 621 | }; | ||
| 622 | |||
| 623 | /** | ||
| 624 | * struct irq_chip_generic - Generic irq chip data structure | ||
| 625 | * @lock: Lock to protect register and cache data access | ||
| 626 | * @reg_base: Register base address (virtual) | ||
| 627 | * @irq_base: Interrupt base nr for this chip | ||
| 628 | * @irq_cnt: Number of interrupts handled by this chip | ||
| 629 | * @mask_cache: Cached mask register | ||
| 630 | * @type_cache: Cached type register | ||
| 631 | * @polarity_cache: Cached polarity register | ||
| 632 | * @wake_enabled: Interrupt can wakeup from suspend | ||
| 633 | * @wake_active: Interrupt is marked as an wakeup from suspend source | ||
| 634 | * @num_ct: Number of available irq_chip_type instances (usually 1) | ||
| 635 | * @private: Private data for non generic chip callbacks | ||
| 636 | * @list: List head for keeping track of instances | ||
| 637 | * @chip_types: Array of interrupt irq_chip_types | ||
| 638 | * | ||
| 639 | * Note, that irq_chip_generic can have multiple irq_chip_type | ||
| 640 | * implementations which can be associated to a particular irq line of | ||
| 641 | * an irq_chip_generic instance. That allows to share and protect | ||
| 642 | * state in an irq_chip_generic instance when we need to implement | ||
| 643 | * different flow mechanisms (level/edge) for it. | ||
| 644 | */ | ||
| 645 | struct irq_chip_generic { | ||
| 646 | raw_spinlock_t lock; | ||
| 647 | void __iomem *reg_base; | ||
| 648 | unsigned int irq_base; | ||
| 649 | unsigned int irq_cnt; | ||
| 650 | u32 mask_cache; | ||
| 651 | u32 type_cache; | ||
| 652 | u32 polarity_cache; | ||
| 653 | u32 wake_enabled; | ||
| 654 | u32 wake_active; | ||
| 655 | unsigned int num_ct; | ||
| 656 | void *private; | ||
| 657 | struct list_head list; | ||
| 658 | struct irq_chip_type chip_types[0]; | ||
| 659 | }; | ||
| 660 | |||
| 661 | /** | ||
| 662 | * enum irq_gc_flags - Initialization flags for generic irq chips | ||
| 663 | * @IRQ_GC_INIT_MASK_CACHE: Initialize the mask_cache by reading mask reg | ||
| 664 | * @IRQ_GC_INIT_NESTED_LOCK: Set the lock class of the irqs to nested for | ||
| 665 | * irq chips which need to call irq_set_wake() on | ||
| 666 | * the parent irq. Usually GPIO implementations | ||
| 667 | */ | ||
| 668 | enum irq_gc_flags { | ||
| 669 | IRQ_GC_INIT_MASK_CACHE = 1 << 0, | ||
| 670 | IRQ_GC_INIT_NESTED_LOCK = 1 << 1, | ||
| 671 | }; | ||
| 672 | |||
| 673 | /* Generic chip callback functions */ | ||
| 674 | void irq_gc_noop(struct irq_data *d); | ||
| 675 | void irq_gc_mask_disable_reg(struct irq_data *d); | ||
| 676 | void irq_gc_mask_set_bit(struct irq_data *d); | ||
| 677 | void irq_gc_mask_clr_bit(struct irq_data *d); | ||
| 678 | void irq_gc_unmask_enable_reg(struct irq_data *d); | ||
| 679 | void irq_gc_ack(struct irq_data *d); | ||
| 680 | void irq_gc_mask_disable_reg_and_ack(struct irq_data *d); | ||
| 681 | void irq_gc_eoi(struct irq_data *d); | ||
| 682 | int irq_gc_set_wake(struct irq_data *d, unsigned int on); | ||
| 683 | |||
| 684 | /* Setup functions for irq_chip_generic */ | ||
| 685 | struct irq_chip_generic * | ||
| 686 | irq_alloc_generic_chip(const char *name, int nr_ct, unsigned int irq_base, | ||
| 687 | void __iomem *reg_base, irq_flow_handler_t handler); | ||
| 688 | void irq_setup_generic_chip(struct irq_chip_generic *gc, u32 msk, | ||
| 689 | enum irq_gc_flags flags, unsigned int clr, | ||
| 690 | unsigned int set); | ||
| 691 | int irq_setup_alt_chip(struct irq_data *d, unsigned int type); | ||
| 692 | void irq_remove_generic_chip(struct irq_chip_generic *gc, u32 msk, | ||
| 693 | unsigned int clr, unsigned int set); | ||
| 694 | |||
| 695 | static inline struct irq_chip_type *irq_data_get_chip_type(struct irq_data *d) | ||
| 696 | { | ||
| 697 | return container_of(d->chip, struct irq_chip_type, chip); | ||
| 698 | } | ||
| 699 | |||
| 700 | #define IRQ_MSK(n) (u32)((n) < 32 ? ((1 << (n)) - 1) : UINT_MAX) | ||
| 701 | |||
| 702 | #ifdef CONFIG_SMP | ||
| 703 | static inline void irq_gc_lock(struct irq_chip_generic *gc) | ||
| 704 | { | ||
| 705 | raw_spin_lock(&gc->lock); | ||
| 706 | } | ||
| 707 | |||
| 708 | static inline void irq_gc_unlock(struct irq_chip_generic *gc) | ||
| 709 | { | ||
| 710 | raw_spin_unlock(&gc->lock); | ||
| 711 | } | ||
| 712 | #else | ||
| 713 | static inline void irq_gc_lock(struct irq_chip_generic *gc) { } | ||
| 714 | static inline void irq_gc_unlock(struct irq_chip_generic *gc) { } | ||
| 715 | #endif | ||
| 716 | |||
| 576 | #endif /* CONFIG_GENERIC_HARDIRQS */ | 717 | #endif /* CONFIG_GENERIC_HARDIRQS */ |
| 577 | 718 | ||
| 578 | #endif /* !CONFIG_S390 */ | 719 | #endif /* !CONFIG_S390 */ |
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h index a082905b5ebe..2d921b35212c 100644 --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h | |||
| @@ -16,16 +16,18 @@ struct timer_rand_state; | |||
| 16 | * @irq_data: per irq and chip data passed down to chip functions | 16 | * @irq_data: per irq and chip data passed down to chip functions |
| 17 | * @timer_rand_state: pointer to timer rand state struct | 17 | * @timer_rand_state: pointer to timer rand state struct |
| 18 | * @kstat_irqs: irq stats per cpu | 18 | * @kstat_irqs: irq stats per cpu |
| 19 | * @handle_irq: highlevel irq-events handler [if NULL, __do_IRQ()] | 19 | * @handle_irq: highlevel irq-events handler |
| 20 | * @preflow_handler: handler called before the flow handler (currently used by sparc) | ||
| 20 | * @action: the irq action chain | 21 | * @action: the irq action chain |
| 21 | * @status: status information | 22 | * @status: status information |
| 22 | * @core_internal_state__do_not_mess_with_it: core internal status information | 23 | * @core_internal_state__do_not_mess_with_it: core internal status information |
| 23 | * @depth: disable-depth, for nested irq_disable() calls | 24 | * @depth: disable-depth, for nested irq_disable() calls |
| 24 | * @wake_depth: enable depth, for multiple set_irq_wake() callers | 25 | * @wake_depth: enable depth, for multiple irq_set_irq_wake() callers |
| 25 | * @irq_count: stats field to detect stalled irqs | 26 | * @irq_count: stats field to detect stalled irqs |
| 26 | * @last_unhandled: aging timer for unhandled count | 27 | * @last_unhandled: aging timer for unhandled count |
| 27 | * @irqs_unhandled: stats field for spurious unhandled interrupts | 28 | * @irqs_unhandled: stats field for spurious unhandled interrupts |
| 28 | * @lock: locking for SMP | 29 | * @lock: locking for SMP |
| 30 | * @affinity_hint: hint to user space for preferred irq affinity | ||
| 29 | * @affinity_notify: context for notification of affinity changes | 31 | * @affinity_notify: context for notification of affinity changes |
| 30 | * @pending_mask: pending rebalanced interrupts | 32 | * @pending_mask: pending rebalanced interrupts |
| 31 | * @threads_oneshot: bitfield to handle shared oneshot threads | 33 | * @threads_oneshot: bitfield to handle shared oneshot threads |
| @@ -109,10 +111,7 @@ static inline void generic_handle_irq_desc(unsigned int irq, struct irq_desc *de | |||
| 109 | desc->handle_irq(irq, desc); | 111 | desc->handle_irq(irq, desc); |
| 110 | } | 112 | } |
| 111 | 113 | ||
| 112 | static inline void generic_handle_irq(unsigned int irq) | 114 | int generic_handle_irq(unsigned int irq); |
| 113 | { | ||
| 114 | generic_handle_irq_desc(irq, irq_to_desc(irq)); | ||
| 115 | } | ||
| 116 | 115 | ||
| 117 | /* Test to see if a driver has successfully requested an irq */ | 116 | /* Test to see if a driver has successfully requested an irq */ |
| 118 | static inline int irq_has_action(unsigned int irq) | 117 | static inline int irq_has_action(unsigned int irq) |
