diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-03 13:56:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-03 13:56:44 -0400 |
commit | 148311d2ade909a79afb85a853c7979eb499563f (patch) | |
tree | 6dde0ac8804b729e084c3bef7226b10d661f12da | |
parent | d97e1dcde5e19ed1f828baff4ab5fd0e517c8dae (diff) | |
parent | dc9b229a58dc0dfed34272ff26c6d5fd17c674e0 (diff) |
Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq fix from Ingo Molnar.
* 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
genirq: Allow irq chips to mark themself oneshot safe
-rw-r--r-- | include/linux/irq.h | 1 | ||||
-rw-r--r-- | kernel/irq/manage.c | 15 |
2 files changed, 15 insertions, 1 deletions
diff --git a/include/linux/irq.h b/include/linux/irq.h index 553fb66da130..216b0ba109d7 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
@@ -349,6 +349,7 @@ enum { | |||
349 | IRQCHIP_MASK_ON_SUSPEND = (1 << 2), | 349 | IRQCHIP_MASK_ON_SUSPEND = (1 << 2), |
350 | IRQCHIP_ONOFFLINE_ENABLED = (1 << 3), | 350 | IRQCHIP_ONOFFLINE_ENABLED = (1 << 3), |
351 | IRQCHIP_SKIP_SET_WAKE = (1 << 4), | 351 | IRQCHIP_SKIP_SET_WAKE = (1 << 4), |
352 | IRQCHIP_ONESHOT_SAFE = (1 << 5), | ||
352 | }; | 353 | }; |
353 | 354 | ||
354 | /* This include will go away once we isolated irq_desc usage to core code */ | 355 | /* This include will go away once we isolated irq_desc usage to core code */ |
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 0a8e8f059627..4c69326aa773 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -944,6 +944,18 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
944 | } | 944 | } |
945 | 945 | ||
946 | /* | 946 | /* |
947 | * Drivers are often written to work w/o knowledge about the | ||
948 | * underlying irq chip implementation, so a request for a | ||
949 | * threaded irq without a primary hard irq context handler | ||
950 | * requires the ONESHOT flag to be set. Some irq chips like | ||
951 | * MSI based interrupts are per se one shot safe. Check the | ||
952 | * chip flags, so we can avoid the unmask dance at the end of | ||
953 | * the threaded handler for those. | ||
954 | */ | ||
955 | if (desc->irq_data.chip->flags & IRQCHIP_ONESHOT_SAFE) | ||
956 | new->flags &= ~IRQF_ONESHOT; | ||
957 | |||
958 | /* | ||
947 | * The following block of code has to be executed atomically | 959 | * The following block of code has to be executed atomically |
948 | */ | 960 | */ |
949 | raw_spin_lock_irqsave(&desc->lock, flags); | 961 | raw_spin_lock_irqsave(&desc->lock, flags); |
@@ -1017,7 +1029,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
1017 | */ | 1029 | */ |
1018 | new->thread_mask = 1 << ffz(thread_mask); | 1030 | new->thread_mask = 1 << ffz(thread_mask); |
1019 | 1031 | ||
1020 | } else if (new->handler == irq_default_primary_handler) { | 1032 | } else if (new->handler == irq_default_primary_handler && |
1033 | !(desc->irq_data.chip->flags & IRQCHIP_ONESHOT_SAFE)) { | ||
1021 | /* | 1034 | /* |
1022 | * The interrupt was requested with handler = NULL, so | 1035 | * The interrupt was requested with handler = NULL, so |
1023 | * we use the default primary handler for it. But it | 1036 | * we use the default primary handler for it. But it |