Commit a1c008b9 authored by Thomas Zimmermann's avatar Thomas Zimmermann Committed by Maarten Lankhorst
Browse files

drm/i915/display: fbdev: Move custom suspend code to new callback



If the fbdev buffer is backed by stolen memory, it has to be cleared
upon resume from hibernation. Move the code into the new callback
fb_set_suspend, so that it can run from DRM's generic fbdev client.
No functional change. Other drivers are not affected.

Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20241212170913.185939-7-tzimmermann@suse.de


Signed-off-by: default avatarMaarten Lankhorst <dev@lankhorst.se>
parent 2ef5754c
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -757,7 +757,12 @@ EXPORT_SYMBOL(drm_fb_helper_deferred_io);
 */
void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, bool suspend)
{
	if (fb_helper && fb_helper->info)
	if (!fb_helper || !fb_helper->info)
		return;

	if (fb_helper->funcs->fb_set_suspend)
		fb_helper->funcs->fb_set_suspend(fb_helper, suspend);
	else
		fb_set_suspend(fb_helper->info, suspend);
}
EXPORT_SYMBOL(drm_fb_helper_set_suspend);
@@ -803,7 +808,7 @@ void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper,
		}
	}

	fb_set_suspend(fb_helper->info, suspend);
	drm_fb_helper_set_suspend(fb_helper, suspend);
	console_unlock();
}
EXPORT_SYMBOL(drm_fb_helper_set_suspend_unlocked);
+17 −11
Original line number Diff line number Diff line
@@ -285,10 +285,27 @@ static void intelfb_restore(struct drm_fb_helper *fb_helper)
	intel_fbdev_invalidate(ifbdev);
}

static void intelfb_set_suspend(struct drm_fb_helper *fb_helper, bool suspend)
{
	struct fb_info *info = fb_helper->info;

	/*
	 * When resuming from hibernation, Linux restores the object's
	 * content from swap if the buffer is backed by shmemfs. If the
	 * object is stolen however, it will be full of whatever garbage
	 * was left in there. Clear it to zero in this case.
	 */
	if (!suspend && !intel_bo_is_shmem(intel_fb_bo(fb_helper->fb)))
		memset_io(info->screen_base, 0, info->screen_size);

	fb_set_suspend(info, suspend);
}

static const struct drm_fb_helper_funcs intel_fb_helper_funcs = {
	.fb_probe = intelfb_create,
	.fb_dirty = intelfb_dirty,
	.fb_restore = intelfb_restore,
	.fb_set_suspend = intelfb_set_suspend,
};

/*
@@ -457,7 +474,6 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous
{
	struct drm_i915_private *dev_priv = to_i915(dev);
	struct intel_fbdev *ifbdev = dev_priv->display.fbdev.fbdev;
	struct fb_info *info;

	if (!ifbdev)
		return;
@@ -468,8 +484,6 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous
	if (!ifbdev->vma)
		return;

	info = ifbdev->helper.info;

	if (synchronous) {
		/* Flush any pending work to turn the console on, and then
		 * wait to turn it off. It must be synchronous as we are
@@ -499,14 +513,6 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous
		}
	}

	/* On resume from hibernation: If the object is shmemfs backed, it has
	 * been restored from swap. If the object is stolen however, it will be
	 * full of whatever garbage was left in there.
	 */
	if (state == FBINFO_STATE_RUNNING &&
	    !intel_bo_is_shmem(intel_fb_bo(&ifbdev->fb->base)))
		memset_io(info->screen_base, 0, info->screen_size);

	drm_fb_helper_set_suspend(&ifbdev->helper, state);
	console_unlock();
}
+14 −0
Original line number Diff line number Diff line
@@ -112,6 +112,20 @@ struct drm_fb_helper_funcs {
	 * TODO: Fix i915 to not require this callback.
	 */
	void (*fb_restore)(struct drm_fb_helper *helper);

	/**
	 * @fb_set_suspend:
	 *
	 * Driver callback to suspend or resume, if set, fbdev emulation will
	 * invoke this callback during suspend and resume. Driver should call
	 * fb_set_suspend() from their implementation. If not set, fbdev
	 * emulation will invoke fb_set_suspend() directly.
	 *
	 * Only for i915. Do not use in new code.
	 *
	 * TODO: Fix i915 to not require this callback.
	 */
	void (*fb_set_suspend)(struct drm_fb_helper *helper, bool suspend);
};

/**