summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--shared-core/radeon_cp.c31
-rw-r--r--shared-core/radeon_drv.h1
-rw-r--r--shared/radeon.h6
-rw-r--r--shared/radeon_cp.c31
-rw-r--r--shared/radeon_drv.h1
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
*/