diff options
author | Arnd Bergmann <abergman@de.ibm.com> | 2006-03-22 18:00:07 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-03-26 22:48:20 -0500 |
commit | 5536408c21cdde38bfdbb59a6fd4fcbf1232699f (patch) | |
tree | 70ef920f6bc97383d1363926f19499167d0d2249 /arch | |
parent | d0e57c68373f8ded8c50245fd082e606f9f63221 (diff) |
[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 <arnd.bergmann@de.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/platforms/cell/interrupt.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c index 9d41e07b0c95..e3fffdfcc674 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); | |||
63 | 63 | ||
64 | void iic_local_enable(void) | 64 | void iic_local_enable(void) |
65 | { | 65 | { |
66 | out_be64(&__get_cpu_var(iic).regs->prio, 0xff); | 66 | struct iic *iic = &__get_cpu_var(iic); |
67 | u64 tmp; | ||
68 | |||
69 | /* | ||
70 | * There seems to be a bug that is present in DD2.x CPUs | ||
71 | * and still only partially fixed in DD3.1. | ||
72 | * This bug causes a value written to the priority register | ||
73 | * not to make it there, resulting in a system hang unless we | ||
74 | * write it again. | ||
75 | * Masking with 0xf0 is done because the Cell BE does not | ||
76 | * implement the lower four bits of the interrupt priority, | ||
77 | * they always read back as zeroes, although future CPUs | ||
78 | * might implement different bits. | ||
79 | */ | ||
80 | do { | ||
81 | out_be64(&iic->regs->prio, 0xff); | ||
82 | tmp = in_be64(&iic->regs->prio); | ||
83 | } while ((tmp & 0xf0) != 0xf0); | ||
67 | } | 84 | } |
68 | 85 | ||
69 | void iic_local_disable(void) | 86 | void iic_local_disable(void) |