Make the radeon drm module better at cleaning up after itself if all the

clients (particularly the X server) exit without doing so for it.
This commit is contained in:
Keith Whitwell 2003-01-02 18:38:07 +00:00
parent ab9eb685c0
commit 208c0779b6
5 changed files with 64 additions and 6 deletions

View file

@ -1354,6 +1354,9 @@ int radeon_cp_stop( DRM_IOCTL_ARGS )
DRM_COPY_FROM_USER_IOCTL( stop, (drm_radeon_cp_stop_t *)data, sizeof(stop) );
if (!dev_priv->cp_running)
return 0;
/* Flush any pending CP commands. This ensures any outstanding
* commands are exectuted by the engine before we turn it off.
*/
@ -1381,6 +1384,31 @@ int radeon_cp_stop( DRM_IOCTL_ARGS )
return 0;
}
void radeon_do_release( drm_device_t *dev )
{
drm_radeon_private_t *dev_priv = dev->dev_private;
printk("radeon_do_release: %p\n", dev_priv);
if (dev_priv) {
/* Stop the cp */
radeon_do_cp_flush( dev_priv );
radeon_do_cp_idle( dev_priv );
radeon_do_cp_stop( dev_priv );
radeon_do_engine_reset( dev );
/* Disable *all* interrupts */
RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
/* Destroy agp heap ??? */
/* radeon_mem_takedown( &(dev_priv->agp_heap) ); */
/* deallocate kernel resources */
radeon_do_cleanup_cp( dev );
}
}
/* Just reset the CP ring. Called as part of an X Server engine reset.
*/
int radeon_cp_reset( DRM_IOCTL_ARGS )
@ -1412,9 +1440,6 @@ int radeon_cp_idle( DRM_IOCTL_ARGS )
LOCK_TEST_WITH_RETURN( dev );
/* if (dev->irq) */
/* radeon_emit_and_wait_irq( dev ); */
return radeon_do_cp_idle( dev_priv );
}

View file

@ -193,6 +193,7 @@ extern int radeon_emit_and_wait_irq(drm_device_t *dev);
extern int radeon_wait_irq(drm_device_t *dev, int swi_nr);
extern int radeon_emit_irq(drm_device_t *dev);
extern void radeon_do_release(drm_device_t *dev);
/* Flags for stats.boxes
*/

View file

@ -127,6 +127,12 @@
} \
} while (0)
#define __HAVE_RELEASE 1
#define DRIVER_RELEASE() do { \
if ( dev->open_count == 1) \
radeon_do_release( dev ); \
} while (0)
/* On unloading the module:
* - Free memory heap structure
* - Remove mappings made at startup and free dev_private.

View file

@ -1354,6 +1354,9 @@ int radeon_cp_stop( DRM_IOCTL_ARGS )
DRM_COPY_FROM_USER_IOCTL( stop, (drm_radeon_cp_stop_t *)data, sizeof(stop) );
if (!dev_priv->cp_running)
return 0;
/* Flush any pending CP commands. This ensures any outstanding
* commands are exectuted by the engine before we turn it off.
*/
@ -1381,6 +1384,31 @@ int radeon_cp_stop( DRM_IOCTL_ARGS )
return 0;
}
void radeon_do_release( drm_device_t *dev )
{
drm_radeon_private_t *dev_priv = dev->dev_private;
printk("radeon_do_release: %p\n", dev_priv);
if (dev_priv) {
/* Stop the cp */
radeon_do_cp_flush( dev_priv );
radeon_do_cp_idle( dev_priv );
radeon_do_cp_stop( dev_priv );
radeon_do_engine_reset( dev );
/* Disable *all* interrupts */
RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
/* Destroy agp heap ??? */
/* radeon_mem_takedown( &(dev_priv->agp_heap) ); */
/* deallocate kernel resources */
radeon_do_cleanup_cp( dev );
}
}
/* Just reset the CP ring. Called as part of an X Server engine reset.
*/
int radeon_cp_reset( DRM_IOCTL_ARGS )
@ -1412,9 +1440,6 @@ int radeon_cp_idle( DRM_IOCTL_ARGS )
LOCK_TEST_WITH_RETURN( dev );
/* if (dev->irq) */
/* radeon_emit_and_wait_irq( dev ); */
return radeon_do_cp_idle( dev_priv );
}

View file

@ -193,6 +193,7 @@ extern int radeon_emit_and_wait_irq(drm_device_t *dev);
extern int radeon_wait_irq(drm_device_t *dev, int swi_nr);
extern int radeon_emit_irq(drm_device_t *dev);
extern void radeon_do_release(drm_device_t *dev);
/* Flags for stats.boxes
*/