diff options
author | Michel Dänzer <michel.daenzer@amd.com> | 2012-03-06 15:52:40 +0100 |
---|---|---|
committer | Michel Dänzer <michel@daenzer.net> | 2012-03-06 15:52:40 +0100 |
commit | fe51469b2e02e4d565050bab077985270fb58a9b (patch) | |
tree | 070918736b34050419bfb6341b961c3254b13d04 | |
parent | 878454ae8d8e96dd27a19d0b30940d014c4cd7e2 (diff) |
Re-register DRM FD wakeup handler for each server generation.
Fixes hang when trying to use DRI2 swap scheduling after a server reset.
Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
Tested-by: Christian König <Christian.koenig@amd.com>
-rw-r--r-- | src/drmmode_display.c | 18 | ||||
-rw-r--r-- | src/drmmode_display.h | 1 | ||||
-rw-r--r-- | src/radeon_kms.c | 2 | ||||
-rw-r--r-- | src/radeon_probe.h | 2 |
4 files changed, 16 insertions, 7 deletions
diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 3a23474b..38f99409 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1479,9 +1479,7 @@ drm_wakeup_handler(pointer data, int err, pointer p) Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) { - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); xf86CrtcConfigPtr xf86_config; - RADEONInfoPtr info = RADEONPTR(pScrn); int i, num_dvi = 0, num_hdmi = 0; xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs); @@ -1509,14 +1507,22 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) drmmode->event_context.version = DRM_EVENT_CONTEXT_VERSION; drmmode->event_context.vblank_handler = drmmode_vblank_handler; drmmode->event_context.page_flip_handler = drmmode_flip_handler; - if (!pRADEONEnt->fd_wakeup_registered && info->dri->pKernelDRMVersion->version_minor >= 4) { + + return TRUE; +} + +void drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode) +{ + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (pRADEONEnt->fd_wakeup_registered != serverGeneration && + info->dri->pKernelDRMVersion->version_minor >= 4) { AddGeneralSocket(drmmode->fd); RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, drm_wakeup_handler, drmmode); - pRADEONEnt->fd_wakeup_registered = TRUE; + pRADEONEnt->fd_wakeup_registered = serverGeneration; } - - return TRUE; } Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, struct radeon_bo_manager *bufmgr) diff --git a/src/drmmode_display.h b/src/drmmode_display.h index eb271f5f..dff03929 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -99,6 +99,7 @@ typedef struct { extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp); +extern void drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode); extern Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, struct radeon_bo_manager *bufmgr); extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct radeon_bo *bo); void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y, int flags); diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 124ce800..c094beab 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -1136,6 +1136,8 @@ Bool RADEONScreenInit_KMS(int scrnIndex, ScreenPtr pScreen, if (serverGeneration == 1) xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + drmmode_init(pScrn, &info->drmmode); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "RADEONScreenInit finished\n"); diff --git a/src/radeon_probe.h b/src/radeon_probe.h index 8ba7214a..3123bccf 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -750,7 +750,7 @@ typedef struct void *FB; /* Map of FB region */ int FB_cnt; /* Map of FB region refcount */ int fd; /* for sharing across zaphod heads */ - Bool fd_wakeup_registered; /* fd has already been registered for wakeup handling */ + unsigned long fd_wakeup_registered; /* server generation for which fd has been registered for wakeup handling */ int dri2_info_cnt; } RADEONEntRec, *RADEONEntPtr; |