>From 19c2dde4fb6b3bb816fc004d6342b9996da301f1 Mon Sep 17 00:00:00 2001
From: Omar Ramirez Luna <[EMAIL PROTECTED]>
Date: Fri, 12 Sep 2008 20:33:28 -0500
Subject: [PATCH] BRIDGE MMUfault infinite timeout fix

Enable loading of the Base image upon MMU fault even in the cases
where the Node has infinite timeout. A new processor state PROC_ERROR
is added to indicate the state of DSP when MMU and Sys error faults occur.
Also a fixed resource cleanup code.

Signed-off-by: Hari Kanigeri <[EMAIL PROTECTED]>
---
 arch/arm/plat-omap/include/mach/bridge/brddefs.h |    2 +-
 arch/arm/plat-omap/include/mach/bridge/dbdefs.h  |    3 +-
 drivers/dsp/bridge/rmgr/drv.c                    |   48 +++++++++++----------
 drivers/dsp/bridge/rmgr/node.c                   |   50 ++++++++++++----------
 drivers/dsp/bridge/rmgr/proc.c                   |    3 +
 drivers/dsp/bridge/wmd/_tiomap_pwr.h             |   18 ++++++++
 drivers/dsp/bridge/wmd/tiomap3430_pwr.c          |    6 ---
 drivers/dsp/bridge/wmd/tiomap_sm.c               |    1 +
 drivers/dsp/bridge/wmd/ue_deh.c                  |   11 ++++-
 9 files changed, 86 insertions(+), 56 deletions(-)

diff --git a/arch/arm/plat-omap/include/mach/bridge/brddefs.h 
b/arch/arm/plat-omap/include/mach/bridge/brddefs.h
index 1706fb7..99f373b 100644
--- a/arch/arm/plat-omap/include/mach/bridge/brddefs.h
+++ b/arch/arm/plat-omap/include/mach/bridge/brddefs.h
@@ -45,7 +45,7 @@
 #define BRD_HIBERNATION 0x7            /* MPU initiated hibernation */
 #define BRD_RETENTION     0x8       /* Retention mode */
 #define BRD_DSP_HIBERNATION     0x9       /* DSP initiated hibernation */
-
+#define BRD_ERROR              0xA       /* Board state is Error */
        typedef u32 BRD_STATUS;
 
 /* BRD Object */
diff --git a/arch/arm/plat-omap/include/mach/bridge/dbdefs.h 
b/arch/arm/plat-omap/include/mach/bridge/dbdefs.h
index e9328a3..e92c24f 100644
--- a/arch/arm/plat-omap/include/mach/bridge/dbdefs.h
+++ b/arch/arm/plat-omap/include/mach/bridge/dbdefs.h
@@ -221,7 +221,8 @@
        enum DSP_PROCSTATE {
                PROC_STOPPED,
                PROC_LOADED,
-               PROC_RUNNING
+               PROC_RUNNING,
+               PROC_ERROR
        } ;
 
 /* Node types */
diff --git a/drivers/dsp/bridge/rmgr/drv.c b/drivers/dsp/bridge/rmgr/drv.c
index 9e298f0..44db771 100644
--- a/drivers/dsp/bridge/rmgr/drv.c
+++ b/drivers/dsp/bridge/rmgr/drv.c
@@ -431,35 +431,40 @@ static DSP_STATUS DRV_ProcFreeNodeRes(HANDLE hPCtxt)
        DSP_STATUS status = DSP_SOK;
        struct NODE_RES_OBJECT *pNodeList = NULL;
        struct NODE_RES_OBJECT *pNodeRes = NULL;
+       u32  nState;
 
        DBC_Assert(hPCtxt != NULL);
        pNodeList = pCtxt->pNodeList;
        while (pNodeList != NULL) {
                GT_0trace(curTrace, GT_ENTER, "DRV_ProcFreeNodeRes: 1");
-       pNodeRes = pNodeList;
-       pNodeList = pNodeList->next;
-       if (pNodeRes->nodeAllocated) {
-                       if (NODE_GetState(pNodeRes->hNode) &
-                         (NODE_ALLOCATED | NODE_CREATED |
-                         NODE_RUNNING | NODE_PAUSED/*| NODE_TERMINATING */)) {
-                               GT_1trace(curTrace, GT_5CLASS,
-                                        "Calling Node_Terminate for Node:"
-                                        " 0x%x\n", pNodeRes->hNode);
-                               status = NODE_Terminate
-                                       (pNodeRes->hNode, &status);
-                               GT_1trace(curTrace, GT_5CLASS,
-                                        "Calling Node_Delete for Node:"
-                                        " 0x%x\n", pNodeRes->hNode);
-                               status = NODE_Delete(pNodeRes->hNode);
-                               GT_1trace(curTrace, GT_5CLASS,
+               pNodeRes = pNodeList;
+               pNodeList = pNodeList->next;
+               if (pNodeRes->nodeAllocated) {
+                       nState = NODE_GetState(pNodeRes->hNode) ;
+                       GT_1trace(curTrace, GT_5CLASS,
+                               "DRV_ProcFreeNodeRes: Node state %x\n", nState);
+                       if (nState <= NODE_DELETING) {
+                               if ((nState == NODE_RUNNING) ||
+                                       (nState == NODE_PAUSED) ||
+                                       (nState == NODE_TERMINATING)) {
+                                       GT_1trace(curTrace, GT_5CLASS,
+                                       "Calling Node_Terminate for Node:"
+                                       " 0x%x\n", pNodeRes->hNode);
+                                       status = NODE_Terminate
+                                               (pNodeRes->hNode, &status);
+                                       GT_1trace(curTrace, GT_5CLASS,
+                                                "Calling Node_Delete for Node:"
+                                                " 0x%x\n", pNodeRes->hNode);
+                                       status = NODE_Delete(pNodeRes->hNode);
+                                       GT_1trace(curTrace, GT_5CLASS,
                                        "the status after the NodeDelete %x\n",
                                        status);
-                       } else /*if (NODE_GetState(pNodeRes->hNode)
-                               == NODE_DONE)*/ {
-                               status = NODE_Delete(pNodeRes->hNode);
+                               } else if ((nState == NODE_ALLOCATED)
+                                       || (nState == NODE_CREATED))
+                                       status = NODE_Delete(pNodeRes->hNode);
                        }
-                       pNodeRes->nodeAllocated = 0;
                }
+               pNodeRes->nodeAllocated = 0;
        }
        return status;
 }
@@ -1300,9 +1305,8 @@ u32 DRV_GetFirstDevObject(void)
        if (DSP_SUCCEEDED
            (CFG_GetObject((u32 *)&pDrvObject, REG_DRV_OBJECT))) {
                if ((pDrvObject->devList != NULL) &&
-                  !LST_IsEmpty(pDrvObject->devList)) {
+                  !LST_IsEmpty(pDrvObject->devList))
                        dwDevObject = (u32) LST_First(pDrvObject->devList);
-               }
        }
 
        return dwDevObject;
diff --git a/drivers/dsp/bridge/rmgr/node.c b/drivers/dsp/bridge/rmgr/node.c
index 598429a..ebedc14 100644
--- a/drivers/dsp/bridge/rmgr/node.c
+++ b/drivers/dsp/bridge/rmgr/node.c
@@ -1669,7 +1669,7 @@ DSP_STATUS NODE_Delete(struct NODE_OBJECT *hNode)
        struct PROCESS_CONTEXT *pCtxt = NULL;
        DSP_STATUS res_status = DSP_SOK;
 #endif
-
+       struct DSP_PROCESSORSTATE procStatus;
        DBC_Require(cRefs > 0);
        GT_1trace(NODE_debugMask, GT_ENTER, "NODE_Delete: hNode: 0x%x\n",
                  hNode);
@@ -1745,9 +1745,18 @@ func_cont1:
                        } else if (procId == IVA_UNIT)
                                ulDeleteFxn = (u32)hNode->nodeEnv;
                        if (DSP_SUCCEEDED(status)) {
-                               status = DISP_NodeDelete(hDisp, hNode,
-                                        hNodeMgr->ulFxnAddrs[RMSDELETENODE],
-                                        ulDeleteFxn, hNode->nodeEnv);
+                               status = PROC_GetState(hProcessor, &procStatus,
+                                       sizeof(struct DSP_PROCESSORSTATE));
+                               GT_1trace(NODE_debugMask, GT_4CLASS,
+                                                "NODE_Delete: proc Status "
+                                                "0x%x\n", procStatus.iState);
+                               if (procStatus.iState != PROC_ERROR) {
+                                       status = DISP_NodeDelete(hDisp, hNode,
+                                       hNodeMgr->ulFxnAddrs[RMSDELETENODE],
+                                       ulDeleteFxn, hNode->nodeEnv);
+                               } else
+                                       NODE_SetState(hNode, NODE_DONE);
+
                                /* Unload execute, if not unloaded, and delete
                                 * function */
                                if (state == NODE_RUNNING &&
@@ -1779,18 +1788,11 @@ func_cont1:
        hNodeMgr->uNumNodes--;
        /* Decrement count of nodes created on DSP */
        if ((state != NODE_ALLOCATED) || ((state == NODE_ALLOCATED) &&
-          (hNode->nodeEnv != (u32) NULL))) {
+       (hNode->nodeEnv != (u32) NULL)))
                hNodeMgr->uNumCreated--;
-               /* This is not acceptable since in deep sleep, all the
-                * peripherals are switched off We just need to put DSP
-                * CPU in idle mode */
-       }
         /*  Free host-side resources allocated by NODE_Create()
         *  DeleteNode() fails if SM buffers not freed by client!  */
 #ifndef RES_CLEANUP_DISABLE
-       if (DSP_FAILED(status))
-               goto func_cont;
-
        /* Update the node and stream resource status */
        PRCS_GetCurrentHandle(&hProcess);
        res_status = CFG_GetObject((u32 *)&hDrvObject, REG_DRV_OBJECT);
@@ -1801,7 +1803,6 @@ func_cont1:
                         &pCtxt, hNode, 0);
        if (pCtxt == NULL)
                goto func_cont;
-
        if (DRV_GetNodeResElement(hNode, &nodeRes, pCtxt) != DSP_ENOTFOUND) {
                GT_0trace(NODE_debugMask, GT_5CLASS, "\nNODE_Delete12:\n");
                DRV_ProcNodeUpdateStatus(nodeRes, false);
@@ -1811,17 +1812,14 @@ func_cont:
        GT_0trace(NODE_debugMask, GT_ENTER, "\nNODE_Delete13:\n ");
        DeleteNode(hNode);
 #ifndef RES_CLEANUP_DISABLE
-       if (DSP_SUCCEEDED(status)) {
-               GT_0trace(NODE_debugMask, GT_5CLASS, "\nNODE_Delete2:\n ");
-               if (pCtxt != NULL)
-                       DRV_RemoveNodeResElement(nodeRes, (HANDLE)pCtxt);
-
-       }
+       GT_0trace(NODE_debugMask, GT_5CLASS, "\nNODE_Delete2:\n ");
+       if (pCtxt != NULL)
+               DRV_RemoveNodeResElement(nodeRes, (HANDLE)pCtxt);
 #endif
        GT_0trace(NODE_debugMask, GT_ENTER, "\nNODE_Delete3:\n ");
-                       /* Exit critical section */
-                       (void)SYNC_LeaveCS(hNodeMgr->hSync);
-                       PROC_NotifyClients(hProcessor, DSP_NODESTATECHANGE);
+       /* Exit critical section */
+       (void)SYNC_LeaveCS(hNodeMgr->hSync);
+       PROC_NotifyClients(hProcessor, DSP_NODESTATECHANGE);
 func_end:
        return status;
 }
@@ -2597,6 +2595,12 @@ DSP_STATUS NODE_Terminate(struct NODE_OBJECT *hNode, OUT 
DSP_STATUS *pStatus)
        GT_1trace(NODE_debugMask, GT_ENTER,
                 "NODE_Terminate: hNode: 0x%x\n", hNode);
 
+       if (pNode->hProcessor == NULL) {
+               GT_1trace(NODE_debugMask, GT_4CLASS,
+               "NODE_Terminate: pNode->hProcessor = 0x%x\n",
+               pNode->hProcessor);
+               goto func_end;
+       }
        status = PROC_GetProcessorId(pNode->hProcessor, &procId);
 
        if (DSP_SUCCEEDED(status)) {
@@ -2703,7 +2707,7 @@ DSP_STATUS NODE_Terminate(struct NODE_OBJECT *hNode, OUT 
DSP_STATUS *pStatus)
                }
                (void)SYNC_LeaveCS(hNodeMgr->hSync);
        }               /*End of SYNC_EnterCS */
-
+func_end:
        return status;
 }
 
diff --git a/drivers/dsp/bridge/rmgr/proc.c b/drivers/dsp/bridge/rmgr/proc.c
index 1835fd0..c765cbf 100644
--- a/drivers/dsp/bridge/rmgr/proc.c
+++ b/drivers/dsp/bridge/rmgr/proc.c
@@ -910,6 +910,9 @@ DSP_STATUS PROC_GetState(DSP_HPROCESSOR hProcessor,
                        case BRD_LOADED:
                                pProcStatus->iState = PROC_LOADED;
                                break;
+                       case BRD_ERROR:
+                               pProcStatus->iState = PROC_ERROR;
+                               break;
                        default:
                                status = DSP_EFAIL;
                                break;
diff --git a/drivers/dsp/bridge/wmd/_tiomap_pwr.h 
b/drivers/dsp/bridge/wmd/_tiomap_pwr.h
index 697097e..faa2309 100644
--- a/drivers/dsp/bridge/wmd/_tiomap_pwr.h
+++ b/drivers/dsp/bridge/wmd/_tiomap_pwr.h
@@ -77,6 +77,24 @@ DSP_STATUS PreScale_DSP(struct WMD_DEV_CONTEXT *pDevContext, 
IN void *pArgs);
  */
 DSP_STATUS handle_constraints_set(struct WMD_DEV_CONTEXT *pDevContext,
                                 IN void *pArgs);
+/*
+ *  ======== DSP_PeripheralClocks_Disable ========
+ *     This function disables all the peripheral clocks that
+ *     were enabled by DSP. Call this function only when
+ *     DSP is entering Hibernation or when DSP is in
+ *     Error state
+ */
+DSP_STATUS DSP_PeripheralClocks_Disable(struct WMD_DEV_CONTEXT *pDevContext,
+                                       IN void *pArgs);
+
+/*
+ *  ======== DSP_PeripheralClocks_Enable ========
+ *     This function enables all the peripheral clocks that
+ *     were requested by DSP.
+ */
+DSP_STATUS DSP_PeripheralClocks_Enable(struct WMD_DEV_CONTEXT *pDevContext,
+                                      IN void *pArgs);
+
 
 #endif                         /* _TIOMAP_PWR_ */
 
diff --git a/drivers/dsp/bridge/wmd/tiomap3430_pwr.c 
b/drivers/dsp/bridge/wmd/tiomap3430_pwr.c
index 751884b..0c207c8 100644
--- a/drivers/dsp/bridge/wmd/tiomap3430_pwr.c
+++ b/drivers/dsp/bridge/wmd/tiomap3430_pwr.c
@@ -82,12 +82,6 @@ extern struct constraint_handle *dsp_constraint_handle;
 #endif
 extern struct MAILBOX_CONTEXT mboxsetting;
 
-extern void GetHWRegs(u32 prm_base, u32 cm_base);
-DSP_STATUS DSP_PeripheralClocks_Disable(struct WMD_DEV_CONTEXT *pDevContext,
-                                       IN void *pArgs);
-DSP_STATUS DSP_PeripheralClocks_Enable(struct WMD_DEV_CONTEXT *pDevContext,
-                                      IN void *pArgs);
-
 /*
  *  ======== handle_constraints_set ========
  *     Sets new DSP constraint
diff --git a/drivers/dsp/bridge/wmd/tiomap_sm.c 
b/drivers/dsp/bridge/wmd/tiomap_sm.c
index ce5e53c..e7adccd 100644
--- a/drivers/dsp/bridge/wmd/tiomap_sm.c
+++ b/drivers/dsp/bridge/wmd/tiomap_sm.c
@@ -65,6 +65,7 @@
 /*  ----------------------------------- This */
 #include "_tiomap.h"
 #include <chnl_sm.h>
+#include "_tiomap_pwr.h"
 
 #ifndef CONFIG_DISABLE_BRIDGE_PM
 #ifndef CONFIG_DISABLE_BRIDGE_DVFS
diff --git a/drivers/dsp/bridge/wmd/ue_deh.c b/drivers/dsp/bridge/wmd/ue_deh.c
index b2a85e2..f5ecc63 100644
--- a/drivers/dsp/bridge/wmd/ue_deh.c
+++ b/drivers/dsp/bridge/wmd/ue_deh.c
@@ -66,7 +66,8 @@
 #include "mmu_fault.h"
 #include "_tiomap.h"
 #include "_deh.h"
-#include <_tiomap_mmu.h>
+#include "_tiomap_mmu.h"
+#include "_tiomap_pwr.h"
 #include <io_sm.h>
 
 static struct HW_MMUMapAttrs_t  mapAttrs = { HW_LITTLE_ENDIAN,
@@ -215,6 +216,8 @@ void WMD_DEH_Notify(struct DEH_MGR *hDehMgr, u32 
ulEventMask,
        if (MEM_IsValidHandle(pDehMgr, SIGNATURE)) {
                printk(KERN_INFO "WMD_DEH_Notify: ********** DEVICE EXCEPTION "
                        "**********\n");
+               pDevContext = (struct WMD_DEV_CONTEXT *)pDehMgr->hWmdContext;
+
                switch (ulEventMask) {
                case DSP_SYSERROR:
                        /* reset errInfo structure before use */
@@ -229,8 +232,6 @@ void WMD_DEH_Notify(struct DEH_MGR *hDehMgr, u32 
ulEventMask,
                case DSP_MMUFAULT:
                        /* MMU fault routine should have set err info
                         * structure */
-                       pDevContext = (struct WMD_DEV_CONTEXT *)pDehMgr->
-                                       hWmdContext;
                        pDehMgr->errInfo.dwErrMask = DSP_MMUFAULT;
                        printk(KERN_INFO "WMD_DEH_Notify: DSP_MMUFAULT,"
                                "errInfo = 0x%x\n", dwErrInfo);
@@ -287,6 +288,10 @@ void WMD_DEH_Notify(struct DEH_MGR *hDehMgr, u32 
ulEventMask,
                /* Call DSP Trace Buffer */
                PrintDspTraceBuffer(hDehMgr->hWmdContext);
 
+               /* Set the Board state as ERROR */
+               pDevContext->dwBrdState = BRD_ERROR;
+               /* Disable all the clocks that were enabled by DSP */
+               (void)DSP_PeripheralClocks_Disable(pDevContext, NULL);
                /* Signal DSP error/exception event. */
                NTFY_Notify(pDehMgr->hNtfy, ulEventMask);
        }
-- 
1.5.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to