return 0;
  }
  
 -int nouveau_pmops_resume(struct device *dev)
 +int
 +nouveau_pmops_suspend(struct device *dev)
 +{
 +      struct pci_dev *pdev = to_pci_dev(dev);
 +      struct drm_device *drm_dev = pci_get_drvdata(pdev);
 +      int ret;
 +
 +      if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF ||
 +          drm_dev->switch_power_state == DRM_SWITCH_POWER_DYNAMIC_OFF)
 +              return 0;
 +
 +      ret = nouveau_do_suspend(drm_dev, false);
 +      if (ret)
 +              return ret;
 +
 +      pci_save_state(pdev);
 +      pci_disable_device(pdev);
-       pci_ignore_hotplug(pdev);
 +      pci_set_power_state(pdev, PCI_D3hot);
 +      return 0;
 +}
 +
 +int
 +nouveau_pmops_resume(struct device *dev)
  {
        struct pci_dev *pdev = to_pci_dev(dev);
        struct drm_device *drm_dev = pci_get_drvdata(pdev);
        return nouveau_do_resume(drm_dev, false);
  }
  
 +static int
 +nouveau_pmops_runtime_suspend(struct device *dev)
 +{
 +      struct pci_dev *pdev = to_pci_dev(dev);
 +      struct drm_device *drm_dev = pci_get_drvdata(pdev);
 +      int ret;
 +
 +      if (nouveau_runtime_pm == 0) {
 +              pm_runtime_forbid(dev);
 +              return -EBUSY;
 +      }
 +
 +      /* are we optimus enabled? */
 +      if (nouveau_runtime_pm == -1 && !nouveau_is_optimus() && !nouveau_is_v1_dsm()) {
 +              DRM_DEBUG_DRIVER("failing to power off - not optimus\n");
 +              pm_runtime_forbid(dev);
 +              return -EBUSY;
 +      }
 +
 +      nv_debug_level(SILENT);
 +      drm_kms_helper_poll_disable(drm_dev);
 +      vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF);
 +      nouveau_switcheroo_optimus_dsm();
 +      ret = nouveau_do_suspend(drm_dev, true);
 +      pci_save_state(pdev);
 +      pci_disable_device(pdev);
++      pci_ignore_hotplug(pdev);
 +      pci_set_power_state(pdev, PCI_D3cold);
 +      drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF;
 +      return ret;
 +}
 +
 +static int
 +nouveau_pmops_runtime_resume(struct device *dev)
 +{
 +      struct pci_dev *pdev = to_pci_dev(dev);
 +      struct drm_device *drm_dev = pci_get_drvdata(pdev);
 +      struct nvif_device *device = &nouveau_drm(drm_dev)->device;
 +      int ret;
 +
 +      if (nouveau_runtime_pm == 0)
 +              return -EINVAL;
 +
 +      pci_set_power_state(pdev, PCI_D0);
 +      pci_restore_state(pdev);
 +      ret = pci_enable_device(pdev);
 +      if (ret)
 +              return ret;
 +      pci_set_master(pdev);
 +
 +      ret = nouveau_do_resume(drm_dev, true);
 +      drm_kms_helper_poll_enable(drm_dev);
 +      /* do magic */
 +      nvif_mask(device, 0x88488, (1 << 25), (1 << 25));
 +      vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON);
 +      drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;
 +      nv_debug_level(NORMAL);
 +      return ret;
 +}
 +
 +static int
 +nouveau_pmops_runtime_idle(struct device *dev)
 +{
 +      struct pci_dev *pdev = to_pci_dev(dev);
 +      struct drm_device *drm_dev = pci_get_drvdata(pdev);
 +      struct nouveau_drm *drm = nouveau_drm(drm_dev);
 +      struct drm_crtc *crtc;
 +
 +      if (nouveau_runtime_pm == 0) {
 +              pm_runtime_forbid(dev);
 +              return -EBUSY;
 +      }
 +
 +      /* are we optimus enabled? */
 +      if (nouveau_runtime_pm == -1 && !nouveau_is_optimus() && !nouveau_is_v1_dsm()) {
 +              DRM_DEBUG_DRIVER("failing to power off - not optimus\n");
 +              pm_runtime_forbid(dev);
 +              return -EBUSY;
 +      }
 +
 +      /* if we have a hdmi audio device - make sure it has a driver loaded */
 +      if (drm->hdmi_device) {
 +              if (!drm->hdmi_device->driver) {
 +                      DRM_DEBUG_DRIVER("failing to power off - no HDMI audio driver loaded\n");
 +                      pm_runtime_mark_last_busy(dev);
 +                      return -EBUSY;
 +              }
 +      }
 +
 +      list_for_each_entry(crtc, &drm->dev->mode_config.crtc_list, head) {
 +              if (crtc->enabled) {
 +                      DRM_DEBUG_DRIVER("failing to power off - crtc active\n");
 +                      return -EBUSY;
 +              }
 +      }
 +      pm_runtime_mark_last_busy(dev);
 +      pm_runtime_autosuspend(dev);
 +      /* we don't want the main rpm_idle to call suspend - we want to autosuspend */
 +      return 1;
 +}
  
  static int
  nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv)