diff options
| -rw-r--r-- | include/linux/irq.h | 1 | ||||
| -rw-r--r-- | kernel/irq/chip.c | 2 | ||||
| -rw-r--r-- | kernel/irq/internals.h | 2 | ||||
| -rw-r--r-- | kernel/irq/manage.c | 8 |
4 files changed, 7 insertions, 6 deletions
diff --git a/include/linux/irq.h b/include/linux/irq.h index 274590fc55a3..1a4c723e74e1 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
| @@ -71,7 +71,6 @@ typedef void (*irq_flow_handler_t)(unsigned int irq, | |||
| 71 | #define IRQ_MOVE_PCNTXT 0x01000000 /* IRQ migration from process context */ | 71 | #define IRQ_MOVE_PCNTXT 0x01000000 /* IRQ migration from process context */ |
| 72 | #define IRQ_AFFINITY_SET 0x02000000 /* IRQ affinity was set from userspace*/ | 72 | #define IRQ_AFFINITY_SET 0x02000000 /* IRQ affinity was set from userspace*/ |
| 73 | #define IRQ_SUSPENDED 0x04000000 /* IRQ has gone through suspend sequence */ | 73 | #define IRQ_SUSPENDED 0x04000000 /* IRQ has gone through suspend sequence */ |
| 74 | #define IRQ_ONESHOT 0x08000000 /* IRQ is not unmasked after hardirq */ | ||
| 75 | #define IRQ_NESTED_THREAD 0x10000000 /* IRQ is nested into another, no own handler thread */ | 74 | #define IRQ_NESTED_THREAD 0x10000000 /* IRQ is nested into another, no own handler thread */ |
| 76 | 75 | ||
| 77 | #define IRQF_MODIFY_MASK \ | 76 | #define IRQF_MODIFY_MASK \ |
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 075385549dcd..420fa6bdb117 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c | |||
| @@ -472,7 +472,7 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc) | |||
| 472 | 472 | ||
| 473 | handle_irq_event(desc); | 473 | handle_irq_event(desc); |
| 474 | 474 | ||
| 475 | if (!(desc->status & (IRQ_DISABLED | IRQ_ONESHOT))) | 475 | if (!(desc->status & IRQ_DISABLED) && !(desc->istate & IRQS_ONESHOT)) |
| 476 | unmask_irq(desc); | 476 | unmask_irq(desc); |
| 477 | out_unlock: | 477 | out_unlock: |
| 478 | raw_spin_unlock(&desc->lock); | 478 | raw_spin_unlock(&desc->lock); |
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h index d1cb1f8df6fe..36563f731ff8 100644 --- a/kernel/irq/internals.h +++ b/kernel/irq/internals.h | |||
| @@ -42,12 +42,14 @@ enum { | |||
| 42 | * detection | 42 | * detection |
| 43 | * IRQS_POLL_INPROGRESS - polling in progress | 43 | * IRQS_POLL_INPROGRESS - polling in progress |
| 44 | * IRQS_INPROGRESS - Interrupt in progress | 44 | * IRQS_INPROGRESS - Interrupt in progress |
| 45 | * IRQS_ONESHOT - irq is not unmasked in primary handler | ||
| 45 | */ | 46 | */ |
| 46 | enum { | 47 | enum { |
| 47 | IRQS_AUTODETECT = 0x00000001, | 48 | IRQS_AUTODETECT = 0x00000001, |
| 48 | IRQS_SPURIOUS_DISABLED = 0x00000002, | 49 | IRQS_SPURIOUS_DISABLED = 0x00000002, |
| 49 | IRQS_POLL_INPROGRESS = 0x00000008, | 50 | IRQS_POLL_INPROGRESS = 0x00000008, |
| 50 | IRQS_INPROGRESS = 0x00000010, | 51 | IRQS_INPROGRESS = 0x00000010, |
| 52 | IRQS_ONESHOT = 0x00000020, | ||
| 51 | }; | 53 | }; |
| 52 | 54 | ||
| 53 | #define irq_data_to_desc(data) container_of(data, struct irq_desc, irq_data) | 55 | #define irq_data_to_desc(data) container_of(data, struct irq_desc, irq_data) |
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 7e5a50825088..aca4208a03ac 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
| @@ -697,7 +697,7 @@ static int irq_thread(void *data) | |||
| 697 | }; | 697 | }; |
| 698 | struct irqaction *action = data; | 698 | struct irqaction *action = data; |
| 699 | struct irq_desc *desc = irq_to_desc(action->irq); | 699 | struct irq_desc *desc = irq_to_desc(action->irq); |
| 700 | int wake, oneshot = desc->status & IRQ_ONESHOT; | 700 | int wake, oneshot = desc->istate & IRQS_ONESHOT; |
| 701 | 701 | ||
| 702 | sched_setscheduler(current, SCHED_FIFO, ¶m); | 702 | sched_setscheduler(current, SCHED_FIFO, ¶m); |
| 703 | current->irqaction = action; | 703 | current->irqaction = action; |
| @@ -897,12 +897,12 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
| 897 | desc->status |= IRQ_PER_CPU; | 897 | desc->status |= IRQ_PER_CPU; |
| 898 | #endif | 898 | #endif |
| 899 | 899 | ||
| 900 | desc->status &= ~(IRQ_WAITING | IRQ_ONESHOT); | 900 | desc->status &= ~IRQ_WAITING; |
| 901 | desc->istate &= ~(IRQS_AUTODETECT | IRQS_SPURIOUS_DISABLED | \ | 901 | desc->istate &= ~(IRQS_AUTODETECT | IRQS_SPURIOUS_DISABLED | \ |
| 902 | IRQS_INPROGRESS); | 902 | IRQS_INPROGRESS | IRQS_ONESHOT); |
| 903 | 903 | ||
| 904 | if (new->flags & IRQF_ONESHOT) | 904 | if (new->flags & IRQF_ONESHOT) |
| 905 | desc->status |= IRQ_ONESHOT; | 905 | desc->istate |= IRQS_ONESHOT; |
| 906 | 906 | ||
| 907 | if (!(desc->status & IRQ_NOAUTOEN)) | 907 | if (!(desc->status & IRQ_NOAUTOEN)) |
| 908 | irq_startup(desc); | 908 | irq_startup(desc); |
