aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2011-06-16 15:09:17 -0400
committerKumar Gala <galak@kernel.crashing.org>2011-06-22 07:15:16 -0400
commit82a9a4809f4cb4ce3f17da99a8150df8455fa096 (patch)
tree06659597671abf80360dd5c89df8aaba26e6962a /arch
parentf3fed682f78dfab384d3dc3f9ca7a7338a93c142 (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.c2
-rw-r--r--arch/powerpc/sysdev/fsl_rio.c35
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
284int fsl_rio_mcheck_exception(struct pt_regs *regs) 284int 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