summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/drmmode_display.c30
-rw-r--r--src/nv_type.h2
2 files changed, 24 insertions, 8 deletions
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index dc15221..6d225cb 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1596,6 +1596,7 @@ drmmode_screen_init(ScreenPtr pScreen)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
drmmode_ptr drmmode = drmmode_from_scrn(scrn);
+ NVEntPtr pNVEnt = NVEntPriv(scrn);
/* Setup handler for DRM events */
drmmode_event_init(scrn);
@@ -1603,10 +1604,17 @@ drmmode_screen_init(ScreenPtr pScreen)
/* Setup handler for udevevents */
drmmode_uevent_init(scrn);
- /* Register a wakeup handler to get informed on DRM events */
- AddGeneralSocket(drmmode->fd);
- RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
- drmmode_wakeup_handler, scrn);
+ /* Register wakeup handler only once per servergen, so ZaphodHeads work */
+ if (pNVEnt->fd_wakeup_registered != serverGeneration) {
+ /* Register a wakeup handler to get informed on DRM events */
+ AddGeneralSocket(drmmode->fd);
+ RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
+ drmmode_wakeup_handler, scrn);
+ pNVEnt->fd_wakeup_registered = serverGeneration;
+ pNVEnt->fd_wakeup_ref = 1;
+ }
+ else
+ pNVEnt->fd_wakeup_ref++;
}
void
@@ -1614,11 +1622,17 @@ drmmode_screen_fini(ScreenPtr pScreen)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
drmmode_ptr drmmode = drmmode_from_scrn(scrn);
+ NVEntPtr pNVEnt = NVEntPriv(scrn);
- /* Unregister wakeup handler */
- RemoveBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
- drmmode_wakeup_handler, scrn);
- RemoveGeneralSocket(drmmode->fd);
+ /* Unregister wakeup handler after last x-screen for this servergen dies. */
+ if (pNVEnt->fd_wakeup_registered == serverGeneration &&
+ !--pNVEnt->fd_wakeup_ref) {
+
+ /* Unregister wakeup handler */
+ RemoveBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
+ drmmode_wakeup_handler, scrn);
+ RemoveGeneralSocket(drmmode->fd);
+ }
/* Tear down udev event handler */
drmmode_uevent_fini(scrn);
diff --git a/src/nv_type.h b/src/nv_type.h
index 3e7c234..c0517c6 100644
--- a/src/nv_type.h
+++ b/src/nv_type.h
@@ -34,6 +34,8 @@ typedef struct {
unsigned long reinitGeneration;
struct xf86_platform_device *platform_dev;
unsigned int assigned_crtcs;
+ unsigned long fd_wakeup_registered;
+ int fd_wakeup_ref;
} NVEntRec, *NVEntPtr;
NVEntPtr NVEntPriv(ScrnInfoPtr pScrn);