[PARISC] Fix our interrupts not to use smp_call_function

Fix our interrupts not to use smp_call_function

On K and D class smp, the generic code calls this under an irq
spinlock, which causes the WARN_ON() message in smp_call_function()
(and is also illegal because it could deadlock).

The fix is to use a new scheme based on the IPI_NOP.

Signed-off-by: James Bottomley <jejb@parisc-linux.org>
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index 268b0f2..ce89da0 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -181,12 +181,19 @@
 		while (ops) {
 			unsigned long which = ffz(~ops);
 
+			ops &= ~(1 << which);
+
 			switch (which) {
+			case IPI_NOP:
+#if (kDEBUG>=100)
+				printk(KERN_DEBUG "CPU%d IPI_NOP\n",this_cpu);
+#endif /* kDEBUG */
+				break;
+				
 			case IPI_RESCHEDULE:
 #if (kDEBUG>=100)
 				printk(KERN_DEBUG "CPU%d IPI_RESCHEDULE\n",this_cpu);
 #endif /* kDEBUG */
-				ops &= ~(1 << IPI_RESCHEDULE);
 				/*
 				 * Reschedule callback.  Everything to be
 				 * done is done by the interrupt return path.
@@ -197,7 +204,6 @@
 #if (kDEBUG>=100)
 				printk(KERN_DEBUG "CPU%d IPI_CALL_FUNC\n",this_cpu);
 #endif /* kDEBUG */
-				ops &= ~(1 << IPI_CALL_FUNC);
 				{
 					volatile struct smp_call_struct *data;
 					void (*func)(void *info);
@@ -231,7 +237,6 @@
 #if (kDEBUG>=100)
 				printk(KERN_DEBUG "CPU%d IPI_CPU_START\n",this_cpu);
 #endif /* kDEBUG */
-				ops &= ~(1 << IPI_CPU_START);
 #ifdef ENTRY_SYS_CPUS
 				p->state = STATE_RUNNING;
 #endif
@@ -241,7 +246,6 @@
 #if (kDEBUG>=100)
 				printk(KERN_DEBUG "CPU%d IPI_CPU_STOP\n",this_cpu);
 #endif /* kDEBUG */
-				ops &= ~(1 << IPI_CPU_STOP);
 #ifdef ENTRY_SYS_CPUS
 #else
 				halt_processor();
@@ -252,13 +256,11 @@
 #if (kDEBUG>=100)
 				printk(KERN_DEBUG "CPU%d is alive!\n",this_cpu);
 #endif /* kDEBUG */
-				ops &= ~(1 << IPI_CPU_TEST);
 				break;
 
 			default:
 				printk(KERN_CRIT "Unknown IPI num on CPU%d: %lu\n",
 					this_cpu, which);
-				ops &= ~(1 << which);
 				return IRQ_NONE;
 			} /* Switch */
 		} /* while (ops) */
@@ -312,6 +314,12 @@
 void 
 smp_send_reschedule(int cpu) { send_IPI_single(cpu, IPI_RESCHEDULE); }
 
+void
+smp_send_all_nop(void)
+{
+	send_IPI_allbutself(IPI_NOP);
+}
+
 
 /**
  * Run a function on all other CPUs.