summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux-core/drm_drv.c43
-rw-r--r--linux/drm_drv.h43
2 files changed, 84 insertions, 2 deletions
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c
index 30a6b6e4..016f9195 100644
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -88,6 +88,13 @@
#ifndef __HAVE_SG
#define __HAVE_SG 0
#endif
+/* __HAVE_KERNEL_CTX_SWITCH isn't used by any of the drm modules in
+ * the DRI cvs tree, but it is required by the kernel tree's sparc
+ * driver.
+ */
+#ifndef __HAVE_KERNEL_CTX_SWITCH
+#define __HAVE_KERNEL_CTX_SWITCH 0
+#endif
#ifndef __HAVE_DRIVER_FOPS_READ
#define __HAVE_DRIVER_FOPS_READ 0
#endif
@@ -1105,6 +1112,16 @@ int DRM(lock)( struct inode *inode, struct file *filp,
DRIVER_DMA_QUIESCENT();
}
#endif
+ /* __HAVE_KERNEL_CTX_SWITCH isn't used by any of the
+ * drm modules in the DRI cvs tree, but it is required
+ * by the Sparc driver.
+ */
+#if __HAVE_KERNEL_CTX_SWITCH
+ if ( dev->last_context != lock.context ) {
+ DRM(context_switch)(dev, dev->last_context,
+ lock.context);
+ }
+#endif
}
DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" );
@@ -1141,6 +1158,29 @@ int DRM(unlock)( struct inode *inode, struct file *filp,
atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] );
+ /* __HAVE_KERNEL_CTX_SWITCH isn't used by any of the drm
+ * modules in the DRI cvs tree, but it is required by the
+ * Sparc driver.
+ */
+#if __HAVE_KERNEL_CTX_SWITCH
+ /* We no longer really hold it, but if we are the next
+ * agent to request it then we should just be able to
+ * take it immediately and not eat the ioctl.
+ */
+ dev->lock.filp = 0;
+ {
+ __volatile__ unsigned int *plock = &dev->lock.hw_lock->lock;
+ unsigned int old, new, prev, ctx;
+
+ ctx = lock.context;
+ do {
+ old = *plock;
+ new = ctx;
+ prev = cmpxchg(plock, old, new);
+ } while (prev != old);
+ }
+ wake_up_interruptible(&dev->lock.lock_queue);
+#else
DRM(lock_transfer)( dev, &dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT );
#if __HAVE_DMA_SCHEDULE
@@ -1149,8 +1189,9 @@ int DRM(unlock)( struct inode *inode, struct file *filp,
if ( DRM(lock_free)( dev, &dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT ) ) {
- DRM_ERROR( "\n" );
+ DRM_ERROR( "\n" );
}
+#endif /* !__HAVE_KERNEL_CTX_SWITCH */
unblock_all_signals();
return 0;
diff --git a/linux/drm_drv.h b/linux/drm_drv.h
index 30a6b6e4..016f9195 100644
--- a/linux/drm_drv.h
+++ b/linux/drm_drv.h
@@ -88,6 +88,13 @@
#ifndef __HAVE_SG
#define __HAVE_SG 0
#endif
+/* __HAVE_KERNEL_CTX_SWITCH isn't used by any of the drm modules in
+ * the DRI cvs tree, but it is required by the kernel tree's sparc
+ * driver.
+ */
+#ifndef __HAVE_KERNEL_CTX_SWITCH
+#define __HAVE_KERNEL_CTX_SWITCH 0
+#endif
#ifndef __HAVE_DRIVER_FOPS_READ
#define __HAVE_DRIVER_FOPS_READ 0
#endif
@@ -1105,6 +1112,16 @@ int DRM(lock)( struct inode *inode, struct file *filp,
DRIVER_DMA_QUIESCENT();
}
#endif
+ /* __HAVE_KERNEL_CTX_SWITCH isn't used by any of the
+ * drm modules in the DRI cvs tree, but it is required
+ * by the Sparc driver.
+ */
+#if __HAVE_KERNEL_CTX_SWITCH
+ if ( dev->last_context != lock.context ) {
+ DRM(context_switch)(dev, dev->last_context,
+ lock.context);
+ }
+#endif
}
DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" );
@@ -1141,6 +1158,29 @@ int DRM(unlock)( struct inode *inode, struct file *filp,
atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] );
+ /* __HAVE_KERNEL_CTX_SWITCH isn't used by any of the drm
+ * modules in the DRI cvs tree, but it is required by the
+ * Sparc driver.
+ */
+#if __HAVE_KERNEL_CTX_SWITCH
+ /* We no longer really hold it, but if we are the next
+ * agent to request it then we should just be able to
+ * take it immediately and not eat the ioctl.
+ */
+ dev->lock.filp = 0;
+ {
+ __volatile__ unsigned int *plock = &dev->lock.hw_lock->lock;
+ unsigned int old, new, prev, ctx;
+
+ ctx = lock.context;
+ do {
+ old = *plock;
+ new = ctx;
+ prev = cmpxchg(plock, old, new);
+ } while (prev != old);
+ }
+ wake_up_interruptible(&dev->lock.lock_queue);
+#else
DRM(lock_transfer)( dev, &dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT );
#if __HAVE_DMA_SCHEDULE
@@ -1149,8 +1189,9 @@ int DRM(unlock)( struct inode *inode, struct file *filp,
if ( DRM(lock_free)( dev, &dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT ) ) {
- DRM_ERROR( "\n" );
+ DRM_ERROR( "\n" );
}
+#endif /* !__HAVE_KERNEL_CTX_SWITCH */
unblock_all_signals();
return 0;