>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