From: Alexandre Bounine <alexandre.boun...@idt.com>

Add Machine Check exception handling into RapidIO port driver
for Freescale SoCs (MPC85xx).

Signed-off-by: Alexandre Bounine <alexandre.boun...@idt.com>
Tested-by: Thomas Moll <thomas.m...@sysgo.com>
---

 fsl_rio.c |   74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 70 insertions(+), 4 deletions(-)

diff -x '*.pj' -X dontdiff_2.6.32-rc5 -pNur w33a/arch/powerpc/sysdev/fsl_rio.c 
w33b/arch/powerpc/sysdev/fsl_rio.c
--- w33a/arch/powerpc/sysdev/fsl_rio.c  2010-03-08 10:38:10.121013000 -0500
+++ w33b/arch/powerpc/sysdev/fsl_rio.c  2010-03-08 11:23:03.274215000 -0500
@@ -31,6 +31,8 @@
 #include <linux/kfifo.h>
 
 #include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/uaccess.h>
 
 #undef DEBUG_PW        /* Port-Write debugging */
 
@@ -46,6 +48,8 @@
 #define RIO_ESCSR              0x158
 #define RIO_CCSR               0x15c
 #define RIO_LTLEDCSR           0x0608
+#define  RIO_LTLEDCSR_IER      0x80000000
+#define  RIO_LTLEDCSR_PRT      0x01000000
 #define RIO_LTLEECSR           0x060c
 #define RIO_EPWISR             0x10010
 #define RIO_ISR_AACR           0x10120
@@ -213,6 +217,54 @@ struct rio_priv {
        spinlock_t pw_fifo_lock;
 };
 
+#define __fsl_read_rio_config(x, addr, err, op)                \
+       __asm__ __volatile__(                           \
+               "1:     "op" %1,0(%2)\n"                \
+               "       eieio\n"                        \
+               "2:\n"                                  \
+               ".section .fixup,\"ax\"\n"              \
+               "3:     li %1,-1\n"                     \
+               "       li %0,%3\n"                     \
+               "       b 2b\n"                         \
+               ".section __ex_table,\"a\"\n"           \
+               "       .align 2\n"                     \
+               "       .long 1b,3b\n"                  \
+               ".text"                                 \
+               : "=r" (err), "=r" (x)                  \
+               : "b" (addr), "i" (-EFAULT), "0" (err))
+
+static void __iomem *rio_regs_win;
+
+static int (*saved_mcheck_exception)(struct pt_regs *regs);
+
+static int fsl_rio_mcheck_exception(struct pt_regs *regs)
+{
+       const struct exception_table_entry *entry = NULL;
+       unsigned long reason = (mfspr(SPRN_MCSR) & MCSR_MASK);
+
+       if (reason & MCSR_BUS_RBERR) {
+               reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR));
+               if (reason & (RIO_LTLEDCSR_IER | RIO_LTLEDCSR_PRT)) {
+                       /* Check if we are prepared to handle this fault */
+                       entry = search_exception_tables(regs->nip);
+                       if (entry) {
+                               pr_debug("RIO: %s - MC Exception handled\n",
+                                        __func__);
+                               out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR),
+                                        0);
+                               regs->msr |= MSR_RI;
+                               regs->nip = entry->fixup;
+                               return 1;
+                       }
+               }
+       }
+
+       if (saved_mcheck_exception)
+               return saved_mcheck_exception(regs);
+       else
+               return cur_cpu_spec->machine_check(regs);
+}
+
 /**
  * fsl_rio_doorbell_send - Send a MPC85xx doorbell message
  * @mport: RapidIO master port info
@@ -313,6 +365,7 @@ fsl_rio_config_read(struct rio_mport *mp
 {
        struct rio_priv *priv = mport->priv;
        u8 *data;
+       u32 rval, err = 0;
 
        pr_debug
            ("fsl_rio_config_read: index %d destid %d hopcount %d offset %8.8x 
len %d\n",
@@ -323,17 +376,24 @@ fsl_rio_config_read(struct rio_mport *mp
        data = (u8 *) priv->maint_win + offset;
        switch (len) {
        case 1:
-               *val = in_8((u8 *) data);
+               __fsl_read_rio_config(rval, data, err, "lbz");
                break;
        case 2:
-               *val = in_be16((u16 *) data);
+               __fsl_read_rio_config(rval, data, err, "lhz");
                break;
        default:
-               *val = in_be32((u32 *) data);
+               __fsl_read_rio_config(rval, data, err, "lwz");
                break;
        }
 
-       return 0;
+       if (err) {
+               pr_debug("RIO: cfg_read error %d for %x:%x:%x\n",
+                        err, destid, hopcount, offset);
+       }
+
+       *val = rval;
+
+       return err;
 }
 
 /**
@@ -1364,6 +1424,7 @@ int fsl_rio_setup(struct of_device *dev)
        rio_register_mport(port);
 
        priv->regs_win = ioremap(regs.start, regs.end - regs.start + 1);
+       rio_regs_win = priv->regs_win;
 
        /* Probe the master port phy type */
        ccsr = in_be32(priv->regs_win + RIO_CCSR);
@@ -1432,6 +1493,11 @@ int fsl_rio_setup(struct of_device *dev)
        fsl_rio_doorbell_init(port);
        fsl_rio_port_write_init(port);
 
+       saved_mcheck_exception = ppc_md.machine_check_exception;
+       ppc_md.machine_check_exception = fsl_rio_mcheck_exception;
+       /* Ensure that RFXE is set */
+       mtspr(SPRN_HID1, (mfspr(SPRN_HID1) | 0x20000));
+
        return 0;
 err:
        iounmap(priv->regs_win);

---

Important Notice: This message is intended for the use of the individual to 
whom it is addressed and may contain information which is privileged, 
confidential and/or exempt from disclosure under applicable law. If the reader 
of this message is not the intended recipient, or is not the employee or agent 
responsible for delivering the message to the intended recipient, you are 
hereby notified that any dissemination, distribution, or copying of this 
communication is strictly prohibited. If you have received this communication 
in error, please notify the sender immediately by telephone or return e-mail 
and delete the original message from your systems. Thank you. 

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to