+#ifdef CONFIG_RK_CONSOLE_THREAD\r
+#include <linux/kfifo.h>\r
+#include <linux/kthread.h>\r
+static struct task_struct *console_task;\r
+#define FIFO_SIZE SZ_512K\r
+static DEFINE_KFIFO(fifo, unsigned char, FIFO_SIZE);\r
+static bool console_thread_stop;\r
+\r
+static void console_putc(struct uart_rk_port *up, unsigned int c)\r
+{\r
+ while (!(serial_in(up, UART_USR) & UART_USR_TX_FIFO_NOT_FULL))\r
+ cpu_relax();\r
+ serial_out(up, UART_TX, c);\r
+}\r
+\r
+static void console_flush(struct uart_rk_port *up)\r
+{\r
+ while (!(serial_in(up, UART_USR) & UART_USR_TX_FIFO_EMPTY))\r
+ cpu_relax();\r
+}\r
+\r
+static int console_thread(void *data)\r
+{\r
+ struct uart_rk_port *up = data;\r
+ unsigned char c;\r
+\r
+ while (1) {\r
+ set_current_state(TASK_INTERRUPTIBLE);\r
+ schedule();\r
+ if (kthread_should_stop())\r
+ break;\r
+ set_current_state(TASK_RUNNING);\r
+ while (!console_thread_stop && serial_in(up, UART_SFE) && kfifo_get(&fifo, &c)) {\r
+ console_putc(up, c);\r
+ }\r
+ if (!console_thread_stop)\r
+ console_flush(up);\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+static void console_write(struct console *co, const char *s, unsigned int count)\r
+{\r
+ struct uart_rk_port *up = serial_rk_console_ports[co->index];\r
+ unsigned int fifo_count = FIFO_SIZE;\r
+ unsigned char c, r = '\r';\r
+\r
+ if (console_thread_stop ||\r
+ oops_in_progress ||\r
+ system_state == SYSTEM_HALT ||\r
+ system_state == SYSTEM_POWER_OFF ||\r
+ system_state == SYSTEM_RESTART) {\r
+ if (!console_thread_stop) {\r
+ console_thread_stop = true;\r
+ smp_wmb();\r
+ console_flush(up);\r
+ while (fifo_count-- && kfifo_get(&fifo, &c))\r
+ console_putc(up, c);\r
+ }\r
+ while (count--) {\r
+ if (*s == '\n') {\r
+ console_putc(up, r);\r
+ }\r
+ console_putc(up, *s++);\r
+ }\r
+ console_flush(up);\r
+ } else {\r
+ while (count--) {\r
+ if (*s == '\n') {\r
+ kfifo_put(&fifo, &r);\r
+ }\r
+ kfifo_put(&fifo, s++);\r
+ }\r
+ wake_up_process(console_task);\r
+ }\r
+}\r
+#endif\r
+\r