Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 82a9a480 authored by Scott Wood's avatar Scott Wood Committed by Kumar Gala
Browse files

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: default avatarScott Wood <scottwood@freescale.com>
Signed-off-by: default avatarKumar Gala <galak@kernel.crashing.org>
parent f3fed682
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -425,7 +425,7 @@ int machine_check_e500mc(struct pt_regs *regs)
	unsigned long reason = mcsr;
	unsigned long reason = mcsr;
	int recoverable = 1;
	int recoverable = 1;


	if (reason & MCSR_BUS_RBERR) {
	if (reason & MCSR_LD) {
		recoverable = fsl_rio_mcheck_exception(regs);
		recoverable = fsl_rio_mcheck_exception(regs);
		if (recoverable == 1)
		if (recoverable == 1)
			goto silent_out;
			goto silent_out;
+18 −17
Original line number Original line Diff line number Diff line
@@ -283,10 +283,12 @@ static void __iomem *rio_regs_win;
#ifdef CONFIG_E500
#ifdef CONFIG_E500
int fsl_rio_mcheck_exception(struct pt_regs *regs)
int fsl_rio_mcheck_exception(struct pt_regs *regs)
{
{
	const struct exception_table_entry *entry = NULL;
	const struct exception_table_entry *entry;
	unsigned long reason = mfspr(SPRN_MCSR);
	unsigned long reason;

	if (!rio_regs_win)
		return 0;


	if (reason & MCSR_BUS_RBERR) {
	reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR));
	reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR));
	if (reason & (RIO_LTLEDCSR_IER | RIO_LTLEDCSR_PRT)) {
	if (reason & (RIO_LTLEDCSR_IER | RIO_LTLEDCSR_PRT)) {
		/* Check if we are prepared to handle this fault */
		/* Check if we are prepared to handle this fault */
@@ -301,7 +303,6 @@ int fsl_rio_mcheck_exception(struct pt_regs *regs)
			return 1;
			return 1;
		}
		}
	}
	}
	}


	return 0;
	return 0;
}
}