Commit a16f6ba4 authored by Thomas Zimmermann's avatar Thomas Zimmermann
Browse files

drm/client: Add client free callback to unprepare fb_helper



Add free callback to struct drm_client_funcs. Invoke function to
free the client memory as part of the release process. Implement
free for fbdev emulation.

Fbdev emulation allocates and prepares client memory in
drm_fbdev_client_setup(). The release happens in fb_destroy from
struct fb_ops. Multiple implementations of this callback exist in
the various drivers that provide an fbdev implementation. Each of
them needs to follow the implementation details of the fbdev setup
code.

Adding a free callback for the client puts the unprepare and release
of the fbdev client in a single place.

Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> # core, msm
Acked-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> # omapdrm
Acked-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com> # gma500
Acked-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Link: https://lore.kernel.org/r/20251009132006.45834-2-tzimmermann@suse.de
parent 550f4dd2
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -28,8 +28,6 @@ static void armada_fbdev_fb_destroy(struct fb_info *info)
	fbh->fb->funcs->destroy(fbh->fb);

	drm_client_release(&fbh->client);
	drm_fb_helper_unprepare(fbh);
	kfree(fbh);
}

static const struct fb_ops armada_fb_ops = {
+15 −2
Original line number Diff line number Diff line
@@ -13,16 +13,28 @@
 * struct drm_client_funcs
 */

static void drm_fbdev_client_free(struct drm_client_dev *client)
{
	struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);

	drm_fb_helper_unprepare(fb_helper);
	kfree(fb_helper);
}

static void drm_fbdev_client_unregister(struct drm_client_dev *client)
{
	struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);

	if (fb_helper->info) {
		/*
		 * Fully probed framebuffer device
		 */
		drm_fb_helper_unregister_info(fb_helper);
	} else {
		/*
		 * Partially initialized client, no framebuffer device yet
		 */
		drm_client_release(&fb_helper->client);
		drm_fb_helper_unprepare(fb_helper);
		kfree(fb_helper);
	}
}

@@ -82,6 +94,7 @@ static int drm_fbdev_client_resume(struct drm_client_dev *client)

static const struct drm_client_funcs drm_fbdev_client_funcs = {
	.owner		= THIS_MODULE,
	.free		= drm_fbdev_client_free,
	.unregister	= drm_fbdev_client_unregister,
	.restore	= drm_fbdev_client_restore,
	.hotplug	= drm_fbdev_client_hotplug,
+4 −0
Original line number Diff line number Diff line
@@ -168,6 +168,10 @@ void drm_client_release(struct drm_client_dev *client)

	drm_client_modeset_free(client);
	drm_client_close(client);

	if (client->funcs && client->funcs->free)
		client->funcs->free(client);

	drm_dev_put(dev);
}
EXPORT_SYMBOL(drm_client_release);
+0 −4
Original line number Diff line number Diff line
@@ -57,8 +57,6 @@ static void drm_fbdev_dma_fb_destroy(struct fb_info *info)
	drm_client_buffer_vunmap(fb_helper->buffer);
	drm_client_framebuffer_delete(fb_helper->buffer);
	drm_client_release(&fb_helper->client);
	drm_fb_helper_unprepare(fb_helper);
	kfree(fb_helper);
}

static const struct fb_ops drm_fbdev_dma_fb_ops = {
@@ -92,8 +90,6 @@ static void drm_fbdev_dma_shadowed_fb_destroy(struct fb_info *info)
	drm_client_buffer_vunmap(fb_helper->buffer);
	drm_client_framebuffer_delete(fb_helper->buffer);
	drm_client_release(&fb_helper->client);
	drm_fb_helper_unprepare(fb_helper);
	kfree(fb_helper);
}

static const struct fb_ops drm_fbdev_dma_shadowed_fb_ops = {
+0 −2
Original line number Diff line number Diff line
@@ -65,8 +65,6 @@ static void drm_fbdev_shmem_fb_destroy(struct fb_info *info)
	drm_client_buffer_vunmap(fb_helper->buffer);
	drm_client_framebuffer_delete(fb_helper->buffer);
	drm_client_release(&fb_helper->client);
	drm_fb_helper_unprepare(fb_helper);
	kfree(fb_helper);
}

static const struct fb_ops drm_fbdev_shmem_fb_ops = {
Loading