From: Arnd Bergmann Date: Wed, 22 Mar 2006 23:00:07 +0000 (+0100) Subject: [PATCH] powerpc: work around a cell interrupt HW bug X-Git-Tag: v2.6.17-rc1~165^2~57 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5536408c21cdde38bfdbb59a6fd4fcbf1232699f;p=linux-2.6 [PATCH] powerpc: work around a cell interrupt HW bug 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 Signed-off-by: Paul Mackerras --- diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c index 9d41e07b0c..e3fffdfcc6 100644 --- a/arch/powerpc/platforms/cell/interrupt.c +++ b/arch/powerpc/platforms/cell/interrupt.c @@ -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)