summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
diff options
context:
space:
mode:
authorThomas Hellstrom <thellstrom@vmware.com>2018-03-22 10:26:37 +0100
committerThomas Hellstrom <thellstrom@vmware.com>2018-03-22 12:08:23 +0100
commitc3b9b165734492b7e42bdd898aba93e1120f9084 (patch)
tree580fb2c15ca29c31102048751608974fa01ecacb /drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
parentbf833fd36f9bdc2c86e1fdc90318e4c99b452472 (diff)
downloadlinux-c3b9b165734492b7e42bdd898aba93e1120f9084.tar.bz2
drm/vmwgfx: Improve on hibernation
Make it possible to hibernate also with masters that don't switch VT at hibernation time. We save and restore modesetting state unless fbdev is active and enabled at hibernation time. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Sinclair Yeh <syeh@vmware.com>
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_kms.c')
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 63159674bf92..3628a9fe705f 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -2848,3 +2848,51 @@ int vmw_kms_set_config(struct drm_mode_set *set,
return drm_atomic_helper_set_config(set, ctx);
}
+
+
+/**
+ * vmw_kms_suspend - Save modesetting state and turn modesetting off.
+ *
+ * @dev: Pointer to the drm device
+ * Return: 0 on success. Negative error code on failure.
+ */
+int vmw_kms_suspend(struct drm_device *dev)
+{
+ struct vmw_private *dev_priv = vmw_priv(dev);
+
+ dev_priv->suspend_state = drm_atomic_helper_suspend(dev);
+ if (IS_ERR(dev_priv->suspend_state)) {
+ int ret = PTR_ERR(dev_priv->suspend_state);
+
+ DRM_ERROR("Failed kms suspend: %d\n", ret);
+ dev_priv->suspend_state = NULL;
+
+ return ret;
+ }
+
+ return 0;
+}
+
+
+/**
+ * vmw_kms_resume - Re-enable modesetting and restore state
+ *
+ * @dev: Pointer to the drm device
+ * Return: 0 on success. Negative error code on failure.
+ *
+ * State is resumed from a previous vmw_kms_suspend(). It's illegal
+ * to call this function without a previous vmw_kms_suspend().
+ */
+int vmw_kms_resume(struct drm_device *dev)
+{
+ struct vmw_private *dev_priv = vmw_priv(dev);
+ int ret;
+
+ if (WARN_ON(!dev_priv->suspend_state))
+ return 0;
+
+ ret = drm_atomic_helper_resume(dev, dev_priv->suspend_state);
+ dev_priv->suspend_state = NULL;
+
+ return ret;
+}