int line, int count, int dy);
 static void fbcon_modechanged(struct fb_info *info);
 static void fbcon_set_all_vcs(struct fb_info *info);
-
+static void fbcon_start(void);
+static void fbcon_exit(void);
 static struct class_device *fbcon_class_device;
 
 #ifdef CONFIG_MAC
        int c;
        int mode;
 
-       if (ops->currcon != -1)
+       acquire_console_sem();
+       if (ops && ops->currcon != -1)
                vc = vc_cons[ops->currcon].d;
 
        if (!vc || !CON_IS_VISIBLE(vc) ||
            fbcon_is_inactive(vc, info) ||
            registered_fb[con2fb_map[vc->vc_num]] != info ||
-           vc_cons[ops->currcon].d->vc_deccm != 1)
+           vc_cons[ops->currcon].d->vc_deccm != 1) {
+               release_console_sem();
                return;
-       acquire_console_sem();
+       }
+
        p = &fb_display[vc->vc_num];
        c = scr_readw((u16 *) vc->vc_pos);
        mode = (!ops->cursor_flash || ops->cursor_state.enable) ?
                if (info->fbops->fb_set_par)
                        info->fbops->fb_set_par(info);
 
-               if (old_info != info) {
+               if (old_info != info)
                        fbcon_del_cursor_timer(old_info);
-                       fbcon_add_cursor_timer(info);
-               }
        }
 
+       fbcon_add_cursor_timer(info);
        set_blitting_type(vc, info);
        ops->cursor_reset = 1;
 
                        ret = fbcon_takeover(1);
        } else {
                for (i = 0; i < MAX_NR_CONSOLES; i++) {
-                       if (con2fb_map_boot[i] == idx)
+                       if (con2fb_map_boot[i] == idx &&
+                           con2fb_map[i] == -1)
                                set_con2fb_map(i, idx, 0);
                }
        }
        return snprintf(buf, PAGE_SIZE, "%d\n", rotate);
 }
 
+static ssize_t store_attach(struct class_device *class_device,
+                           const char *buf, size_t count)
+{
+       if (info_idx == -1)
+               fbcon_start();
+
+       return count;
+}
+
+static ssize_t store_detach(struct class_device *class_device,
+                           const char *buf, size_t count)
+{
+       if (info_idx != -1) {
+               fbcon_exit();
+               give_up_console(&fb_con);
+       }
+
+       info_idx = -1;
+       return count;
+}
+
 static struct class_device_attribute class_device_attrs[] = {
        __ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate),
        __ATTR(rotate_all, S_IWUSR, NULL, store_rotate_all),
+       __ATTR(attach, S_IWUSR, NULL, store_attach),
+       __ATTR(detach, S_IWUSR, NULL, store_detach),
 };
 
 static int fbcon_init_class_device(void)
        return 0;
 }
 
-static int __init fb_console_init(void)
+static void fbcon_start(void)
 {
-       int i;
-
-       acquire_console_sem();
-       fb_register_client(&fbcon_event_notifier);
-       release_console_sem();
-
-       fbcon_class_device =
-           class_device_create(fb_class, NULL,
-                               MKDEV(FB_MAJOR, FB_MAX), NULL,
-                               "fbcon");
-       if (IS_ERR(fbcon_class_device)) {
-           printk(KERN_WARNING "Unable to create class_device "
-                  "for fbcon; errno = %ld\n",
-                  PTR_ERR(fbcon_class_device));
-           fbcon_class_device = NULL;
-       } else
-           fbcon_init_class_device();
+       if (num_registered_fb) {
+               int i;
 
-       for (i = 0; i < MAX_NR_CONSOLES; i++)
-               con2fb_map[i] = -1;
+               acquire_console_sem();
 
-       if (num_registered_fb) {
                for (i = 0; i < FB_MAX; i++) {
                        if (registered_fb[i] != NULL) {
                                info_idx = i;
                                break;
                        }
                }
+
+               release_console_sem();
                fbcon_takeover(0);
        }
-
-       return 0;
-}
-
-module_init(fb_console_init);
-
-#ifdef MODULE
-
-static void __exit fbcon_deinit_class_device(void)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
-               class_device_remove_file(fbcon_class_device,
-                                        &class_device_attrs[i]);
 }
 
-static void __exit fbcon_exit(void)
+static void fbcon_exit(void)
 {
        struct fb_info *info;
        int i, j, mapped;
 
-       for (i = 0; i < FB_MAX; i++) {
-               info = registered_fb[i];
-
-               if (info && info->fbcon_par)
-                       fbcon_del_cursor_timer(info);
-       }
-
+       acquire_console_sem();
 #ifdef CONFIG_ATARI
        free_irq(IRQ_AUTO_4, fbcon_vbl_handler);
 #endif
 #endif
 
        kfree((void *)softback_buf);
+       softback_buf = 0UL;
 
        for (i = 0; i < FB_MAX; i++) {
                mapped = 0;
                        if (info->fbops->fb_release)
                                info->fbops->fb_release(info, 0);
                        module_put(info->fbops->owner);
-                       kfree(info->fbcon_par);
-                       info->fbcon_par = NULL;
+
+                       if (info->fbcon_par) {
+                               fbcon_del_cursor_timer(info);
+                               kfree(info->fbcon_par);
+                               info->fbcon_par = NULL;
+                       }
+
+                       if (info->queue.func == fb_flashcursor)
+                               info->queue.func = NULL;
+
                }
        }
 
-       fbcon_deinit_class_device();
-       class_device_destroy(fb_class, MKDEV(FB_MAJOR, FB_MAX));
+       release_console_sem();
+}
+
+static int __init fb_console_init(void)
+{
+       int i;
+
+       acquire_console_sem();
+       fb_register_client(&fbcon_event_notifier);
+       fbcon_class_device =
+           class_device_create(fb_class, NULL,
+                               MKDEV(FB_MAJOR, FB_MAX), NULL,
+                               "fbcon");
+
+       if (IS_ERR(fbcon_class_device)) {
+               printk(KERN_WARNING "Unable to create class_device "
+                      "for fbcon; errno = %ld\n",
+                      PTR_ERR(fbcon_class_device));
+               fbcon_class_device = NULL;
+       } else
+               fbcon_init_class_device();
+
+       for (i = 0; i < MAX_NR_CONSOLES; i++)
+               con2fb_map[i] = -1;
+
+       release_console_sem();
+       fbcon_start();
+       return 0;
+}
+
+module_init(fb_console_init);
+
+#ifdef MODULE
+
+static void fbcon_deinit_class_device(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
+               class_device_remove_file(fbcon_class_device,
+                                        &class_device_attrs[i]);
 }
 
 static void __exit fb_console_exit(void)
 {
        acquire_console_sem();
        fb_unregister_client(&fbcon_event_notifier);
-       fbcon_exit();
+       fbcon_deinit_class_device();
+       class_device_destroy(fb_class, MKDEV(FB_MAJOR, FB_MAX));
        release_console_sem();
-       give_up_console(&fb_con);
 }      
 
 module_exit(fb_console_exit);