diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-03 19:56:44 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-03 19:56:44 +0200 |
commit | 148311d2ade909a79afb85a853c7979eb499563f (patch) | |
tree | 6dde0ac8804b729e084c3bef7226b10d661f12da /kernel/irq/manage.c | |
parent | Merge tag 'for_linux-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/gi... (diff) | |
parent | genirq: Allow irq chips to mark themself oneshot safe (diff) | |
download | linux-148311d2ade909a79afb85a853c7979eb499563f.tar.xz linux-148311d2ade909a79afb85a853c7979eb499563f.zip |
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
Diffstat (limited to 'kernel/irq/manage.c')
-rw-r--r-- | kernel/irq/manage.c | 15 |
1 files changed, 14 insertions, 1 deletions
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) } /* + * Drivers are often written to work w/o knowledge about the + * underlying irq chip implementation, so a request for a + * threaded irq without a primary hard irq context handler + * requires the ONESHOT flag to be set. Some irq chips like + * MSI based interrupts are per se one shot safe. Check the + * chip flags, so we can avoid the unmask dance at the end of + * the threaded handler for those. + */ + if (desc->irq_data.chip->flags & IRQCHIP_ONESHOT_SAFE) + new->flags &= ~IRQF_ONESHOT; + + /* * The following block of code has to be executed atomically */ raw_spin_lock_irqsave(&desc->lock, flags); @@ -1017,7 +1029,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) */ new->thread_mask = 1 << ffz(thread_mask); - } else if (new->handler == irq_default_primary_handler) { + } else if (new->handler == irq_default_primary_handler && + !(desc->irq_data.chip->flags & IRQCHIP_ONESHOT_SAFE)) { /* * The interrupt was requested with handler = NULL, so * we use the default primary handler for it. But it |