diff options
Diffstat (limited to 'shared/radeon_cp.c')
-rw-r--r-- | shared/radeon_cp.c | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/shared/radeon_cp.c b/shared/radeon_cp.c index 7c869c029..6994fe9eb 100644 --- a/shared/radeon_cp.c +++ b/shared/radeon_cp.c @@ -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,39 @@ 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; + int ret; + + if (dev_priv) { + if (dev_priv->cp_running) { + /* Stop the cp */ + while ((ret = radeon_do_cp_idle( dev_priv )) != 0) { + DRM_DEBUG("radeon_do_cp_idle %d\n", ret); +#ifdef __linux__ + schedule(); +#else + tsleep(&ret, PZERO, "rdnrel", 1); +#endif + } + radeon_do_cp_stop( dev_priv ); + radeon_do_engine_reset( dev ); + } + + /* Disable *all* interrupts */ + RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 ); + + /* Free memory heap structures */ + radeon_mem_takedown( &(dev_priv->agp_heap) ); + radeon_mem_takedown( &(dev_priv->fb_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 +1448,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 ); } |