]> err.no Git - linux-2.6/blobdiff - drivers/char/drm/mga_irq.c
Merge branches 'at91', 'dyntick', 'ep93xx', 'iop', 'ixp', 'misc', 'orion', 'omap...
[linux-2.6] / drivers / char / drm / mga_irq.c
index 06852fb4b278fd0c5b0f3d84ff0d915858135913..9302cb8f0f83bef1e99be219a9b977884d3f6d28 100644 (file)
 #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)