diff options
author | Scott Wood <scottwood@freescale.com> | 2011-06-16 15:09:17 -0400 |
---|---|---|
committer | Kumar Gala <galak@kernel.crashing.org> | 2011-06-22 07:15:16 -0400 |
commit | 82a9a4809f4cb4ce3f17da99a8150df8455fa096 (patch) | |
tree | 06659597671abf80360dd5c89df8aaba26e6962a /arch | |
parent | f3fed682f78dfab384d3dc3f9ca7a7338a93c142 (diff) |
powerpc/e500: fix breakage with fsl_rio_mcheck_exception
The wrong MCSR bit was being used on e500mc. MCSR_BUS_RBERR only exists
on e500v1/v2. Use MCSR_LD on e500mc, and remove all MCSR checking
in fsl_rio_mcheck_exception as we now no longer call that function
if the appropriate bit in MCSR is not set.
If RIO support was enabled at compile-time, but was never probed, just
return from fsl_rio_mcheck_exception rather than dereference a NULL
pointer.
TODO: There is still a remaining, though comparitively minor, issue in
that this recovery mechanism will falsely engage if there's an unrelated
MCSR_LD event at the same time as a RIO error.
Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/kernel/traps.c | 2 | ||||
-rw-r--r-- | arch/powerpc/sysdev/fsl_rio.c | 35 |
2 files changed, 19 insertions, 18 deletions
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 0ff4ab98d50c..6414a0d5ba65 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -425,7 +425,7 @@ int machine_check_e500mc(struct pt_regs *regs) | |||
425 | unsigned long reason = mcsr; | 425 | unsigned long reason = mcsr; |
426 | int recoverable = 1; | 426 | int recoverable = 1; |
427 | 427 | ||
428 | if (reason & MCSR_BUS_RBERR) { | 428 | if (reason & MCSR_LD) { |
429 | recoverable = fsl_rio_mcheck_exception(regs); | 429 | recoverable = fsl_rio_mcheck_exception(regs); |
430 | if (recoverable == 1) | 430 | if (recoverable == 1) |
431 | goto silent_out; | 431 | goto silent_out; |
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 5b206a2fe17c..b3fd081d56f5 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c | |||
@@ -283,23 +283,24 @@ static void __iomem *rio_regs_win; | |||
283 | #ifdef CONFIG_E500 | 283 | #ifdef CONFIG_E500 |
284 | int fsl_rio_mcheck_exception(struct pt_regs *regs) | 284 | int fsl_rio_mcheck_exception(struct pt_regs *regs) |
285 | { | 285 | { |
286 | const struct exception_table_entry *entry = NULL; | 286 | const struct exception_table_entry *entry; |
287 | unsigned long reason = mfspr(SPRN_MCSR); | 287 | unsigned long reason; |
288 | 288 | ||
289 | if (reason & MCSR_BUS_RBERR) { | 289 | if (!rio_regs_win) |
290 | reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR)); | 290 | return 0; |
291 | if (reason & (RIO_LTLEDCSR_IER | RIO_LTLEDCSR_PRT)) { | 291 | |
292 | /* Check if we are prepared to handle this fault */ | 292 | reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR)); |
293 | entry = search_exception_tables(regs->nip); | 293 | if (reason & (RIO_LTLEDCSR_IER | RIO_LTLEDCSR_PRT)) { |
294 | if (entry) { | 294 | /* Check if we are prepared to handle this fault */ |
295 | pr_debug("RIO: %s - MC Exception handled\n", | 295 | entry = search_exception_tables(regs->nip); |
296 | __func__); | 296 | if (entry) { |
297 | out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR), | 297 | pr_debug("RIO: %s - MC Exception handled\n", |
298 | 0); | 298 | __func__); |
299 | regs->msr |= MSR_RI; | 299 | out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR), |
300 | regs->nip = entry->fixup; | 300 | 0); |
301 | return 1; | 301 | regs->msr |= MSR_RI; |
302 | } | 302 | regs->nip = entry->fixup; |
303 | return 1; | ||
303 | } | 304 | } |
304 | } | 305 | } |
305 | 306 | ||