return -EBUSY;  /* No exclusive opens */
        if (!drm_cpu_valid())
                return -EINVAL;
+       if (dev->switch_power_state != DRM_SWITCH_POWER_ON)
+               return -EINVAL;
 
        DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor_id);
 
 
        pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
        if (state == VGA_SWITCHEROO_ON) {
                printk(KERN_INFO "i915: switched on\n");
+               dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
                /* i915 resume handler doesn't set to D0 */
                pci_set_power_state(dev->pdev, PCI_D0);
                i915_resume(dev);
+               dev->switch_power_state = DRM_SWITCH_POWER_ON;
        } else {
                printk(KERN_ERR "i915: switched off\n");
+               dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
                i915_suspend(dev, pmm);
+               dev->switch_power_state = DRM_SWITCH_POWER_OFF;
        }
 }
 
 
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
 
+       drm_kms_helper_poll_disable(dev);
+
        pci_save_state(dev->pdev);
 
        /* If KMS is active, we do the leavevt stuff here */
        if (state.event == PM_EVENT_PRETHAW)
                return 0;
 
-       drm_kms_helper_poll_disable(dev);
+
+       if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
+               return 0;
 
        error = i915_drm_freeze(dev);
        if (error)
 {
        int ret;
 
+       if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
+               return 0;
+
        if (pci_enable_device(dev->pdev))
                return -EIO;
 
                return -ENODEV;
        }
 
+       if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF)
+               return 0;
+
        error = i915_drm_freeze(drm_dev);
        if (error)
                return error;
 
        if (pm_state.event == PM_EVENT_PRETHAW)
                return 0;
 
+       if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
+               return 0;
+
        NV_INFO(dev, "Disabling fbcon acceleration...\n");
        nouveau_fbcon_save_disable_accel(dev);
 
        struct drm_crtc *crtc;
        int ret, i;
 
+       if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
+               return 0;
+
        nouveau_fbcon_save_disable_accel(dev);
 
        NV_INFO(dev, "We're back, enabling device...\n");
 
 
        struct nouveau_fbdev *nfbdev;
        struct apertures_struct *apertures;
+
+       bool powered_down;
 };
 
 static inline struct drm_nouveau_private *
 
        pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
        if (state == VGA_SWITCHEROO_ON) {
                printk(KERN_ERR "VGA switcheroo: switched nouveau on\n");
+               dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
                nouveau_pci_resume(pdev);
                drm_kms_helper_poll_enable(dev);
+               dev->switch_power_state = DRM_SWITCH_POWER_ON;
        } else {
                printk(KERN_ERR "VGA switcheroo: switched nouveau off\n");
+               dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
                drm_kms_helper_poll_disable(dev);
                nouveau_pci_suspend(pdev, pmm);
+               dev->switch_power_state = DRM_SWITCH_POWER_OFF;
        }
 }
 
 
        uint8_t                 audio_status_bits;
        uint8_t                 audio_category_code;
 
-       bool powered_down;
        struct notifier_block acpi_nb;
        /* only one userspace can use Hyperz features at a time */
        struct drm_file *hyperz_filp;
 
 static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state)
 {
        struct drm_device *dev = pci_get_drvdata(pdev);
-       struct radeon_device *rdev = dev->dev_private;
        pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
        if (state == VGA_SWITCHEROO_ON) {
                printk(KERN_INFO "radeon: switched on\n");
                /* don't suspend or resume card normally */
-               rdev->powered_down = false;
+               dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
                radeon_resume_kms(dev);
+               dev->switch_power_state = DRM_SWITCH_POWER_ON;
                drm_kms_helper_poll_enable(dev);
        } else {
                printk(KERN_INFO "radeon: switched off\n");
                drm_kms_helper_poll_disable(dev);
+               dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
                radeon_suspend_kms(dev, pmm);
-               /* don't suspend or resume card normally */
-               rdev->powered_down = true;
+               dev->switch_power_state = DRM_SWITCH_POWER_OFF;
        }
 }
 
        }
        rdev = dev->dev_private;
 
-       if (rdev->powered_down)
+       if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
                return 0;
 
        /* turn off display hw */
        struct drm_connector *connector;
        struct radeon_device *rdev = dev->dev_private;
 
-       if (rdev->powered_down)
+       if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
                return 0;
 
        acquire_console_sem();
 
  */
 int radeon_driver_firstopen_kms(struct drm_device *dev)
 {
-       struct radeon_device *rdev = dev->dev_private;
-
-       if (rdev->powered_down)
-               return -EINVAL;
        return 0;
 }
 
 
        spinlock_t object_name_lock;
        struct idr object_name_idr;
        /*@} */
-
+       int switch_power_state;
 };
 
+#define DRM_SWITCH_POWER_ON 0
+#define DRM_SWITCH_POWER_OFF 1
+#define DRM_SWITCH_POWER_CHANGING 2
+
 static __inline__ int drm_core_check_feature(struct drm_device *dev,
                                             int feature)
 {