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

drm/nouveau/fbcon: refcount the drm_framebuffer



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 595b61cc
Loading
Loading
Loading
Loading
+25 −28
Original line number Diff line number Diff line
@@ -245,28 +245,32 @@ static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = {
};

int
nouveau_framebuffer_init(struct drm_device *dev,
			 struct nouveau_framebuffer *nv_fb,
nouveau_framebuffer_new(struct drm_device *dev,
			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 drm_framebuffer *fb = &nv_fb->base;
	struct nouveau_framebuffer *fb;
	int ret;

	drm_helper_mode_fill_fb_struct(fb, mode_cmd);
	nv_fb->nvbo = nvbo;
	if (!(fb = kzalloc(sizeof(*fb), GFP_KERNEL)))
		return -ENOMEM;

	ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs);
	if (ret)
		return ret;
	drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd);
	fb->nvbo = nvbo;

	if (disp->fb_ctor) {
		ret = disp->fb_ctor(fb);
		if (ret)
			disp->fb_dtor(fb);
	ret = drm_framebuffer_init(dev, &fb->base, &nouveau_framebuffer_funcs);
	if (ret == 0) {
		if (!disp->fb_ctor || !(ret = disp->fb_ctor(&fb->base))) {
			*pfb = fb;
			return 0;
		}
		disp->fb_dtor(&fb->base);
		drm_framebuffer_cleanup(&fb->base);
	}

	kfree(fb);
	return ret;
}

@@ -275,27 +279,20 @@ nouveau_user_framebuffer_create(struct drm_device *dev,
				struct drm_file *file_priv,
				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;
	int ret = -ENOMEM;
	int ret;

	gem = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]);
	if (!gem)
		return ERR_PTR(-ENOENT);
	nvbo = nouveau_gem_object(gem);

	nouveau_fb = kzalloc(sizeof(struct nouveau_framebuffer), GFP_KERNEL);
	if (!nouveau_fb)
		goto err_unref;

	ret = nouveau_framebuffer_init(dev, nouveau_fb, mode_cmd, nouveau_gem_object(gem));
	if (ret)
		goto err;

	return &nouveau_fb->base;
	ret = nouveau_framebuffer_new(dev, mode_cmd, nvbo, &fb);
	if (ret == 0)
		return &fb->base;

err:
	kfree(nouveau_fb);
err_unref:
	drm_gem_object_unreference_unlocked(gem);
	return ERR_PTR(ret);
}
+3 −2
Original line number Diff line number Diff line
@@ -22,8 +22,9 @@ nouveau_framebuffer(struct drm_framebuffer *fb)
	return container_of(fb, struct nouveau_framebuffer, base);
}

int nouveau_framebuffer_init(struct drm_device *, struct nouveau_framebuffer *,
			     const struct drm_mode_fb_cmd2 *, struct nouveau_bo *);
int nouveau_framebuffer_new(struct drm_device *,
			    const struct drm_mode_fb_cmd2 *,
			    struct nouveau_bo *, struct nouveau_framebuffer **);

struct nouveau_page_flip_state {
	struct list_head head;
+6 −7
Original line number Diff line number Diff line
@@ -359,8 +359,9 @@ nouveau_fbcon_create(struct drm_fb_helper *helper,
		goto out;
	}

	nouveau_framebuffer_init(dev, &fbcon->fb, &mode_cmd, nvbo);
	fb = &fbcon->fb;
	ret = nouveau_framebuffer_new(dev, &mode_cmd, nvbo, &fb);
	if (ret)
		goto out_unref;

	ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM, false);
	if (ret) {
@@ -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_release_fbi(&fbcon->helper);
	drm_fb_helper_fini(&fbcon->helper);

	if (nouveau_fb->nvbo) {
		nouveau_bo_vma_del(nouveau_fb->nvbo, &nouveau_fb->vma);
		nouveau_bo_unmap(nouveau_fb->nvbo);
		nouveau_bo_unpin(nouveau_fb->nvbo);
		drm_gem_object_unreference_unlocked(&nouveau_fb->nvbo->gem);
		nouveau_fb->nvbo = NULL;
		drm_framebuffer_unreference(&nouveau_fb->base);
	}
	drm_fb_helper_fini(&fbcon->helper);
	drm_framebuffer_unregister_private(&nouveau_fb->base);
	drm_framebuffer_cleanup(&nouveau_fb->base);

	return 0;
}

+0 −1
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@

struct nouveau_fbdev {
	struct drm_fb_helper helper;
	struct nouveau_framebuffer fb;
	unsigned int saved_flags;
	struct nvif_object surf2d;
	struct nvif_object clip;