[PATCH 5/7][OMAP 3/4+] BRIDGE MMUfault infinite timeout fix

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>From 19c2dde4fb6b3bb816fc004d6342b9996da301f1 Mon Sep 17 00:00:00 2001
From: Omar Ramirez Luna <x0084701@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>
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 <h-kanigeri2@xxxxxx>
---
 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux