drm/i915: restore only the mode of this driver on lastclose (v2)
[linux-flexiantxendom0-natty.git] / drivers / gpu / drm / drm_fb_helper.c
index 8208e19..efe756e 100644 (file)
@@ -289,8 +289,7 @@ int drm_fb_helper_debug_enter(struct fb_info *info)
                                                    mode_set->fb,
                                                    mode_set->x,
                                                    mode_set->y,
-                                                   1);
-
+                                                   ENTER_ATOMIC_MODE_SET);
                }
        }
 
@@ -336,16 +335,29 @@ int drm_fb_helper_debug_leave(struct fb_info *info)
 
                drm_fb_helper_restore_lut_atomic(mode_set->crtc);
                funcs->mode_set_base_atomic(mode_set->crtc, fb, crtc->x,
-                                           crtc->y, 0);
+                                           crtc->y, LEAVE_ATOMIC_MODE_SET);
        }
 
        return 0;
 }
 EXPORT_SYMBOL(drm_fb_helper_debug_leave);
 
+bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper)
+{
+       bool error = false;
+       int i, ret;
+       for (i = 0; i < fb_helper->crtc_count; i++) {
+               struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set;
+               ret = drm_crtc_helper_set_config(mode_set);
+               if (ret)
+                       error = true;
+       }
+       return error;
+}
+EXPORT_SYMBOL(drm_fb_helper_restore_fbdev_mode);
+
 bool drm_fb_helper_force_kernel_mode(void)
 {
-       int i = 0;
        bool ret, error = false;
        struct drm_fb_helper *helper;
 
@@ -353,12 +365,12 @@ bool drm_fb_helper_force_kernel_mode(void)
                return false;
 
        list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) {
-               for (i = 0; i < helper->crtc_count; i++) {
-                       struct drm_mode_set *mode_set = &helper->crtc_info[i].mode_set;
-                       ret = drm_crtc_helper_set_config(mode_set);
-                       if (ret)
-                               error = true;
-               }
+               if (helper->dev->switch_power_state == DRM_SWITCH_POWER_OFF)
+                       continue;
+
+               ret = drm_fb_helper_restore_fbdev_mode(helper);
+               if (ret)
+                       error = true;
        }
        return error;
 }
@@ -673,7 +685,7 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info)
        struct drm_crtc_helper_funcs *crtc_funcs;
        u16 *red, *green, *blue, *transp;
        struct drm_crtc *crtc;
-       int i, rc = 0;
+       int i, j, rc = 0;
        int start;
 
        for (i = 0; i < fb_helper->crtc_count; i++) {
@@ -686,7 +698,7 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info)
                transp = cmap->transp;
                start = cmap->start;
 
-               for (i = 0; i < cmap->len; i++) {
+               for (j = 0; j < cmap->len; j++) {
                        u16 hred, hgreen, hblue, htransp = 0xffff;
 
                        hred = *red++;
@@ -986,6 +998,8 @@ void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
        info->fix.type = FB_TYPE_PACKED_PIXELS;
        info->fix.visual = depth == 8 ? FB_VISUAL_PSEUDOCOLOR :
                FB_VISUAL_TRUECOLOR;
+       info->fix.mmio_start = 0;
+       info->fix.mmio_len = 0;
        info->fix.type_aux = 0;
        info->fix.xpanstep = 1; /* doing it in hw */
        info->fix.ypanstep = 1; /* doing it in hw */
@@ -1006,6 +1020,7 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helpe
        info->var.xres_virtual = fb->width;
        info->var.yres_virtual = fb->height;
        info->var.bits_per_pixel = fb->bits_per_pixel;
+       info->var.accel_flags = FB_ACCELF_TEXT;
        info->var.xoffset = 0;
        info->var.yoffset = 0;
        info->var.activate = FB_ACTIVATE_NOW;
@@ -1531,3 +1546,24 @@ bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
 }
 EXPORT_SYMBOL(drm_fb_helper_hotplug_event);
 
+/* The Kconfig DRM_KMS_HELPER selects FRAMEBUFFER_CONSOLE (if !EXPERT)
+ * but the module doesn't depend on any fb console symbols.  At least
+ * attempt to load fbcon to avoid leaving the system without a usable console.
+ */
+#if defined(CONFIG_FRAMEBUFFER_CONSOLE_MODULE) && !defined(CONFIG_EXPERT)
+static int __init drm_fb_helper_modinit(void)
+{
+       const char *name = "fbcon";
+       struct module *fbcon;
+
+       mutex_lock(&module_mutex);
+       fbcon = find_module(name);
+       mutex_unlock(&module_mutex);
+
+       if (!fbcon)
+               request_module_nowait(name);
+       return 0;
+}
+
+module_init(drm_fb_helper_modinit);
+#endif