aboutsummaryrefslogtreecommitdiff
path: root/kernel/printk.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/printk.c')
-rw-r--r--kernel/printk.c41
1 files changed, 41 insertions, 0 deletions
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