diff options
| author | Shaohui Xie <b21989@freescale.com> | 2010-11-18 01:57:32 -0500 |
|---|---|---|
| committer | Kumar Gala <galak@kernel.crashing.org> | 2011-05-20 09:46:57 -0400 |
| commit | cce1f106c64dc1d19d5e9406320fde18dfc662df (patch) | |
| tree | 0fe38cf975577cb22de977ab36dc1cde82d80125 | |
| parent | d08e44570ed611c527a1062eb4f8c6ac61832e6e (diff) | |
powerpc/fsl_rio: move machine_check handler
Add support for machine_check support into machine_check_e500 and
machine_check_e500mc.
Signed-off-by: Shaohui Xie <b21989@freescale.com>
Cc: Li Yang <leoli@freescale.com>
Cc: Roy Zang <tie-fei.zang@freescale.com>
Cc: Alexandre Bounine <alexandre.bounine@idt.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
| -rw-r--r-- | arch/powerpc/include/asm/rio.h | 5 | ||||
| -rw-r--r-- | arch/powerpc/kernel/traps.c | 13 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/fsl_rio.c | 15 |
3 files changed, 21 insertions, 12 deletions
diff --git a/arch/powerpc/include/asm/rio.h b/arch/powerpc/include/asm/rio.h index 0018bf80cb25..d902abd33995 100644 --- a/arch/powerpc/include/asm/rio.h +++ b/arch/powerpc/include/asm/rio.h | |||
| @@ -14,5 +14,10 @@ | |||
| 14 | #define ASM_PPC_RIO_H | 14 | #define ASM_PPC_RIO_H |
| 15 | 15 | ||
| 16 | extern void platform_rio_init(void); | 16 | extern void platform_rio_init(void); |
| 17 | #ifdef CONFIG_RAPIDIO | ||
| 18 | extern int fsl_rio_mcheck_exception(struct pt_regs *); | ||
| 19 | #else | ||
| 20 | static inline int fsl_rio_mcheck_exception(struct pt_regs *regs) {return 0; } | ||
| 21 | #endif | ||
| 17 | 22 | ||
| 18 | #endif /* ASM_PPC_RIO_H */ | 23 | #endif /* ASM_PPC_RIO_H */ |
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index b13306b0d925..0ff4ab98d50c 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
| @@ -55,6 +55,7 @@ | |||
| 55 | #endif | 55 | #endif |
| 56 | #include <asm/kexec.h> | 56 | #include <asm/kexec.h> |
| 57 | #include <asm/ppc-opcode.h> | 57 | #include <asm/ppc-opcode.h> |
| 58 | #include <asm/rio.h> | ||
| 58 | 59 | ||
| 59 | #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) | 60 | #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) |
| 60 | int (*__debugger)(struct pt_regs *regs) __read_mostly; | 61 | int (*__debugger)(struct pt_regs *regs) __read_mostly; |
| @@ -424,6 +425,12 @@ int machine_check_e500mc(struct pt_regs *regs) | |||
| 424 | unsigned long reason = mcsr; | 425 | unsigned long reason = mcsr; |
| 425 | int recoverable = 1; | 426 | int recoverable = 1; |
| 426 | 427 | ||
| 428 | if (reason & MCSR_BUS_RBERR) { | ||
| 429 | recoverable = fsl_rio_mcheck_exception(regs); | ||
| 430 | if (recoverable == 1) | ||
| 431 | goto silent_out; | ||
| 432 | } | ||
| 433 | |||
| 427 | printk("Machine check in kernel mode.\n"); | 434 | printk("Machine check in kernel mode.\n"); |
| 428 | printk("Caused by (from MCSR=%lx): ", reason); | 435 | printk("Caused by (from MCSR=%lx): ", reason); |
| 429 | 436 | ||
| @@ -499,6 +506,7 @@ int machine_check_e500mc(struct pt_regs *regs) | |||
| 499 | reason & MCSR_MEA ? "Effective" : "Physical", addr); | 506 | reason & MCSR_MEA ? "Effective" : "Physical", addr); |
| 500 | } | 507 | } |
| 501 | 508 | ||
| 509 | silent_out: | ||
| 502 | mtspr(SPRN_MCSR, mcsr); | 510 | mtspr(SPRN_MCSR, mcsr); |
| 503 | return mfspr(SPRN_MCSR) == 0 && recoverable; | 511 | return mfspr(SPRN_MCSR) == 0 && recoverable; |
| 504 | } | 512 | } |
| @@ -507,6 +515,11 @@ int machine_check_e500(struct pt_regs *regs) | |||
| 507 | { | 515 | { |
| 508 | unsigned long reason = get_mc_reason(regs); | 516 | unsigned long reason = get_mc_reason(regs); |
| 509 | 517 | ||
| 518 | if (reason & MCSR_BUS_RBERR) { | ||
| 519 | if (fsl_rio_mcheck_exception(regs)) | ||
| 520 | return 1; | ||
| 521 | } | ||
| 522 | |||
| 510 | printk("Machine check in kernel mode.\n"); | 523 | printk("Machine check in kernel mode.\n"); |
| 511 | printk("Caused by (from MCSR=%lx): ", reason); | 524 | printk("Caused by (from MCSR=%lx): ", reason); |
| 512 | 525 | ||
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 49798532b477..34440e1bac18 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c | |||
| @@ -260,9 +260,7 @@ struct rio_priv { | |||
| 260 | static void __iomem *rio_regs_win; | 260 | static void __iomem *rio_regs_win; |
| 261 | 261 | ||
| 262 | #ifdef CONFIG_E500 | 262 | #ifdef CONFIG_E500 |
| 263 | static int (*saved_mcheck_exception)(struct pt_regs *regs); | 263 | int fsl_rio_mcheck_exception(struct pt_regs *regs) |
| 264 | |||
| 265 | static int fsl_rio_mcheck_exception(struct pt_regs *regs) | ||
| 266 | { | 264 | { |
| 267 | const struct exception_table_entry *entry = NULL; | 265 | const struct exception_table_entry *entry = NULL; |
| 268 | unsigned long reason = mfspr(SPRN_MCSR); | 266 | unsigned long reason = mfspr(SPRN_MCSR); |
| @@ -284,11 +282,9 @@ static int fsl_rio_mcheck_exception(struct pt_regs *regs) | |||
| 284 | } | 282 | } |
| 285 | } | 283 | } |
| 286 | 284 | ||
| 287 | if (saved_mcheck_exception) | 285 | return 0; |
| 288 | return saved_mcheck_exception(regs); | ||
| 289 | else | ||
| 290 | return cur_cpu_spec->machine_check(regs); | ||
| 291 | } | 286 | } |
| 287 | EXPORT_SYMBOL_GPL(fsl_rio_mcheck_exception); | ||
| 292 | #endif | 288 | #endif |
| 293 | 289 | ||
| 294 | /** | 290 | /** |
| @@ -1538,11 +1534,6 @@ int fsl_rio_setup(struct platform_device *dev) | |||
| 1538 | fsl_rio_doorbell_init(port); | 1534 | fsl_rio_doorbell_init(port); |
| 1539 | fsl_rio_port_write_init(port); | 1535 | fsl_rio_port_write_init(port); |
| 1540 | 1536 | ||
| 1541 | #ifdef CONFIG_E500 | ||
| 1542 | saved_mcheck_exception = ppc_md.machine_check_exception; | ||
| 1543 | ppc_md.machine_check_exception = fsl_rio_mcheck_exception; | ||
| 1544 | #endif | ||
| 1545 | |||
| 1546 | return 0; | 1537 | return 0; |
| 1547 | err: | 1538 | err: |
| 1548 | iounmap(priv->regs_win); | 1539 | iounmap(priv->regs_win); |
