mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 20:32:04 +09:00
soc: rockchip: rk_fiq_debugger: better console thread print
- Print by message other than by byte. Make messages more readable. - Sleep while block other than busy loop. Reduce cpu usage while print a lot of messages. - Show how many messages dropped. Let people know that the messages are not complete. - Wake up console_task when needed. Reduce unneeded call wake_up_process. Change-Id: I508d2f5b6671695413b01bc167d768ec9b614934 Signed-off-by: Tao Huang <huangtao@rock-chips.com>
This commit is contained in:
@@ -207,26 +207,95 @@ static void debug_flush(struct platform_device *pdev)
|
||||
|
||||
#ifdef CONFIG_RK_CONSOLE_THREAD
|
||||
#define FIFO_SIZE SZ_64K
|
||||
#define LINE_MAX 1024
|
||||
static DEFINE_KFIFO(fifo, unsigned char, FIFO_SIZE);
|
||||
static char console_buf[LINE_MAX]; /* avoid FRAME WARN */
|
||||
static bool console_thread_stop;
|
||||
static unsigned int console_dropped_messages;
|
||||
|
||||
static void console_putc(struct platform_device *pdev, unsigned int c)
|
||||
{
|
||||
struct rk_fiq_debugger *t;
|
||||
unsigned int count = 500;
|
||||
|
||||
t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
|
||||
|
||||
while (!(rk_fiq_read(t, UART_USR) & UART_USR_TX_FIFO_NOT_FULL) &&
|
||||
count--)
|
||||
usleep_range(200, 210);
|
||||
/* If uart is always busy, maybe it is abnormal, reinit it */
|
||||
if ((count == 0) && (rk_fiq_read(t, UART_USR) & UART_USR_BUSY))
|
||||
debug_port_init(pdev);
|
||||
|
||||
rk_fiq_write(t, c, UART_TX);
|
||||
}
|
||||
|
||||
static void console_flush(struct platform_device *pdev)
|
||||
{
|
||||
struct rk_fiq_debugger *t;
|
||||
unsigned int count = 500;
|
||||
|
||||
t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
|
||||
|
||||
while (!(rk_fiq_read_lsr(t) & UART_LSR_TEMT) && count--)
|
||||
usleep_range(200, 210);
|
||||
/* If uart is always busy, maybe it is abnormal, reinit it */
|
||||
if ((count == 0) && (rk_fiq_read(t, UART_USR) & UART_USR_BUSY))
|
||||
debug_port_init(pdev);
|
||||
}
|
||||
|
||||
static void console_put(struct platform_device *pdev,
|
||||
const char *s, unsigned int count)
|
||||
{
|
||||
while (count--) {
|
||||
if (*s == '\n')
|
||||
console_putc(pdev, '\r');
|
||||
console_putc(pdev, *s++);
|
||||
}
|
||||
}
|
||||
|
||||
static void debug_put(struct platform_device *pdev,
|
||||
const char *s, unsigned int count)
|
||||
{
|
||||
while (count--) {
|
||||
if (*s == '\n')
|
||||
debug_putc(pdev, '\r');
|
||||
debug_putc(pdev, *s++);
|
||||
}
|
||||
}
|
||||
|
||||
static int console_thread(void *data)
|
||||
{
|
||||
struct platform_device *pdev = data;
|
||||
struct rk_fiq_debugger *t;
|
||||
unsigned char c;
|
||||
t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
|
||||
char *buf = console_buf;
|
||||
unsigned int len;
|
||||
|
||||
while (1) {
|
||||
unsigned int dropped;
|
||||
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
schedule();
|
||||
if (kfifo_is_empty(&fifo))
|
||||
schedule();
|
||||
if (kthread_should_stop())
|
||||
break;
|
||||
set_current_state(TASK_RUNNING);
|
||||
while (!console_thread_stop && kfifo_get(&fifo, &c))
|
||||
debug_putc(pdev, c);
|
||||
while (!console_thread_stop) {
|
||||
len = kfifo_out(&fifo, buf, LINE_MAX);
|
||||
if (!len)
|
||||
break;
|
||||
console_put(pdev, buf, len);
|
||||
}
|
||||
dropped = console_dropped_messages;
|
||||
if (dropped && !console_thread_stop) {
|
||||
console_dropped_messages = 0;
|
||||
smp_wmb();
|
||||
len = snprintf(buf, LINE_MAX,
|
||||
"** %u console messages dropped **\n",
|
||||
dropped);
|
||||
console_put(pdev, buf, len);
|
||||
}
|
||||
if (!console_thread_stop)
|
||||
debug_flush(pdev);
|
||||
console_flush(pdev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -235,8 +304,9 @@ 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';
|
||||
unsigned char c;
|
||||
struct rk_fiq_debugger *t;
|
||||
|
||||
t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
|
||||
|
||||
if (console_thread_stop ||
|
||||
@@ -249,23 +319,21 @@ static void console_write(struct platform_device *pdev, const char *s, unsigned
|
||||
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);
|
||||
}
|
||||
debug_putc(pdev, *s++);
|
||||
debug_put(pdev, &c, 1);
|
||||
}
|
||||
debug_put(pdev, s, count);
|
||||
debug_flush(pdev);
|
||||
} else {
|
||||
while (count--) {
|
||||
if (*s == '\n') {
|
||||
kfifo_put(&fifo, r);
|
||||
}
|
||||
kfifo_put(&fifo, *s++);
|
||||
} else if (count) {
|
||||
unsigned int ret = 0;
|
||||
|
||||
if (kfifo_len(&fifo) + count < FIFO_SIZE)
|
||||
ret = kfifo_in(&fifo, s, count);
|
||||
if (!ret) {
|
||||
console_dropped_messages++;
|
||||
smp_wmb();
|
||||
} else {
|
||||
wake_up_process(t->console_task);
|
||||
}
|
||||
wake_up_process(t->console_task);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user