drm/<drivers>: reorder framebuffer init sequence
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Thu, 13 Dec 2012 22:38:38 +0000 (23:38 +0100)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Sun, 20 Jan 2013 14:29:24 +0000 (15:29 +0100)
With more fine-grained locking we can no longer rely on the big
mode_config lock to prevent concurrent access to mode resources
like framebuffers. Instead a framebuffer becomes accessible to
other threads as soon as it is added to the relevant lookup
structures. Hence it needs to be fully set up by the time drivers
call drm_framebuffer_init.

This patch here is the drivers part of that reorg. Nothing really fancy
going on safe for three special cases.

- exynos needs to be careful to properly unref all handles.
- nouveau gets a resource leak fixed for free: one of the error
  cases didn't cleanup the framebuffer, which is now moot since
  the framebuffer is only registered once it is fully set up.
- vmwgfx requires a slight reordering of operations, I'm hoping I didn't
  break anything (but it's refcount management only, so should be safe).

v2: Split out exynos, since it's a bit more hairy than expected.

v3: Drop bogus cirrus hunk noticed by Richard Wilbur.

v4: Split out vmwgfx since there's a small change in return values.

Reviewed-by: Rob Clark <rob@ti.com> (core + omapdrm)
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/ast/ast_main.c
drivers/gpu/drm/cirrus/cirrus_main.c
drivers/gpu/drm/drm_fb_cma_helper.c
drivers/gpu/drm/gma500/framebuffer.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/mgag200/mgag200_main.c
drivers/gpu/drm/nouveau/nouveau_display.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/udl/udl_fb.c
drivers/staging/omapdrm/omap_fb.c

index f668e6cc0f7a54ecd0640fce21512428fb6efdb8..d5ba7097e5b53bcf9eb50b67de7bb678b8c527a9 100644 (file)
@@ -266,13 +266,13 @@ int ast_framebuffer_init(struct drm_device *dev,
 {
        int ret;
 
+       drm_helper_mode_fill_fb_struct(&ast_fb->base, mode_cmd);
+       ast_fb->obj = obj;
        ret = drm_framebuffer_init(dev, &ast_fb->base, &ast_fb_funcs);
        if (ret) {
                DRM_ERROR("framebuffer init failed %d\n", ret);
                return ret;
        }
-       drm_helper_mode_fill_fb_struct(&ast_fb->base, mode_cmd);
-       ast_fb->obj = obj;
        return 0;
 }
 
index 6a9b12e88d467946336a8582c61c067482b3f656..364474c66202cc9587fa51d8acddda5e0af03fd1 100644 (file)
@@ -42,13 +42,13 @@ int cirrus_framebuffer_init(struct drm_device *dev,
 {
        int ret;
 
+       drm_helper_mode_fill_fb_struct(&gfb->base, mode_cmd);
+       gfb->obj = obj;
        ret = drm_framebuffer_init(dev, &gfb->base, &cirrus_fb_funcs);
        if (ret) {
                DRM_ERROR("drm_framebuffer_init failed: %d\n", ret);
                return ret;
        }
-       drm_helper_mode_fill_fb_struct(&gfb->base, mode_cmd);
-       gfb->obj = obj;
        return 0;
 }
 
index fd9d0af4d5369bb7ebac13662a3d612188c87921..e1e0cb0d531a08d62b80d29e2fde3e7c8ef1f5f7 100644 (file)
@@ -85,6 +85,11 @@ static struct drm_fb_cma *drm_fb_cma_alloc(struct drm_device *dev,
        if (!fb_cma)
                return ERR_PTR(-ENOMEM);
 
+       drm_helper_mode_fill_fb_struct(&fb_cma->fb, mode_cmd);
+
+       for (i = 0; i < num_planes; i++)
+               fb_cma->obj[i] = obj[i];
+
        ret = drm_framebuffer_init(dev, &fb_cma->fb, &drm_fb_cma_funcs);
        if (ret) {
                dev_err(dev->dev, "Failed to initalize framebuffer: %d\n", ret);
@@ -92,11 +97,6 @@ static struct drm_fb_cma *drm_fb_cma_alloc(struct drm_device *dev,
                return ERR_PTR(ret);
        }
 
-       drm_helper_mode_fill_fb_struct(&fb_cma->fb, mode_cmd);
-
-       for (i = 0; i < num_planes; i++)
-               fb_cma->obj[i] = obj[i];
-
        return fb_cma;
 }
 
index afded54dbb10c2b8c3b1e727625a5f637002330e..38e7e7597de24d1e61dda9acaee8145124dcbc1d 100644 (file)
@@ -260,13 +260,13 @@ static int psb_framebuffer_init(struct drm_device *dev,
        default:
                return -EINVAL;
        }
+       drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd);
+       fb->gtt = gt;
        ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs);
        if (ret) {
                dev_err(dev->dev, "framebuffer init failed: %d\n", ret);
                return ret;
        }
-       drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd);
-       fb->gtt = gt;
        return 0;
 }
 
index da1ad9c80bb53722e7afd423b27a819f31ff6927..26fa6a795afe1d1a48710007a723f24ebd924c64 100644 (file)
@@ -8666,14 +8666,15 @@ int intel_framebuffer_init(struct drm_device *dev,
        if (mode_cmd->offsets[0] != 0)
                return -EINVAL;
 
+       drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd);
+       intel_fb->obj = obj;
+
        ret = drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs);
        if (ret) {
                DRM_ERROR("framebuffer init failed %d\n", ret);
                return ret;
        }
 
-       drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd);
-       intel_fb->obj = obj;
        return 0;
 }
 
index 70dd3c5529d400f492b8cd113ce9fd0950036963..266438af61eacd59a339fea1f2ff1e1ef7088f2d 100644 (file)
@@ -40,13 +40,15 @@ int mgag200_framebuffer_init(struct drm_device *dev,
                             struct drm_mode_fb_cmd2 *mode_cmd,
                             struct drm_gem_object *obj)
 {
-       int ret = drm_framebuffer_init(dev, &gfb->base, &mga_fb_funcs);
+       int ret;
+       
+       drm_helper_mode_fill_fb_struct(&gfb->base, mode_cmd);
+       gfb->obj = obj;
+       ret = drm_framebuffer_init(dev, &gfb->base, &mga_fb_funcs);
        if (ret) {
                DRM_ERROR("drm_framebuffer_init failed: %d\n", ret);
                return ret;
        }
-       drm_helper_mode_fill_fb_struct(&gfb->base, mode_cmd);
-       gfb->obj = obj;
        return 0;
 }
 
index 508b00a2ce0de6d48b80e33d1ef1bc515598b3d2..d42c9e860c169b16bd46391cf99ad5933ea5d3a6 100644 (file)
@@ -78,11 +78,6 @@ nouveau_framebuffer_init(struct drm_device *dev,
        struct drm_framebuffer *fb = &nv_fb->base;
        int ret;
 
-       ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs);
-       if (ret) {
-               return ret;
-       }
-
        drm_helper_mode_fill_fb_struct(fb, mode_cmd);
        nv_fb->nvbo = nvbo;
 
@@ -125,6 +120,11 @@ nouveau_framebuffer_init(struct drm_device *dev,
                }
        }
 
+       ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs);
+       if (ret) {
+               return ret;
+       }
+
        return 0;
 }
 
index 1da2386d7cf74a9eac82674a53ac2cee3e8e52a5..12ec3effb409f2a9bbdf31d2ebb960742c0749fc 100644 (file)
@@ -1089,12 +1089,12 @@ radeon_framebuffer_init(struct drm_device *dev,
 {
        int ret;
        rfb->obj = obj;
+       drm_helper_mode_fill_fb_struct(&rfb->base, mode_cmd);
        ret = drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs);
        if (ret) {
                rfb->obj = NULL;
                return ret;
        }
-       drm_helper_mode_fill_fb_struct(&rfb->base, mode_cmd);
        return 0;
 }
 
index d4ab3beaada027825d6182a1330b79bd75d220d4..829c4a76938c44e147c7c81be2ddcb673aca5b4e 100644 (file)
@@ -435,8 +435,8 @@ udl_framebuffer_init(struct drm_device *dev,
        int ret;
 
        ufb->obj = obj;
-       ret = drm_framebuffer_init(dev, &ufb->base, &udlfb_funcs);
        drm_helper_mode_fill_fb_struct(&ufb->base, mode_cmd);
+       ret = drm_framebuffer_init(dev, &ufb->base, &udlfb_funcs);
        return ret;
 }
 
index 09028e9c1093e247476d4be7fa7684395bede40f..bf6421f26c40f74f1b419a306a7e82bc22baf1ac 100644 (file)
@@ -424,14 +424,6 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,
        }
 
        fb = &omap_fb->base;
-       ret = drm_framebuffer_init(dev, fb, &omap_framebuffer_funcs);
-       if (ret) {
-               dev_err(dev->dev, "framebuffer init failed: %d\n", ret);
-               goto fail;
-       }
-
-       DBG("create: FB ID: %d (%p)", fb->base.id, fb);
-
        omap_fb->format = format;
 
        for (i = 0; i < n; i++) {
@@ -462,6 +454,14 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,
 
        drm_helper_mode_fill_fb_struct(fb, mode_cmd);
 
+       ret = drm_framebuffer_init(dev, fb, &omap_framebuffer_funcs);
+       if (ret) {
+               dev_err(dev->dev, "framebuffer init failed: %d\n", ret);
+               goto fail;
+       }
+
+       DBG("create: FB ID: %d (%p)", fb->base.id, fb);
+
        return fb;
 
 fail: