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 <dwmw2@infradead.org>
Cc: Andy Gospodarek <andy@greyhouse.net>
Cc: Fernando Luis Vzquez Cao <fernando@oss.ntt.co.jp>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 7230d91..80eab7a0 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -405,7 +405,6 @@
 	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 @@
 
 			/* 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 @@
 		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);