Commit 1608a0fb authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/fbcon: refcount the drm_framebuffer

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 595b61cc
...@@ -245,28 +245,32 @@ static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = { ...@@ -245,28 +245,32 @@ static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = {
}; };
int int
nouveau_framebuffer_init(struct drm_device *dev, nouveau_framebuffer_new(struct drm_device *dev,
struct nouveau_framebuffer *nv_fb,
const struct drm_mode_fb_cmd2 *mode_cmd, const struct drm_mode_fb_cmd2 *mode_cmd,
struct nouveau_bo *nvbo) struct nouveau_bo *nvbo,
struct nouveau_framebuffer **pfb)
{ {
struct nouveau_display *disp = nouveau_display(dev); struct nouveau_display *disp = nouveau_display(dev);
struct drm_framebuffer *fb = &nv_fb->base; struct nouveau_framebuffer *fb;
int ret; int ret;
drm_helper_mode_fill_fb_struct(fb, mode_cmd); if (!(fb = kzalloc(sizeof(*fb), GFP_KERNEL)))
nv_fb->nvbo = nvbo; return -ENOMEM;
ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs); drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd);
if (ret) fb->nvbo = nvbo;
return ret;
if (disp->fb_ctor) { ret = drm_framebuffer_init(dev, &fb->base, &nouveau_framebuffer_funcs);
ret = disp->fb_ctor(fb); if (ret == 0) {
if (ret) if (!disp->fb_ctor || !(ret = disp->fb_ctor(&fb->base))) {
disp->fb_dtor(fb); *pfb = fb;
return 0;
}
disp->fb_dtor(&fb->base);
drm_framebuffer_cleanup(&fb->base);
} }
kfree(fb);
return ret; return ret;
} }
...@@ -275,27 +279,20 @@ nouveau_user_framebuffer_create(struct drm_device *dev, ...@@ -275,27 +279,20 @@ nouveau_user_framebuffer_create(struct drm_device *dev,
struct drm_file *file_priv, struct drm_file *file_priv,
const struct drm_mode_fb_cmd2 *mode_cmd) const struct drm_mode_fb_cmd2 *mode_cmd)
{ {
struct nouveau_framebuffer *nouveau_fb; struct nouveau_framebuffer *fb;
struct nouveau_bo *nvbo;
struct drm_gem_object *gem; struct drm_gem_object *gem;
int ret = -ENOMEM; int ret;
gem = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]); gem = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]);
if (!gem) if (!gem)
return ERR_PTR(-ENOENT); return ERR_PTR(-ENOENT);
nvbo = nouveau_gem_object(gem);
nouveau_fb = kzalloc(sizeof(struct nouveau_framebuffer), GFP_KERNEL); ret = nouveau_framebuffer_new(dev, mode_cmd, nvbo, &fb);
if (!nouveau_fb) if (ret == 0)
goto err_unref; return &fb->base;
ret = nouveau_framebuffer_init(dev, nouveau_fb, mode_cmd, nouveau_gem_object(gem));
if (ret)
goto err;
return &nouveau_fb->base;
err:
kfree(nouveau_fb);
err_unref:
drm_gem_object_unreference_unlocked(gem); drm_gem_object_unreference_unlocked(gem);
return ERR_PTR(ret); return ERR_PTR(ret);
} }
......
...@@ -22,8 +22,9 @@ nouveau_framebuffer(struct drm_framebuffer *fb) ...@@ -22,8 +22,9 @@ nouveau_framebuffer(struct drm_framebuffer *fb)
return container_of(fb, struct nouveau_framebuffer, base); return container_of(fb, struct nouveau_framebuffer, base);
} }
int nouveau_framebuffer_init(struct drm_device *, struct nouveau_framebuffer *, int nouveau_framebuffer_new(struct drm_device *,
const struct drm_mode_fb_cmd2 *, struct nouveau_bo *); const struct drm_mode_fb_cmd2 *,
struct nouveau_bo *, struct nouveau_framebuffer **);
struct nouveau_page_flip_state { struct nouveau_page_flip_state {
struct list_head head; struct list_head head;
......
...@@ -359,8 +359,9 @@ nouveau_fbcon_create(struct drm_fb_helper *helper, ...@@ -359,8 +359,9 @@ nouveau_fbcon_create(struct drm_fb_helper *helper,
goto out; goto out;
} }
nouveau_framebuffer_init(dev, &fbcon->fb, &mode_cmd, nvbo); ret = nouveau_framebuffer_new(dev, &mode_cmd, nvbo, &fb);
fb = &fbcon->fb; if (ret)
goto out_unref;
ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM, false); ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM, false);
if (ret) { if (ret) {
...@@ -454,17 +455,15 @@ nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *fbcon) ...@@ -454,17 +455,15 @@ nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *fbcon)
drm_fb_helper_unregister_fbi(&fbcon->helper); drm_fb_helper_unregister_fbi(&fbcon->helper);
drm_fb_helper_release_fbi(&fbcon->helper); drm_fb_helper_release_fbi(&fbcon->helper);
drm_fb_helper_fini(&fbcon->helper);
if (nouveau_fb->nvbo) { if (nouveau_fb->nvbo) {
nouveau_bo_vma_del(nouveau_fb->nvbo, &nouveau_fb->vma); nouveau_bo_vma_del(nouveau_fb->nvbo, &nouveau_fb->vma);
nouveau_bo_unmap(nouveau_fb->nvbo); nouveau_bo_unmap(nouveau_fb->nvbo);
nouveau_bo_unpin(nouveau_fb->nvbo); nouveau_bo_unpin(nouveau_fb->nvbo);
drm_gem_object_unreference_unlocked(&nouveau_fb->nvbo->gem); drm_framebuffer_unreference(&nouveau_fb->base);
nouveau_fb->nvbo = NULL;
} }
drm_fb_helper_fini(&fbcon->helper);
drm_framebuffer_unregister_private(&nouveau_fb->base);
drm_framebuffer_cleanup(&nouveau_fb->base);
return 0; return 0;
} }
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
struct nouveau_fbdev { struct nouveau_fbdev {
struct drm_fb_helper helper; struct drm_fb_helper helper;
struct nouveau_framebuffer fb;
unsigned int saved_flags; unsigned int saved_flags;
struct nvif_object surf2d; struct nvif_object surf2d;
struct nvif_object clip; struct nvif_object clip;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment