summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <michel.daenzer@amd.com>2012-03-06 15:52:40 +0100
committerMichel Dänzer <michel@daenzer.net>2012-03-06 15:52:40 +0100
commitfe51469b2e02e4d565050bab077985270fb58a9b (patch)
tree070918736b34050419bfb6341b961c3254b13d04
parent878454ae8d8e96dd27a19d0b30940d014c4cd7e2 (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.c18
-rw-r--r--src/drmmode_display.h1
-rw-r--r--src/radeon_kms.c2
-rw-r--r--src/radeon_probe.h2
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;