Commit 943240d3 authored by Thomas Zimmermann's avatar Thomas Zimmermann
Browse files

drm/client: Pass force parameter to client restore



Add force parameter to client restore and pass value through the
layers. The only currently used value is false.

If force is true, the client should restore its display even if it
does not hold the DRM master lock. This is be required for emergency
output, such as sysrq.

While at it, inline drm_fb_helper_lastclose(), which is a trivial
wrapper around drm_fb_helper_restore_fbdev_mode_unlocked().

Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: default avatarJocelyn Falempe <jfalempe@redhat.com>
Link: https://patch.msgid.link/20251110154616.539328-2-tzimmermann@suse.de
parent 94124ea5
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -38,9 +38,11 @@ static void drm_fbdev_client_unregister(struct drm_client_dev *client)
	}
}

static int drm_fbdev_client_restore(struct drm_client_dev *client)
static int drm_fbdev_client_restore(struct drm_client_dev *client, bool force)
{
	drm_fb_helper_lastclose(client->dev);
	struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);

	drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper, force);

	return 0;
}
+2 −2
Original line number Diff line number Diff line
@@ -102,7 +102,7 @@ void drm_client_dev_hotplug(struct drm_device *dev)
}
EXPORT_SYMBOL(drm_client_dev_hotplug);

void drm_client_dev_restore(struct drm_device *dev)
void drm_client_dev_restore(struct drm_device *dev, bool force)
{
	struct drm_client_dev *client;
	int ret;
@@ -115,7 +115,7 @@ void drm_client_dev_restore(struct drm_device *dev)
		if (!client->funcs || !client->funcs->restore)
			continue;

		ret = client->funcs->restore(client);
		ret = client->funcs->restore(client, force);
		drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret);
		if (!ret) /* The first one to return zero gets the privilege to restore */
			break;
+6 −18
Original line number Diff line number Diff line
@@ -255,6 +255,7 @@ __drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper,
/**
 * drm_fb_helper_restore_fbdev_mode_unlocked - restore fbdev configuration
 * @fb_helper: driver-allocated fbdev helper, can be NULL
 * @force: ignore present DRM master
 *
 * This helper should be called from fbdev emulation's &drm_client_funcs.restore
 * callback. It ensures that the user isn't greeted with a black screen when the
@@ -263,9 +264,9 @@ __drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper,
 * Returns:
 * 0 on success, or a negative errno code otherwise.
 */
int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper)
int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper, bool force)
{
	return __drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper, false);
	return __drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper, force);
}
EXPORT_SYMBOL(drm_fb_helper_restore_fbdev_mode_unlocked);

@@ -1328,9 +1329,9 @@ int drm_fb_helper_set_par(struct fb_info *info)
	 * the KDSET IOCTL with KD_TEXT, and only after that drops the master
	 * status when exiting.
	 *
	 * In the past this was caught by drm_fb_helper_lastclose(), but on
	 * modern systems where logind always keeps a drm fd open to orchestrate
	 * the vt switching, this doesn't work.
	 * In the past this was caught by drm_fb_helper_restore_fbdev_mode_unlocked(),
	 * but on modern systems where logind always keeps a drm fd open to
	 * orchestrate the vt switching, this doesn't work.
	 *
	 * To not break the userspace ABI we have this special case here, which
	 * is only used for the above case. Everything else uses the normal
@@ -1955,16 +1956,3 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
	return 0;
}
EXPORT_SYMBOL(drm_fb_helper_hotplug_event);

/**
 * drm_fb_helper_lastclose - DRM driver lastclose helper for fbdev emulation
 * @dev: DRM device
 *
 * This function is obsolete. Call drm_fb_helper_restore_fbdev_mode_unlocked()
 * instead.
 */
void drm_fb_helper_lastclose(struct drm_device *dev)
{
	drm_fb_helper_restore_fbdev_mode_unlocked(dev->fb_helper);
}
EXPORT_SYMBOL(drm_fb_helper_lastclose);
+1 −1
Original line number Diff line number Diff line
@@ -405,7 +405,7 @@ EXPORT_SYMBOL(drm_open);

static void drm_lastclose(struct drm_device *dev)
{
	drm_client_dev_restore(dev);
	drm_client_dev_restore(dev, false);

	if (dev_is_pci(dev->dev))
		vga_switcheroo_process_delayed_switch();
+5 −3
Original line number Diff line number Diff line
@@ -57,12 +57,14 @@ struct drm_client_funcs {
	 *
	 * Note that the core does not guarantee exclusion against concurrent
	 * drm_open(). Clients need to ensure this themselves, for example by
	 * using drm_master_internal_acquire() and
	 * drm_master_internal_release().
	 * using drm_master_internal_acquire() and drm_master_internal_release().
	 *
	 * If the caller passes force, the client should ignore any present DRM
	 * master and restore the display anyway.
	 *
	 * This callback is optional.
	 */
	int (*restore)(struct drm_client_dev *client);
	int (*restore)(struct drm_client_dev *client, bool force);

	/**
	 * @hotplug:
Loading