drm/nv50/disp: fixup error paths in crtc object creation
authorBen Skeggs <bskeggs@redhat.com>
Fri, 20 Apr 2012 01:01:46 +0000 (11:01 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Thu, 24 May 2012 06:31:56 +0000 (16:31 +1000)
Reported-by: Marcin Slusarz <marcin.slusarz@gmail.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nv50_crtc.c
drivers/gpu/drm/nouveau/nv50_display.c

index 7eb3aa3b099eaa26cbebeb4303c1ddcdd601e401..97a477b3d52d8d41ecff7b560df389496b510a9d 100644 (file)
@@ -383,23 +383,15 @@ nv50_crtc_set_clock(struct drm_device *dev, int head, int pclk)
 static void
 nv50_crtc_destroy(struct drm_crtc *crtc)
 {
-       struct drm_device *dev;
-       struct nouveau_crtc *nv_crtc;
-
-       if (!crtc)
-               return;
-
-       dev = crtc->dev;
-       nv_crtc = nouveau_crtc(crtc);
-
-       NV_DEBUG_KMS(dev, "\n");
+       struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
 
-       drm_crtc_cleanup(&nv_crtc->base);
+       NV_DEBUG_KMS(crtc->dev, "\n");
 
        nouveau_bo_unmap(nv_crtc->lut.nvbo);
        nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo);
        nouveau_bo_unmap(nv_crtc->cursor.nvbo);
        nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
+       drm_crtc_cleanup(&nv_crtc->base);
        kfree(nv_crtc);
 }
 
@@ -755,18 +747,22 @@ nv50_crtc_create(struct drm_device *dev, int index)
        if (!nv_crtc)
                return -ENOMEM;
 
+       nv_crtc->index = index;
+       nv_crtc->set_dither = nv50_crtc_set_dither;
+       nv_crtc->set_scale = nv50_crtc_set_scale;
+       nv_crtc->set_color_vibrance = nv50_crtc_set_color_vibrance;
        nv_crtc->color_vibrance = 50;
        nv_crtc->vibrant_hue = 0;
-
-       /* Default CLUT parameters, will be activated on the hw upon
-        * first mode set.
-        */
+       nv_crtc->lut.depth = 0;
        for (i = 0; i < 256; i++) {
                nv_crtc->lut.r[i] = i << 8;
                nv_crtc->lut.g[i] = i << 8;
                nv_crtc->lut.b[i] = i << 8;
        }
-       nv_crtc->lut.depth = 0;
+
+       drm_crtc_init(dev, &nv_crtc->base, &nv50_crtc_funcs);
+       drm_crtc_helper_add(&nv_crtc->base, &nv50_crtc_helper_funcs);
+       drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256);
 
        ret = nouveau_bo_new(dev, 4096, 0x100, TTM_PL_FLAG_VRAM,
                             0, 0x0000, NULL, &nv_crtc->lut.nvbo);
@@ -778,21 +774,9 @@ nv50_crtc_create(struct drm_device *dev, int index)
                        nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo);
        }
 
-       if (ret) {
-               kfree(nv_crtc);
-               return ret;
-       }
-
-       nv_crtc->index = index;
+       if (ret)
+               goto out;
 
-       /* set function pointers */
-       nv_crtc->set_dither = nv50_crtc_set_dither;
-       nv_crtc->set_scale = nv50_crtc_set_scale;
-       nv_crtc->set_color_vibrance = nv50_crtc_set_color_vibrance;
-
-       drm_crtc_init(dev, &nv_crtc->base, &nv50_crtc_funcs);
-       drm_crtc_helper_add(&nv_crtc->base, &nv50_crtc_helper_funcs);
-       drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256);
 
        ret = nouveau_bo_new(dev, 64*64*4, 0x100, TTM_PL_FLAG_VRAM,
                             0, 0x0000, NULL, &nv_crtc->cursor.nvbo);
@@ -804,6 +788,12 @@ nv50_crtc_create(struct drm_device *dev, int index)
                        nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
        }
 
+       if (ret)
+               goto out;
+
        nv50_cursor_init(nv_crtc);
-       return 0;
+out:
+       if (ret)
+               nv50_crtc_destroy(&nv_crtc->base);
+       return ret;
 }
index 211e5e9565ce1c4cb2e32832842d9602571e9701..b526e3f61c1723da90e221f7e17c3490a51f6e69 100644 (file)
@@ -358,8 +358,11 @@ nv50_display_create(struct drm_device *dev)
        dev_priv->engine.display.priv = priv;
 
        /* Create CRTC objects */
-       for (i = 0; i < 2; i++)
-               nv50_crtc_create(dev, i);
+       for (i = 0; i < 2; i++) {
+               ret = nv50_crtc_create(dev, i);
+               if (ret)
+                       return ret;
+       }
 
        /* We setup the encoders from the BIOS table */
        for (i = 0 ; i < dcb->entries; i++) {