tty: Power: fix suspend vt regression
[safe/jmp/linux-2.6] / drivers / char / vt.c
index a5af607..0c80c68 100644 (file)
 #include <linux/mutex.h>
 #include <linux/vt_kern.h>
 #include <linux/selection.h>
+#include <linux/smp_lock.h>
 #include <linux/tiocl.h>
 #include <linux/kbd_kern.h>
 #include <linux/consolemap.h>
 #include <linux/timer.h>
 #include <linux/interrupt.h>
 #include <linux/workqueue.h>
-#include <linux/bootmem.h>
 #include <linux/pm.h>
 #include <linux/font.h>
 #include <linux/bitops.h>
@@ -172,8 +172,9 @@ int do_poke_blanked_console;
 int console_blanked;
 
 static int vesa_blank_mode; /* 0:none 1:suspendV 2:suspendH 3:powerdown */
-static int blankinterval = 10*60*HZ;
 static int vesa_off_interval;
+static int blankinterval = 10*60;
+core_param(consoleblank, blankinterval, int, 0444);
 
 static DECLARE_WORK(console_work, console_callback);
 
@@ -251,7 +252,6 @@ static void notify_update(struct vc_data *vc)
        struct vt_notifier_param param = { .vc = vc };
        atomic_notifier_call_chain(&vt_notifier_list, VT_UPDATE, &param);
 }
-
 /*
  *     Low-Level Functions
  */
@@ -769,15 +769,14 @@ int vc_allocate(unsigned int currcons)    /* return 0 on success */
            visual_init(vc, currcons, 1);
            if (!*vc->vc_uni_pagedir_loc)
                con_set_default_unimap(vc);
-           if (!vc->vc_kmalloced)
-               vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL);
+           vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL);
            if (!vc->vc_screenbuf) {
                kfree(vc);
                vc_cons[currcons].d = NULL;
                return -ENOMEM;
            }
-           vc->vc_kmalloced = 1;
            vc_init(vc, vc->vc_rows, vc->vc_cols, 1);
+           vcs_make_sysfs(currcons);
            atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, &param);
        }
        return 0;
@@ -819,8 +818,8 @@ static inline int resize_screen(struct vc_data *vc, int width, int height,
  *     ctrl_lock of the tty IFF a tty is passed.
  */
 
-static int vc_do_resize(struct tty_struct *tty, struct tty_struct *real_tty,
-               struct vc_data *vc, unsigned int cols, unsigned int lines)
+static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
+                               unsigned int cols, unsigned int lines)
 {
        unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0;
        unsigned int old_cols, old_rows, old_row_size, old_screen_size;
@@ -911,10 +910,8 @@ static int vc_do_resize(struct tty_struct *tty, struct tty_struct *real_tty,
        if (new_scr_end > new_origin)
                scr_memsetw((void *)new_origin, vc->vc_video_erase_char,
                            new_scr_end - new_origin);
-       if (vc->vc_kmalloced)
-               kfree(vc->vc_screenbuf);
+       kfree(vc->vc_screenbuf);
        vc->vc_screenbuf = newscreen;
-       vc->vc_kmalloced = 1;
        vc->vc_screenbuf_size = new_screen_size;
        set_origin(vc);
 
@@ -932,11 +929,12 @@ static int vc_do_resize(struct tty_struct *tty, struct tty_struct *real_tty,
                ws.ws_row = vc->vc_rows;
                ws.ws_col = vc->vc_cols;
                ws.ws_ypixel = vc->vc_scan_lines;
-               tty_do_resize(tty, real_tty, &ws);
+               tty_do_resize(tty, &ws);
        }
 
        if (CON_IS_VISIBLE(vc))
                update_screen(vc);
+       vt_event_post(VT_EVENT_RESIZE, vc->vc_num, vc->vc_num);
        return err;
 }
 
@@ -954,13 +952,12 @@ static int vc_do_resize(struct tty_struct *tty, struct tty_struct *real_tty,
 
 int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int rows)
 {
-       return vc_do_resize(vc->vc_tty, vc->vc_tty, vc, cols, rows);
+       return vc_do_resize(vc->vc_tty, vc, cols, rows);
 }
 
 /**
  *     vt_resize               -       resize a VT
  *     @tty: tty to resize
- *     @real_tty: tty if a pty/tty pair
  *     @ws: winsize attributes
  *
  *     Resize a virtual terminal. This is called by the tty layer as we
@@ -970,15 +967,13 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int rows)
  *     Takes the console sem and the called methods then take the tty
  *     termios_mutex and the tty ctrl_lock in that order.
  */
-
-int vt_resize(struct tty_struct *tty, struct tty_struct *real_tty,
-       struct winsize *ws)
+static int vt_resize(struct tty_struct *tty, struct winsize *ws)
 {
        struct vc_data *vc = tty->driver_data;
        int ret;
 
        acquire_console_sem();
-       ret = vc_do_resize(tty, real_tty, vc, ws->ws_col, ws->ws_row);
+       ret = vc_do_resize(tty, vc, ws->ws_col, ws->ws_row);
        release_console_sem();
        return ret;
 }
@@ -990,12 +985,13 @@ void vc_deallocate(unsigned int currcons)
        if (vc_cons_allocated(currcons)) {
                struct vc_data *vc = vc_cons[currcons].d;
                struct vt_notifier_param param = { .vc = vc };
+
                atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, &param);
+               vcs_remove_sysfs(currcons);
                vc->vc_sw->con_deinit(vc);
                put_pid(vc->vt_pid);
                module_put(vc->vc_sw->owner);
-               if (vc->vc_kmalloced)
-                       kfree(vc->vc_screenbuf);
+               kfree(vc->vc_screenbuf);
                if (currcons >= MIN_NR_CONSOLES)
                        kfree(vc);
                vc_cons[currcons].d = NULL;
@@ -1486,7 +1482,7 @@ static void setterm_command(struct vc_data *vc)
                        update_attr(vc);
                        break;
                case 9: /* set blanking interval */
-                       blankinterval = ((vc->vc_par[1] < 60) ? vc->vc_par[1] : 60) * 60 * HZ;
+                       blankinterval = ((vc->vc_par[1] < 60) ? vc->vc_par[1] : 60) * 60;
                        poke_blanked_console();
                        break;
                case 10: /* set bell frequency in Hz */
@@ -2133,11 +2129,7 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
        currcons = vc->vc_num;
        if (!vc_cons_allocated(currcons)) {
            /* could this happen? */
-           static int error = 0;
-           if (!error) {
-               error = 1;
-               printk("con_write: tty %d not allocated\n", currcons+1);
-           }
+               printk_once("con_write: tty %d not allocated\n", currcons+1);
            release_console_sem();
            return 0;
        }
@@ -2679,7 +2671,7 @@ static int con_write_room(struct tty_struct *tty)
 {
        if (tty->stopped)
                return 0;
-       return 4096;            /* No limit, really; we're not buffering */
+       return 32768;           /* No limit, really; we're not buffering */
 }
 
 static int con_chars_in_buffer(struct tty_struct *tty)
@@ -2778,7 +2770,6 @@ static int con_open(struct tty_struct *tty, struct file *filp)
                                tty->termios->c_iflag |= IUTF8;
                        else
                                tty->termios->c_iflag &= ~IUTF8;
-                       vcs_make_sysfs(tty);
                        release_console_sem();
                        return ret;
                }
@@ -2798,7 +2789,6 @@ static void con_shutdown(struct tty_struct *tty)
        BUG_ON(vc == NULL);
        acquire_console_sem();
        vc->vc_tty = NULL;
-       vcs_remove_sysfs(tty);
        release_console_sem();
        tty_shutdown(tty);
 }
@@ -2874,18 +2864,14 @@ static int __init con_init(void)
 
        if (blankinterval) {
                blank_state = blank_normal_wait;
-               mod_timer(&console_timer, jiffies + blankinterval);
+               mod_timer(&console_timer, jiffies + (blankinterval * HZ));
        }
 
-       /*
-        * kmalloc is not running yet - we use the bootmem allocator.
-        */
        for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
-               vc_cons[currcons].d = vc = alloc_bootmem(sizeof(struct vc_data));
+               vc_cons[currcons].d = vc = kzalloc(sizeof(struct vc_data), GFP_NOWAIT);
                INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
                visual_init(vc, currcons, 1);
-               vc->vc_screenbuf = (unsigned short *)alloc_bootmem(vc->vc_screenbuf_size);
-               vc->vc_kmalloced = 0;
+               vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT);
                vc_init(vc, vc->vc_rows, vc->vc_cols,
                        currcons || !vc->vc_sw->con_save_screen);
        }
@@ -2920,6 +2906,9 @@ static const struct tty_operations con_ops = {
        .flush_chars = con_flush_chars,
        .chars_in_buffer = con_chars_in_buffer,
        .ioctl = vt_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl = vt_compat_ioctl,
+#endif
        .stop = con_stop,
        .start = con_start,
        .throttle = con_throttle,
@@ -2958,9 +2947,6 @@ int __init vty_init(const struct file_operations *console_fops)
                panic("Couldn't register console driver\n");
        kbd_init();
        console_map_init();
-#ifdef CONFIG_PROM_CONSOLE
-       prom_con_init();
-#endif
 #ifdef CONFIG_MDA_CONSOLE
        mda_console_init();
 #endif
@@ -2968,7 +2954,6 @@ int __init vty_init(const struct file_operations *console_fops)
 }
 
 #ifndef VT_SINGLE_DRIVER
-#include <linux/device.h>
 
 static struct class *vtconsole_class;
 
@@ -3651,6 +3636,7 @@ void do_blank_screen(int entering_gfx)
                blank_state = blank_vesa_wait;
                mod_timer(&console_timer, jiffies + vesa_off_interval);
        }
+       vt_event_post(VT_EVENT_BLANK, vc->vc_num, vc->vc_num);
 }
 EXPORT_SYMBOL(do_blank_screen);
 
@@ -3683,7 +3669,7 @@ void do_unblank_screen(int leaving_gfx)
                return; /* but leave console_blanked != 0 */
 
        if (blankinterval) {
-               mod_timer(&console_timer, jiffies + blankinterval);
+               mod_timer(&console_timer, jiffies + (blankinterval * HZ));
                blank_state = blank_normal_wait;
        }
 
@@ -3695,6 +3681,7 @@ void do_unblank_screen(int leaving_gfx)
                console_blank_hook(0);
        set_palette(vc);
        set_cursor(vc);
+       vt_event_post(VT_EVENT_UNBLANK, vc->vc_num, vc->vc_num);
 }
 EXPORT_SYMBOL(do_unblank_screen);
 
@@ -3717,7 +3704,7 @@ void unblank_screen(void)
 static void blank_screen_t(unsigned long dummy)
 {
        if (unlikely(!keventd_up())) {
-               mod_timer(&console_timer, jiffies + blankinterval);
+               mod_timer(&console_timer, jiffies + (blankinterval * HZ));
                return;
        }
        blank_timer_expired = 1;
@@ -3747,7 +3734,7 @@ void poke_blanked_console(void)
        if (console_blanked)
                unblank_screen();
        else if (blankinterval) {
-               mod_timer(&console_timer, jiffies + blankinterval);
+               mod_timer(&console_timer, jiffies + (blankinterval * HZ));
                blank_state = blank_normal_wait;
        }
 }