]> err.no Git - linux-2.6/commitdiff
[PATCH] powerpc: work around a cell interrupt HW bug
authorArnd Bergmann <abergman@de.ibm.com>
Wed, 22 Mar 2006 23:00:07 +0000 (00:00 +0100)
committerPaul Mackerras <paulus@samba.org>
Mon, 27 Mar 2006 03:48:20 +0000 (14:48 +1100)
Apparently we have found a bug in the CPU that causes
external interrupts to sometimes get disabled indefinitely.
This adds a workaround for the problem.

Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
arch/powerpc/platforms/cell/interrupt.c

index 9d41e07b0c9517beeecd5b62b14a9b12b80cd30c..e3fffdfcc67476e3f8f4a583facd1fd2b61e255d 100644 (file)
@@ -63,7 +63,24 @@ static DEFINE_PER_CPU(struct iic, iic);
 
 void iic_local_enable(void)
 {
-       out_be64(&__get_cpu_var(iic).regs->prio, 0xff);
+       struct iic *iic = &__get_cpu_var(iic);
+       u64 tmp;
+
+       /*
+        * There seems to be a bug that is present in DD2.x CPUs
+        * and still only partially fixed in DD3.1.
+        * This bug causes a value written to the priority register
+        * not to make it there, resulting in a system hang unless we
+        * write it again.
+        * Masking with 0xf0 is done because the Cell BE does not
+        * implement the lower four bits of the interrupt priority,
+        * they always read back as zeroes, although future CPUs
+        * might implement different bits.
+        */
+       do {
+               out_be64(&iic->regs->prio, 0xff);
+               tmp = in_be64(&iic->regs->prio);
+       } while ((tmp & 0xf0) != 0xf0);
 }
 
 void iic_local_disable(void)