fbcon: Clean up fbcon data in fb_info on FB_EVENT_FB_UNBIND with 0 fbs
[sfrench/cifs-2.6.git] / drivers / video / console / fbcon.c
index 4e39291ac8b47212431d6990b180b65bb622e5dc..f447734b09b48a11edff75b19f46999709233096 100644 (file)
@@ -759,7 +759,7 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo,
                  newinfo in an undefined state. Thus, a call to
                  fb_set_par() may be needed for the newinfo.
                */
-               if (newinfo->fbops->fb_set_par) {
+               if (newinfo && newinfo->fbops->fb_set_par) {
                        ret = newinfo->fbops->fb_set_par(newinfo);
 
                        if (ret)
@@ -3028,8 +3028,31 @@ static int fbcon_fb_unbind(int idx)
                        if (con2fb_map[i] == idx)
                                set_con2fb_map(i, new_idx, 0);
                }
-       } else
+       } else {
+               struct fb_info *info = registered_fb[idx];
+
+               /* This is sort of like set_con2fb_map, except it maps
+                * the consoles to no device and then releases the
+                * oldinfo to free memory and cancel the cursor blink
+                * timer. I can imagine this just becoming part of
+                * set_con2fb_map where new_idx is -1
+                */
+               for (i = first_fb_vc; i <= last_fb_vc; i++) {
+                       if (con2fb_map[i] == idx) {
+                               con2fb_map[i] = -1;
+                               if (!search_fb_in_map(idx)) {
+                                       ret = con2fb_release_oldinfo(vc_cons[i].d,
+                                                                    info, NULL, i,
+                                                                    idx, 0);
+                                       if (ret) {
+                                               con2fb_map[i] = idx;
+                                               return ret;
+                                       }
+                               }
+                       }
+               }
                ret = fbcon_unbind();
+       }
 
        return ret;
 }