This patch adds support for parisc to and applies on top of:
	http://redhat.com/~mingo/spinlock-patches/consolidate-spinlocks.patch

Posted as:
> Date: Fri, 3 Jun 2005 17:40:29 +0200
> From: Ingo Molnar <mingo@elte.hu>
> Subject: [patch] spinlock consolidation, v2


Booted and lightly tested on a500-44 (64-bit, SMP kernel, dual CPU).

I used raw_spinlock_t for bitops, tlb, and IPI locks.
Doing so avoids some ugly nesting of linux/*.h and asm/*.h
spinlock files. Those particular locks are well tested
and contained entirely inside arch specific code.
I do NOT expect any new issues to arise with them.

If someone does ever need to use debug/metrics with them, then they
will need to unravel this hairball between spinlocks, atomic ops,
and bit ops that exist only because parisc has exactly one atomic
instruction: LDCW (load and clear word).

thanks,
grant


Signed-off-by: Grant Grundler <grundler@parisc-linux.org>

--- linux/arch/parisc/kernel/processor.c-orig	29 Oct 2004 13:08:47 -0000
+++ linux/arch/parisc/kernel/processor.c	6 Jun 2005 04:32:33 -0000
@@ -43,6 +43,7 @@
 #include <asm/pdcpat.h>
 #include <asm/irq.h>		/* for struct irq_region */
 #include <asm/parisc-device.h>
+#include <asm/spinlock.h>
 
 struct system_cpuinfo_parisc boot_cpu_data;
 EXPORT_SYMBOL(boot_cpu_data);
@@ -153,7 +154,7 @@ static int __init processor_probe(struct
 	p->cpuid = cpuid;	/* save CPU id */
 	p->txn_addr = txn_addr;	/* save CPU IRQ address */
 #ifdef CONFIG_SMP
-	spin_lock_init(&p->lock);
+	__raw_spin_unlock(&p->pending_lock);	/* initialize */
 
 	/*
 	** FIXME: review if any other initialization is clobbered
--- linux/arch/parisc/kernel/smp.c-orig	13 May 2005 05:25:09 -0000
+++ linux/arch/parisc/kernel/smp.c	6 Jun 2005 04:32:33 -0000
@@ -168,10 +168,12 @@ ipi_interrupt(int irq, void *dev_id, str
 	mb();	/* Order interrupt and bit testing. */
 
 	for (;;) {
-		spin_lock_irqsave(&(p->lock),flags);
+		local_irq_save(flags);
+		__raw_spin_lock(&(p->pending_lock));
 		ops = p->pending_ipi;
 		p->pending_ipi = 0;
-		spin_unlock_irqrestore(&(p->lock),flags);
+		__raw_spin_unlock(&(p->pending_lock));
+		local_irq_restore(flags);
 
 		mb(); /* Order bit clearing and data access. */
 
@@ -273,10 +275,12 @@ ipi_send(int cpu, enum ipi_message_type 
 	struct cpuinfo_parisc *p = &cpu_data[cpu];
 	unsigned long flags;
 
-	spin_lock_irqsave(&(p->lock),flags);
+	local_irq_save(flags);
+	__raw_spin_lock(&(p->pending_lock));
 	p->pending_ipi |= 1 << op;
 	gsc_writel(IPI_IRQ - CPU_IRQ_BASE, cpu_data[cpu].hpa);
-	spin_unlock_irqrestore(&(p->lock),flags);
+	__raw_spin_unlock(&(p->pending_lock));
+	local_irq_restore(flags);
 }
 
 
--- linux/arch/parisc/lib/bitops.c-orig	15 Aug 2004 14:17:39 -0000
+++ linux/arch/parisc/lib/bitops.c	6 Jun 2005 04:32:33 -0000
@@ -11,10 +11,11 @@
 #include <linux/spinlock.h>
 #include <asm/system.h>
 #include <asm/atomic.h>
+#include <asm/spinlock_types.h>
 
 #ifdef CONFIG_SMP
-spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned = {
-	[0 ... (ATOMIC_HASH_SIZE-1)]  = SPIN_LOCK_UNLOCKED
+raw_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned = {
+	[0 ... (ATOMIC_HASH_SIZE-1)]  = __RAW_SPIN_LOCK_UNLOCKED
 };
 #endif
 
--- linux/include/asm-parisc/atomic.h-orig	27 Aug 2004 17:38:21 -0000
+++ linux/include/asm-parisc/atomic.h	6 Jun 2005 04:32:36 -0000
@@ -15,6 +15,7 @@
 
 #ifdef CONFIG_SMP
 #include <asm/spinlock.h>
+#include <asm/spinlock_types.h>
 #include <asm/cache.h>		/* we use L1_CACHE_BYTES */
 
 /* Use an array of spinlocks for our atomic_ts.
@@ -24,19 +25,19 @@
 #  define ATOMIC_HASH_SIZE 4
 #  define ATOMIC_HASH(a) (&(__atomic_hash[ (((unsigned long) a)/L1_CACHE_BYTES) & (ATOMIC_HASH_SIZE-1) ]))
 
-extern spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned;
+extern raw_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned;
 
-/* Can't use _raw_spin_lock_irq because of #include problems, so
+/* Can't use raw_spin_lock_irq because of #include problems, so
  * this is the substitute */
 #define _atomic_spin_lock_irqsave(l,f) do {	\
-	spinlock_t *s = ATOMIC_HASH(l);		\
+	raw_spinlock_t *s = ATOMIC_HASH(l);		\
 	local_irq_save(f);			\
-	_raw_spin_lock(s);			\
+	__raw_spin_lock(s);			\
 } while(0)
 
 #define _atomic_spin_unlock_irqrestore(l,f) do {	\
-	spinlock_t *s = ATOMIC_HASH(l);			\
-	_raw_spin_unlock(s);				\
+	raw_spinlock_t *s = ATOMIC_HASH(l);			\
+	__raw_spin_unlock(s);				\
 	local_irq_restore(f);				\
 } while(0)
 
--- linux/include/asm-parisc/bitops.h-orig	4 Jun 2005 05:42:21 -0000
+++ linux/include/asm-parisc/bitops.h	6 Jun 2005 04:32:36 -0000
@@ -3,7 +3,7 @@
 
 #include <linux/compiler.h>
 #include <asm/types.h>		/* for BITS_PER_LONG/SHIFT_PER_LONG */
-#include <asm/system.h>
+#include <asm/spinlock.h>
 #include <asm/byteorder.h>
 #include <asm/atomic.h>
 
--- linux/include/asm-parisc/cacheflush.h-orig	18 Mar 2005 13:17:43 -0000
+++ linux/include/asm-parisc/cacheflush.h	6 Jun 2005 04:32:36 -0000
@@ -3,6 +3,7 @@
 
 #include <linux/config.h>
 #include <linux/mm.h>
+#include <asm/cache.h>	/* for flush_user_dcache_range_asm() proto */
 
 /* The usual comment is "Caches aren't brain-dead on the <architecture>".
  * Unfortunately, that doesn't apply to PA-RISC. */
--- linux/include/asm-parisc/processor.h-orig	20 May 2005 00:05:13 -0000
+++ linux/include/asm-parisc/processor.h	6 Jun 2005 04:32:36 -0000
@@ -18,6 +18,7 @@
 #include <asm/ptrace.h>
 #include <asm/types.h>
 #include <asm/system.h>
+#include <asm/spinlock_types.h>
 #endif /* __ASSEMBLY__ */
 
 #define KERNEL_STACK_SIZE 	(4*PAGE_SIZE)
@@ -87,7 +88,7 @@ struct cpuinfo_parisc {
 	unsigned long hpa;          /* Host Physical address */
 	unsigned long txn_addr;     /* MMIO addr of EIR or id_eid */
 #ifdef CONFIG_SMP
-	spinlock_t lock;            /* synchronization for ipi's */
+	raw_spinlock_t pending_lock;  /* protect sender/receiver races */
 	unsigned long pending_ipi;  /* bitmap of type ipi_message_type */
 	unsigned long ipi_count;    /* number ipi Interrupts */
 #endif
--- linux/include/asm-parisc/spinlock.h-orig	7 Mar 2005 15:05:48
+++ linux/include/asm-parisc/spinlock.h	6 Jun 2005 04:32:36 -0000
@@ -2,6 +2,8 @@
 #define __ASM_SPINLOCK_H
 
 #include <asm/system.h>
+#include <asm/processor.h>
+#include <asm/spinlock_types.h>
 
 /* Note that PA-RISC has to use `1' to mean unlocked and `0' to mean locked
  * since it only has load-and-zero. Moreover, at least on some PA processors,
