summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@canonical.com>2013-03-21 10:33:19 +0100
committerMaarten Lankhorst <maarten.lankhorst@canonical.com>2013-03-21 10:34:30 +0100
commit1643b8cd2dc53ed36916e11003590c7037b4ddd6 (patch)
tree73629198c357b5fcc63547534804d67cdb9e30aa
parenta4d1bc43d4d10e2ca1e512c1010e962c587d6c16 (diff)
radeon: add refcounts to fix up zaphod open/close.
Oops, turns out my previous commits were buggy. Adding proper refcounts will handle this correctly. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
-rw-r--r--src/drmmode_display.c16
-rw-r--r--src/radeon.h1
-rw-r--r--src/radeon_kms.c12
-rw-r--r--src/radeon_probe.h2
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;