DC_ERROR Deinit(void)
{
	DC_NOHW_DEVINFO *psDevInfo, *psDevFirst;
#if !defined(USE_BASE_VIDEO_FRAMEBUFFER)
	unsigned long i;
#endif

	psDevFirst = GetAnchorPtr();
	psDevInfo = psDevFirst;

	
	if (psDevInfo == 0)
	{
		return (DC_ERROR_GENERIC);
	}

	
	psDevInfo->ulRefCount--;

	if (psDevInfo->ulRefCount == 0UL)
	{
		
		PVRSRV_DC_DISP2SRV_KMJTABLE	*psJTable = &psDevInfo->sPVRJTable;

		
		if (psJTable->pfnPVRSRVRemoveDCDevice((IMG_UINT32)psDevInfo->uiDeviceID) != PVRSRV_OK)
		{
			return (DC_ERROR_GENERIC);
		}

		if (psDevInfo->sPVRJTable.pfnPVRSRVRemoveCmdProcList(psDevInfo->uiDeviceID,
															 DC_NOHW_COMMAND_COUNT) != PVRSRV_OK)
		{
			return (DC_ERROR_GENERIC);
		}

		if (ClosePVRServices(psDevInfo->hPVRServices) != DC_OK)
		{
			psDevInfo->hPVRServices = 0;
			return (DC_ERROR_GENERIC);
		}

#if !defined(USE_BASE_VIDEO_FRAMEBUFFER)
		for(i=0; i<DC_NOHW_MAX_BACKBUFFERS; i++)
		{
			if (psDevInfo->asBackBuffers[i].sCPUVAddr)
			{
				#if defined(DC_NOHW_DISCONTIG_BUFFERS)
				FreeDiscontigMemory(psDevInfo->ui32BufferSize,
							 psDevInfo->asBackBuffers[i].hMemChunk,
							 psDevInfo->asBackBuffers[i].sCPUVAddr,
							 psDevInfo->asBackBuffers[i].psSysAddr);
				#else

				FreeContigMemory(psDevInfo->ui32BufferSize,
							 psDevInfo->asBackBuffers[i].hMemChunk,
							 psDevInfo->asBackBuffers[i].sCPUVAddr,
							 SysPAddrToCpuPAddr(psDevInfo->asBackBuffers[i].sSysAddr));
				#endif
			}
		}
#endif 

		
		FreeKernelMem(psDevInfo);
	}

#if defined (ENABLE_DISPLAY_MODE_TRACKING)
	CloseMiniport();
#endif
	
	SetAnchorPtr(0);

	
	return (DC_OK);
}
/*
 *	Deinit
 */
DC_ERROR Deinit(void)
{
	DC_NOHW_DEVINFO *psDevInfo, *psDevFirst;
#if !defined(USE_BASE_VIDEO_FRAMEBUFFER)
	unsigned long i;
#endif

	psDevFirst = GetAnchorPtr();
	psDevInfo = psDevFirst;

	/* check DevInfo has been setup */
	if (psDevInfo == 0)
	{
		return (DC_ERROR_GENERIC);/* failure */
	}

	/* decrement ref count */
	psDevInfo->ulRefCount--;

	if (psDevInfo->ulRefCount == 0UL)
	{
		/* all references gone - de-init device information */
		PVRSRV_DC_DISP2SRV_KMJTABLE	*psJTable = &psDevInfo->sPVRJTable;

		/* Remove display class device from kernel services device register */
		if (psJTable->pfnPVRSRVRemoveDCDevice((IMG_UINT32)psDevInfo->uiDeviceID) != PVRSRV_OK)
		{
			return (DC_ERROR_GENERIC);/* failure */
		}

		if (psDevInfo->sPVRJTable.pfnPVRSRVRemoveCmdProcList(psDevInfo->uiDeviceID,
															 DC_NOHW_COMMAND_COUNT) != PVRSRV_OK)
		{
			return (DC_ERROR_GENERIC);/* failure */
		}

		if (ClosePVRServices(psDevInfo->hPVRServices) != DC_OK)
		{
			psDevInfo->hPVRServices = 0;
			return (DC_ERROR_GENERIC);/* failure */
		}

#if !defined(USE_BASE_VIDEO_FRAMEBUFFER)
		for(i=0; i<DC_NOHW_MAX_BACKBUFFERS; i++)
		{
			if (psDevInfo->asBackBuffers[i].sCPUVAddr)
			{
				#if defined(DC_NOHW_DISCONTIG_BUFFERS)
				FreeDiscontigMemory(psDevInfo->ui32BufferSize,
							 psDevInfo->asBackBuffers[i].hMemChunk,
							 psDevInfo->asBackBuffers[i].sCPUVAddr,
							 psDevInfo->asBackBuffers[i].psSysAddr);
				#else

				FreeContigMemory(psDevInfo->ui32BufferSize,
							 psDevInfo->asBackBuffers[i].hMemChunk,
							 psDevInfo->asBackBuffers[i].sCPUVAddr,
							 SysPAddrToCpuPAddr(psDevInfo->asBackBuffers[i].sSysAddr));
				#endif
			}
		}
#endif /* #if !defined(USE_BASE_VIDEO_FRAMEBUFFER) */

		/* de-allocate data structure */
		FreeKernelMem(psDevInfo);
	}

#if defined (ENABLE_DISPLAY_MODE_TRACKING)
	CloseMiniport();
#endif
	/* clear the top-level anchor */
	SetAnchorPtr(0);

	/* return success */
	return (DC_OK);
}