diff options
Diffstat (limited to 'drivers/char/drm/mga_irq.c')
| -rw-r--r-- | drivers/char/drm/mga_irq.c | 69 | 
1 files changed, 18 insertions, 51 deletions
diff --git a/drivers/char/drm/mga_irq.c b/drivers/char/drm/mga_irq.c index 06852fb4b27..9302cb8f0f8 100644 --- a/drivers/char/drm/mga_irq.c +++ b/drivers/char/drm/mga_irq.c @@ -35,20 +35,6 @@  #include "mga_drm.h"  #include "mga_drv.h" -u32 mga_get_vblank_counter(struct drm_device *dev, int crtc) -{ -	const drm_mga_private_t *const dev_priv = -		(drm_mga_private_t *) dev->dev_private; - -	if (crtc != 0) { -		return 0; -	} - - -	return atomic_read(&dev_priv->vbl_received); -} - -  irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)  {  	struct drm_device *dev = (struct drm_device *) arg; @@ -61,8 +47,9 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)  	/* VBLANK interrupt */  	if (status & MGA_VLINEPEN) {  		MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR); -		atomic_inc(&dev_priv->vbl_received); -		drm_handle_vblank(dev, 0); +		atomic_inc(&dev->vbl_received); +		DRM_WAKEUP(&dev->vbl_queue); +		drm_vbl_send_signals(dev);  		handled = 1;  	} @@ -91,34 +78,22 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)  	return IRQ_NONE;  } -int mga_enable_vblank(struct drm_device *dev, int crtc) +int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence)  { -	drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - -	if (crtc != 0) { -		DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", -			  crtc); -		return 0; -	} - -	MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); -	return 0; -} +	unsigned int cur_vblank; +	int ret = 0; +	/* Assume that the user has missed the current sequence number +	 * by about a day rather than she wants to wait for years +	 * using vertical blanks... +	 */ +	DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, +		    (((cur_vblank = atomic_read(&dev->vbl_received)) +		      - *sequence) <= (1 << 23))); -void mga_disable_vblank(struct drm_device *dev, int crtc) -{ -	if (crtc != 0) { -		DRM_ERROR("tried to disable vblank on non-existent crtc %d\n", -			  crtc); -	} +	*sequence = cur_vblank; -	/* Do *NOT* disable the vertical refresh interrupt.  MGA doesn't have -	 * a nice hardware counter that tracks the number of refreshes when -	 * the interrupt is disabled, and the kernel doesn't know the refresh -	 * rate to calculate an estimate. -	 */ -	/* MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); */ +	return ret;  }  int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence) @@ -150,22 +125,14 @@ void mga_driver_irq_preinstall(struct drm_device * dev)  	MGA_WRITE(MGA_ICLEAR, ~0);  } -int mga_driver_irq_postinstall(struct drm_device * dev) +void mga_driver_irq_postinstall(struct drm_device * dev)  {  	drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; -	int ret; - -	ret = drm_vblank_init(dev, 1); -	if (ret) -		return ret;  	DRM_INIT_WAITQUEUE(&dev_priv->fence_queue); -	/* Turn on soft trap interrupt.  Vertical blank interrupts are enabled -	 * in mga_enable_vblank. -	 */ -	MGA_WRITE(MGA_IEN, MGA_SOFTRAPEN); -	return 0; +	/* Turn on vertical blank interrupt and soft trap interrupt. */ +	MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN);  }  void mga_driver_irq_uninstall(struct drm_device * dev)  |