diff options
author | Jose Fonseca <jrfonseca@users.sourceforge.net> | 2003-06-21 13:39:38 +0000 |
---|---|---|
committer | Jose Fonseca <jrfonseca@users.sourceforge.net> | 2003-06-21 13:39:38 +0000 |
commit | 6253e9154580c87568bfcd0f37a07de62154f157 (patch) | |
tree | d31a2b7118dc13e08612450d7a1a3ac855b4bc3d | |
parent | c9796d6a46e24001220d6cd3328c35edaa980f94 (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.c | 12 | ||||
-rw-r--r-- | linux/drm_agp.h | 6 | ||||
-rw-r--r-- | linux/drm_agp_tmp.h | 46 | ||||
-rw-r--r-- | linux/drm_drv.h | 12 |
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)); |