diff options
| -rw-r--r-- | linux-core/drm_drv.c | 43 | ||||
| -rw-r--r-- | linux/drm_drv.h | 43 | 
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; | 
