Esempio n. 1
0
/*
 *  ======== DSP_Deinit ========
 *  	Frees the resources allocated for bridge.
 */
bool DSP_Deinit(u32 deviceContext)
{
	bool retVal = true;
	u32 deviceNode;
	struct MGR_OBJECT *mgrObject = NULL;

	GT_0trace(curTrace, GT_ENTER, "Entering DSP_Deinit \r\n");

	while ((deviceNode = DRV_GetFirstDevExtension()) != 0) {
		(void)DEV_RemoveDevice((struct CFG_DEVNODE *)deviceNode);

		(void)DRV_ReleaseResources((u32)deviceNode,
			 (struct DRV_OBJECT *)deviceContext);
	}

	(void) DRV_Destroy((struct DRV_OBJECT *) deviceContext);

	/* Get the Manager Object from Registry
	 * MGR Destroy will unload the DCD dll */
	if (DSP_SUCCEEDED(CFG_GetObject((u32 *)&mgrObject, REG_MGR_OBJECT)))
		(void)MGR_Destroy(mgrObject);

	WCD_Exit();

	return retVal;
}
Esempio n. 2
0
bool CHNLSM_ISR(struct WMD_DEV_CONTEXT *pDevContext, bool *pfSchedDPC,
		u16 *pwIntrVal)
{
	struct CFG_HOSTRES resources;
	u32 numMbxMsg;
	u32 mbxValue;

	DBG_Trace(DBG_ENTER, "CHNLSM_ISR(0x%x)\n", pDevContext);

	CFG_GetHostResources((struct CFG_DEVNODE *)DRV_GetFirstDevExtension(), &resources);

	HW_MBOX_NumMsgGet(resources.dwMboxBase, MBOX_DSP2ARM, &numMbxMsg);

	if (numMbxMsg > 0) {
		HW_MBOX_MsgRead(resources.dwMboxBase, MBOX_DSP2ARM, &mbxValue);

		HW_MBOX_EventAck(resources.dwMboxBase, MBOX_DSP2ARM,
				 HW_MBOX_U0_ARM, HW_MBOX_INT_NEW_MSG);

		DBG_Trace(DBG_LEVEL3, "Read %x from Mailbox\n", mbxValue);
		*pwIntrVal = (u16) mbxValue;
	}
	/* Set *pfSchedDPC to true; */
	*pfSchedDPC = true;
	return true;
}
Esempio n. 3
0
DSP_STATUS CHNLSM_DisableInterrupt(struct WMD_DEV_CONTEXT *pDevContext)
{
	struct CFG_HOSTRES resources;

	DBG_Trace(DBG_ENTER, "CHNLSM_DisableInterrupt(0x%x)\n", pDevContext);

	CFG_GetHostResources((struct CFG_DEVNODE *)DRV_GetFirstDevExtension(),
			     &resources);
	HW_MBOX_EventDisable(resources.dwMboxBase, MBOX_DSP2ARM,
			     MBOX_ARM, HW_MBOX_INT_NEW_MSG);
	return DSP_SOK;
}
Esempio n. 4
0
DSP_STATUS CHNLSM_EnableInterrupt(struct WMD_DEV_CONTEXT *pDevContext)
{
	DSP_STATUS status = DSP_SOK;
	u32 numMbxMsg;
	u32 mbxValue;
	struct CFG_HOSTRES resources;
	u32 devType;
	struct IO_MGR *hIOMgr;

	DBG_Trace(DBG_ENTER, "CHNLSM_EnableInterrupt(0x%x)\n", pDevContext);

	/* Read the messages in the mailbox until the message queue is empty */

	CFG_GetHostResources((struct CFG_DEVNODE *)DRV_GetFirstDevExtension(),
			     &resources);
	DEV_GetDevType(pDevContext->hDevObject, &devType);
	status = DEV_GetIOMgr(pDevContext->hDevObject, &hIOMgr);
	if (devType == DSP_UNIT) {
		HW_MBOX_NumMsgGet(resources.dwMboxBase,
				  MBOX_DSP2ARM, &numMbxMsg);
		while (numMbxMsg != 0) {
			HW_MBOX_MsgRead(resources.dwMboxBase,
					MBOX_DSP2ARM,
					&mbxValue);
			numMbxMsg--;
		}
		/* clear the DSP mailbox as well...*/
		HW_MBOX_NumMsgGet(resources.dwMboxBase,
				  MBOX_ARM2DSP, &numMbxMsg);
		while (numMbxMsg != 0) {
			HW_MBOX_MsgRead(resources.dwMboxBase,
					MBOX_ARM2DSP, &mbxValue);
			numMbxMsg--;
			udelay(10);

			HW_MBOX_EventAck(resources.dwMboxBase, MBOX_ARM2DSP,
					 HW_MBOX_U1_DSP1,
					 HW_MBOX_INT_NEW_MSG);
		}
		/* Enable the new message events on this IRQ line */
		HW_MBOX_EventEnable(resources.dwMboxBase,
				    MBOX_DSP2ARM,
				    MBOX_ARM,
				    HW_MBOX_INT_NEW_MSG);
	}

	return status;
}
/*
 *  ======== WriteDspData ========
 *  purpose:
 *      Copies buffers to the DSP internal/external memory.
 */
DSP_STATUS WriteDspData(struct WMD_DEV_CONTEXT *hDevContext, IN u8 *pbHostBuf,
			u32 dwDSPAddr, u32 ulNumBytes, u32 ulMemType)
{
	u32 offset;
	u32 dwBaseAddr = hDevContext->dwDspBaseAddr;
	struct CFG_HOSTRES resources;
	DSP_STATUS status;
	u32 base1, base2, base3;
	base1 = OMAP_DSP_MEM1_SIZE;
	base2 = OMAP_DSP_MEM2_BASE - OMAP_DSP_MEM1_BASE;
	base3 = OMAP_DSP_MEM3_BASE - OMAP_DSP_MEM1_BASE;

	status =  CFG_GetHostResources(
		 (struct CFG_DEVNODE *)DRV_GetFirstDevExtension(), &resources);

	if (DSP_FAILED(status))
		return status;

	offset = dwDSPAddr - hDevContext->dwDSPStartAdd;
	if (offset < base1) {
		dwBaseAddr = MEM_LinearAddress(resources.dwMemBase[2],
						resources.dwMemLength[2]);
	} else if (offset > base1 && offset < base2+OMAP_DSP_MEM2_SIZE) {
		dwBaseAddr = MEM_LinearAddress(resources.dwMemBase[3],
						resources.dwMemLength[3]);
		offset = offset - base2;
	} else if (offset >= base2+OMAP_DSP_MEM2_SIZE &&
		offset < base3 + OMAP_DSP_MEM3_SIZE) {
		dwBaseAddr = MEM_LinearAddress(resources.dwMemBase[4],
						resources.dwMemLength[4]);
		offset = offset - base3;
	} else{
		return DSP_EFAIL;
	}
	if (ulNumBytes)
		memcpy((u8 *) (dwBaseAddr+offset), pbHostBuf, ulNumBytes);
	else
		*((u32 *) pbHostBuf) = dwBaseAddr+offset;

	return status;
}
Esempio n. 6
0
DSP_STATUS CHNLSM_InterruptDSP2(struct WMD_DEV_CONTEXT *pDevContext,
				u16 wMbVal)
{
	struct CFG_HOSTRES resources;
	DSP_STATUS status = DSP_SOK;
	unsigned long timeout;
	u32 temp;

	status = CFG_GetHostResources((struct CFG_DEVNODE *)
			DRV_GetFirstDevExtension(), &resources);
	if (DSP_FAILED(status))
		return DSP_EFAIL;

	if (pDevContext->dwBrdState == BRD_DSP_HIBERNATION ||
	    pDevContext->dwBrdState == BRD_HIBERNATION) {
#ifdef CONFIG_BRIDGE_DVFS
		struct dspbridge_platform_data *pdata =
			omap_dspbridge_dev->dev.platform_data;
		/*
		 * When Smartreflex is ON, DSP requires at least OPP level 3
		 * to operate reliably. So boost lower OPP levels to OPP3.
		 */
		if (pdata->dsp_set_min_opp)
			(*pdata->dsp_set_min_opp)(min_active_opp);
#endif
		/* Restart the peripheral clocks */
		DSP_PeripheralClocks_Enable(pDevContext, NULL);

		/*
		 * 2:0 AUTO_IVA2_DPLL - Enabling IVA2 DPLL auto control
		 *     in CM_AUTOIDLE_PLL_IVA2 register
		 */
		*(REG_UWORD32 *)(resources.dwCmBase + 0x34) = 0x1;

		/*
		 * 7:4 IVA2_DPLL_FREQSEL - IVA2 internal frq set to
		 *     0.75 MHz - 1.0 MHz
		 * 2:0 EN_IVA2_DPLL - Enable IVA2 DPLL in lock mode
		 */
		temp = *(REG_UWORD32 *)(resources.dwCmBase + 0x4);
		temp = (temp & 0xFFFFFF08) | 0x37;
		*(REG_UWORD32 *)(resources.dwCmBase + 0x4) = temp;

		/*
		 * This delay is needed to avoid mailbox timed out
		 * issue experienced while SmartReflex is ON.
		 * TODO: Instead of 1 ms calculate proper value.
		 */
		mdelay(1);

		/* Restore mailbox settings */
		HW_MBOX_restoreSettings(resources.dwMboxBase);

		/* Access MMU SYS CONFIG register to generate a short wakeup */
		temp = *(REG_UWORD32 *)(resources.dwDmmuBase + 0x10);

		pDevContext->dwBrdState = BRD_RUNNING;
	}

	timeout = jiffies + msecs_to_jiffies(1);
	while (fifo_full((void __iomem *) resources.dwMboxBase, 0)) {
		if (time_after(jiffies, timeout)) {
			pr_err("dspbridge: timed out waiting for mailbox\n");
			return WMD_E_TIMEOUT;
		}
	}

	DBG_Trace(DBG_LEVEL3, "writing %x to Mailbox\n", wMbVal);
	HW_MBOX_MsgWrite(resources.dwMboxBase, MBOX_ARM2DSP, wMbVal);
	return DSP_SOK;
}
Esempio n. 7
0
DSP_STATUS CHNLSM_InterruptDSP2(struct WMD_DEV_CONTEXT *pDevContext,
				u16 wMbVal)
{
#ifndef CONFIG_DISABLE_BRIDGE_PM
#ifndef CONFIG_DISABLE_BRIDGE_DVFS
	u32 opplevel;
#endif
#endif
	struct CFG_HOSTRES resources;
	unsigned long timeout;
	u32 temp;
	DSP_STATUS status = DSP_SOK;

	/* We are waiting indefinitely here. This needs to be fixed in the
	 * second phase */
	CFG_GetHostResources((struct CFG_DEVNODE *)DRV_GetFirstDevExtension(),
			&resources);

	if (pDevContext->dwBrdState == BRD_DSP_HIBERNATION ||
	    pDevContext->dwBrdState == BRD_HIBERNATION) {
#ifndef CONFIG_DISABLE_BRIDGE_PM
#ifndef CONFIG_DISABLE_BRIDGE_DVFS
#ifndef CONFIG_OMAP3_PM
		opplevel = omap_pm_dsp_get_opp();
		/* If OPP is at minimum level, increase it before waking up
		* the DSP */
		if (opplevel == 1) {
			omap_pm_dsp_set_min_opp(opplevel+1);
			DBG_Trace(DBG_LEVEL7, "CHNLSM_InterruptDSP:Setting "
			"the vdd1 constraint level to %d before "
			"waking DSP \n", (opplevel + 1));
		}

#else
		opplevel = constraint_get_level(dsp_constraint_handle);
		/* If OPP is at minimum level, increase it before waking up
		 * the DSP */
		if (opplevel == 1) {
			if (constraint_set(dsp_constraint_handle,
			   (opplevel+1)) != 0) {
				DBG_Trace(DBG_LEVEL7, "CHNLSM_InterruptDSP: "
					 "Constraint set failed\n");
				return DSP_EFAIL;
			}
			DBG_Trace(DBG_LEVEL7, "CHNLSM_InterruptDSP:Setting "
				 "the vdd1 constraint level to %d before "
				 "waking DSP \n", (opplevel + 1));
		}

#endif
#endif
#endif
		/* Restart the IVA clock that was disabled while
		 * the DSP initiated Hibernation. */
		if ((pDevContext->dwBrdState == BRD_DSP_HIBERNATION)
		   || (pDevContext->dwBrdState == BRD_HIBERNATION)) {
			status = CLK_Enable(SERVICESCLK_iva2_ck);
			if (DSP_FAILED(status))
				return status;
		}

		/* Read MMU register to invoke short wakeup of DSP */
		temp = (u32) *((REG_UWORD32 *) ((u32)
		       (resources.dwDmmuBase) + 0x10));

		/* Restore mailbox settings */
		HW_MBOX_restoreSettings(resources.dwMboxBase);
		DBG_Trace(DBG_LEVEL6, "MailBoxSettings: SYSCONFIG = 0x%x\n",
			  mboxsetting.sysconfig);
		DBG_Trace(DBG_LEVEL6, "MailBoxSettings: IRQENABLE0 = 0x%x\n",
			  mboxsetting.irqEnable0);
		DBG_Trace(DBG_LEVEL6, "MailBoxSettings: IRQENABLE1 = 0x%x\n",
			 mboxsetting.irqEnable1);
		/* Restart the peripheral clocks that were disabled only
		 * in DSP initiated Hibernation case.*/
		if (pDevContext->dwBrdState == BRD_DSP_HIBERNATION)
			DSP_PeripheralClocks_Enable(pDevContext, NULL);

		pDevContext->dwBrdState = BRD_RUNNING;
	}
	timeout = jiffies + msecs_to_jiffies(35);
	while (HW_MBOX_IsFull(resources.dwMboxBase, MBOX_ARM2DSP)) {
		if (time_after(jiffies, timeout)) {
			printk(KERN_ERR "dspbridge: "
				"timed out waiting for mailbox\n");
			return WMD_E_TIMEOUT;
		}
	}
	DBG_Trace(DBG_LEVEL3, "writing %x to Mailbox\n",
		  wMbVal);

	HW_MBOX_MsgWrite(resources.dwMboxBase, MBOX_ARM2DSP,
			 wMbVal);
	return DSP_SOK;
}
/*
 *  ======== WriteExtDspData ========
 *  purpose:
 *      Copies buffers to the external memory.
 *
 */
DSP_STATUS WriteExtDspData(struct WMD_DEV_CONTEXT *pDevContext,
			  IN u8 *pbHostBuf, u32 dwDSPAddr, u32 ulNumBytes,
			  u32 ulMemType, bool bDynamicLoad)
{
	u32 dwBaseAddr = pDevContext->dwDspExtBaseAddr;
	u32 dwOffset = 0;
	u8 bTempByte1, bTempByte2;
	u8 remainByte[4];
	s32 i;
	DSP_STATUS retVal = DSP_SOK;
	u32 dwExtProgVirtMem;
	u32 ulTLBBaseVirt = 0;
	u32 ulShmOffsetVirt = 0;
	struct CFG_HOSTRES hostRes;
	bool bTraceLoad = false;
	bTempByte1 = 0x0;
	bTempByte2 = 0x0;

	  if (bSymbolsReloaded) {
		/* Check if it is a load to Trace section */
		retVal = DEV_GetSymbol(pDevContext->hDevObject,
					DSP_TRACESEC_BEG, &ulTraceSecBeg);
		if (DSP_SUCCEEDED(retVal))
			retVal = DEV_GetSymbol(pDevContext->hDevObject,
				 DSP_TRACESEC_END, &ulTraceSecEnd);
	}
	if (DSP_SUCCEEDED(retVal)) {
		if ((dwDSPAddr <= ulTraceSecEnd) &&
		   (dwDSPAddr >= ulTraceSecBeg))
			bTraceLoad = true;
	}

	/* If dynamic, force remap/unmap */
	if ((bDynamicLoad || bTraceLoad) && dwBaseAddr) {
		dwBaseAddr = 0;
		MEM_UnmapLinearAddress((void *)pDevContext->dwDspExtBaseAddr);
		pDevContext->dwDspExtBaseAddr = 0x0;
	}
	if (!dwBaseAddr) {
		if (bSymbolsReloaded)
			/* Get SHM_BEG  EXT_BEG and EXT_END. */
			retVal = DEV_GetSymbol(pDevContext->hDevObject,
						SHMBASENAME, &ulShmBaseVirt);
		DBC_Assert(ulShmBaseVirt != 0);
		if (bDynamicLoad) {
			if (DSP_SUCCEEDED(retVal)) {
				if (bSymbolsReloaded)
					retVal = DEV_GetSymbol(pDevContext->
						hDevObject, DYNEXTBASE,
						&ulExtBase);
			}
			DBC_Assert(ulExtBase != 0);
			if (DSP_SUCCEEDED(retVal)) {
				/* DR  OMAPS00013235 : DLModules array may be
				 * in EXTMEM. It is expected that DYNEXTMEM and
				 * EXTMEM are contiguous, so checking for the
				 * upper bound at EXTEND should be Ok. */
				if (bSymbolsReloaded)
					retVal = DEV_GetSymbol(pDevContext->
						hDevObject, EXTEND, &ulExtEnd);
			}
		} else {
			if (bSymbolsReloaded) {
				if (DSP_SUCCEEDED(retVal))
					retVal = DEV_GetSymbol(pDevContext->
						hDevObject, EXTBASE,
						&ulExtBase);
				DBC_Assert(ulExtBase != 0);
				if (DSP_SUCCEEDED(retVal))
					retVal = DEV_GetSymbol(pDevContext->
						hDevObject, EXTEND, &ulExtEnd);
			}
		}
		/* Trace buffer it right after the SHM SEG0, so set the
		 * 	base address to SHMBASE */
		if (bTraceLoad)
			ulExtBase = ulShmBaseVirt;

		DBC_Assert(ulExtEnd != 0);
		DBC_Assert(ulExtEnd > ulExtBase);
		if (ulExtEnd < ulExtBase)
			retVal = DSP_EFAIL;

		if (DSP_SUCCEEDED(retVal)) {
			ulTLBBaseVirt = pDevContext->aTLBEntry[0].ulDspVa *
					DSPWORDSIZE;
			DBC_Assert(ulTLBBaseVirt <= ulShmBaseVirt);

			if (bSymbolsReloaded) {
				if (DSP_SUCCEEDED(retVal)) {
					retVal = DEV_GetSymbol(pDevContext->
						 hDevObject, DSP_TRACESEC_END,
						 &ulShm0End);
				}
				if (DSP_SUCCEEDED(retVal)) {
					retVal = DEV_GetSymbol(pDevContext->
						 hDevObject, DYNEXTBASE,
						 &ulDynExtBase);
				}
			}
			ulShmOffsetVirt = ulShmBaseVirt - ulTLBBaseVirt;
			if (bTraceLoad) {
				dwExtProgVirtMem = pDevContext->aTLBEntry[0].
						   ulGppVa;
			} else {
				CFG_GetHostResources(
					(struct CFG_DEVNODE *)
					DRV_GetFirstDevExtension(), &hostRes);
				dwExtProgVirtMem = hostRes.dwMemBase[1];
				dwExtProgVirtMem += (ulExtBase - ulDynExtBase);
			}

			pDevContext->dwDspExtBaseAddr =
				(u32)MEM_LinearAddress((void *)dwExtProgVirtMem,
					ulExtEnd - ulExtBase);
			dwBaseAddr += pDevContext->dwDspExtBaseAddr;
			/* This dwDspExtBaseAddr will get cleared only when
			 * the board is stopped.  */
			if (!pDevContext->dwDspExtBaseAddr)
				retVal = DSP_EFAIL;
		}
	}
	if (!dwBaseAddr || !ulExtBase || !ulExtEnd)
		retVal = DSP_EFAIL;

	if (DSP_SUCCEEDED(retVal)) {
		for (i = 0; i < 4; i++)
			remainByte[i] = 0x0;

		dwOffset = dwDSPAddr - ulExtBase;
		/* Also make sure the dwDSPAddr is < ulExtEnd */
		if (dwDSPAddr > ulExtEnd || dwOffset > dwDSPAddr)
			retVal = DSP_EFAIL;
	}
	if (DSP_SUCCEEDED(retVal)) {
		if (ulNumBytes)
			memcpy((u8 *) dwBaseAddr + dwOffset, pbHostBuf,
				ulNumBytes);
		else
			*((u32 *) pbHostBuf) = dwBaseAddr+dwOffset;
	}
	/* Unmap here to force remap for other Ext loads */
	if ((bDynamicLoad || bTraceLoad) && pDevContext->dwDspExtBaseAddr) {
		MEM_UnmapLinearAddress((void *) pDevContext->dwDspExtBaseAddr);
		pDevContext->dwDspExtBaseAddr = 0x0;
	}
	bSymbolsReloaded = false;
	return retVal;
}
Esempio n. 9
0
DSP_STATUS CHNLSM_InterruptDSP2(struct WMD_DEV_CONTEXT *pDevContext,
				u16 wMbVal)
{
#ifdef CONFIG_BRIDGE_DVFS
	struct dspbridge_platform_data *pdata =
		omap_dspbridge_dev->dev.platform_data;
	u32 opplevel = 0;
#endif
	struct CFG_HOSTRES resources;
	DSP_STATUS status = DSP_SOK;
	unsigned long timeout;
	u32 temp;

	status = CFG_GetHostResources((struct CFG_DEVNODE *)DRV_GetFirstDevExtension(),
				      &resources);
	if (DSP_FAILED(status))
		return DSP_EFAIL;
#ifdef CONFIG_BRIDGE_DVFS
	if (pDevContext->dwBrdState == BRD_DSP_HIBERNATION ||
	    pDevContext->dwBrdState == BRD_HIBERNATION) {
		if (pdata->dsp_get_opp)
			opplevel = (*pdata->dsp_get_opp)();
		if (opplevel == 1) {
			if (pdata->dsp_set_min_opp)
				(*pdata->dsp_set_min_opp)(opplevel+1);
		}
	}
#endif

	if (pDevContext->dwBrdState == BRD_DSP_HIBERNATION ||
	    pDevContext->dwBrdState == BRD_HIBERNATION) {
		/* Restart the IVA clock that was disabled while
		 * the DSP initiated Hibernation. */
			status = CLK_Enable(SERVICESCLK_iva2_ck);
			if (DSP_FAILED(status))
				return status;

		/* Restore mailbox settings */
		/* Restart the peripheral clocks that were disabled only
		 * in DSP initiated Hibernation case.*/
		if (pDevContext->dwBrdState == BRD_DSP_HIBERNATION) {
			DSP_PeripheralClocks_Enable(pDevContext, NULL);
			/* Enabling Dpll in lock mode*/
			temp = (u32) *((REG_UWORD32 *)
				       ((u32) (resources.dwCmBase) + 0x34));
			temp = (temp & 0xFFFFFFFE) | 0x1;
			*((REG_UWORD32 *) ((u32) (resources.dwCmBase) + 0x34)) =
				(u32) temp;
			temp = (u32) *((REG_UWORD32 *)
				       ((u32) (resources.dwCmBase) + 0x4));
			temp = (temp & 0xFFFFFC8) | 0x37;

			*((REG_UWORD32 *) ((u32) (resources.dwCmBase) + 0x4)) =
				(u32) temp;
		}
		HW_MBOX_restoreSettings(resources.dwMboxBase);

		/*  Access MMU SYS CONFIG register to generate a short wakeup */
		temp = (u32) *((REG_UWORD32 *) ((u32)
						(resources.dwDmmuBase) + 0x10));

		pDevContext->dwBrdState = BRD_RUNNING;
	}
	timeout = jiffies + msecs_to_jiffies(1);
	while (fifo_full((void __iomem *) resources.dwMboxBase, 0)) {
		if (time_after(jiffies, timeout)) {
			printk(KERN_ERR "dspbridge: timed out waiting for mailbox\n");
			return WMD_E_TIMEOUT;
		}
	}
	DBG_Trace(DBG_LEVEL3, "writing %x to Mailbox\n",
		  wMbVal);

	HW_MBOX_MsgWrite(resources.dwMboxBase, MBOX_ARM2DSP,
			 wMbVal);
	return DSP_SOK;
}
Esempio n. 10
0
/*
 *  ======== DSP_Init ========
 *  	Allocates bridge resources. Loads a base image onto DSP, if specified.
 */
u32 DSP_Init(OUT u32 *initStatus)
{
	char devNode[MAXREGPATHLENGTH] = "TIOMAP1510";
	DSP_STATUS status = DSP_EFAIL;
	struct DRV_OBJECT *drvObject = NULL;
	u32 index = 0;
	u32 deviceNode;
	u32 deviceNodeString;

	GT_create(&curTrace, "DD");

	GT_0trace(curTrace, GT_ENTER, "Entering DSP_Init \r\n");

	if (DSP_FAILED(WCD_Init())) {
		GT_0trace(curTrace, GT_7CLASS, "DSP_Init Failed \n");
		goto func_cont;
	}			/* End WCD_Exit */
	if (DSP_FAILED(DRV_Create(&drvObject))) {
		GT_0trace(curTrace, GT_7CLASS, "DSP_Init:DRV_Create Failed \n");
		WCD_Exit();
		goto func_cont;
	}		/* End DRV_Create */
	GT_0trace(curTrace, GT_5CLASS, "DSP_Init:DRV Created \r\n");

	/* Request Resources */
	if (DSP_SUCCEEDED(DRV_RequestResources((u32)&devNode,
	   &deviceNodeString))) {
		/* Attempt to Start the Device */
		if (DSP_SUCCEEDED(DEV_StartDevice(
		   (struct CFG_DEVNODE *)deviceNodeString))) {
			/* Retreive the DevObject from the Registry */
			GT_2trace(curTrace, GT_1CLASS,
				 "DSP_Init Succeeded for Device1:"
				 "%d: value: %x\n", index, deviceNodeString);
			status = DSP_SOK;
		} else {
			GT_0trace(curTrace, GT_7CLASS,
				 "DSP_Init:DEV_StartDevice Failed\n");
			(void)DRV_ReleaseResources
				((u32) deviceNodeString, drvObject);
			status = DSP_EFAIL;
		}
	} else {
		GT_0trace(curTrace, GT_7CLASS,
			 "DSP_Init:DRV_RequestResources Failed \r\n");
		status = DSP_EFAIL;
	}	/* DRV_RequestResources */
	index++;

	/* Unwind whatever was loaded */
	if (DSP_FAILED(status)) {
		/* irrespective of the status of DEV_RemoveDevice we conitinue
		 * unloading. Get the Driver Object iterate through and remove.
		 * Reset the status to E_FAIL to avoid going through
		 * WCD_InitComplete2. */
		status = DSP_EFAIL;
		for (deviceNode = DRV_GetFirstDevExtension(); deviceNode != 0;
		    deviceNode = DRV_GetNextDevExtension(deviceNode)) {
			(void)DEV_RemoveDevice
				((struct CFG_DEVNODE *)deviceNode);
			(void)DRV_ReleaseResources((u32)deviceNode,
				drvObject);
		}
		/* Remove the Driver Object */
		(void)DRV_Destroy(drvObject);
		drvObject = NULL;
		WCD_Exit();
		GT_0trace(curTrace, GT_7CLASS,
			 "DSP_Init:Logical device Failed to Load\n");
	}	/* Unwinding the loaded drivers */
func_cont:
	/* Attempt to Start the Board */
	if (DSP_SUCCEEDED(status)) {
		/* BRD_AutoStart could fail if the dsp execuetable is not the
		 * correct one. We should not propagate that error
		 * into the device loader. */
		(void)WCD_InitComplete2();
		GT_0trace(curTrace, GT_1CLASS, "DSP_Init Succeeded\n");
	} else {
		GT_0trace(curTrace, GT_7CLASS, "DSP_Init Failed\n");
	}			/* End WCD_InitComplete2 */
	DBC_Ensure((DSP_SUCCEEDED(status) && drvObject != NULL) ||
		  (DSP_FAILED(status) && drvObject == NULL));
	*initStatus = status;
	/* Return the Driver Object */
	return (u32)drvObject;
}