irq fix
Linus,
Please pull the latest irq-urgent-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus
HEAD: dc9b229a58dc0dfed34272ff26c6d5fd17c674e0 genirq: Allow irq chips to mark themself oneshot safe
Thanks,
Ingo
------------------>
Thomas Gleixner (1):
genirq: Allow irq chips to mark themself oneshot safe
include/linux/irq.h | 1 + kernel/irq/manage.c | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-)
include/linux/irq.h +1 -0
@@ -349,6 +349,7 @@ enum {IRQCHIP_MASK_ON_SUSPEND = (1 <<2 ),IRQCHIP_ONOFFLINE_ENABLED = (1 <<3 ),IRQCHIP_SKIP_SET_WAKE = (1 <<4 ), + IRQCHIP_ONESHOT_SAFE = (1 << 5), };/* This include will go away once we isolated irq_desc usage to core code */
kernel/irq/manage.c +14 -1
@@ -960,6 +960,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);
@@ -1033,7 +1045,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