Loading arch/powerpc/include/asm/fsl_lbc.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -157,6 +157,8 @@ struct fsl_lbc_regs { #define LBCR_EPAR_SHIFT 16 #define LBCR_EPAR_SHIFT 16 #define LBCR_BMT 0x0000FF00 #define LBCR_BMT 0x0000FF00 #define LBCR_BMT_SHIFT 8 #define LBCR_BMT_SHIFT 8 #define LBCR_BMTPS 0x0000000F #define LBCR_BMTPS_SHIFT 0 #define LBCR_INIT 0x00040000 #define LBCR_INIT 0x00040000 __be32 lcrr; /**< Clock Ratio Register */ __be32 lcrr; /**< Clock Ratio Register */ #define LCRR_DBYP 0x80000000 #define LCRR_DBYP 0x80000000 Loading arch/powerpc/include/asm/rio.h +5 −0 Original line number Original line Diff line number Diff line Loading @@ -14,5 +14,10 @@ #define ASM_PPC_RIO_H #define ASM_PPC_RIO_H extern void platform_rio_init(void); extern void platform_rio_init(void); #ifdef CONFIG_RAPIDIO extern int fsl_rio_mcheck_exception(struct pt_regs *); #else static inline int fsl_rio_mcheck_exception(struct pt_regs *regs) {return 0; } #endif #endif /* ASM_PPC_RIO_H */ #endif /* ASM_PPC_RIO_H */ arch/powerpc/kernel/traps.c +13 −0 Original line number Original line Diff line number Diff line Loading @@ -55,6 +55,7 @@ #endif #endif #include <asm/kexec.h> #include <asm/kexec.h> #include <asm/ppc-opcode.h> #include <asm/ppc-opcode.h> #include <asm/rio.h> #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) int (*__debugger)(struct pt_regs *regs) __read_mostly; int (*__debugger)(struct pt_regs *regs) __read_mostly; Loading Loading @@ -424,6 +425,12 @@ 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) { recoverable = fsl_rio_mcheck_exception(regs); if (recoverable == 1) goto silent_out; } printk("Machine check in kernel mode.\n"); printk("Machine check in kernel mode.\n"); printk("Caused by (from MCSR=%lx): ", reason); printk("Caused by (from MCSR=%lx): ", reason); Loading Loading @@ -499,6 +506,7 @@ int machine_check_e500mc(struct pt_regs *regs) reason & MCSR_MEA ? "Effective" : "Physical", addr); reason & MCSR_MEA ? "Effective" : "Physical", addr); } } silent_out: mtspr(SPRN_MCSR, mcsr); mtspr(SPRN_MCSR, mcsr); return mfspr(SPRN_MCSR) == 0 && recoverable; return mfspr(SPRN_MCSR) == 0 && recoverable; } } Loading @@ -507,6 +515,11 @@ int machine_check_e500(struct pt_regs *regs) { { unsigned long reason = get_mc_reason(regs); unsigned long reason = get_mc_reason(regs); if (reason & MCSR_BUS_RBERR) { if (fsl_rio_mcheck_exception(regs)) return 1; } printk("Machine check in kernel mode.\n"); printk("Machine check in kernel mode.\n"); printk("Caused by (from MCSR=%lx): ", reason); printk("Caused by (from MCSR=%lx): ", reason); Loading arch/powerpc/sysdev/fsl_lbc.c +7 −2 Original line number Original line Diff line number Diff line Loading @@ -184,7 +184,8 @@ int fsl_upm_run_pattern(struct fsl_upm *upm, void __iomem *io_base, u32 mar) } } EXPORT_SYMBOL(fsl_upm_run_pattern); EXPORT_SYMBOL(fsl_upm_run_pattern); static int __devinit fsl_lbc_ctrl_init(struct fsl_lbc_ctrl *ctrl) static int __devinit fsl_lbc_ctrl_init(struct fsl_lbc_ctrl *ctrl, struct device_node *node) { { struct fsl_lbc_regs __iomem *lbc = ctrl->regs; struct fsl_lbc_regs __iomem *lbc = ctrl->regs; Loading @@ -198,6 +199,10 @@ static int __devinit fsl_lbc_ctrl_init(struct fsl_lbc_ctrl *ctrl) /* Enable interrupts for any detected events */ /* Enable interrupts for any detected events */ out_be32(&lbc->lteir, LTEIR_ENABLE); out_be32(&lbc->lteir, LTEIR_ENABLE); /* Set the monitor timeout value to the maximum for erratum A001 */ if (of_device_is_compatible(node, "fsl,elbc")) clrsetbits_be32(&lbc->lbcr, LBCR_BMT, LBCR_BMTPS); return 0; return 0; } } Loading Loading @@ -304,7 +309,7 @@ static int __devinit fsl_lbc_ctrl_probe(struct platform_device *dev) fsl_lbc_ctrl_dev->dev = &dev->dev; fsl_lbc_ctrl_dev->dev = &dev->dev; ret = fsl_lbc_ctrl_init(fsl_lbc_ctrl_dev); ret = fsl_lbc_ctrl_init(fsl_lbc_ctrl_dev, dev->dev.of_node); if (ret < 0) if (ret < 0) goto err; goto err; Loading arch/powerpc/sysdev/fsl_rio.c +80 −20 Original line number Original line Diff line number Diff line Loading @@ -10,7 +10,7 @@ * - Added Port-Write message handling * - Added Port-Write message handling * - Added Machine Check exception handling * - Added Machine Check exception handling * * * Copyright (C) 2007, 2008 Freescale Semiconductor, Inc. * Copyright (C) 2007, 2008, 2010 Freescale Semiconductor, Inc. * Zhang Wei <wei.zhang@freescale.com> * Zhang Wei <wei.zhang@freescale.com> * * * Copyright 2005 MontaVista Software, Inc. * Copyright 2005 MontaVista Software, Inc. Loading Loading @@ -47,11 +47,29 @@ #define IRQ_RIO_RX(m) (((struct rio_priv *)(m->priv))->rxirq) #define IRQ_RIO_RX(m) (((struct rio_priv *)(m->priv))->rxirq) #define IRQ_RIO_PW(m) (((struct rio_priv *)(m->priv))->pwirq) #define IRQ_RIO_PW(m) (((struct rio_priv *)(m->priv))->pwirq) #define IPWSR_CLEAR 0x98 #define OMSR_CLEAR 0x1cb3 #define IMSR_CLEAR 0x491 #define IDSR_CLEAR 0x91 #define ODSR_CLEAR 0x1c00 #define LTLEECSR_ENABLE_ALL 0xFFC000FC #define ESCSR_CLEAR 0x07120204 #define RIO_PORT1_EDCSR 0x0640 #define RIO_PORT2_EDCSR 0x0680 #define RIO_PORT1_IECSR 0x10130 #define RIO_PORT2_IECSR 0x101B0 #define RIO_IM0SR 0x13064 #define RIO_IM1SR 0x13164 #define RIO_OM0SR 0x13004 #define RIO_OM1SR 0x13104 #define RIO_ATMU_REGS_OFFSET 0x10c00 #define RIO_ATMU_REGS_OFFSET 0x10c00 #define RIO_P_MSG_REGS_OFFSET 0x11000 #define RIO_P_MSG_REGS_OFFSET 0x11000 #define RIO_S_MSG_REGS_OFFSET 0x13000 #define RIO_S_MSG_REGS_OFFSET 0x13000 #define RIO_GCCSR 0x13c #define RIO_GCCSR 0x13c #define RIO_ESCSR 0x158 #define RIO_ESCSR 0x158 #define RIO_PORT2_ESCSR 0x178 #define RIO_CCSR 0x15c #define RIO_CCSR 0x15c #define RIO_LTLEDCSR 0x0608 #define RIO_LTLEDCSR 0x0608 #define RIO_LTLEDCSR_IER 0x80000000 #define RIO_LTLEDCSR_IER 0x80000000 Loading Loading @@ -88,7 +106,10 @@ #define RIO_IPWSR_PWD 0x00000008 #define RIO_IPWSR_PWD 0x00000008 #define RIO_IPWSR_PWB 0x00000004 #define RIO_IPWSR_PWB 0x00000004 #define RIO_EPWISR_PINT 0x80000000 /* EPWISR Error match value */ #define RIO_EPWISR_PINT1 0x80000000 #define RIO_EPWISR_PINT2 0x40000000 #define RIO_EPWISR_MU 0x00000002 #define RIO_EPWISR_PW 0x00000001 #define RIO_EPWISR_PW 0x00000001 #define RIO_MSG_DESC_SIZE 32 #define RIO_MSG_DESC_SIZE 32 Loading Loading @@ -260,9 +281,7 @@ struct rio_priv { static void __iomem *rio_regs_win; static void __iomem *rio_regs_win; #ifdef CONFIG_E500 #ifdef CONFIG_E500 static int (*saved_mcheck_exception)(struct pt_regs *regs); int fsl_rio_mcheck_exception(struct pt_regs *regs) static int fsl_rio_mcheck_exception(struct pt_regs *regs) { { const struct exception_table_entry *entry = NULL; const struct exception_table_entry *entry = NULL; unsigned long reason = mfspr(SPRN_MCSR); unsigned long reason = mfspr(SPRN_MCSR); Loading @@ -284,11 +303,9 @@ static int fsl_rio_mcheck_exception(struct pt_regs *regs) } } } } if (saved_mcheck_exception) return 0; return saved_mcheck_exception(regs); else return cur_cpu_spec->machine_check(regs); } } EXPORT_SYMBOL_GPL(fsl_rio_mcheck_exception); #endif #endif /** /** Loading Loading @@ -1064,6 +1081,40 @@ static int fsl_rio_doorbell_init(struct rio_mport *mport) return rc; return rc; } } static void port_error_handler(struct rio_mport *port, int offset) { /*XXX: Error recovery is not implemented, we just clear errors */ out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR), 0); if (offset == 0) { out_be32((u32 *)(rio_regs_win + RIO_PORT1_EDCSR), 0); out_be32((u32 *)(rio_regs_win + RIO_PORT1_IECSR), 0); out_be32((u32 *)(rio_regs_win + RIO_ESCSR), ESCSR_CLEAR); } else { out_be32((u32 *)(rio_regs_win + RIO_PORT2_EDCSR), 0); out_be32((u32 *)(rio_regs_win + RIO_PORT2_IECSR), 0); out_be32((u32 *)(rio_regs_win + RIO_PORT2_ESCSR), ESCSR_CLEAR); } } static void msg_unit_error_handler(struct rio_mport *port) { struct rio_priv *priv = port->priv; /*XXX: Error recovery is not implemented, we just clear errors */ out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR), 0); out_be32((u32 *)(rio_regs_win + RIO_IM0SR), IMSR_CLEAR); out_be32((u32 *)(rio_regs_win + RIO_IM1SR), IMSR_CLEAR); out_be32((u32 *)(rio_regs_win + RIO_OM0SR), OMSR_CLEAR); out_be32((u32 *)(rio_regs_win + RIO_OM1SR), OMSR_CLEAR); out_be32(&priv->msg_regs->odsr, ODSR_CLEAR); out_be32(&priv->msg_regs->dsr, IDSR_CLEAR); out_be32(&priv->msg_regs->pwsr, IPWSR_CLEAR); } /** /** * fsl_rio_port_write_handler - MPC85xx port write interrupt handler * fsl_rio_port_write_handler - MPC85xx port write interrupt handler * @irq: Linux interrupt number * @irq: Linux interrupt number Loading Loading @@ -1144,10 +1195,22 @@ fsl_rio_port_write_handler(int irq, void *dev_instance) } } pw_done: pw_done: if (epwisr & RIO_EPWISR_PINT) { if (epwisr & RIO_EPWISR_PINT1) { tmp = in_be32(priv->regs_win + RIO_LTLEDCSR); pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp); port_error_handler(port, 0); } if (epwisr & RIO_EPWISR_PINT2) { tmp = in_be32(priv->regs_win + RIO_LTLEDCSR); tmp = in_be32(priv->regs_win + RIO_LTLEDCSR); pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp); pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp); out_be32(priv->regs_win + RIO_LTLEDCSR, 0); port_error_handler(port, 1); } if (epwisr & RIO_EPWISR_MU) { tmp = in_be32(priv->regs_win + RIO_LTLEDCSR); pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp); msg_unit_error_handler(port); } } return IRQ_HANDLED; return IRQ_HANDLED; Loading Loading @@ -1258,12 +1321,14 @@ static int fsl_rio_port_write_init(struct rio_mport *mport) /* Hook up port-write handler */ /* Hook up port-write handler */ rc = request_irq(IRQ_RIO_PW(mport), fsl_rio_port_write_handler, 0, rc = request_irq(IRQ_RIO_PW(mport), fsl_rio_port_write_handler, "port-write", (void *)mport); IRQF_SHARED, "port-write", (void *)mport); if (rc < 0) { if (rc < 0) { pr_err("MPC85xx RIO: unable to request inbound doorbell irq"); pr_err("MPC85xx RIO: unable to request inbound doorbell irq"); goto err_out; goto err_out; } } /* Enable Error Interrupt */ out_be32((u32 *)(rio_regs_win + RIO_LTLEECSR), LTLEECSR_ENABLE_ALL); INIT_WORK(&priv->pw_work, fsl_pw_dpc); INIT_WORK(&priv->pw_work, fsl_pw_dpc); spin_lock_init(&priv->pw_fifo_lock); spin_lock_init(&priv->pw_fifo_lock); Loading Loading @@ -1538,11 +1603,6 @@ int fsl_rio_setup(struct platform_device *dev) fsl_rio_doorbell_init(port); fsl_rio_doorbell_init(port); fsl_rio_port_write_init(port); fsl_rio_port_write_init(port); #ifdef CONFIG_E500 saved_mcheck_exception = ppc_md.machine_check_exception; ppc_md.machine_check_exception = fsl_rio_mcheck_exception; #endif return 0; return 0; err: err: iounmap(priv->regs_win); iounmap(priv->regs_win); Loading Loading
arch/powerpc/include/asm/fsl_lbc.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -157,6 +157,8 @@ struct fsl_lbc_regs { #define LBCR_EPAR_SHIFT 16 #define LBCR_EPAR_SHIFT 16 #define LBCR_BMT 0x0000FF00 #define LBCR_BMT 0x0000FF00 #define LBCR_BMT_SHIFT 8 #define LBCR_BMT_SHIFT 8 #define LBCR_BMTPS 0x0000000F #define LBCR_BMTPS_SHIFT 0 #define LBCR_INIT 0x00040000 #define LBCR_INIT 0x00040000 __be32 lcrr; /**< Clock Ratio Register */ __be32 lcrr; /**< Clock Ratio Register */ #define LCRR_DBYP 0x80000000 #define LCRR_DBYP 0x80000000 Loading
arch/powerpc/include/asm/rio.h +5 −0 Original line number Original line Diff line number Diff line Loading @@ -14,5 +14,10 @@ #define ASM_PPC_RIO_H #define ASM_PPC_RIO_H extern void platform_rio_init(void); extern void platform_rio_init(void); #ifdef CONFIG_RAPIDIO extern int fsl_rio_mcheck_exception(struct pt_regs *); #else static inline int fsl_rio_mcheck_exception(struct pt_regs *regs) {return 0; } #endif #endif /* ASM_PPC_RIO_H */ #endif /* ASM_PPC_RIO_H */
arch/powerpc/kernel/traps.c +13 −0 Original line number Original line Diff line number Diff line Loading @@ -55,6 +55,7 @@ #endif #endif #include <asm/kexec.h> #include <asm/kexec.h> #include <asm/ppc-opcode.h> #include <asm/ppc-opcode.h> #include <asm/rio.h> #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) int (*__debugger)(struct pt_regs *regs) __read_mostly; int (*__debugger)(struct pt_regs *regs) __read_mostly; Loading Loading @@ -424,6 +425,12 @@ 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) { recoverable = fsl_rio_mcheck_exception(regs); if (recoverable == 1) goto silent_out; } printk("Machine check in kernel mode.\n"); printk("Machine check in kernel mode.\n"); printk("Caused by (from MCSR=%lx): ", reason); printk("Caused by (from MCSR=%lx): ", reason); Loading Loading @@ -499,6 +506,7 @@ int machine_check_e500mc(struct pt_regs *regs) reason & MCSR_MEA ? "Effective" : "Physical", addr); reason & MCSR_MEA ? "Effective" : "Physical", addr); } } silent_out: mtspr(SPRN_MCSR, mcsr); mtspr(SPRN_MCSR, mcsr); return mfspr(SPRN_MCSR) == 0 && recoverable; return mfspr(SPRN_MCSR) == 0 && recoverable; } } Loading @@ -507,6 +515,11 @@ int machine_check_e500(struct pt_regs *regs) { { unsigned long reason = get_mc_reason(regs); unsigned long reason = get_mc_reason(regs); if (reason & MCSR_BUS_RBERR) { if (fsl_rio_mcheck_exception(regs)) return 1; } printk("Machine check in kernel mode.\n"); printk("Machine check in kernel mode.\n"); printk("Caused by (from MCSR=%lx): ", reason); printk("Caused by (from MCSR=%lx): ", reason); Loading
arch/powerpc/sysdev/fsl_lbc.c +7 −2 Original line number Original line Diff line number Diff line Loading @@ -184,7 +184,8 @@ int fsl_upm_run_pattern(struct fsl_upm *upm, void __iomem *io_base, u32 mar) } } EXPORT_SYMBOL(fsl_upm_run_pattern); EXPORT_SYMBOL(fsl_upm_run_pattern); static int __devinit fsl_lbc_ctrl_init(struct fsl_lbc_ctrl *ctrl) static int __devinit fsl_lbc_ctrl_init(struct fsl_lbc_ctrl *ctrl, struct device_node *node) { { struct fsl_lbc_regs __iomem *lbc = ctrl->regs; struct fsl_lbc_regs __iomem *lbc = ctrl->regs; Loading @@ -198,6 +199,10 @@ static int __devinit fsl_lbc_ctrl_init(struct fsl_lbc_ctrl *ctrl) /* Enable interrupts for any detected events */ /* Enable interrupts for any detected events */ out_be32(&lbc->lteir, LTEIR_ENABLE); out_be32(&lbc->lteir, LTEIR_ENABLE); /* Set the monitor timeout value to the maximum for erratum A001 */ if (of_device_is_compatible(node, "fsl,elbc")) clrsetbits_be32(&lbc->lbcr, LBCR_BMT, LBCR_BMTPS); return 0; return 0; } } Loading Loading @@ -304,7 +309,7 @@ static int __devinit fsl_lbc_ctrl_probe(struct platform_device *dev) fsl_lbc_ctrl_dev->dev = &dev->dev; fsl_lbc_ctrl_dev->dev = &dev->dev; ret = fsl_lbc_ctrl_init(fsl_lbc_ctrl_dev); ret = fsl_lbc_ctrl_init(fsl_lbc_ctrl_dev, dev->dev.of_node); if (ret < 0) if (ret < 0) goto err; goto err; Loading
arch/powerpc/sysdev/fsl_rio.c +80 −20 Original line number Original line Diff line number Diff line Loading @@ -10,7 +10,7 @@ * - Added Port-Write message handling * - Added Port-Write message handling * - Added Machine Check exception handling * - Added Machine Check exception handling * * * Copyright (C) 2007, 2008 Freescale Semiconductor, Inc. * Copyright (C) 2007, 2008, 2010 Freescale Semiconductor, Inc. * Zhang Wei <wei.zhang@freescale.com> * Zhang Wei <wei.zhang@freescale.com> * * * Copyright 2005 MontaVista Software, Inc. * Copyright 2005 MontaVista Software, Inc. Loading Loading @@ -47,11 +47,29 @@ #define IRQ_RIO_RX(m) (((struct rio_priv *)(m->priv))->rxirq) #define IRQ_RIO_RX(m) (((struct rio_priv *)(m->priv))->rxirq) #define IRQ_RIO_PW(m) (((struct rio_priv *)(m->priv))->pwirq) #define IRQ_RIO_PW(m) (((struct rio_priv *)(m->priv))->pwirq) #define IPWSR_CLEAR 0x98 #define OMSR_CLEAR 0x1cb3 #define IMSR_CLEAR 0x491 #define IDSR_CLEAR 0x91 #define ODSR_CLEAR 0x1c00 #define LTLEECSR_ENABLE_ALL 0xFFC000FC #define ESCSR_CLEAR 0x07120204 #define RIO_PORT1_EDCSR 0x0640 #define RIO_PORT2_EDCSR 0x0680 #define RIO_PORT1_IECSR 0x10130 #define RIO_PORT2_IECSR 0x101B0 #define RIO_IM0SR 0x13064 #define RIO_IM1SR 0x13164 #define RIO_OM0SR 0x13004 #define RIO_OM1SR 0x13104 #define RIO_ATMU_REGS_OFFSET 0x10c00 #define RIO_ATMU_REGS_OFFSET 0x10c00 #define RIO_P_MSG_REGS_OFFSET 0x11000 #define RIO_P_MSG_REGS_OFFSET 0x11000 #define RIO_S_MSG_REGS_OFFSET 0x13000 #define RIO_S_MSG_REGS_OFFSET 0x13000 #define RIO_GCCSR 0x13c #define RIO_GCCSR 0x13c #define RIO_ESCSR 0x158 #define RIO_ESCSR 0x158 #define RIO_PORT2_ESCSR 0x178 #define RIO_CCSR 0x15c #define RIO_CCSR 0x15c #define RIO_LTLEDCSR 0x0608 #define RIO_LTLEDCSR 0x0608 #define RIO_LTLEDCSR_IER 0x80000000 #define RIO_LTLEDCSR_IER 0x80000000 Loading Loading @@ -88,7 +106,10 @@ #define RIO_IPWSR_PWD 0x00000008 #define RIO_IPWSR_PWD 0x00000008 #define RIO_IPWSR_PWB 0x00000004 #define RIO_IPWSR_PWB 0x00000004 #define RIO_EPWISR_PINT 0x80000000 /* EPWISR Error match value */ #define RIO_EPWISR_PINT1 0x80000000 #define RIO_EPWISR_PINT2 0x40000000 #define RIO_EPWISR_MU 0x00000002 #define RIO_EPWISR_PW 0x00000001 #define RIO_EPWISR_PW 0x00000001 #define RIO_MSG_DESC_SIZE 32 #define RIO_MSG_DESC_SIZE 32 Loading Loading @@ -260,9 +281,7 @@ struct rio_priv { static void __iomem *rio_regs_win; static void __iomem *rio_regs_win; #ifdef CONFIG_E500 #ifdef CONFIG_E500 static int (*saved_mcheck_exception)(struct pt_regs *regs); int fsl_rio_mcheck_exception(struct pt_regs *regs) static int fsl_rio_mcheck_exception(struct pt_regs *regs) { { const struct exception_table_entry *entry = NULL; const struct exception_table_entry *entry = NULL; unsigned long reason = mfspr(SPRN_MCSR); unsigned long reason = mfspr(SPRN_MCSR); Loading @@ -284,11 +303,9 @@ static int fsl_rio_mcheck_exception(struct pt_regs *regs) } } } } if (saved_mcheck_exception) return 0; return saved_mcheck_exception(regs); else return cur_cpu_spec->machine_check(regs); } } EXPORT_SYMBOL_GPL(fsl_rio_mcheck_exception); #endif #endif /** /** Loading Loading @@ -1064,6 +1081,40 @@ static int fsl_rio_doorbell_init(struct rio_mport *mport) return rc; return rc; } } static void port_error_handler(struct rio_mport *port, int offset) { /*XXX: Error recovery is not implemented, we just clear errors */ out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR), 0); if (offset == 0) { out_be32((u32 *)(rio_regs_win + RIO_PORT1_EDCSR), 0); out_be32((u32 *)(rio_regs_win + RIO_PORT1_IECSR), 0); out_be32((u32 *)(rio_regs_win + RIO_ESCSR), ESCSR_CLEAR); } else { out_be32((u32 *)(rio_regs_win + RIO_PORT2_EDCSR), 0); out_be32((u32 *)(rio_regs_win + RIO_PORT2_IECSR), 0); out_be32((u32 *)(rio_regs_win + RIO_PORT2_ESCSR), ESCSR_CLEAR); } } static void msg_unit_error_handler(struct rio_mport *port) { struct rio_priv *priv = port->priv; /*XXX: Error recovery is not implemented, we just clear errors */ out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR), 0); out_be32((u32 *)(rio_regs_win + RIO_IM0SR), IMSR_CLEAR); out_be32((u32 *)(rio_regs_win + RIO_IM1SR), IMSR_CLEAR); out_be32((u32 *)(rio_regs_win + RIO_OM0SR), OMSR_CLEAR); out_be32((u32 *)(rio_regs_win + RIO_OM1SR), OMSR_CLEAR); out_be32(&priv->msg_regs->odsr, ODSR_CLEAR); out_be32(&priv->msg_regs->dsr, IDSR_CLEAR); out_be32(&priv->msg_regs->pwsr, IPWSR_CLEAR); } /** /** * fsl_rio_port_write_handler - MPC85xx port write interrupt handler * fsl_rio_port_write_handler - MPC85xx port write interrupt handler * @irq: Linux interrupt number * @irq: Linux interrupt number Loading Loading @@ -1144,10 +1195,22 @@ fsl_rio_port_write_handler(int irq, void *dev_instance) } } pw_done: pw_done: if (epwisr & RIO_EPWISR_PINT) { if (epwisr & RIO_EPWISR_PINT1) { tmp = in_be32(priv->regs_win + RIO_LTLEDCSR); pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp); port_error_handler(port, 0); } if (epwisr & RIO_EPWISR_PINT2) { tmp = in_be32(priv->regs_win + RIO_LTLEDCSR); tmp = in_be32(priv->regs_win + RIO_LTLEDCSR); pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp); pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp); out_be32(priv->regs_win + RIO_LTLEDCSR, 0); port_error_handler(port, 1); } if (epwisr & RIO_EPWISR_MU) { tmp = in_be32(priv->regs_win + RIO_LTLEDCSR); pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp); msg_unit_error_handler(port); } } return IRQ_HANDLED; return IRQ_HANDLED; Loading Loading @@ -1258,12 +1321,14 @@ static int fsl_rio_port_write_init(struct rio_mport *mport) /* Hook up port-write handler */ /* Hook up port-write handler */ rc = request_irq(IRQ_RIO_PW(mport), fsl_rio_port_write_handler, 0, rc = request_irq(IRQ_RIO_PW(mport), fsl_rio_port_write_handler, "port-write", (void *)mport); IRQF_SHARED, "port-write", (void *)mport); if (rc < 0) { if (rc < 0) { pr_err("MPC85xx RIO: unable to request inbound doorbell irq"); pr_err("MPC85xx RIO: unable to request inbound doorbell irq"); goto err_out; goto err_out; } } /* Enable Error Interrupt */ out_be32((u32 *)(rio_regs_win + RIO_LTLEECSR), LTLEECSR_ENABLE_ALL); INIT_WORK(&priv->pw_work, fsl_pw_dpc); INIT_WORK(&priv->pw_work, fsl_pw_dpc); spin_lock_init(&priv->pw_fifo_lock); spin_lock_init(&priv->pw_fifo_lock); Loading Loading @@ -1538,11 +1603,6 @@ int fsl_rio_setup(struct platform_device *dev) fsl_rio_doorbell_init(port); fsl_rio_doorbell_init(port); fsl_rio_port_write_init(port); fsl_rio_port_write_init(port); #ifdef CONFIG_E500 saved_mcheck_exception = ppc_md.machine_check_exception; ppc_md.machine_check_exception = fsl_rio_mcheck_exception; #endif return 0; return 0; err: err: iounmap(priv->regs_win); iounmap(priv->regs_win); Loading