drm/nouveau: initialise display before enabling interrupts
authorBen Skeggs <bskeggs@redhat.com>
Fri, 9 Jul 2010 00:56:08 +0000 (10:56 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Tue, 13 Jul 2010 00:13:56 +0000 (10:13 +1000)
In some situations it's possible we can receive a spurious hotplug IRQ
before we're ready to handle it, leading to an oops.

Calling the display init before enabling interrupts should clear any
pending IRQs on the GPU and prevent this from happening.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_state.c

index 67ee32fbba9d48a43fe5f6889871ab22424c1fd6..c58ff9c48603e38529d732f70d24c99796491490 100644 (file)
@@ -471,12 +471,19 @@ nouveau_card_init(struct drm_device *dev)
                        goto out_graph;
        }
 
+       if (dev_priv->card_type >= NV_50)
+               ret = nv50_display_create(dev);
+       else
+               ret = nv04_display_create(dev);
+       if (ret)
+               goto out_fifo;
+
        /* this call irq_preinstall, register irq handler and
         * call irq_postinstall
         */
        ret = drm_irq_install(dev);
        if (ret)
-               goto out_fifo;
+               goto out_display;
 
        ret = drm_vblank_init(dev, 0);
        if (ret)
@@ -490,13 +497,6 @@ nouveau_card_init(struct drm_device *dev)
                        goto out_irq;
        }
 
-       if (dev_priv->card_type >= NV_50)
-               ret = nv50_display_create(dev);
-       else
-               ret = nv04_display_create(dev);
-       if (ret)
-               goto out_channel;
-
        ret = nouveau_backlight_init(dev);
        if (ret)
                NV_ERROR(dev, "Error %d registering backlight\n", ret);
@@ -505,13 +505,13 @@ nouveau_card_init(struct drm_device *dev)
        drm_kms_helper_poll_init(dev);
        return 0;
 
-out_channel:
-       if (dev_priv->channel) {
-               nouveau_channel_free(dev_priv->channel);
-               dev_priv->channel = NULL;
-       }
 out_irq:
        drm_irq_uninstall(dev);
+out_display:
+       if (dev_priv->card_type >= NV_50)
+               nv50_display_destroy(dev);
+       else
+               nv04_display_destroy(dev);
 out_fifo:
        if (!nouveau_noaccel)
                engine->fifo.takedown(dev);