diff options
-rw-r--r-- | shared-core/radeon_cp.c | 31 | ||||
-rw-r--r-- | shared-core/radeon_drv.h | 1 | ||||
-rw-r--r-- | shared/radeon.h | 6 | ||||
-rw-r--r-- | shared/radeon_cp.c | 31 | ||||
-rw-r--r-- | shared/radeon_drv.h | 1 |
5 files changed, 64 insertions, 6 deletions
diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 7c869c02..02fceced 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/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,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 ); } diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 65f3c926..22c5d04f 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -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 */ diff --git a/shared/radeon.h b/shared/radeon.h index fe71687a..caf6aee0 100644 --- a/shared/radeon.h +++ b/shared/radeon.h @@ -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. diff --git a/shared/radeon_cp.c b/shared/radeon_cp.c index 7c869c02..02fceced 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,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 ); } diff --git a/shared/radeon_drv.h b/shared/radeon_drv.h index 65f3c926..22c5d04f 100644 --- a/shared/radeon_drv.h +++ b/shared/radeon_drv.h @@ -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 */ |