Esempio n. 1
0
/*!
******************************************************************************

 @Function	PVRSRVPowerUnlock

 @Description	Release the mutex for power transitions

 @Return	PVRSRV_ERROR

******************************************************************************/
IMG_EXPORT
IMG_VOID PVRSRVPowerUnlock()
{
	PVRSRV_DATA	*psPVRSRVData = PVRSRVGetPVRSRVData();

	OSLockRelease(psPVRSRVData->hPowerLock);
}
Esempio n. 2
0
/*!
******************************************************************************

 @Function	PVRSRVDevicePostClockSpeedChange

 @Description

	Notification from system layer that a device clock speed change has just happened.

 @Input		ui32DeviceIndex : device index
 @Input		bIdleDevice : whether the device had been idled
 @Input		pvInfo

 @Return	IMG_VOID

******************************************************************************/
IMG_VOID PVRSRVDevicePostClockSpeedChange(IMG_UINT32	ui32DeviceIndex,
										  IMG_BOOL		bIdleDevice,
										  IMG_VOID		*pvInfo)
{
	PVRSRV_ERROR		eError;
	PVRSRV_DATA			*psPVRSRVData = PVRSRVGetPVRSRVData();
	PVRSRV_POWER_DEV	*psPowerDevice;

	PVR_UNREFERENCED_PARAMETER(pvInfo);

	/*search the device and then do the post clock speed change*/
	psPowerDevice = (PVRSRV_POWER_DEV*)
					List_PVRSRV_POWER_DEV_Any_va(psPVRSRVData->psPowerDeviceList,
												 &MatchPowerDeviceIndex_AnyVaCb,
												 ui32DeviceIndex);

	if (psPowerDevice && psPowerDevice->pfnPostClockSpeedChange)
	{
		eError = psPowerDevice->pfnPostClockSpeedChange(psPowerDevice->hDevCookie,
														bIdleDevice,
														psPowerDevice->eCurrentPowerState);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR,
					"PVRSRVDevicePostClockSpeedChange : Device %u failed, error:0x%x",
					ui32DeviceIndex, eError));
		}
	}


	/* This mutex was acquired in PVRSRVDevicePreClockSpeedChange. */
	PVRSRVPowerUnlock();
}
Esempio n. 3
0
PVRSRV_ERROR CacheOpQueue(PVRSRV_CACHE_OP uiCacheOp)
{
	PVRSRV_DATA *psData = PVRSRVGetPVRSRVData();

	psData->uiCacheOp = SetCacheOp(psData->uiCacheOp, uiCacheOp);
	return PVRSRV_OK;
}
Esempio n. 4
0
/*!
******************************************************************************

 @Function	PVRSRVDevicePreClockSpeedChange

 @Description

	Notification from system layer that a device clock speed change is about to happen.

 @Input		ui32DeviceIndex : device index
 @Input		bIdleDevice : whether the device should be idled
 @Input		pvInfo

 @Return	IMG_VOID

******************************************************************************/
PVRSRV_ERROR PVRSRVDevicePreClockSpeedChange(IMG_UINT32	ui32DeviceIndex,
											 IMG_BOOL	bIdleDevice,
											 IMG_VOID	*pvInfo)
{
	PVRSRV_ERROR		eError = PVRSRV_OK;
	PVRSRV_DATA			*psPVRSRVData = PVRSRVGetPVRSRVData();
	PVRSRV_POWER_DEV	*psPowerDevice;

	PVR_UNREFERENCED_PARAMETER(pvInfo);

	/*search the device and then do the pre clock speed change*/
	psPowerDevice = (PVRSRV_POWER_DEV*)
					List_PVRSRV_POWER_DEV_Any_va(psPVRSRVData->psPowerDeviceList,
												 &MatchPowerDeviceIndex_AnyVaCb,
												 ui32DeviceIndex);

	do
	{
		/* This mutex is released in PVRSRVDevicePostClockSpeedChange. */
		eError = PVRSRVPowerLock();
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR,	"PVRSRVDevicePreClockSpeedChange : failed to acquire lock, error:0x%x", eError));
			return eError;
		}

		if (psPowerDevice && psPowerDevice->pfnPostClockSpeedChange)
		{
			eError = psPowerDevice->pfnPreClockSpeedChange(psPowerDevice->hDevCookie,
														   bIdleDevice,
														   psPowerDevice->eCurrentPowerState);
			
			if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED))
			{
				PVR_DPF((PVR_DBG_ERROR,
						"PVRSRVDevicePreClockSpeedChange : Device %u failed, error:0x%x",
						ui32DeviceIndex, eError));
			}
			else if (eError == PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED)
			{
				PVR_DPF((PVR_DBG_MESSAGE,
						"PVRSRVDevicePreClockSpeedChange : Device %u denied transition to IDLE",
						ui32DeviceIndex));
		
				PVRSRVPowerUnlock();
				OSSleepms(1);
			}
		}
	}
	while (eError == PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED);

	if (eError != PVRSRV_OK)
	{
		PVRSRVPowerUnlock();
	}

	return eError;
}
Esempio n. 5
0
/* PVRSRVConnectionConnect*/
PVRSRV_ERROR PVRSRVConnectionConnect(IMG_PVOID *ppvPrivData, IMG_PVOID pvOSData)
{
	PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
	CONNECTION_DATA *psConnection;
	PVRSRV_ERROR eError = PVRSRV_OK;

	/* Allocate per-process data area */
	psConnection = OSAllocMem(sizeof(*psConnection));
	if (psConnection == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "PVRSRVConnectionConnect: Couldn't allocate per-process data (%d)", eError));
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}
	OSMemSet(psConnection, 0, sizeof(*psConnection));

	/* Call environment specific per process init function */
	eError = OSConnectionPrivateDataInit(&psConnection->hOsPrivateData, pvOSData);
	if (eError != PVRSRV_OK)
	{
		 PVR_DPF((PVR_DBG_ERROR, "PVRSRVConnectionConnect: OSConnectionPrivateDataInit failed (%d)", eError));
		goto failure;
	}

	/* Allocate handle base for this process */
	eError = PVRSRVAllocHandleBase(&psConnection->psHandleBase);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "PVRSRVConnectionConnect: Couldn't allocate handle base for process (%d)", eError));
		goto failure;
	}

	/* Create a resource manager context for the process */
	eError = PVRSRVResManConnect(psPVRSRVData->hResManDeferContext, &psConnection->hResManContext);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "PVRSRVConnectionConnect: Couldn't register with the resource manager"));
		goto failure;
	}

	*ppvPrivData = psConnection;

	return eError;

failure:
	(IMG_VOID)FreeConnectionData(psConnection);
	return eError;
}
Esempio n. 6
0
/*!
******************************************************************************

 @Function	PVRSRVIsDevicePowered

 @Description

	Whether the device is powered, for the purposes of lockup detection.

 @Input		ui32DeviceIndex : device index

 @Return	IMG_BOOL

******************************************************************************/
IMG_EXPORT
IMG_BOOL PVRSRVIsDevicePowered(IMG_UINT32 ui32DeviceIndex)
{
	PVRSRV_DATA            *psPVRSRVData = PVRSRVGetPVRSRVData();
	PVRSRV_DEV_POWER_STATE ePowerState;

	if (OSLockIsLocked(psPVRSRVData->hPowerLock))
	{
		return IMG_FALSE;
	}

	if (PVRSRVGetDevicePowerState(ui32DeviceIndex, &ePowerState) != PVRSRV_OK)
	{
		return IMG_FALSE;
	}

	return (ePowerState == PVRSRV_DEV_POWER_STATE_ON);
}
Esempio n. 7
0
PVRSRV_ERROR PVRSRVRegisterPowerDevice(IMG_UINT32					ui32DeviceIndex,
									   PFN_PRE_POWER				pfnDevicePrePower,
									   PFN_POST_POWER				pfnDevicePostPower,
									   PFN_SYS_DEV_PRE_POWER		pfnSystemPrePower,
									   PFN_SYS_DEV_POST_POWER		pfnSystemPostPower,
									   PFN_PRE_CLOCKSPEED_CHANGE	pfnPreClockSpeedChange,
									   PFN_POST_CLOCKSPEED_CHANGE	pfnPostClockSpeedChange,
									   IMG_HANDLE					hDevCookie,
									   PVRSRV_DEV_POWER_STATE		eCurrentPowerState,
									   PVRSRV_DEV_POWER_STATE		eDefaultPowerState)
{
	PVRSRV_DATA			*psPVRSRVData = PVRSRVGetPVRSRVData();
	PVRSRV_POWER_DEV	*psPowerDevice;

	if (pfnDevicePrePower == IMG_NULL &&
		pfnDevicePostPower == IMG_NULL)
	{
		return PVRSRVRemovePowerDevice(ui32DeviceIndex);
	}

	psPowerDevice = OSAllocMem(sizeof(PVRSRV_POWER_DEV));
	if (psPowerDevice == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterPowerDevice: Failed to alloc PVRSRV_POWER_DEV"));
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}

	/* setup device for power manager */
	psPowerDevice->pfnDevicePrePower = pfnDevicePrePower;
	psPowerDevice->pfnDevicePostPower = pfnDevicePostPower;
	psPowerDevice->pfnSystemPrePower = pfnSystemPrePower;
	psPowerDevice->pfnSystemPostPower = pfnSystemPostPower;
	psPowerDevice->pfnPreClockSpeedChange = pfnPreClockSpeedChange;
	psPowerDevice->pfnPostClockSpeedChange = pfnPostClockSpeedChange;
	psPowerDevice->hDevCookie = hDevCookie;
	psPowerDevice->ui32DeviceIndex = ui32DeviceIndex;
	psPowerDevice->eCurrentPowerState = eCurrentPowerState;
	psPowerDevice->eDefaultPowerState = eDefaultPowerState;

	/* insert into power device list */
	List_PVRSRV_POWER_DEV_Insert(&(psPVRSRVData->psPowerDeviceList), psPowerDevice);

	return (PVRSRV_OK);
}
Esempio n. 8
0
/*!
******************************************************************************

 @Function	PVRSRVGetDevicePowerState

 @Description

	Return the device power state

 @Input		ui32DeviceIndex : device index
 @Output	psPowerState : Current power state 

 @Return	PVRSRV_ERROR_UNKNOWN_POWER_STATE if device could not be found. PVRSRV_OK otherwise.

******************************************************************************/
IMG_EXPORT
PVRSRV_ERROR PVRSRVGetDevicePowerState(IMG_UINT32 ui32DeviceIndex, PPVRSRV_DEV_POWER_STATE pePowerState)
{
	PVRSRV_DATA			*psPVRSRVData = PVRSRVGetPVRSRVData();
	PVRSRV_POWER_DEV	*psPowerDevice;

	psPowerDevice = (PVRSRV_POWER_DEV*)
					List_PVRSRV_POWER_DEV_Any_va(psPVRSRVData->psPowerDeviceList,
												 &MatchPowerDeviceIndex_AnyVaCb,
												 ui32DeviceIndex);
	if (psPowerDevice == IMG_NULL)
	{
		return PVRSRV_ERROR_UNKNOWN_POWER_STATE;
	}

	*pePowerState = psPowerDevice->eCurrentPowerState;

	return PVRSRV_OK;
}
Esempio n. 9
0
/*!
******************************************************************************

 @Function	PVRSRVDevicePostPowerStateKM

 @Description

 Perform device-specific processing required after a power transition

 @Input		bAllDevices : IMG_TRUE - All devices
 						  IMG_FALSE - Use ui32DeviceIndex
 @Input		ui32DeviceIndex : device index
 @Input		eNewPowerState : New power state

 @Return	PVRSRV_ERROR

******************************************************************************/
static
PVRSRV_ERROR PVRSRVDevicePostPowerStateKM(IMG_BOOL					bAllDevices,
										  IMG_UINT32				ui32DeviceIndex,
										  PVRSRV_DEV_POWER_STATE	eNewPowerState,
										  IMG_BOOL					bForced)
{
	PVRSRV_ERROR		eError;
	PVRSRV_DATA			*psPVRSRVData = PVRSRVGetPVRSRVData();

	/* Loop through the power devices. */
	eError = List_PVRSRV_POWER_DEV_PVRSRV_ERROR_Any_va(psPVRSRVData->psPowerDeviceList,
														&PVRSRVDevicePostPowerStateKM_AnyVaCb,
														bAllDevices,
														ui32DeviceIndex,
														eNewPowerState,
														bForced);

	return eError;
}
Esempio n. 10
0
/*!
******************************************************************************

 @Function	PVRSRVPowerLock

 @Description	Obtain the mutex for power transitions. Only allowed when
                system power is on.

 @Return	PVRSRV_ERROR_RETRY or PVRSRV_OK

******************************************************************************/
IMG_EXPORT
PVRSRV_ERROR PVRSRVPowerLock()
{
	PVRSRV_ERROR	eError;
	PVRSRV_DATA		*psPVRSRVData = PVRSRVGetPVRSRVData();

	/* Only allow to take powerlock when the system power is on */
	if (_IsSystemStatePowered(psPVRSRVData->eCurrentPowerState))
	{
		OSLockAcquire(psPVRSRVData->hPowerLock);
		eError = PVRSRV_OK;
	}
	else
	{
		eError = PVRSRV_ERROR_RETRY;
	}

	return eError;
}
Esempio n. 11
0
/*!
******************************************************************************

 @Function	PVRSRVRemovePowerDevice

 @Description

 Removes device from power management register. Device is located by Device Index

 @Input		ui32DeviceIndex : device index

 @Return	PVRSRV_ERROR

******************************************************************************/
PVRSRV_ERROR PVRSRVRemovePowerDevice (IMG_UINT32 ui32DeviceIndex)
{
	PVRSRV_DATA			*psPVRSRVData = PVRSRVGetPVRSRVData();
	PVRSRV_POWER_DEV	*psPowerDev;

	/* find device in list and remove it */
	psPowerDev = (PVRSRV_POWER_DEV*)
					List_PVRSRV_POWER_DEV_Any_va(psPVRSRVData->psPowerDeviceList,
												 &MatchPowerDeviceIndex_AnyVaCb,
												 ui32DeviceIndex);

	if (psPowerDev)
	{
		List_PVRSRV_POWER_DEV_Remove(psPowerDev);
		OSFreeMem(psPowerDev);
		/*not nulling pointer, copy on stack*/
	}

	return (PVRSRV_OK);
}
Esempio n. 12
0
/*!
******************************************************************************

 @Function	PVRSRVSetPowerStateKM

 @Description	Set the system into a new state

 @Input		eNewPowerState :
 @Input		bForced : TRUE if the transition should not fail (e.g. OS request)

 @Return	PVRSRV_ERROR

******************************************************************************/
IMG_EXPORT
PVRSRV_ERROR PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState, IMG_BOOL bForced)
{
	PVRSRV_ERROR	eError;
	PVRSRV_DATA		*psPVRSRVData = PVRSRVGetPVRSRVData();
	IMG_UINT        uiStage = 0;

	PVRSRV_DEV_POWER_STATE eNewDevicePowerState = 
	  _IsSystemStatePowered(eNewSysPowerState)? PVRSRV_DEV_POWER_STATE_DEFAULT : PVRSRV_DEV_POWER_STATE_OFF;

	/* require a proper power state */
	if (eNewSysPowerState == PVRSRV_SYS_POWER_STATE_Unspecified)
	{
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	/* no power transition requested, so do nothing */
	if (eNewSysPowerState == psPVRSRVData->eCurrentPowerState)
	{
		return PVRSRV_OK;
	}

	/* Prevent simultaneous SetPowerStateKM calls */
	PVRSRVForcedPowerLock();

	/* Perform pre transitions: first device and then sys layer */
	eError = PVRSRVDevicePrePowerStateKM(IMG_TRUE, 0, eNewDevicePowerState, bForced);
	if (eError != PVRSRV_OK)
	{
		uiStage++;
		goto ErrorExit;
	}
	eError = PVRSRVSysPrePowerState(eNewSysPowerState, bForced);
	if (eError != PVRSRV_OK)
	{
		uiStage++;
		goto ErrorExit;
	}

	/* Perform system-specific post power transitions: first sys layer and then device */
	eError = PVRSRVSysPostPowerState(eNewSysPowerState, bForced);
	if (eError != PVRSRV_OK)
	{
		uiStage++;
		goto ErrorExit;
	}
	eError = PVRSRVDevicePostPowerStateKM(IMG_TRUE, 0, eNewDevicePowerState, bForced);
	if (eError != PVRSRV_OK)
	{
		uiStage++;
		goto ErrorExit;
	}

	psPVRSRVData->eCurrentPowerState = eNewSysPowerState;
	psPVRSRVData->eFailedPowerState = PVRSRV_SYS_POWER_STATE_Unspecified;

	PVRSRVPowerUnlock();

	/*
		Reprocess the devices' queues in case commands were blocked during
		the power transition.
	*/
	if (_IsSystemStatePowered(eNewSysPowerState) &&
			PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL))
	{
		PVRSRVCheckStatus(IMG_NULL);
	}

	return PVRSRV_OK;

ErrorExit:
	/* save the power state for the re-attempt */
	psPVRSRVData->eFailedPowerState = eNewSysPowerState;

	PVRSRVPowerUnlock();

	PVR_DPF((PVR_DBG_ERROR,
			"PVRSRVSetPowerStateKM: Transition from %d to %d FAILED (%s) at stage %d, forced: %d. Dumping debug info.",
			psPVRSRVData->eCurrentPowerState, eNewSysPowerState, PVRSRVGetErrorStringKM(eError), uiStage, bForced));

	PVRSRVDebugRequest(DEBUG_REQUEST_VERBOSITY_MAX);

	return eError;
}
Esempio n. 13
0
/*!
******************************************************************************

 @Function	PVRSRVSetDevicePowerStateKM

 @Description	Set the Device into a new state

 @Input		ui32DeviceIndex : device index
 @Input		eNewPowerState : New power state
 @Input		bForced : TRUE if the transition should not fail (e.g. OS request)

 @Return	PVRSRV_ERROR

******************************************************************************/
IMG_EXPORT
PVRSRV_ERROR PVRSRVSetDevicePowerStateKM(IMG_UINT32				ui32DeviceIndex,
										 PVRSRV_DEV_POWER_STATE	eNewPowerState,
										 IMG_BOOL				bForced)
{
	PVRSRV_DATA*    psPVRSRVData = PVRSRVGetPVRSRVData();
	PVRSRV_ERROR	eError;
	PVRSRV_DEV_POWER_STATE eOldPowerState;

	eError = PVRSRVGetDevicePowerState(ui32DeviceIndex, &eOldPowerState);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_WARNING, "PVRSRVSetDevicePowerStateKM: Couldn't read power state."));
		eOldPowerState = PVRSRV_DEV_POWER_STATE_DEFAULT;
	}

	#if defined(PDUMP)
	if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT)
	{
		/*
			Pdump a power-up regardless of the default state.
			Then disable pdump and transition to the default power state.
			This ensures that a power-up is always present in the pdump when necessary.
		*/
		eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON, bForced);
		if(eError != PVRSRV_OK)
		{
			goto Exit;
		}

		eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON, bForced);

		if (eError != PVRSRV_OK)
		{
			goto Exit;
		}

		PDUMPPOWCMDSTART();
	}
	#endif /* PDUMP */

	eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState, bForced);
	if(eError != PVRSRV_OK)
	{
		if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT)
		{
			PDUMPPOWCMDEND();
		}
		goto Exit;
	}

	eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState, bForced);

	if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT)
	{
		PDUMPPOWCMDEND();
	}

	/* Signal Device Watchdog Thread about power mode change. */
	if (eOldPowerState != eNewPowerState && eNewPowerState == PVRSRV_DEV_POWER_STATE_ON)
	{
		psPVRSRVData->ui32DevicesWatchdogPwrTrans++;

		if (psPVRSRVData->ui32DevicesWatchdogTimeout == DEVICES_WATCHDOG_POWER_OFF_SLEEP_TIMEOUT)
		{
			if (psPVRSRVData->hDevicesWatchdogEvObj)
			{
				eError = OSEventObjectSignal(psPVRSRVData->hDevicesWatchdogEvObj);
				PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
			}
		}
	}

Exit:

	if (eError == PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED)
	{
		PVR_DPF((PVR_DBG_MESSAGE,
				"PVRSRVSetDevicePowerStateKM : Transition to %d was denied, Forced=%d", eNewPowerState, bForced));
	}
	else if(eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_WARNING,
				"PVRSRVSetDevicePowerStateKM : Transition to %d FAILED (%s)", eNewPowerState, PVRSRVGetErrorStringKM(eError)));
	}
	
	return eError;
}
Esempio n. 14
0
/*!
******************************************************************************

 @Function	PVRSRVForcedPowerLock

 @Description	Obtain the mutex for power transitions regardless of
                system power state

 @Return	PVRSRV_ERROR_RETRY or PVRSRV_OK

******************************************************************************/
IMG_EXPORT
IMG_VOID PVRSRVForcedPowerLock()
{
	PVRSRV_DATA		*psPVRSRVData = PVRSRVGetPVRSRVData();
	OSLockAcquire(psPVRSRVData->hPowerLock);
}
Esempio n. 15
0
static int PVRSRVDRMLoad(struct drm_device *dev, unsigned long flags)
{
	struct pvr_drm_dev_priv *psDevPriv;
	int iRes = 0;
#if defined(SUPPORT_SYSTEM_INTERRUPT_HANDLING)
	PVRSRV_ERROR eError;
#endif

	PVR_TRACE(("PVRSRVDRMLoad"));

#if defined(LDM_PLATFORM)
	/* The equivalent is done for PCI modesetting drivers by drm_get_pci_dev() */
	platform_set_drvdata(dev->platformdev, dev);
#endif

	psDevPriv = kzalloc(sizeof *psDevPriv, GFP_KERNEL);
	if (psDevPriv == NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: Failed to allocate DRM device private data", __FUNCTION__));
		iRes = -ENOMEM;
		goto error_exit;
	}
	dev->dev_private = psDevPriv;

	/* Module initialisation */
	iRes = PVRSRVSystemInit(dev);
	if (iRes != 0)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: System initialisation failed (error = %d)", __FUNCTION__, iRes));
		goto error_free_dev_priv;
	}

	psDevPriv->dev_node = List_PVRSRV_DEVICE_NODE_Any(PVRSRVGetPVRSRVData()->psDeviceNodeList,
							  PVRSRVFindRGXDevNode);
	if (psDevPriv->dev_node == NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: Failed to get Rogue device node", __FUNCTION__));
		iRes = -ENODEV;
		goto error_system_deinit;
	}

#if defined(SUPPORT_SYSTEM_INTERRUPT_HANDLING)
	/* Acquire the system data so it can be used by our interrupt handler */
	eError = SysAcquireSystemData(psDevPriv->dev_node->psDevConfig->hSysData);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: Failed to acquire system data", __FUNCTION__));
		iRes = -EINVAL;
		goto error_system_deinit;
	}
	psDevPriv->hSysData = psDevPriv->dev_node->psDevConfig->hSysData;

	if (psDevPriv->dev_node->psDevConfig->bIRQIsShared)
	{
		dev->driver->driver_features |= DRIVER_IRQ_SHARED;
	}

	iRes = drm_irq_install(dev);
	if (iRes != 0)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: Failed to install interrupt handler (error = %d)", __FUNCTION__, iRes));
		goto error_system_data_release;
	}
#endif

#if defined(SUPPORT_DRM_DC_MODULE)
	iRes = PVRSRVDRMDisplayInit(dev);
	if (iRes != 0)
	{
#if defined(SUPPORT_SYSTEM_INTERRUPT_HANDLING)
		goto error_irq_uninstall;
#else
		goto error_system_deinit;
#endif
	}
#else
	drm_mode_config_init(dev);
#endif /* defined(SUPPORT_DRM_DC_MODULE) */

	goto exit;

#if defined(SUPPORT_SYSTEM_INTERRUPT_HANDLING)
#if defined(SUPPORT_DRM_DC_MODULE)
error_irq_uninstall:
	drm_irq_uninstall(dev);
#endif

error_system_data_release:
	SysReleaseSystemData(psDevPriv->hSysData);
#endif

error_system_deinit:
	PVRSRVSystemDeInit();

error_free_dev_priv:
	dev->dev_private = NULL;
	kfree(psDevPriv);

error_exit:
	wake_up_interruptible(&sWaitForInit);

	bInitFailed = IMG_TRUE;

exit:
	bInitComplete = IMG_TRUE;

	return iRes;
}