static PVRSRV_ERROR DestroyDCSwapChain(IMG_HANDLE hDevice, IMG_HANDLE hSwapChain) { OMAPLFB_DEVINFO *psDevInfo; OMAPLFB_SWAPCHAIN *psSwapChain; OMAPLFB_ERROR eError; if(!hDevice || !hSwapChain) { return PVRSRV_ERROR_INVALID_PARAMS; } psDevInfo = (OMAPLFB_DEVINFO*)hDevice; psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain; OMAPLFBCreateSwapChainLock(psDevInfo); if (SwapChainHasChanged(psDevInfo, psSwapChain)) { printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Swap chain mismatch\n", __FUNCTION__, psDevInfo->uiFBDevID); eError = PVRSRV_ERROR_INVALID_PARAMS; goto ExitUnLock; } OMAPLFBDestroySwapQueue(psSwapChain); eError = OMAPLFBDisableLFBEventNotification(psDevInfo); if (eError != OMAPLFB_OK) { printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't disable framebuffer event notification\n", __FUNCTION__, psDevInfo->uiFBDevID); } OMAPLFBFreeKernelMem(psSwapChain->psBuffer); OMAPLFBFreeKernelMem(psSwapChain); psDevInfo->psSwapChain = NULL; OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer); (void) OMAPLFBCheckModeAndSync(psDevInfo); eError = PVRSRV_OK; ExitUnLock: OMAPLFBCreateSwapChainUnLock(psDevInfo); return eError; }
int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Ioctl)(struct drm_device unref__ *dev, void *arg, struct drm_file unref__ *pFile) { uint32_t *puiArgs; uint32_t uiCmd; unsigned uiPVRDevID; int ret = 0; OMAPLFB_DEVINFO *psDevInfo; if (arg == NULL) { return -EFAULT; } puiArgs = (uint32_t *)arg; uiCmd = puiArgs[PVR_DRM_DISP_ARG_CMD]; uiPVRDevID = puiArgs[PVR_DRM_DISP_ARG_DEV]; psDevInfo = OMAPLFBPVRDevIDToDevInfo(uiPVRDevID); if (psDevInfo == NULL) { return -EINVAL; } switch (uiCmd) { case PVR_DRM_DISP_CMD_LEAVE_VT: case PVR_DRM_DISP_CMD_ENTER_VT: { OMAPLFB_BOOL bLeaveVT = (uiCmd == PVR_DRM_DISP_CMD_LEAVE_VT); DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: PVR Device %u: %s\n", __FUNCTION__, uiPVRDevID, bLeaveVT ? "Leave VT" : "Enter VT")); OMAPLFBCreateSwapChainLock(psDevInfo); OMAPLFBAtomicBoolSet(&psDevInfo->sLeaveVT, bLeaveVT); if (psDevInfo->psSwapChain != NULL) { flush_workqueue(psDevInfo->psSwapChain->psWorkQueue); if (bLeaveVT) { OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer); (void) OMAPLFBCheckModeAndSync(psDevInfo); } } OMAPLFBCreateSwapChainUnLock(psDevInfo); (void) OMAPLFBUnblankDisplay(psDevInfo); break; } case PVR_DRM_DISP_CMD_ON: case PVR_DRM_DISP_CMD_STANDBY: case PVR_DRM_DISP_CMD_SUSPEND: case PVR_DRM_DISP_CMD_OFF: { int iFBMode; #if defined(DEBUG) { const char *pszMode; switch(uiCmd) { case PVR_DRM_DISP_CMD_ON: pszMode = "On"; break; case PVR_DRM_DISP_CMD_STANDBY: pszMode = "Standby"; break; case PVR_DRM_DISP_CMD_SUSPEND: pszMode = "Suspend"; break; case PVR_DRM_DISP_CMD_OFF: pszMode = "Off"; break; default: pszMode = "(Unknown Mode)"; break; } printk(KERN_WARNING DRIVER_PREFIX ": %s: PVR Device %u: Display %s\n", __FUNCTION__, uiPVRDevID, pszMode); } #endif switch(uiCmd) { case PVR_DRM_DISP_CMD_ON: iFBMode = FB_BLANK_UNBLANK; break; case PVR_DRM_DISP_CMD_STANDBY: iFBMode = FB_BLANK_HSYNC_SUSPEND; break; case PVR_DRM_DISP_CMD_SUSPEND: iFBMode = FB_BLANK_VSYNC_SUSPEND; break; case PVR_DRM_DISP_CMD_OFF: iFBMode = FB_BLANK_POWERDOWN; break; default: return -EINVAL; } OMAPLFBCreateSwapChainLock(psDevInfo); if (psDevInfo->psSwapChain != NULL) { flush_workqueue(psDevInfo->psSwapChain->psWorkQueue); } OMAPLFB_CONSOLE_LOCK(); ret = fb_blank(psDevInfo->psLINFBInfo, iFBMode); OMAPLFB_CONSOLE_UNLOCK(); OMAPLFBCreateSwapChainUnLock(psDevInfo); break; } default: { ret = -EINVAL; break; } } return ret; }