From: Michael Bringmann <[email protected]>

Add support to reset the AXXIA RIO controller when a Link Reset Request
symbol is received.

Signed-off-by: Michael Bringmann <[email protected]>
---
 drivers/rapidio/devices/lsi/axxia-rio-irq.c   |   64 +++++++++++++++++++------
 drivers/rapidio/devices/lsi/axxia-rio-irq.h   |    1 +
 drivers/rapidio/devices/lsi/axxia-rio-sysfs.c |   15 +++---
 drivers/rapidio/devices/lsi/axxia-rio.c       |    2 +-
 4 files changed, 60 insertions(+), 22 deletions(-)

diff --git a/drivers/rapidio/devices/lsi/axxia-rio-irq.c 
b/drivers/rapidio/devices/lsi/axxia-rio-irq.c
index f26adac..9b8708e 100644
--- a/drivers/rapidio/devices/lsi/axxia-rio-irq.c
+++ b/drivers/rapidio/devices/lsi/axxia-rio-irq.c
@@ -141,7 +141,7 @@ static inline void __misc_info_dbg(struct rio_priv *priv, 
u32 misc_state)
        /* Log only - no enable bit or state to clear */
        if (misc_state & (UNEXP_MSG_LOG | UNEXP_MSG_INT |
                          LL_TL_INT | GRIO_INT |
-                         UNSP_RIO_REQ_INT)) {
+                         UNSP_RIO_REQ_INT | LINK_REQ_INT)) {
                if (misc_state & UNEXP_MSG_INT)
                        __irq_dbg(priv, RIO_MISC_UNEXP);
                if (misc_state & LL_TL_INT)
@@ -150,6 +150,8 @@ static inline void __misc_info_dbg(struct rio_priv *priv, 
u32 misc_state)
                        __irq_dbg(priv, RIO_MISC_GRIO);
                if (misc_state & UNSP_RIO_REQ_INT)
                        __irq_dbg(priv, RIO_MISC_UNSUP);
+               if (misc_state & LINK_REQ_INT)
+                       __irq_dbg(priv, RIO_MISC_LINK_REQ);
        }
 }
 
@@ -534,6 +536,42 @@ static inline void __misc_fatal(struct rio_mport *mport,
 }
 
 /**
+ * srio_sw_reset - Reset the SRIO (GRIO) module when it reaches a fatal
+ *                 lockup state
+ * @mport: Master port with triggered interrupt
+ */
+static void srio_sw_reset(struct rio_mport *mport)
+{
+       struct rio_priv *priv = mport->priv;
+
+       /**
+        * Reset platform if port is broken
+        */
+       if (priv->linkdown_reset.win) {
+               u32 r0, r00, r1, r2;
+
+               __rio_local_read_config_32(mport, RIO_DID_CSR, &r1);
+               __rio_local_read_config_32(mport, RIO_COMPONENT_TAG_CSR, &r2);
+
+               r0 = *((u32 *)priv->linkdown_reset.win+
+                               priv->linkdown_reset.reg_addr);
+               *((u32 *)priv->linkdown_reset.win+
+                       priv->linkdown_reset.reg_addr) =
+                               r0 | priv->linkdown_reset.reg_mask;
+
+               r00 = *((u32 *)priv->linkdown_reset.win+
+                               priv->linkdown_reset.reg_addr);
+                       /* Verify that the bit was set? */
+
+               *((u32 *)priv->linkdown_reset.win+
+                       priv->linkdown_reset.reg_addr) = r0;
+
+               __rio_local_write_config_32(mport, RIO_DID_CSR, r1);
+               __rio_local_write_config_32(mport, RIO_COMPONENT_TAG_CSR, r2);
+       }
+}
+
+/**
  * misc_irq_handler - MISC interrupt handler
  * @h: handler specific data
  * @state: Interrupt state
@@ -545,8 +583,14 @@ static void misc_irq_handler(struct rio_irq_handler *h, 
u32 state)
        struct rio_priv *priv = mport->priv;
 #endif
 
+       /*
+        * Handle miscellaneous 'Link (IPG) Reset Request'
+        */
+       if (state & LINK_REQ_INT)
+               srio_sw_reset(mport);
+
        /**
-        * notify platform if port is broken
+        * Notify platform if port is broken
         */
        __misc_fatal(mport, state);
 
@@ -573,17 +617,8 @@ static void linkdown_irq_handler(struct rio_irq_handler 
*h, u32 state)
        /**
         * Reset platform if port is broken
         */
-       if (state & RAB_SRDS_STAT1_LINKDOWN_INT) {
-               u32 r32;
-               r32 = *((u32 *)priv->linkdown_reset.win+
-                               priv->linkdown_reset.reg_addr);
-               r32 |= priv->linkdown_reset.reg_mask;
-               *((u32 *)priv->linkdown_reset.win+
-                        priv->linkdown_reset.reg_addr) =
-                   r32 | priv->linkdown_reset.reg_mask;
-               *((u32 *)priv->linkdown_reset.win+
-                        priv->linkdown_reset.reg_addr) = r32;
-       }
+       if (state & RAB_SRDS_STAT1_LINKDOWN_INT)
+               srio_sw_reset(mport);
 
 #if defined(CONFIG_AXXIA_RIO_STAT)
        /**
@@ -2522,7 +2557,8 @@ void axxia_rio_port_irq_init(struct rio_mport *mport)
        priv->misc_irq.mport = mport;
        priv->misc_irq.irq_enab_reg_addr = RAB_INTR_ENAB_MISC;
        priv->misc_irq.irq_state_reg_addr = RAB_INTR_STAT_MISC;
-       priv->misc_irq.irq_state_mask = AMST_INT | ASLV_INT;
+       priv->misc_irq.irq_state_mask = AMST_INT | ASLV_INT |
+                                       LINK_REQ_INT;
 #if defined(CONFIG_AXXIA_RIO_STAT)
        priv->misc_irq.irq_state_mask |=
                GRIO_INT | LL_TL_INT | UNEXP_MSG_LOG |
diff --git a/drivers/rapidio/devices/lsi/axxia-rio-irq.h 
b/drivers/rapidio/devices/lsi/axxia-rio-irq.h
index f80ca93..201f846 100644
--- a/drivers/rapidio/devices/lsi/axxia-rio-irq.h
+++ b/drivers/rapidio/devices/lsi/axxia-rio-irq.h
@@ -59,6 +59,7 @@ enum rio_irq_dbg {
        RIO_MISC_TL,
        RIO_MISC_GRIO,
        RIO_MISC_UNSUP,
+       RIO_MISC_LINK_REQ,
        RIO_LINKDOWN,
        /**
         * Peripheral Bus bridge, RapidIO -> Peripheral bus events - mostly bad!
diff --git a/drivers/rapidio/devices/lsi/axxia-rio-sysfs.c 
b/drivers/rapidio/devices/lsi/axxia-rio-sysfs.c
index 909d406..db47761 100644
--- a/drivers/rapidio/devices/lsi/axxia-rio-sysfs.c
+++ b/drivers/rapidio/devices/lsi/axxia-rio-sysfs.c
@@ -53,16 +53,17 @@ static const char *state_str[] = {
 
 static const char *irq_str[] = {
        /* Axxia Error Events - really bad! */
-       "Axxia Master Write timouts                            ",
-       "Axxia Master Read timouts                             ",
-       "Axxia Slave write decode error response               ",
-       "Axxia Slave write error response                      ",
-       "Axxia Slave read decode error response                ",
-       "Axxia Slave read error response                       ",
-       "Axxia Slave unsupported cmds                          ",
+       "Axxia Master Write timouts                           ",
+       "Axxia Master Read timouts                            ",
+       "Axxia Slave write decode error response              ",
+       "Axxia Slave write error response                     ",
+       "Axxia Slave read decode error response               ",
+       "Axxia Slave read error response                      ",
+       "Axxia Slave unsupported cmds                         ",
        "Logical/Transport layer errors                       ",
        "General RapidIO Controller errors                    ",
        "Unsupported RIO req received                         ",
+       "Link Reset RIO req received                          ",
        "Linkdown per Deadman Monitor IRQ                     ",
        /*
         * Peripheral Bus bridge, RapidIO -> Peripheral
diff --git a/drivers/rapidio/devices/lsi/axxia-rio.c 
b/drivers/rapidio/devices/lsi/axxia-rio.c
index 8dbe58d..9e32652 100644
--- a/drivers/rapidio/devices/lsi/axxia-rio.c
+++ b/drivers/rapidio/devices/lsi/axxia-rio.c
@@ -761,7 +761,7 @@ void axxia_rio_set_mport_disc_mode(struct rio_mport *mport)
 
 #ifdef SRIO_IODEBUG
        __rio_local_read_config_32(mport, RIO_GCCSR, &result);
-       dev_dbg(priv->dev, "%d RIO_GEN_CTL_CSR set to 0x%X for main port\n",
+       IODP("rio[%d]: RIO_GEN_CTL_CSR set to 0x%X for main port\n",
                mport->id, result);
 #endif
 
-- 
1.7.9.5

-- 
_______________________________________________
linux-yocto mailing list
[email protected]
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to