Skip to content

Commit cea2a68

Browse files
committed
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>
1 parent 09aeb6e commit cea2a68

1 file changed

Lines changed: 90 additions & 22 deletions

File tree

drivers/soc/rockchip/rk_fiq_debugger.c

Lines changed: 90 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -207,26 +207,95 @@ static void debug_flush(struct platform_device *pdev)
207207

208208
#ifdef CONFIG_RK_CONSOLE_THREAD
209209
#define FIFO_SIZE SZ_64K
210+
#define LINE_MAX 1024
210211
static DEFINE_KFIFO(fifo, unsigned char, FIFO_SIZE);
212+
static char console_buf[LINE_MAX]; /* avoid FRAME WARN */
211213
static bool console_thread_stop;
214+
static unsigned int console_dropped_messages;
212215

213-
static int console_thread(void *data)
216+
static void console_putc(struct platform_device *pdev, unsigned int c)
214217
{
215-
struct platform_device *pdev = data;
216218
struct rk_fiq_debugger *t;
217-
unsigned char c;
219+
unsigned int count = 500;
220+
218221
t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
219222

223+
while (!(rk_fiq_read(t, UART_USR) & UART_USR_TX_FIFO_NOT_FULL) &&
224+
count--)
225+
usleep_range(200, 210);
226+
/* If uart is always busy, maybe it is abnormal, reinit it */
227+
if ((count == 0) && (rk_fiq_read(t, UART_USR) & UART_USR_BUSY))
228+
debug_port_init(pdev);
229+
230+
rk_fiq_write(t, c, UART_TX);
231+
}
232+
233+
static void console_flush(struct platform_device *pdev)
234+
{
235+
struct rk_fiq_debugger *t;
236+
unsigned int count = 500;
237+
238+
t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
239+
240+
while (!(rk_fiq_read_lsr(t) & UART_LSR_TEMT) && count--)
241+
usleep_range(200, 210);
242+
/* If uart is always busy, maybe it is abnormal, reinit it */
243+
if ((count == 0) && (rk_fiq_read(t, UART_USR) & UART_USR_BUSY))
244+
debug_port_init(pdev);
245+
}
246+
247+
static void console_put(struct platform_device *pdev,
248+
const char *s, unsigned int count)
249+
{
250+
while (count--) {
251+
if (*s == '\n')
252+
console_putc(pdev, '\r');
253+
console_putc(pdev, *s++);
254+
}
255+
}
256+
257+
static void debug_put(struct platform_device *pdev,
258+
const char *s, unsigned int count)
259+
{
260+
while (count--) {
261+
if (*s == '\n')
262+
debug_putc(pdev, '\r');
263+
debug_putc(pdev, *s++);
264+
}
265+
}
266+
267+
static int console_thread(void *data)
268+
{
269+
struct platform_device *pdev = data;
270+
char *buf = console_buf;
271+
unsigned int len;
272+
220273
while (1) {
274+
unsigned int dropped;
275+
221276
set_current_state(TASK_INTERRUPTIBLE);
222-
schedule();
277+
if (kfifo_is_empty(&fifo))
278+
schedule();
223279
if (kthread_should_stop())
224280
break;
225281
set_current_state(TASK_RUNNING);
226-
while (!console_thread_stop && kfifo_get(&fifo, &c))
227-
debug_putc(pdev, c);
282+
while (!console_thread_stop) {
283+
len = kfifo_out(&fifo, buf, LINE_MAX);
284+
if (!len)
285+
break;
286+
console_put(pdev, buf, len);
287+
}
288+
dropped = console_dropped_messages;
289+
if (dropped && !console_thread_stop) {
290+
console_dropped_messages = 0;
291+
smp_wmb();
292+
len = snprintf(buf, LINE_MAX,
293+
"** %u console messages dropped **\n",
294+
dropped);
295+
console_put(pdev, buf, len);
296+
}
228297
if (!console_thread_stop)
229-
debug_flush(pdev);
298+
console_flush(pdev);
230299
}
231300

232301
return 0;
@@ -235,8 +304,9 @@ static int console_thread(void *data)
235304
static void console_write(struct platform_device *pdev, const char *s, unsigned int count)
236305
{
237306
unsigned int fifo_count = FIFO_SIZE;
238-
unsigned char c, r = '\r';
307+
unsigned char c;
239308
struct rk_fiq_debugger *t;
309+
240310
t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
241311

242312
if (console_thread_stop ||
@@ -249,23 +319,21 @@ static void console_write(struct platform_device *pdev, const char *s, unsigned
249319
smp_wmb();
250320
debug_flush(pdev);
251321
while (fifo_count-- && kfifo_get(&fifo, &c))
252-
debug_putc(pdev, c);
253-
}
254-
while (count--) {
255-
if (*s == '\n') {
256-
debug_putc(pdev, r);
257-
}
258-
debug_putc(pdev, *s++);
322+
debug_put(pdev, &c, 1);
259323
}
324+
debug_put(pdev, s, count);
260325
debug_flush(pdev);
261-
} else {
262-
while (count--) {
263-
if (*s == '\n') {
264-
kfifo_put(&fifo, r);
265-
}
266-
kfifo_put(&fifo, *s++);
326+
} else if (count) {
327+
unsigned int ret = 0;
328+
329+
if (kfifo_len(&fifo) + count < FIFO_SIZE)
330+
ret = kfifo_in(&fifo, s, count);
331+
if (!ret) {
332+
console_dropped_messages++;
333+
smp_wmb();
334+
} else {
335+
wake_up_process(t->console_task);
267336
}
268-
wake_up_process(t->console_task);
269337
}
270338
}
271339
#endif

0 commit comments

Comments
 (0)