aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/power/main.c7
-rw-r--r--kernel/printk.c41
2 files changed, 48 insertions, 0 deletions
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 19122cf6d82..3fdc1f42376 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -132,6 +132,9 @@ static inline int suspend_test(int level) { return 0; }
#endif /* CONFIG_PM_SLEEP */
+int global_inside_suspend;
+EXPORT_SYMBOL(global_inside_suspend);
+
#ifdef CONFIG_SUSPEND
#ifdef CONFIG_PM_TEST_SUSPEND
@@ -322,6 +325,8 @@ int suspend_devices_and_enter(suspend_state_t state)
if (!suspend_ops)
return -ENOSYS;
+ global_inside_suspend = 1;
+
if (suspend_ops->begin) {
error = suspend_ops->begin(state);
if (error)
@@ -365,6 +370,8 @@ int suspend_devices_and_enter(suspend_state_t state)
Close:
if (suspend_ops->end)
suspend_ops->end();
+ global_inside_suspend = 0;
+
return error;
Recover_platform:
diff --git a/kernel/printk.c b/kernel/printk.c
index f492f1583d7..c81ad8638aa 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -32,8 +32,12 @@
#include <linux/security.h>
#include <linux/bootmem.h>
#include <linux/syscalls.h>
+#include <linux/jiffies.h>
+#include <linux/suspend.h>
#include <asm/uaccess.h>
+#include <asm/plat-s3c24xx/neo1973.h>
+#include <asm/arch/gta02.h>
/*
* Architectures can override it:
@@ -67,6 +71,12 @@ int console_printk[4] = {
int oops_in_progress;
EXPORT_SYMBOL(oops_in_progress);
+void (*printk_emergency_debug_spew_init)(void) = NULL;
+EXPORT_SYMBOL(printk_emergency_debug_spew_init);
+
+void (*printk_emergency_debug_spew_send_string)(const char *) = NULL;
+EXPORT_SYMBOL(printk_emergency_debug_spew_send_string);
+
/*
* console_sem protects the console_drivers list, and also
* provides serialisation for access to the entire console
@@ -668,6 +678,37 @@ asmlinkage int vprintk(const char *fmt, va_list args)
printed_len += vscnprintf(printk_buf + printed_len,
sizeof(printk_buf) - printed_len, fmt, args);
+ /* if you're debugging resume, the normal methods can change resume
+ * ordering behaviours because their debugging output is synchronous
+ * (ie, CONFIG_DEBUG_LL). If your problem is an OOPS, this code
+ * will not affect the speed and duration and ordering of resume
+ * actions, but will give you a chance to read the full undumped
+ * syslog AND the OOPS data when it happens
+ *
+ * if you support it, your debug device init can override the exported
+ * emergency_debug_spew_init and emergency_debug_spew_send_string to
+ * usually force polling or bitbanging on your debug console device
+ */
+ if (oops_in_progress && global_inside_suspend &&
+ printk_emergency_debug_spew_init &&
+ printk_emergency_debug_spew_send_string) {
+ unsigned long cur_index;
+ char ch[2];
+
+ if (global_inside_suspend == 1) {
+ (printk_emergency_debug_spew_init)();
+
+ ch[1] = '\0';
+ cur_index = con_start;
+ while (cur_index != log_end) {
+ ch[0] = LOG_BUF(cur_index);
+ (printk_emergency_debug_spew_send_string)(ch);
+ cur_index++;
+ }
+ global_inside_suspend++; /* only once */
+ }
+ (printk_emergency_debug_spew_send_string)(printk_buf);
+ }
/*
* Copy the output into log_buf. If the caller didn't provide