return false;
 }
 
+static int i915_drm_prepare(struct drm_device *dev)
+{
+       struct drm_i915_private *i915 = to_i915(dev);
+       int err;
+
+       /*
+        * NB intel_display_suspend() may issue new requests after we've
+        * ostensibly marked the GPU as ready-to-sleep here. We need to
+        * split out that work and pull it forward so that after point,
+        * the GPU is not woken again.
+        */
+       err = i915_gem_suspend(i915);
+       if (err)
+               dev_err(&i915->drm.pdev->dev,
+                       "GEM idle failed, suspend/resume might fail\n");
+
+       return err;
+}
+
 static int i915_drm_suspend(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct pci_dev *pdev = dev_priv->drm.pdev;
        pci_power_t opregion_target_state;
-       int error;
 
        /* ignore lid events during suspend */
        mutex_lock(&dev_priv->modeset_restore_lock);
 
        pci_save_state(pdev);
 
-       error = i915_gem_suspend(dev_priv);
-       if (error) {
-               dev_err(&pdev->dev,
-                       "GEM idle failed, resume might fail\n");
-               goto out;
-       }
-
        intel_display_suspend(dev);
 
        intel_dp_mst_suspend(dev);
 
        intel_csr_ucode_suspend(dev_priv);
 
-out:
        enable_rpm_wakeref_asserts(dev_priv);
 
-       return error;
+       return 0;
 }
 
 static int i915_drm_suspend_late(struct drm_device *dev, bool hibernation)
        return ret;
 }
 
+static int i915_pm_prepare(struct device *kdev)
+{
+       struct pci_dev *pdev = to_pci_dev(kdev);
+       struct drm_device *dev = pci_get_drvdata(pdev);
+
+       if (!dev) {
+               dev_err(kdev, "DRM not initialized, aborting suspend.\n");
+               return -ENODEV;
+       }
+
+       if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
+               return 0;
+
+       return i915_drm_prepare(dev);
+}
+
 static int i915_pm_suspend(struct device *kdev)
 {
        struct pci_dev *pdev = to_pci_dev(kdev);
         * S0ix (via system suspend) and S3 event handlers [PMSG_SUSPEND,
         * PMSG_RESUME]
         */
+       .prepare = i915_pm_prepare,
        .suspend = i915_pm_suspend,
        .suspend_late = i915_pm_suspend_late,
        .resume_early = i915_pm_resume_early,