*/
 void drm_framebuffer_unreference(struct drm_framebuffer *fb)
 {
-       struct drm_device *dev = fb->dev;
        DRM_DEBUG("FB ID: %d\n", fb->base.id);
-       WARN_ON(!drm_modeset_is_locked(dev));
        kref_put(&fb->refcount, drm_framebuffer_free);
 }
 EXPORT_SYMBOL(drm_framebuffer_unreference);
 
 {
        struct psb_framebuffer *psbfb = to_psb_fb(fb);
        struct gtt_range *r = psbfb->gtt;
-       struct drm_device *dev = fb->dev;
-       struct drm_psb_private *dev_priv = dev->dev_private;
-       struct psb_fbdev *fbdev = dev_priv->fbdev;
-       struct drm_crtc *crtc;
-       int reset = 0;
-
-       /* Should never get stolen memory for a user fb */
-       WARN_ON(r->stolen);
-
-       /* Check if we are erroneously live */
-       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
-               if (crtc->fb == fb)
-                       reset = 1;
-
-       if (reset)
-               /*
-                * Now force a sane response before we permit the DRM CRTC
-                * layer to do stupid things like blank the display. Instead
-                * we reset this framebuffer as if the user had forced a reset.
-                * We must do this before the cleanup so that the DRM layer
-                * doesn't get a chance to stick its oar in where it isn't
-                * wanted.
-                */
-               drm_fb_helper_restore_fbdev_mode(&fbdev->psb_fb_helper);
 
        /* Let DRM do its clean up */
        drm_framebuffer_cleanup(fb);
 
 
 static void psb_lastclose(struct drm_device *dev)
 {
+       int ret;
+       struct drm_psb_private *dev_priv = dev->dev_private;
+       struct psb_fbdev *fbdev = dev_priv->fbdev;
+
+       mutex_lock(&dev->mode_config.mutex);
+       ret = drm_fb_helper_restore_fbdev_mode(&fbdev->psb_fb_helper);
+       if (ret)
+               DRM_DEBUG("failed to restore crtc mode\n");
+       mutex_unlock(&dev->mode_config.mutex);
+
        return;
 }