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 | |
| 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>
| -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 | ||
