diff options
-rw-r--r-- | src/drmmode_display.c | 16 | ||||
-rw-r--r-- | src/radeon.h | 1 | ||||
-rw-r--r-- | src/radeon_kms.c | 12 | ||||
-rw-r--r-- | src/radeon_probe.h | 2 |
4 files changed, 26 insertions, 5 deletions
diff --git a/src/drmmode_display.c b/src/drmmode_display.c index d09c69ce..87ab2689 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1575,13 +1575,18 @@ void drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode) RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); RADEONInfoPtr info = RADEONPTR(pScrn); - if (pRADEONEnt->fd_wakeup_registered != serverGeneration && - info->dri2.pKernelDRMVersion->version_minor >= 4) { + if (info->dri2.pKernelDRMVersion->version_minor < 4) + return; + + info->drmmode_inited = TRUE; + if (pRADEONEnt->fd_wakeup_registered != serverGeneration) { AddGeneralSocket(drmmode->fd); RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, drm_wakeup_handler, drmmode); pRADEONEnt->fd_wakeup_registered = serverGeneration; - } + pRADEONEnt->fd_wakeup_ref = 1; + } else + pRADEONEnt->fd_wakeup_ref++; } void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode) @@ -1589,8 +1594,11 @@ void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode) RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); RADEONInfoPtr info = RADEONPTR(pScrn); + if (info->dri2.pKernelDRMVersion->version_minor < 4 || !info->drmmode_inited) + return; + if (pRADEONEnt->fd_wakeup_registered == serverGeneration && - info->dri2.pKernelDRMVersion->version_minor >= 4) { + !--pRADEONEnt->fd_wakeup_ref) { RemoveGeneralSocket(drmmode->fd); RemoveBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, drm_wakeup_handler, drmmode); diff --git a/src/radeon.h b/src/radeon.h index f9863473..1cbeef67 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -453,6 +453,7 @@ typedef struct { uint64_t vram_size; uint64_t gart_size; drmmode_rec drmmode; + Bool drmmode_inited; /* r6xx+ tile config */ Bool have_tiling_info; uint32_t tile_config; diff --git a/src/radeon_kms.c b/src/radeon_kms.c index f997d8a5..763acd0d 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -555,6 +555,7 @@ static Bool radeon_open_drm_master(ScrnInfoPtr pScrn) " reusing fd for second head\n"); info->dri2.drm_fd = pRADEONEnt->fd; + pRADEONEnt->fd_ref++; goto out; } @@ -596,6 +597,7 @@ static Bool radeon_open_drm_master(ScrnInfoPtr pScrn) } pRADEONEnt->fd = info->dri2.drm_fd; + pRADEONEnt->fd_ref = 1; out: info->drmmode.fd = info->dri2.drm_fd; return TRUE; @@ -1068,7 +1070,6 @@ static Bool RADEONCloseScreen_KMS(CLOSE_SCREEN_ARGS_DECL) drmmode_fini(pScrn, &info->drmmode); if (info->dri2.enabled) radeon_dri2_close_screen(pScreen); - drmClose(info->dri2.drm_fd); pScrn->vtSema = FALSE; xf86ClearPrimInitDone(info->pEnt->index); @@ -1082,10 +1083,19 @@ void RADEONFreeScreen_KMS(FREE_SCREEN_ARGS_DECL) { SCRN_INFO_PTR(arg); RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "RADEONFreeScreen\n"); + if (info->dri2.drm_fd > 0) { + pRADEONEnt->fd_ref--; + if (!pRADEONEnt->fd_ref) { + drmClose(pRADEONEnt->fd); + pRADEONEnt->fd = 0; + } + } + /* when server quits at PreInit, we don't need do this anymore*/ if (!info) return; diff --git a/src/radeon_probe.h b/src/radeon_probe.h index 516b7b48..1899a16c 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -128,7 +128,9 @@ typedef struct ScrnInfoPtr pPrimaryScrn; int fd; /* for sharing across zaphod heads */ + int fd_ref; unsigned long fd_wakeup_registered; /* server generation for which fd has been registered for wakeup handling */ + int fd_wakeup_ref; int dri2_info_cnt; } RADEONEntRec, *RADEONEntPtr; |