From 04c848d398797a626608ff48804d809ae6687163 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 31 May 2017 11:58:33 +0200 Subject: genirq: Warn when IRQ_NOAUTOEN is used with shared interrupts Shared interrupts do not go well with disabling auto enable: 1) The sharing interrupt might request it while it's still disabled and then wait for interrupts forever. 2) The interrupt might have been requested by the driver sharing the line before IRQ_NOAUTOEN has been set. So the driver which expects that disabled state after calling request_irq() will not get what it wants. Even worse, when it calls enable_irq() later, it will trigger the unbalanced enable_irq() warning. Reported-by: Brian Norris Signed-off-by: Thomas Gleixner Cc: dianders@chromium.org Cc: jeffy Cc: Marc Zyngier Cc: tfiga@chromium.org Link: http://lkml.kernel.org/r/20170531100212.210682135@linutronix.de --- kernel/irq/manage.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'kernel/irq/manage.c') diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 57056109f176..49c37f1e71c0 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -1334,11 +1334,19 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) if (new->flags & IRQF_ONESHOT) desc->istate |= IRQS_ONESHOT; - if (irq_settings_can_autoenable(desc)) + if (irq_settings_can_autoenable(desc)) { irq_startup(desc, true); - else + } else { + /* + * Shared interrupts do not go well with disabling + * auto enable. The sharing interrupt might request + * it while it's still disabled and then wait for + * interrupts forever. + */ + WARN_ON_ONCE(new->flags & IRQF_SHARED); /* Undo nested disables: */ desc->depth = 1; + } /* Exclude IRQ from balancing if requested */ if (new->flags & IRQF_NOBALANCING) { -- cgit v1.2.3