drm: move drm vblank initialization/cleanup to driver load/unload
Keith Packard [Tue, 18 Nov 2008 17:30:25 +0000 (09:30 -0800)]
drm vblank initialization keeps track of the changes in driver-supplied
frame counts across vt switch and mode setting, but only if you let it by
not tearing down the drm vblank structure.

Signed-off-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>

15 files changed:
drivers/gpu/drm/drm_drv.c
drivers/gpu/drm/drm_irq.c
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/mga/mga_dma.c
drivers/gpu/drm/mga/mga_irq.c
drivers/gpu/drm/r128/r128_drv.c
drivers/gpu/drm/r128/r128_drv.h
drivers/gpu/drm/r128/r128_irq.c
drivers/gpu/drm/radeon/radeon_cp.c
drivers/gpu/drm/radeon/radeon_irq.c
drivers/gpu/drm/via/via_irq.c
drivers/gpu/drm/via/via_map.c
include/drm/drmP.h

index 3ab1e9c..996097a 100644 (file)
@@ -305,6 +305,8 @@ static void drm_cleanup(struct drm_device * dev)
                return;
        }
 
+       drm_vblank_cleanup(dev);
+
        drm_lastclose(dev);
 
        if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
index 15c8dab..1e787f8 100644 (file)
@@ -94,7 +94,7 @@ static void vblank_disable_fn(unsigned long arg)
        }
 }
 
-static void drm_vblank_cleanup(struct drm_device *dev)
+void drm_vblank_cleanup(struct drm_device *dev)
 {
        /* Bail if the driver didn't call drm_vblank_init() */
        if (dev->num_crtcs == 0)
@@ -278,8 +278,6 @@ int drm_irq_uninstall(struct drm_device * dev)
 
        free_irq(dev->pdev->irq, dev);
 
-       drm_vblank_cleanup(dev);
-
        return 0;
 }
 EXPORT_SYMBOL(drm_irq_uninstall);
index 0d215e3..ba89b42 100644 (file)
@@ -856,6 +856,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 
        spin_lock_init(&dev_priv->user_irq_lock);
 
+       ret = drm_vblank_init(dev, I915_NUM_PIPE);
+
+       if (ret) {
+               (void) i915_driver_unload(dev);
+               return ret;
+       }
+
        return ret;
 }
 
index ed1edcf..b24d522 100644 (file)
@@ -47,6 +47,8 @@ enum pipe {
        PIPE_B,
 };
 
+#define I915_NUM_PIPE  2
+
 /* Interface history:
  *
  * 1.1: Original.
index c367358..fe3d9cc 100644 (file)
@@ -498,11 +498,6 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
 int i915_driver_irq_postinstall(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-       int ret, num_pipes = 2;
-
-       ret = drm_vblank_init(dev, num_pipes);
-       if (ret)
-               return ret;
 
        dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
 
index c1d12db..b49c5ff 100644 (file)
@@ -396,6 +396,7 @@ int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf)
 int mga_driver_load(struct drm_device * dev, unsigned long flags)
 {
        drm_mga_private_t *dev_priv;
+       int ret;
 
        dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
        if (!dev_priv)
@@ -415,6 +416,13 @@ int mga_driver_load(struct drm_device * dev, unsigned long flags)
        dev->types[7] = _DRM_STAT_PRIMARY;
        dev->types[8] = _DRM_STAT_SECONDARY;
 
+       ret = drm_vblank_init(dev, 1);
+
+       if (ret) {
+               (void) mga_driver_unload(dev);
+               return ret;
+       }
+
        return 0;
 }
 
index bab42f4..daa6041 100644 (file)
@@ -152,11 +152,6 @@ void mga_driver_irq_preinstall(struct drm_device * dev)
 int 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);
 
index 3265d53..601f4c0 100644 (file)
@@ -45,6 +45,7 @@ static struct drm_driver driver = {
            DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
            DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
        .dev_priv_size = sizeof(drm_r128_buf_priv_t),
+       .load = r128_driver_load,
        .preclose = r128_driver_preclose,
        .lastclose = r128_driver_lastclose,
        .get_vblank_counter = r128_get_vblank_counter,
@@ -84,6 +85,11 @@ static struct drm_driver driver = {
        .patchlevel = DRIVER_PATCHLEVEL,
 };
 
+int r128_driver_load(struct drm_device * dev, unsigned long flags)
+{
+       return drm_vblank_init(dev, 1);
+}
+
 static int __init r128_init(void)
 {
        driver.num_ioctls = r128_max_ioctl;
index 5898b27..797a26c 100644 (file)
@@ -159,6 +159,7 @@ extern void r128_driver_irq_preinstall(struct drm_device * dev);
 extern int r128_driver_irq_postinstall(struct drm_device *dev);
 extern void r128_driver_irq_uninstall(struct drm_device * dev);
 extern void r128_driver_lastclose(struct drm_device * dev);
+extern int r128_driver_load(struct drm_device * dev, unsigned long flags);
 extern void r128_driver_preclose(struct drm_device * dev,
                                 struct drm_file *file_priv);
 
index d734901..69810fb 100644 (file)
@@ -102,7 +102,7 @@ void r128_driver_irq_preinstall(struct drm_device * dev)
 
 int r128_driver_irq_postinstall(struct drm_device *dev)
 {
-       return drm_vblank_init(dev, 1);
+       return 0;
 }
 
 void r128_driver_irq_uninstall(struct drm_device * dev)
index abdc1ae..dcebb4b 100644 (file)
@@ -1757,6 +1757,12 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
        if (ret != 0)
                return ret;
 
+       ret = drm_vblank_init(dev, 2);
+       if (ret) {
+               radeon_driver_unload(dev);
+               return ret;
+       }
+
        DRM_DEBUG("%s card detected\n",
                  ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI"))));
        return ret;
index 5079f70..97c0599 100644 (file)
@@ -337,15 +337,10 @@ int radeon_driver_irq_postinstall(struct drm_device *dev)
 {
        drm_radeon_private_t *dev_priv =
            (drm_radeon_private_t *) dev->dev_private;
-       int ret;
 
        atomic_set(&dev_priv->swi_emitted, 0);
        DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
 
-       ret = drm_vblank_init(dev, 2);
-       if (ret)
-               return ret;
-
        dev->max_vblank_count = 0x001fffff;
 
        radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
index 665d319..c248c1d 100644 (file)
@@ -314,7 +314,6 @@ int via_driver_irq_postinstall(struct drm_device *dev)
        if (!dev_priv)
                return -EINVAL;
 
-       drm_vblank_init(dev, 1);
        status = VIA_READ(VIA_REG_INTERRUPT);
        VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL
                  | dev_priv->irq_enable_mask);
index a967556..2c4f0b4 100644 (file)
@@ -107,8 +107,17 @@ int via_driver_load(struct drm_device *dev, unsigned long chipset)
        ret = drm_sman_init(&dev_priv->sman, 2, 12, 8);
        if (ret) {
                drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
+               return ret;
        }
-       return ret;
+
+       ret = drm_vblank_init(dev, 1);
+       if (ret) {
+               drm_sman_takedown(&dev_priv->sman);
+               drm_free(dev_priv, sizeof(drm_via_private_t), DRM_MEM_DRIVER);
+               return ret;
+       }
+
+       return 0;
 }
 
 int via_driver_unload(struct drm_device *dev)
index 28c7f16..d5e8e5c 100644 (file)
@@ -1151,6 +1151,7 @@ extern u32 drm_vblank_count(struct drm_device *dev, int crtc);
 extern void drm_handle_vblank(struct drm_device *dev, int crtc);
 extern int drm_vblank_get(struct drm_device *dev, int crtc);
 extern void drm_vblank_put(struct drm_device *dev, int crtc);
+extern void drm_vblank_cleanup(struct drm_device *dev);
 /* Modesetting support */
 extern int drm_modeset_ctl(struct drm_device *dev, void *data,
                           struct drm_file *file_priv);