Blame view
kernel/power/console.c
3.46 KB
1da177e4c Linux-2.6.12-rc2 |
1 |
/* |
37cce26b3 PM / VT: Cleanup ... |
2 |
* Functions for saving/restoring console. |
1da177e4c Linux-2.6.12-rc2 |
3 4 5 |
* * Originally from swsusp. */ |
f43f627d2 PM: make VT switc... |
6 |
#include <linux/console.h> |
1da177e4c Linux-2.6.12-rc2 |
7 8 |
#include <linux/vt_kern.h> #include <linux/kbd_kern.h> |
5ada918b8 vt: introduce and... |
9 |
#include <linux/vt.h> |
b6f448e99 PM/gxfb: add hook... |
10 |
#include <linux/module.h> |
1ff6bbfd1 arm, pm, vmpressu... |
11 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
12 |
#include "power.h" |
46cd2f32b [PATCH] Fix build... |
13 |
#define SUSPEND_CONSOLE (MAX_NR_CONSOLES-1) |
1da177e4c Linux-2.6.12-rc2 |
14 |
static int orig_fgconsole, orig_kmsg; |
1da177e4c Linux-2.6.12-rc2 |
15 |
|
f43f627d2 PM: make VT switc... |
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
static DEFINE_MUTEX(vt_switch_mutex); struct pm_vt_switch { struct list_head head; struct device *dev; bool required; }; static LIST_HEAD(pm_vt_switch_list); /** * pm_vt_switch_required - indicate VT switch at suspend requirements * @dev: device * @required: if true, caller needs VT switch at suspend/resume time * * The different console drivers may or may not require VT switches across * suspend/resume, depending on how they handle restoring video state and * what may be running. * * Drivers can indicate support for switchless suspend/resume, which can * save time and flicker, by using this routine and passing 'false' as * the argument. If any loaded driver needs VT switching, or the * no_console_suspend argument has been passed on the command line, VT * switches will occur. */ void pm_vt_switch_required(struct device *dev, bool required) { struct pm_vt_switch *entry, *tmp; mutex_lock(&vt_switch_mutex); list_for_each_entry(tmp, &pm_vt_switch_list, head) { if (tmp->dev == dev) { /* already registered, update requirement */ tmp->required = required; goto out; } } entry = kmalloc(sizeof(*entry), GFP_KERNEL); if (!entry) goto out; entry->required = required; entry->dev = dev; list_add(&entry->head, &pm_vt_switch_list); out: mutex_unlock(&vt_switch_mutex); } EXPORT_SYMBOL(pm_vt_switch_required); /** * pm_vt_switch_unregister - stop tracking a device's VT switching needs * @dev: device * * Remove @dev from the vt switch list. */ void pm_vt_switch_unregister(struct device *dev) { struct pm_vt_switch *tmp; mutex_lock(&vt_switch_mutex); list_for_each_entry(tmp, &pm_vt_switch_list, head) { if (tmp->dev == dev) { list_del(&tmp->head); |
c60685040 PM / sleep: Fix m... |
82 |
kfree(tmp); |
f43f627d2 PM: make VT switc... |
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
break; } } mutex_unlock(&vt_switch_mutex); } EXPORT_SYMBOL(pm_vt_switch_unregister); /* * There are three cases when a VT switch on suspend/resume are required: * 1) no driver has indicated a requirement one way or another, so preserve * the old behavior * 2) console suspend is disabled, we want to see debug messages across * suspend/resume * 3) any registered driver indicates it needs a VT switch * * If none of these conditions is present, meaning we have at least one driver * that doesn't need the switch, and none that do, we can avoid it to make * resume look a little prettier (and suspend too, but that's usually hidden, * e.g. when closing the lid on a laptop). */ static bool pm_vt_switch(void) { struct pm_vt_switch *entry; bool ret = true; mutex_lock(&vt_switch_mutex); if (list_empty(&pm_vt_switch_list)) goto out; if (!console_suspend_enabled) goto out; list_for_each_entry(entry, &pm_vt_switch_list, head) { if (entry->required) goto out; } ret = false; out: mutex_unlock(&vt_switch_mutex); return ret; } |
ca5f2b4c4 PM / sleep: Make ... |
125 |
void pm_prepare_console(void) |
1da177e4c Linux-2.6.12-rc2 |
126 |
{ |
f43f627d2 PM: make VT switc... |
127 |
if (!pm_vt_switch()) |
ca5f2b4c4 PM / sleep: Make ... |
128 |
return; |
f43f627d2 PM: make VT switc... |
129 |
|
8d233558c vt: remove power ... |
130 131 |
orig_fgconsole = vt_move_to_console(SUSPEND_CONSOLE, 1); if (orig_fgconsole < 0) |
ca5f2b4c4 PM / sleep: Make ... |
132 |
return; |
1da177e4c Linux-2.6.12-rc2 |
133 |
|
5ada918b8 vt: introduce and... |
134 |
orig_kmsg = vt_kmsg_redirect(SUSPEND_CONSOLE); |
ca5f2b4c4 PM / sleep: Make ... |
135 |
return; |
1da177e4c Linux-2.6.12-rc2 |
136 137 138 139 |
} void pm_restore_console(void) { |
f43f627d2 PM: make VT switc... |
140 141 |
if (!pm_vt_switch()) return; |
8d233558c vt: remove power ... |
142 143 |
if (orig_fgconsole >= 0) { vt_move_to_console(orig_fgconsole, 0); |
5ada918b8 vt: introduce and... |
144 |
vt_kmsg_redirect(orig_kmsg); |
b090f9fa5 PM: Wait for cons... |
145 |
} |
1da177e4c Linux-2.6.12-rc2 |
146 |
} |