diff options
| author | Jiri Kosina <jkosina@suse.cz> | 2011-11-13 14:55:35 -0500 |
|---|---|---|
| committer | Jiri Kosina <jkosina@suse.cz> | 2011-11-13 14:55:53 -0500 |
| commit | 2290c0d06d82faee87b1ab2d9d4f7bf81ef64379 (patch) | |
| tree | e075e4d5534193f28e6059904f61e5ca03958d3c /kernel/irq/chip.c | |
| parent | 4da669a2e3e5bc70b30a0465f3641528681b5f77 (diff) | |
| parent | 52e4c2a05256cb83cda12f3c2137ab1533344edb (diff) | |
Merge branch 'master' into for-next
Sync with Linus tree to have 157550ff ("mtd: add GPMI-NAND driver
in the config and Makefile") as I have patch depending on that one.
Diffstat (limited to 'kernel/irq/chip.c')
| -rw-r--r-- | kernel/irq/chip.c | 64 |
1 files changed, 57 insertions, 7 deletions
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index dc5114b4c16c..f7c543a801d9 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | int irq_set_chip(unsigned int irq, struct irq_chip *chip) | 26 | int irq_set_chip(unsigned int irq, struct irq_chip *chip) |
| 27 | { | 27 | { |
| 28 | unsigned long flags; | 28 | unsigned long flags; |
| 29 | struct irq_desc *desc = irq_get_desc_lock(irq, &flags); | 29 | struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0); |
| 30 | 30 | ||
| 31 | if (!desc) | 31 | if (!desc) |
| 32 | return -EINVAL; | 32 | return -EINVAL; |
| @@ -54,7 +54,7 @@ EXPORT_SYMBOL(irq_set_chip); | |||
| 54 | int irq_set_irq_type(unsigned int irq, unsigned int type) | 54 | int irq_set_irq_type(unsigned int irq, unsigned int type) |
| 55 | { | 55 | { |
| 56 | unsigned long flags; | 56 | unsigned long flags; |
| 57 | struct irq_desc *desc = irq_get_desc_buslock(irq, &flags); | 57 | struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL); |
| 58 | int ret = 0; | 58 | int ret = 0; |
| 59 | 59 | ||
| 60 | if (!desc) | 60 | if (!desc) |
| @@ -78,7 +78,7 @@ EXPORT_SYMBOL(irq_set_irq_type); | |||
| 78 | int irq_set_handler_data(unsigned int irq, void *data) | 78 | int irq_set_handler_data(unsigned int irq, void *data) |
| 79 | { | 79 | { |
| 80 | unsigned long flags; | 80 | unsigned long flags; |
| 81 | struct irq_desc *desc = irq_get_desc_lock(irq, &flags); | 81 | struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0); |
| 82 | 82 | ||
| 83 | if (!desc) | 83 | if (!desc) |
| 84 | return -EINVAL; | 84 | return -EINVAL; |
| @@ -98,7 +98,7 @@ EXPORT_SYMBOL(irq_set_handler_data); | |||
| 98 | int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry) | 98 | int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry) |
| 99 | { | 99 | { |
| 100 | unsigned long flags; | 100 | unsigned long flags; |
| 101 | struct irq_desc *desc = irq_get_desc_lock(irq, &flags); | 101 | struct irq_desc *desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL); |
| 102 | 102 | ||
| 103 | if (!desc) | 103 | if (!desc) |
| 104 | return -EINVAL; | 104 | return -EINVAL; |
| @@ -119,7 +119,7 @@ int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry) | |||
| 119 | int irq_set_chip_data(unsigned int irq, void *data) | 119 | int irq_set_chip_data(unsigned int irq, void *data) |
| 120 | { | 120 | { |
| 121 | unsigned long flags; | 121 | unsigned long flags; |
| 122 | struct irq_desc *desc = irq_get_desc_lock(irq, &flags); | 122 | struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0); |
| 123 | 123 | ||
| 124 | if (!desc) | 124 | if (!desc) |
| 125 | return -EINVAL; | 125 | return -EINVAL; |
| @@ -204,6 +204,24 @@ void irq_disable(struct irq_desc *desc) | |||
| 204 | } | 204 | } |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | void irq_percpu_enable(struct irq_desc *desc, unsigned int cpu) | ||
| 208 | { | ||
| 209 | if (desc->irq_data.chip->irq_enable) | ||
| 210 | desc->irq_data.chip->irq_enable(&desc->irq_data); | ||
| 211 | else | ||
| 212 | desc->irq_data.chip->irq_unmask(&desc->irq_data); | ||
| 213 | cpumask_set_cpu(cpu, desc->percpu_enabled); | ||
| 214 | } | ||
| 215 | |||
| 216 | void irq_percpu_disable(struct irq_desc *desc, unsigned int cpu) | ||
| 217 | { | ||
| 218 | if (desc->irq_data.chip->irq_disable) | ||
| 219 | desc->irq_data.chip->irq_disable(&desc->irq_data); | ||
| 220 | else | ||
| 221 | desc->irq_data.chip->irq_mask(&desc->irq_data); | ||
| 222 | cpumask_clear_cpu(cpu, desc->percpu_enabled); | ||
| 223 | } | ||
| 224 | |||
| 207 | static inline void mask_ack_irq(struct irq_desc *desc) | 225 | static inline void mask_ack_irq(struct irq_desc *desc) |
| 208 | { | 226 | { |
| 209 | if (desc->irq_data.chip->irq_mask_ack) | 227 | if (desc->irq_data.chip->irq_mask_ack) |
| @@ -544,12 +562,44 @@ handle_percpu_irq(unsigned int irq, struct irq_desc *desc) | |||
| 544 | chip->irq_eoi(&desc->irq_data); | 562 | chip->irq_eoi(&desc->irq_data); |
| 545 | } | 563 | } |
| 546 | 564 | ||
| 565 | /** | ||
| 566 | * handle_percpu_devid_irq - Per CPU local irq handler with per cpu dev ids | ||
| 567 | * @irq: the interrupt number | ||
| 568 | * @desc: the interrupt description structure for this irq | ||
| 569 | * | ||
| 570 | * Per CPU interrupts on SMP machines without locking requirements. Same as | ||
| 571 | * handle_percpu_irq() above but with the following extras: | ||
| 572 | * | ||
| 573 | * action->percpu_dev_id is a pointer to percpu variables which | ||
| 574 | * contain the real device id for the cpu on which this handler is | ||
| 575 | * called | ||
| 576 | */ | ||
| 577 | void handle_percpu_devid_irq(unsigned int irq, struct irq_desc *desc) | ||
| 578 | { | ||
| 579 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
| 580 | struct irqaction *action = desc->action; | ||
| 581 | void *dev_id = __this_cpu_ptr(action->percpu_dev_id); | ||
| 582 | irqreturn_t res; | ||
| 583 | |||
| 584 | kstat_incr_irqs_this_cpu(irq, desc); | ||
| 585 | |||
| 586 | if (chip->irq_ack) | ||
| 587 | chip->irq_ack(&desc->irq_data); | ||
| 588 | |||
| 589 | trace_irq_handler_entry(irq, action); | ||
| 590 | res = action->handler(irq, dev_id); | ||
| 591 | trace_irq_handler_exit(irq, action, res); | ||
| 592 | |||
| 593 | if (chip->irq_eoi) | ||
| 594 | chip->irq_eoi(&desc->irq_data); | ||
| 595 | } | ||
| 596 | |||
| 547 | void | 597 | void |
| 548 | __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, | 598 | __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, |
| 549 | const char *name) | 599 | const char *name) |
| 550 | { | 600 | { |
| 551 | unsigned long flags; | 601 | unsigned long flags; |
| 552 | struct irq_desc *desc = irq_get_desc_buslock(irq, &flags); | 602 | struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0); |
| 553 | 603 | ||
| 554 | if (!desc) | 604 | if (!desc) |
| 555 | return; | 605 | return; |
| @@ -593,7 +643,7 @@ irq_set_chip_and_handler_name(unsigned int irq, struct irq_chip *chip, | |||
| 593 | void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set) | 643 | void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set) |
| 594 | { | 644 | { |
| 595 | unsigned long flags; | 645 | unsigned long flags; |
| 596 | struct irq_desc *desc = irq_get_desc_lock(irq, &flags); | 646 | struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0); |
| 597 | 647 | ||
| 598 | if (!desc) | 648 | if (!desc) |
| 599 | return; | 649 | return; |
