@@ -1863,7 +1863,16 @@ static int i915_pm_resume(struct device *kdev)
/* freeze: before creating the hibernation_image */
static int i915_pm_freeze(struct device *kdev)
{
- return i915_pm_suspend(kdev);
+ int ret;
+ ret = i915_pm_suspend(kdev);
+ if (ret)
+ return ret;
+
+ ret = i915_gem_freeze(kdev_to_i915(kdev));
+ if (ret)
+ return ret;
+
+ return 0;
}
static int i915_pm_freeze_late(struct device *kdev)
@@ -3076,6 +3076,7 @@ int i915_gem_wait_ioctl(struct drm_device *dev, void *data,
void i915_gem_load_init(struct drm_device *dev);
void i915_gem_load_cleanup(struct drm_device *dev);
void i915_gem_load_init_fences(struct drm_i915_private *dev_priv);
+int i915_gem_freeze(struct drm_i915_private *dev_priv);
int i915_gem_freeze_late(struct drm_i915_private *dev_priv);
void *i915_gem_object_alloc(struct drm_device *dev);
@@ -4593,6 +4593,19 @@ void i915_gem_load_cleanup(struct drm_device *dev)
rcu_barrier();
}
+int i915_gem_freeze(struct drm_i915_private *dev_priv)
+{
+ intel_runtime_pm_get(dev_priv);
+
+ mutex_lock(&dev_priv->drm.struct_mutex);
+ i915_gem_shrink_all(dev_priv);
+ mutex_unlock(&dev_priv->drm.struct_mutex);
+
+ intel_runtime_pm_put(dev_priv);
+
+ return 0;
+}
+
int i915_gem_freeze_late(struct drm_i915_private *dev_priv)
{
struct drm_i915_gem_object *obj;
@@ -4616,7 +4629,8 @@ int i915_gem_freeze_late(struct drm_i915_private *dev_priv)
* the objects as well.
*/
- i915_gem_shrink_all(dev_priv);
+ mutex_lock(&dev_priv->drm.struct_mutex);
+ i915_gem_shrink(dev_priv, -1UL, I915_SHRINK_UNBOUND);
for (p = phases; *p; p++) {
list_for_each_entry(obj, *p, global_list) {
@@ -4624,6 +4638,7 @@ int i915_gem_freeze_late(struct drm_i915_private *dev_priv)
obj->base.write_domain = I915_GEM_DOMAIN_CPU;
}
}
+ mutex_unlock(&dev_priv->drm.struct_mutex);
return 0;
}