diff options
-rw-r--r-- | drivers/char/vt_ioctl.c | 56 | ||||
-rw-r--r-- | include/linux/vt_kern.h | 1 | ||||
-rw-r--r-- | kernel/power/console.c | 63 |
3 files changed, 62 insertions, 58 deletions
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 35ad94e65d0d..d29fbd44bdca 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/tty.h> | 16 | #include <linux/tty.h> |
17 | #include <linux/timer.h> | 17 | #include <linux/timer.h> |
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/module.h> | ||
19 | #include <linux/kd.h> | 20 | #include <linux/kd.h> |
20 | #include <linux/vt.h> | 21 | #include <linux/vt.h> |
21 | #include <linux/string.h> | 22 | #include <linux/string.h> |
@@ -1483,3 +1484,58 @@ void change_console(struct vc_data *new_vc) | |||
1483 | 1484 | ||
1484 | complete_change_console(new_vc); | 1485 | complete_change_console(new_vc); |
1485 | } | 1486 | } |
1487 | |||
1488 | /* Perform a kernel triggered VT switch for suspend/resume */ | ||
1489 | |||
1490 | static int disable_vt_switch; | ||
1491 | |||
1492 | int vt_move_to_console(unsigned int vt, int alloc) | ||
1493 | { | ||
1494 | int prev; | ||
1495 | |||
1496 | acquire_console_sem(); | ||
1497 | /* Graphics mode - up to X */ | ||
1498 | if (disable_vt_switch) { | ||
1499 | release_console_sem(); | ||
1500 | return 0; | ||
1501 | } | ||
1502 | prev = fg_console; | ||
1503 | |||
1504 | if (alloc && vc_allocate(vt)) { | ||
1505 | /* we can't have a free VC for now. Too bad, | ||
1506 | * we don't want to mess the screen for now. */ | ||
1507 | release_console_sem(); | ||
1508 | return -ENOSPC; | ||
1509 | } | ||
1510 | |||
1511 | if (set_console(vt)) { | ||
1512 | /* | ||
1513 | * We're unable to switch to the SUSPEND_CONSOLE. | ||
1514 | * Let the calling function know so it can decide | ||
1515 | * what to do. | ||
1516 | */ | ||
1517 | release_console_sem(); | ||
1518 | return -EIO; | ||
1519 | } | ||
1520 | release_console_sem(); | ||
1521 | if (vt_waitactive(vt)) { | ||
1522 | pr_debug("Suspend: Can't switch VCs."); | ||
1523 | return -EINTR; | ||
1524 | } | ||
1525 | return prev; | ||
1526 | } | ||
1527 | |||
1528 | /* | ||
1529 | * Normally during a suspend, we allocate a new console and switch to it. | ||
1530 | * When we resume, we switch back to the original console. This switch | ||
1531 | * can be slow, so on systems where the framebuffer can handle restoration | ||
1532 | * of video registers anyways, there's little point in doing the console | ||
1533 | * switch. This function allows you to disable it by passing it '0'. | ||
1534 | */ | ||
1535 | void pm_set_vt_switch(int do_switch) | ||
1536 | { | ||
1537 | acquire_console_sem(); | ||
1538 | disable_vt_switch = !do_switch; | ||
1539 | release_console_sem(); | ||
1540 | } | ||
1541 | EXPORT_SYMBOL(pm_set_vt_switch); | ||
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h index f8c797d57c8b..5b53efe41b5c 100644 --- a/include/linux/vt_kern.h +++ b/include/linux/vt_kern.h | |||
@@ -117,4 +117,5 @@ struct vt_spawn_console { | |||
117 | }; | 117 | }; |
118 | extern struct vt_spawn_console vt_spawn_con; | 118 | extern struct vt_spawn_console vt_spawn_con; |
119 | 119 | ||
120 | extern int vt_move_to_console(unsigned int vt, int alloc); | ||
120 | #endif /* _VT_KERN_H */ | 121 | #endif /* _VT_KERN_H */ |
diff --git a/kernel/power/console.c b/kernel/power/console.c index a3961b205de7..5187136fe1de 100644 --- a/kernel/power/console.c +++ b/kernel/power/console.c | |||
@@ -14,56 +14,13 @@ | |||
14 | #define SUSPEND_CONSOLE (MAX_NR_CONSOLES-1) | 14 | #define SUSPEND_CONSOLE (MAX_NR_CONSOLES-1) |
15 | 15 | ||
16 | static int orig_fgconsole, orig_kmsg; | 16 | static int orig_fgconsole, orig_kmsg; |
17 | static int disable_vt_switch; | ||
18 | |||
19 | /* | ||
20 | * Normally during a suspend, we allocate a new console and switch to it. | ||
21 | * When we resume, we switch back to the original console. This switch | ||
22 | * can be slow, so on systems where the framebuffer can handle restoration | ||
23 | * of video registers anyways, there's little point in doing the console | ||
24 | * switch. This function allows you to disable it by passing it '0'. | ||
25 | */ | ||
26 | void pm_set_vt_switch(int do_switch) | ||
27 | { | ||
28 | acquire_console_sem(); | ||
29 | disable_vt_switch = !do_switch; | ||
30 | release_console_sem(); | ||
31 | } | ||
32 | EXPORT_SYMBOL(pm_set_vt_switch); | ||
33 | 17 | ||
34 | int pm_prepare_console(void) | 18 | int pm_prepare_console(void) |
35 | { | 19 | { |
36 | acquire_console_sem(); | 20 | orig_fgconsole = vt_move_to_console(SUSPEND_CONSOLE, 1); |
37 | 21 | if (orig_fgconsole < 0) | |
38 | if (disable_vt_switch) { | ||
39 | release_console_sem(); | ||
40 | return 0; | ||
41 | } | ||
42 | |||
43 | orig_fgconsole = fg_console; | ||
44 | |||
45 | if (vc_allocate(SUSPEND_CONSOLE)) { | ||
46 | /* we can't have a free VC for now. Too bad, | ||
47 | * we don't want to mess the screen for now. */ | ||
48 | release_console_sem(); | ||
49 | return 1; | 22 | return 1; |
50 | } | ||
51 | 23 | ||
52 | if (set_console(SUSPEND_CONSOLE)) { | ||
53 | /* | ||
54 | * We're unable to switch to the SUSPEND_CONSOLE. | ||
55 | * Let the calling function know so it can decide | ||
56 | * what to do. | ||
57 | */ | ||
58 | release_console_sem(); | ||
59 | return 1; | ||
60 | } | ||
61 | release_console_sem(); | ||
62 | |||
63 | if (vt_waitactive(SUSPEND_CONSOLE)) { | ||
64 | pr_debug("Suspend: Can't switch VCs."); | ||
65 | return 1; | ||
66 | } | ||
67 | orig_kmsg = kmsg_redirect; | 24 | orig_kmsg = kmsg_redirect; |
68 | kmsg_redirect = SUSPEND_CONSOLE; | 25 | kmsg_redirect = SUSPEND_CONSOLE; |
69 | return 0; | 26 | return 0; |
@@ -71,19 +28,9 @@ int pm_prepare_console(void) | |||
71 | 28 | ||
72 | void pm_restore_console(void) | 29 | void pm_restore_console(void) |
73 | { | 30 | { |
74 | acquire_console_sem(); | 31 | if (orig_fgconsole >= 0) { |
75 | if (disable_vt_switch) { | 32 | vt_move_to_console(orig_fgconsole, 0); |
76 | release_console_sem(); | 33 | kmsg_redirect = orig_kmsg; |
77 | return; | ||
78 | } | ||
79 | set_console(orig_fgconsole); | ||
80 | release_console_sem(); | ||
81 | |||
82 | if (vt_waitactive(orig_fgconsole)) { | ||
83 | pr_debug("Resume: Can't switch VCs."); | ||
84 | return; | ||
85 | } | 34 | } |
86 | |||
87 | kmsg_redirect = orig_kmsg; | ||
88 | } | 35 | } |
89 | #endif | 36 | #endif |