From: David Woodhouse Andy Gospodarek pointed out that because we return in the middle of the free_irq() function, we never actually do call the IRQ handler that just got deregistered. This should fix it, although I expect Andrew will want to convert those 'return's to 'break'. That's a separate change though. Signed-off-by: David Woodhouse Cc: Andy Gospodarek Cc: Fernando Luis Vzquez Cao Signed-off-by: Andrew Morton --- kernel/irq/manage.c | 24 +++++++++++------------- 1 files changed, 11 insertions(+), 13 deletions(-) diff -puN kernel/irq/manage.c~fix-config_debug_shirq-trigger-on-free_irq kernel/irq/manage.c --- a/kernel/irq/manage.c~fix-config_debug_shirq-trigger-on-free_irq +++ a/kernel/irq/manage.c @@ -405,7 +405,6 @@ void free_irq(unsigned int irq, void *de struct irq_desc *desc; struct irqaction **p; unsigned long flags; - irqreturn_t (*handler)(int, void *) = NULL; WARN_ON(in_interrupt()); if (irq >= NR_IRQS) @@ -445,8 +444,18 @@ void free_irq(unsigned int irq, void *de /* Make sure it's not being used on another CPU */ synchronize_irq(irq); +#ifdef CONFIG_DEBUG_SHIRQ + /* + * It's a shared IRQ -- the driver ought to be + * prepared for it to happen even now it's + * being freed, so let's make sure.... We do + * this after actually deregistering it, to + * make sure that a 'real' IRQ doesn't run in + * parallel with our fake + */ if (action->flags & IRQF_SHARED) - handler = action->handler; + action->handler(irq, dev_id); +#endif kfree(action); return; } @@ -454,17 +463,6 @@ void free_irq(unsigned int irq, void *de spin_unlock_irqrestore(&desc->lock, flags); return; } -#ifdef CONFIG_DEBUG_SHIRQ - if (handler) { - /* - * It's a shared IRQ -- the driver ought to be prepared for it - * to happen even now it's being freed, so let's make sure.... - * We do this after actually deregistering it, to make sure that - * a 'real' IRQ doesn't run in parallel with our fake - */ - handler(irq, dev_id); - } -#endif } EXPORT_SYMBOL(free_irq); _