[PATCH] genirq: add ->retrigger() irq op to consolidate hw_irq_resend()

Add ->retrigger() irq op to consolidate hw_irq_resend() implementations.
(Most architectures had it defined to NOP anyway.)

NOTE: ia64 needs testing. i386 and x86_64 tested.

Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index afe54f2..ec9ea02 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -2071,6 +2071,13 @@
 #endif
 #endif
 
+static int ioapic_retrigger(unsigned int irq)
+{
+	send_IPI_self(IO_APIC_VECTOR(irq));
+
+	return 1;
+}
+
 /*
  * Level and edge triggered IO-APIC interrupts need different handling,
  * so we use two separate IRQ descriptors. Edge triggered IRQs can be
@@ -2090,6 +2097,7 @@
 #ifdef CONFIG_SMP
 	.set_affinity 	= set_ioapic_affinity,
 #endif
+	.retrigger	= ioapic_retrigger,
 };
 
 static struct hw_interrupt_type ioapic_level_type __read_mostly = {
@@ -2103,6 +2111,7 @@
 #ifdef CONFIG_SMP
 	.set_affinity 	= set_ioapic_affinity,
 #endif
+	.retrigger	= ioapic_retrigger,
 };
 
 static inline void init_IO_APIC_traps(void)
diff --git a/arch/ia64/kernel/irq_lsapic.c b/arch/ia64/kernel/irq_lsapic.c
index ea14e6a..1ab58b0 100644
--- a/arch/ia64/kernel/irq_lsapic.c
+++ b/arch/ia64/kernel/irq_lsapic.c
@@ -26,6 +26,13 @@
 	/* nuthing to do... */
 }
 
+static int lsapic_retrigger(unsigned int irq)
+{
+	ia64_resend_irq(irq);
+
+	return 1;
+}
+
 struct hw_interrupt_type irq_type_ia64_lsapic = {
 	.typename =	"LSAPIC",
 	.startup =	lsapic_noop_startup,
@@ -33,5 +40,6 @@
 	.enable =	lsapic_noop,
 	.disable =	lsapic_noop,
 	.ack =		lsapic_noop,
-	.end =		lsapic_noop
+	.end =		lsapic_noop,
+	.retrigger =	lsapic_retrigger,
 };
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index 6d7bc8f..a0055d3 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -6165,7 +6165,7 @@
 		/*
 		 * will replay the PMU interrupt
 		 */
-		if (need_irq_resend) hw_resend_irq(NULL, IA64_PERFMON_VECTOR);
+		if (need_irq_resend) ia64_resend_irq(IA64_PERFMON_VECTOR);
 
 		pfm_stats[smp_processor_id()].pfm_replay_ovfl_intr_count++;
 	}
@@ -6305,7 +6305,7 @@
 		/*
 		 * will replay the PMU interrupt
 		 */
-		if (need_irq_resend) hw_resend_irq(NULL, IA64_PERFMON_VECTOR);
+		if (need_irq_resend) ia64_resend_irq(IA64_PERFMON_VECTOR);
 
 		pfm_stats[smp_processor_id()].pfm_replay_ovfl_intr_count++;
 	}
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index ea6a55e..82fe6ba 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -125,6 +125,10 @@
 #ifdef CONFIG_SMP
 	.set_affinity	= cpu_set_affinity_irq,
 #endif
+	/* XXX: Needs to be written.  We managed without it so far, but
+	 * we really ought to write it.
+	 */
+	.retrigger	= NULL,
 };
 
 int show_interrupts(struct seq_file *p, void *v)
@@ -404,13 +408,6 @@
 
 }
 
-void hw_resend_irq(struct hw_interrupt_type *type, unsigned int irq)
-{
-	/* XXX: Needs to be written.  We managed without it so far, but
-	 * we really ought to write it.
-	 */
-}
-
 void ack_bad_irq(unsigned int irq)
 {
 	printk("unexpected IRQ %d\n", irq);
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index 88a8736..401b687 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -1618,6 +1618,13 @@
 #endif // CONFIG_SMP
 #endif // CONFIG_PCI_MSI
 
+static int ioapic_retrigger(unsigned int irq)
+{
+	send_IPI_self(IO_APIC_VECTOR(irq));
+
+	return 1;
+}
+
 /*
  * Level and edge triggered IO-APIC interrupts need different handling,
  * so we use two separate IRQ descriptors. Edge triggered IRQs can be
@@ -1638,6 +1645,7 @@
 #ifdef CONFIG_SMP
 	.set_affinity = set_ioapic_affinity,
 #endif
+	.retrigger	= ioapic_retrigger,
 };
 
 static struct hw_interrupt_type ioapic_level_type __read_mostly = {
@@ -1651,6 +1659,7 @@
 #ifdef CONFIG_SMP
 	.set_affinity = set_ioapic_affinity,
 #endif
+	.retrigger	= ioapic_retrigger,
 };
 
 static inline void init_IO_APIC_traps(void)
diff --git a/include/asm-alpha/hw_irq.h b/include/asm-alpha/hw_irq.h
index ca9d43b..a37db0f 100644
--- a/include/asm-alpha/hw_irq.h
+++ b/include/asm-alpha/hw_irq.h
@@ -2,8 +2,6 @@
 #define _ALPHA_HW_IRQ_H
 
 
-static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
-
 extern volatile unsigned long irq_err_count;
 
 #ifdef CONFIG_ALPHA_GENERIC
diff --git a/include/asm-cris/hw_irq.h b/include/asm-cris/hw_irq.h
index 341536a..2980660 100644
--- a/include/asm-cris/hw_irq.h
+++ b/include/asm-cris/hw_irq.h
@@ -1,7 +1,5 @@
 #ifndef _ASM_HW_IRQ_H
 #define _ASM_HW_IRQ_H
 
-static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
-
 #endif
 
diff --git a/include/asm-i386/hw_irq.h b/include/asm-i386/hw_irq.h
index a4c0a5a..87e5a35 100644
--- a/include/asm-i386/hw_irq.h
+++ b/include/asm-i386/hw_irq.h
@@ -69,14 +69,4 @@
 
 #define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs))
 
-#if defined(CONFIG_X86_IO_APIC)
-static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
-{
-	if (IO_APIC_IRQ(i))
-		send_IPI_self(IO_APIC_VECTOR(i));
-}
-#else
-static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
-#endif
-
 #endif /* _ASM_HW_IRQ_H */
diff --git a/include/asm-ia64/hw_irq.h b/include/asm-ia64/hw_irq.h
index ea8b8c4..27f9df6 100644
--- a/include/asm-ia64/hw_irq.h
+++ b/include/asm-ia64/hw_irq.h
@@ -97,8 +97,7 @@
 extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect);
 extern void register_percpu_irq (ia64_vector vec, struct irqaction *action);
 
-static inline void
-hw_resend_irq (struct hw_interrupt_type *h, unsigned int vector)
+static inline void ia64_resend_irq(unsigned int vector)
 {
 	platform_send_ipi(smp_processor_id(), vector, IA64_IPI_DM_INT, 0);
 }
diff --git a/include/asm-m32r/hw_irq.h b/include/asm-m32r/hw_irq.h
index 8d7e9d0..7138537 100644
--- a/include/asm-m32r/hw_irq.h
+++ b/include/asm-m32r/hw_irq.h
@@ -1,9 +1,4 @@
 #ifndef _ASM_M32R_HW_IRQ_H
 #define _ASM_M32R_HW_IRQ_H
 
-static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
-{
-	/* Nothing to do */
-}
-
 #endif /* _ASM_M32R_HW_IRQ_H */
diff --git a/include/asm-mips/hw_irq.h b/include/asm-mips/hw_irq.h
index c854d01..458d9fd 100644
--- a/include/asm-mips/hw_irq.h
+++ b/include/asm-mips/hw_irq.h
@@ -19,9 +19,9 @@
 
 extern atomic_t irq_err_count;
 
-/* This may not be apropriate for all machines, we'll see ...  */
-static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
-{
-}
+/*
+ * interrupt-retrigger: NOP for now. This may not be apropriate for all
+ * machines, we'll see ...
+ */
 
 #endif /* __ASM_HW_IRQ_H */
diff --git a/include/asm-parisc/hw_irq.h b/include/asm-parisc/hw_irq.h
index 151426e..6707f7d 100644
--- a/include/asm-parisc/hw_irq.h
+++ b/include/asm-parisc/hw_irq.h
@@ -3,15 +3,6 @@
 
 /*
  *	linux/include/asm/hw_irq.h
- *
- *	(C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar
- *
- *	moved some of the old arch/i386/kernel/irq.h to here. VY
- *
- *	IRQ/IPI changes taken from work by Thomas Radke
- *	<tomsoft@informatik.tu-chemnitz.de>
  */
 
-extern void hw_resend_irq(struct hw_interrupt_type *, unsigned int);
-
 #endif
diff --git a/include/asm-powerpc/hw_irq.h b/include/asm-powerpc/hw_irq.h
index a27ed3f..d403592 100644
--- a/include/asm-powerpc/hw_irq.h
+++ b/include/asm-powerpc/hw_irq.h
@@ -102,11 +102,11 @@
 			desc->chip->ack(irq);		\
 	})
 
-/* Should we handle this via lost interrupts and IPIs or should we don't care like
- * we do now ? --BenH.
+/*
+ * interrupt-retrigger: should we handle this via lost interrupts and IPIs
+ * or should we not care like we do now ? --BenH.
  */
 struct hw_interrupt_type;
-static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
 
 #endif	/* __KERNEL__ */
 #endif	/* _ASM_POWERPC_HW_IRQ_H */
diff --git a/include/asm-sh/hw_irq.h b/include/asm-sh/hw_irq.h
index 1d934fb..fed2661 100644
--- a/include/asm-sh/hw_irq.h
+++ b/include/asm-sh/hw_irq.h
@@ -1,9 +1,4 @@
 #ifndef __ASM_SH_HW_IRQ_H
 #define __ASM_SH_HW_IRQ_H
 
-static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
-{
-	/* Nothing to do */
-}
-
 #endif /* __ASM_SH_HW_IRQ_H */
diff --git a/include/asm-sh64/hw_irq.h b/include/asm-sh64/hw_irq.h
index ae718d1..ebb3908 100644
--- a/include/asm-sh64/hw_irq.h
+++ b/include/asm-sh64/hw_irq.h
@@ -11,6 +11,5 @@
  * Copyright (C) 2000, 2001  Paolo Alberelli
  *
  */
-static __inline__ void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) { /* Nothing to do */ }
 
 #endif /* __ASM_SH64_HW_IRQ_H */
diff --git a/include/asm-um/hw_irq.h b/include/asm-um/hw_irq.h
index 4ee38c0..1cf84cf 100644
--- a/include/asm-um/hw_irq.h
+++ b/include/asm-um/hw_irq.h
@@ -4,7 +4,4 @@
 #include "asm/irq.h"
 #include "asm/archparam.h"
 
-static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
-{}
-
 #endif
diff --git a/include/asm-v850/hw_irq.h b/include/asm-v850/hw_irq.h
index a8aab43..043e94b 100644
--- a/include/asm-v850/hw_irq.h
+++ b/include/asm-v850/hw_irq.h
@@ -1,8 +1,4 @@
 #ifndef __V850_HW_IRQ_H__
 #define __V850_HW_IRQ_H__
 
-static inline void hw_resend_irq (struct hw_interrupt_type *h, unsigned int i)
-{
-}
-
 #endif /* __V850_HW_IRQ_H__ */
diff --git a/include/asm-x86_64/hw_irq.h b/include/asm-x86_64/hw_irq.h
index 9318774..48a4a53 100644
--- a/include/asm-x86_64/hw_irq.h
+++ b/include/asm-x86_64/hw_irq.h
@@ -127,15 +127,6 @@
 	"push $~(" #nr ") ; " \
 	"jmp common_interrupt");
 
-#if defined(CONFIG_X86_IO_APIC)
-static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {
-	if (IO_APIC_IRQ(i))
-		send_IPI_self(IO_APIC_VECTOR(i));
-}
-#else
-static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
-#endif
-
 #define platform_legacy_irq(irq)	((irq) < 16)
 
 #endif
diff --git a/include/asm-xtensa/hw_irq.h b/include/asm-xtensa/hw_irq.h
index ccf4362..3ddbea7 100644
--- a/include/asm-xtensa/hw_irq.h
+++ b/include/asm-xtensa/hw_irq.h
@@ -11,8 +11,4 @@
 #ifndef _XTENSA_HW_IRQ_H
 #define _XTENSA_HW_IRQ_H
 
-static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
-{
-}
-
 #endif
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 519a1cb..e58cfb9 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -53,6 +53,8 @@
 	void		(*ack)(unsigned int irq);
 	void		(*end)(unsigned int irq);
 	void		(*set_affinity)(unsigned int irq, cpumask_t dest);
+	int		(*retrigger)(unsigned int irq);
+
 	/* Currently used only by UML, might disappear one day.*/
 #ifdef CONFIG_IRQ_RELEASE_METHOD
 	void		(*release)(unsigned int irq, void *dev_id);
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 76c8eda..19b438e 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -123,7 +123,8 @@
 		desc->status = status;
 		if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
 			desc->status = status | IRQ_REPLAY;
-			hw_resend_irq(desc->chip,irq);
+			if (desc->chip && desc->chip->retrigger)
+				desc->chip->retrigger(irq);
 		}
 		desc->chip->enable(irq);
 		/* fall-through */