From 1d99493b3a68e40e56459ea3565d4402fb6e5f3a Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 16 Oct 2007 23:26:29 -0700 Subject: Fix CONFIG_DEBUG_SHIRQ trigger on free_irq() 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 Signed-off-by: Linus Torvalds --- kernel/irq/manage.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 7230d914eaa2..80eab7a04205 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -405,7 +405,6 @@ void free_irq(unsigned int irq, void *dev_id) 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,21 @@ void free_irq(unsigned int irq, void *dev_id) /* Make sure it's not being used on another CPU */ synchronize_irq(irq); - if (action->flags & IRQF_SHARED) - handler = action->handler; +#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) { + local_irq_save(flags); + action->handler(irq, dev_id); + local_irq_restore(flags); + } +#endif kfree(action); return; } @@ -454,19 +466,6 @@ void free_irq(unsigned int irq, void *dev_id) 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 - */ - local_irq_save(flags); - handler(irq, dev_id); - local_irq_restore(flags); - } -#endif } EXPORT_SYMBOL(free_irq); -- cgit v1.2.3