|  | /* kernel/power/consoleearlysuspend.c | 
|  | * | 
|  | * Copyright (C) 2005-2008 Google, Inc. | 
|  | * | 
|  | * This software is licensed under the terms of the GNU General Public | 
|  | * License version 2, as published by the Free Software Foundation, and | 
|  | * may be copied, distributed, and modified under those terms. | 
|  | * | 
|  | * This program is distributed in the hope that it will be useful, | 
|  | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | * GNU General Public License for more details. | 
|  | * | 
|  | */ | 
|  |  | 
|  | #include <linux/console.h> | 
|  | #include <linux/earlysuspend.h> | 
|  | #include <linux/kbd_kern.h> | 
|  | #include <linux/module.h> | 
|  | #include <linux/vt_kern.h> | 
|  | #include <linux/wait.h> | 
|  |  | 
|  | #define EARLY_SUSPEND_CONSOLE	(MAX_NR_CONSOLES-1) | 
|  |  | 
|  | static int orig_fgconsole; | 
|  | static void console_early_suspend(struct early_suspend *h) | 
|  | { | 
|  | acquire_console_sem(); | 
|  | orig_fgconsole = fg_console; | 
|  | if (vc_allocate(EARLY_SUSPEND_CONSOLE)) | 
|  | goto err; | 
|  | if (set_console(EARLY_SUSPEND_CONSOLE)) | 
|  | goto err; | 
|  | release_console_sem(); | 
|  |  | 
|  | if (vt_waitactive(EARLY_SUSPEND_CONSOLE + 1)) | 
|  | pr_warning("console_early_suspend: Can't switch VCs.\n"); | 
|  | return; | 
|  | err: | 
|  | pr_warning("console_early_suspend: Can't set console\n"); | 
|  | release_console_sem(); | 
|  | } | 
|  |  | 
|  | static void console_late_resume(struct early_suspend *h) | 
|  | { | 
|  | int ret; | 
|  | acquire_console_sem(); | 
|  | ret = set_console(orig_fgconsole); | 
|  | release_console_sem(); | 
|  | if (ret) { | 
|  | pr_warning("console_late_resume: Can't set console.\n"); | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (vt_waitactive(orig_fgconsole + 1)) | 
|  | pr_warning("console_late_resume: Can't switch VCs.\n"); | 
|  | } | 
|  |  | 
|  | static struct early_suspend console_early_suspend_desc = { | 
|  | .level = EARLY_SUSPEND_LEVEL_STOP_DRAWING, | 
|  | .suspend = console_early_suspend, | 
|  | .resume = console_late_resume, | 
|  | }; | 
|  |  | 
|  | static int __init console_early_suspend_init(void) | 
|  | { | 
|  | register_early_suspend(&console_early_suspend_desc); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static void  __exit console_early_suspend_exit(void) | 
|  | { | 
|  | unregister_early_suspend(&console_early_suspend_desc); | 
|  | } | 
|  |  | 
|  | module_init(console_early_suspend_init); | 
|  | module_exit(console_early_suspend_exit); | 
|  |  |