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 /arch | |
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>
Diffstat (limited to 'arch')
-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); |