Commit 8f4ce8c3 authored by Andres Salomon's avatar Andres Salomon Committed by Linus Torvalds

serial: turn serial console suspend a boot rather than compile time option

Currently, there's a CONFIG_DISABLE_CONSOLE_SUSPEND that allows one to stop
the serial console from being suspended when the rest of the machine goes
to sleep.  This is incredibly useful for debugging power management-related
things; however, having it as a compile-time option has proved to be
incredibly inconvenient for us (OLPC).  There are plenty of times that we
want serial console to not suspend, but for the most part we'd like serial
console to be suspended.

This drops CONFIG_DISABLE_CONSOLE_SUSPEND, and replaces it with a kernel
boot parameter (no_console_suspend).  By default, the serial console will
be suspended along with the rest of the system; by passing
'no_console_suspend' to the kernel during boot, serial console will remain
alive during suspend.

For now, this is pretty serial console specific; further fixes could be
applied to make this work for things like netconsole.
Signed-off-by: default avatarAndres Salomon <dilinger@debian.org>
Acked-by: default avatar"Rafael J. Wysocki" <rjw@sisk.pl>
Acked-by: default avatarPavel Machek <pavel@ucw.cz>
Cc: Nigel Cunningham <nigel@suspend2.net>
Cc: Russell King <rmk@arm.linux.org.uk>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 438e2ce6
...@@ -479,6 +479,16 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -479,6 +479,16 @@ and is between 256 and 4096 characters. It is defined in the file
UART at the specified I/O port or MMIO address. UART at the specified I/O port or MMIO address.
The options are the same as for ttyS, above. The options are the same as for ttyS, above.
no_console_suspend
[HW] Never suspend the console
Disable suspending of consoles during suspend and
hibernate operations. Once disabled, debugging
messages can reach various consoles while the rest
of the system is being put to sleep (ie, while
debugging driver suspend/resume hooks). This may
not work reliably with all consoles, but is known
to work with serial and VGA consoles.
cpcihp_generic= [HW,PCI] Generic port I/O CompactPCI driver cpcihp_generic= [HW,PCI] Generic port I/O CompactPCI driver
Format: Format:
<first_slot>,<last_slot>,<port>,<enum_bit>[,<debug>] <first_slot>,<last_slot>,<port>,<enum_bit>[,<debug>]
......
...@@ -78,8 +78,8 @@ c) Advanced debugging ...@@ -78,8 +78,8 @@ c) Advanced debugging
In case the STD does not work on your system even in the minimal configuration In case the STD does not work on your system even in the minimal configuration
and compiling more drivers as modules is not practical or some modules cannot and compiling more drivers as modules is not practical or some modules cannot
be unloaded, you can use one of the more advanced debugging techniques to find be unloaded, you can use one of the more advanced debugging techniques to find
the problem. First, if there is a serial port in your box, you can set the the problem. First, if there is a serial port in your box, you can boot the
CONFIG_DISABLE_CONSOLE_SUSPEND kernel configuration option and try to log kernel kernel with the 'no_console_suspend' parameter and try to log kernel
messages using the serial console. This may provide you with some information messages using the serial console. This may provide you with some information
about the reasons of the suspend (resume) failure. Alternatively, it may be about the reasons of the suspend (resume) failure. Alternatively, it may be
possible to use a FireWire port for debugging with firescope possible to use a FireWire port for debugging with firescope
......
...@@ -209,7 +209,6 @@ CONFIG_PM=y ...@@ -209,7 +209,6 @@ CONFIG_PM=y
# CONFIG_PM_LEGACY is not set # CONFIG_PM_LEGACY is not set
CONFIG_PM_DEBUG=y CONFIG_PM_DEBUG=y
# CONFIG_PM_VERBOSE is not set # CONFIG_PM_VERBOSE is not set
# CONFIG_DISABLE_CONSOLE_SUSPEND is not set
CONFIG_PM_SLEEP=y CONFIG_PM_SLEEP=y
CONFIG_SUSPEND=y CONFIG_SUSPEND=y
CONFIG_HIBERNATION=y CONFIG_HIBERNATION=y
......
...@@ -1959,12 +1959,11 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port) ...@@ -1959,12 +1959,11 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
mutex_lock(&state->mutex); mutex_lock(&state->mutex);
#ifdef CONFIG_DISABLE_CONSOLE_SUSPEND if (!console_suspend_enabled && uart_console(port)) {
if (uart_console(port)) { /* we're going to avoid suspending serial console */
mutex_unlock(&state->mutex); mutex_unlock(&state->mutex);
return 0; return 0;
} }
#endif
tty_dev = device_find_child(port->dev, &match, serial_match_port); tty_dev = device_find_child(port->dev, &match, serial_match_port);
if (device_may_wakeup(tty_dev)) { if (device_may_wakeup(tty_dev)) {
...@@ -2016,12 +2015,11 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port) ...@@ -2016,12 +2015,11 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
mutex_lock(&state->mutex); mutex_lock(&state->mutex);
#ifdef CONFIG_DISABLE_CONSOLE_SUSPEND if (!console_suspend_enabled && uart_console(port)) {
if (uart_console(port)) { /* no need to resume serial console, it wasn't suspended */
mutex_unlock(&state->mutex); mutex_unlock(&state->mutex);
return 0; return 0;
} }
#endif
if (!port->suspended) { if (!port->suspended) {
disable_irq_wake(port->irq); disable_irq_wake(port->irq);
......
...@@ -122,14 +122,11 @@ extern void console_stop(struct console *); ...@@ -122,14 +122,11 @@ extern void console_stop(struct console *);
extern void console_start(struct console *); extern void console_start(struct console *);
extern int is_console_locked(void); extern int is_console_locked(void);
#ifndef CONFIG_DISABLE_CONSOLE_SUSPEND extern int console_suspend_enabled;
/* Suspend and resume console messages over PM events */ /* Suspend and resume console messages over PM events */
extern void suspend_console(void); extern void suspend_console(void);
extern void resume_console(void); extern void resume_console(void);
#else
static inline void suspend_console(void) {}
static inline void resume_console(void) {}
#endif /* CONFIG_DISABLE_CONSOLE_SUSPEND */
int mda_console_init(void); int mda_console_init(void);
void prom_con_init(void); void prom_con_init(void);
......
...@@ -44,17 +44,6 @@ config PM_VERBOSE ...@@ -44,17 +44,6 @@ config PM_VERBOSE
---help--- ---help---
This option enables verbose messages from the Power Management code. This option enables verbose messages from the Power Management code.
config DISABLE_CONSOLE_SUSPEND
bool "Keep console(s) enabled during suspend/resume (DANGEROUS)"
depends on PM_DEBUG && PM_SLEEP
default n
---help---
This option turns off the console suspend mechanism that prevents
debug messages from reaching the console during the suspend/resume
operations. This may be helpful when debugging device drivers'
suspend/resume routines, but may itself lead to problems, for example
if netconsole is used.
config PM_TRACE config PM_TRACE
bool "Suspend/resume event tracing" bool "Suspend/resume event tracing"
depends on PM_DEBUG && X86 && PM_SLEEP && EXPERIMENTAL depends on PM_DEBUG && X86 && PM_SLEEP && EXPERIMENTAL
......
...@@ -862,7 +862,16 @@ int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, cha ...@@ -862,7 +862,16 @@ int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, cha
return -1; return -1;
} }
#ifndef CONFIG_DISABLE_CONSOLE_SUSPEND int console_suspend_enabled = 1;
EXPORT_SYMBOL(console_suspend_enabled);
static int __init console_suspend_disable(char *str)
{
console_suspend_enabled = 0;
return 1;
}
__setup("no_console_suspend", console_suspend_disable);
/** /**
* suspend_console - suspend the console subsystem * suspend_console - suspend the console subsystem
* *
...@@ -870,6 +879,8 @@ int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, cha ...@@ -870,6 +879,8 @@ int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, cha
*/ */
void suspend_console(void) void suspend_console(void)
{ {
if (!console_suspend_enabled)
return;
printk("Suspending console(s)\n"); printk("Suspending console(s)\n");
acquire_console_sem(); acquire_console_sem();
console_suspended = 1; console_suspended = 1;
...@@ -877,10 +888,11 @@ void suspend_console(void) ...@@ -877,10 +888,11 @@ void suspend_console(void)
void resume_console(void) void resume_console(void)
{ {
if (!console_suspend_enabled)
return;
console_suspended = 0; console_suspended = 0;
release_console_sem(); release_console_sem();
} }
#endif /* CONFIG_DISABLE_CONSOLE_SUSPEND */
/** /**
* acquire_console_sem - lock the console system for exclusive use. * acquire_console_sem - lock the console system for exclusive use.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment