ARM: rockchip: dump kernel log to uart when panic or reboot/shutdown
author黄涛 <huangtao@rock-chips.com>
Sun, 4 May 2014 08:45:09 +0000 (16:45 +0800)
committer黄涛 <huangtao@rock-chips.com>
Sun, 4 May 2014 08:47:11 +0000 (16:47 +0800)
arch/arm/mach-rockchip/common.c
arch/arm/mach-rockchip/rk_fiq_debugger.c
kernel/printk.c

index e3dce56e33bf78e3addde3f063943150de935051..acd5ee725991878967268036747e7c37ebc337a9 100755 (executable)
@@ -177,9 +177,13 @@ int __init rockchip_pie_init(void)
 #endif
 
 static bool is_panic = false;
+extern void console_disable_suspend(void);
 
 static int panic_event(struct notifier_block *this, unsigned long event, void *ptr)
 {
+#if CONFIG_RK_DEBUG_UART >= 0
+       console_disable_suspend();
+#endif
        is_panic = true;
        return NOTIFY_DONE;
 }
index 951118dfca0ca36f56dd37e229d89ed4839b38c7..1b1cc20f812ed1a1b3b3ca25fd6e8a7378718f91 100644 (file)
@@ -131,7 +131,9 @@ static void debug_flush(struct platform_device *pdev)
 }
 
 #ifdef CONFIG_RK_CONSOLE_THREAD
-static DEFINE_KFIFO(fifo, unsigned char, SZ_64K);
+#define FIFO_SIZE SZ_64K
+static DEFINE_KFIFO(fifo, unsigned char, FIFO_SIZE);
+static bool console_thread_stop;
 
 static int console_thread(void *data)
 {
@@ -146,9 +148,10 @@ static int console_thread(void *data)
                if (kthread_should_stop())
                        break;
                set_current_state(TASK_RUNNING);
-               while (kfifo_get(&fifo, &c))
+               while (!console_thread_stop && kfifo_get(&fifo, &c))
                        debug_putc(pdev, c);
-               debug_flush(pdev);
+               if (!console_thread_stop)
+                       debug_flush(pdev);
        }
 
        return 0;
@@ -156,15 +159,23 @@ static int console_thread(void *data)
 
 static void console_write(struct platform_device *pdev, const char *s, unsigned int count)
 {
+       unsigned int fifo_count = FIFO_SIZE;
        unsigned char c, r = '\r';
-       static bool oops = false;
        struct rk_fiq_debugger *t;
        t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
 
-       if (oops_in_progress || oops) {
-               debug_flush(pdev);
-               while (kfifo_get(&fifo, &c))
-                       debug_putc(pdev, c);
+       if (console_thread_stop ||
+           oops_in_progress ||
+           system_state == SYSTEM_HALT ||
+           system_state == SYSTEM_POWER_OFF ||
+           system_state == SYSTEM_RESTART) {
+               if (!console_thread_stop) {
+                       console_thread_stop = true;
+                       smp_wmb();
+                       debug_flush(pdev);
+                       while (fifo_count-- && kfifo_get(&fifo, &c))
+                               debug_putc(pdev, c);
+               }
                while (count--) {
                        if (*s == '\n') {
                                debug_putc(pdev, r);
@@ -172,17 +183,15 @@ static void console_write(struct platform_device *pdev, const char *s, unsigned
                        debug_putc(pdev, *s++);
                }
                debug_flush(pdev);
-               oops = true;
-               return;
-       }
-
-       while (count--) {
-               if (*s == '\n') {
-                       kfifo_put(&fifo, &r);
+       } else {
+               while (count--) {
+                       if (*s == '\n') {
+                               kfifo_put(&fifo, &r);
+                       }
+                       kfifo_put(&fifo, s++);
                }
-               kfifo_put(&fifo, s++);
+               wake_up_process(t->console_task);
        }
-       wake_up_process(t->console_task);
 }
 #endif
 
index a6b2f1fc21c10f37ca9b0e8675cf4d3b71814002..4a81eb6e44d6331e42f097cf91e0554723d7f28a 100644 (file)
@@ -1722,6 +1722,12 @@ void __init switch_log_buf(char *new_log_buf, unsigned size)
        raw_spin_unlock_irqrestore(&logbuf_lock, flags);
 }
 #endif /* CONFIG_RK_LAST_LOG */
+#if CONFIG_RK_DEBUG_UART >= 0
+void console_disable_suspend(void)
+{
+       console_suspended = 0;
+}
+#endif
 #else /* CONFIG_PRINTK */
 
 #define LOG_LINE_MAX           0