summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJose Fonseca <jrfonseca@users.sourceforge.net>2003-06-21 13:39:38 +0000
committerJose Fonseca <jrfonseca@users.sourceforge.net>2003-06-21 13:39:38 +0000
commit6253e9154580c87568bfcd0f37a07de62154f157 (patch)
treed31a2b7118dc13e08612450d7a1a3ac855b4bc3d
parentc9796d6a46e24001220d6cd3328c35edaa980f94 (diff)
Do an internal reference count of the AGPGART external "drm_agp" - this
should hopefully resolve the AGPGART module release problem, but it's still untested.
-rw-r--r--linux-core/drm_drv.c12
-rw-r--r--linux/drm_agp.h6
-rw-r--r--linux/drm_agp_tmp.h46
-rw-r--r--linux/drm_drv.h12
4 files changed, 23 insertions, 53 deletions
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c
index 78fb0aadd..ae5b7425d 100644
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -590,10 +590,6 @@ static int __init drm_init( void )
DRIVER_PREINIT();
-#if __REALLY_HAVE_AGP
- DRM(agp_init)();
-#endif
-
for (i = 0; i < DRM(numdevs); i++) {
dev = &(DRM(device)[i]);
memset( (void *)dev, 0, sizeof(*dev) );
@@ -606,7 +602,7 @@ static int __init drm_init( void )
dev->name = DRIVER_NAME;
#if __REALLY_HAVE_AGP
- DRM(agp_init_dev)( dev );
+ DRM(agp_init)( dev );
#if __MUST_HAVE_AGP
if ( dev->agp == NULL ) {
@@ -687,14 +683,10 @@ static void __exit drm_cleanup( void )
DRM(takedown)( dev );
#if __REALLY_HAVE_AGP
- DRM(agp_cleanup_dev)( dev );
+ DRM(agp_cleanup)( dev );
#endif
}
-#if __REALLY_HAVE_AGP
- DRM(agp_cleanup)();
-#endif
-
DRIVER_POSTCLEANUP();
kfree(DRM(minor));
kfree(DRM(device));
diff --git a/linux/drm_agp.h b/linux/drm_agp.h
index d76af6516..2cf1b547b 100644
--- a/linux/drm_agp.h
+++ b/linux/drm_agp.h
@@ -98,10 +98,8 @@ extern int DRM(agp_free_ioctl)(struct inode *inode, struct file *filp, unsigned
extern int DRM(agp_bind_ioctl)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
extern int DRM(agp_unbind_ioctl)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
-extern void DRM(agp_init)(void);
-extern void DRM(agp_cleanup)(void);
-extern void DRM(agp_init_dev)(drm_device_t *dev);
-extern void DRM(agp_cleanup_dev)(drm_device_t *dev);
+extern void DRM(agp_init)(drm_device_t *dev);
+extern void DRM(agp_cleanup)(drm_device_t *dev);
/*@}*/
diff --git a/linux/drm_agp_tmp.h b/linux/drm_agp_tmp.h
index 5f47b4214..e4da3a737 100644
--- a/linux/drm_agp_tmp.h
+++ b/linux/drm_agp_tmp.h
@@ -44,6 +44,7 @@
* Pointer to the drm_agp_t structure made available by the AGPGART module.
*/
static const drm_agp_t *drm_agp = NULL;
+static unsigned drm_agp_refcount = 0;
/**********************************************************************/
@@ -463,40 +464,21 @@ int DRM(agp_free_ioctl)(struct inode *inode, struct file *filp,
/*@{*/
/**
- * Initialize the global AGP resources.
- *
- * Gets the drm_agp_t structure which is made available by the agpgart module
- * via the inter_module_* functions.
- */
-void DRM(agp_init)(void)
-{
- drm_agp = (drm_agp_t *)inter_module_get("drm_agp");
-}
-
-/**
- * Free the global AGP resources.
- *
- * Releases the pointer in ::drm_agp.
- */
-void DRM(agp_cleanup)(void)
-{
- if (drm_agp) {
- inter_module_put("drm_agp");
- drm_agp = NULL;
- }
-}
-
-/**
* Initialize the device AGP resources.
*
* Creates and initializes a drm_agp_head structure in drm_device_t::agp.
*/
-void DRM(agp_init_dev)(drm_device_t *dev)
+void DRM(agp_init)(drm_device_t *dev)
{
drm_agp_head_t *head = NULL;
- if (!drm_agp)
- return;
+ if (!drm_agp) {
+ drm_agp = (drm_agp_t *)inter_module_get("drm_agp");
+
+ if (!drm_agp)
+ return;
+ }
+ ++drm_agp_refcount;
if (!(head = DRM(alloc)(sizeof(*head), DRM_MEM_AGPLISTS)))
return;
@@ -528,7 +510,7 @@ void DRM(agp_init_dev)(drm_device_t *dev)
/**
* Free the device AGP resources.
*/
-void DRM(agp_cleanup_dev)(drm_device_t *dev)
+void DRM(agp_cleanup)(drm_device_t *dev)
{
if ( dev->agp ) {
drm_agp_mem_t *entry;
@@ -538,7 +520,8 @@ void DRM(agp_cleanup_dev)(drm_device_t *dev)
intact until drv_cleanup is called. */
for ( entry = dev->agp->memory ; entry ; entry = nexte ) {
nexte = entry->next;
- if ( entry->bound ) DRM(agp_unbind)( entry->memory );
+ if ( entry->bound )
+ DRM(agp_unbind)( entry->memory );
DRM(agp_free)( entry->memory );
DRM(free)( entry, sizeof(*entry), DRM_MEM_AGPLISTS );
}
@@ -553,6 +536,11 @@ void DRM(agp_cleanup_dev)(drm_device_t *dev)
DRM(free)( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS );
dev->agp = NULL;
}
+
+ if (!--drm_agp_refcount) {
+ inter_module_put("drm_agp");
+ drm_agp = NULL;
+ }
}
/*@}*/
diff --git a/linux/drm_drv.h b/linux/drm_drv.h
index 78fb0aadd..ae5b7425d 100644
--- a/linux/drm_drv.h
+++ b/linux/drm_drv.h
@@ -590,10 +590,6 @@ static int __init drm_init( void )
DRIVER_PREINIT();
-#if __REALLY_HAVE_AGP
- DRM(agp_init)();
-#endif
-
for (i = 0; i < DRM(numdevs); i++) {
dev = &(DRM(device)[i]);
memset( (void *)dev, 0, sizeof(*dev) );
@@ -606,7 +602,7 @@ static int __init drm_init( void )
dev->name = DRIVER_NAME;
#if __REALLY_HAVE_AGP
- DRM(agp_init_dev)( dev );
+ DRM(agp_init)( dev );
#if __MUST_HAVE_AGP
if ( dev->agp == NULL ) {
@@ -687,14 +683,10 @@ static void __exit drm_cleanup( void )
DRM(takedown)( dev );
#if __REALLY_HAVE_AGP
- DRM(agp_cleanup_dev)( dev );
+ DRM(agp_cleanup)( dev );
#endif
}
-#if __REALLY_HAVE_AGP
- DRM(agp_cleanup)();
-#endif
-
DRIVER_POSTCLEANUP();
kfree(DRM(minor));
kfree(DRM(device));