From: Frank Rowand <frank.rowand@xxxxxxxxxxxxxx> Not intended to be applied to mainline. This is debug code that captures a trace of msm_serial reads by handle_rx_dm(). The trace is printed to the console when the sys_sync() system call is invoked (that is, when the sync user space command is executed). Not-signed-off-by-yet: Frank Rowand <frank.rowand@xxxxxxxxxxxxxx> --- arch/arm/boot/dts/qcom-msm8974.dtsi | 1 drivers/tty/serial/msm_serial.c | 110 ++++++++++++++++++++++++++++++++++++ fs/sync.c | 5 + 3 files changed, 116 insertions(+) Index: b/drivers/tty/serial/msm_serial.c =================================================================== --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -100,6 +100,80 @@ static void msm_enable_ms(struct uart_po msm_write(port, msm_port->imr, UART_IMR); } +#define dbg_rx_c_MAX 95 +struct dbg_rx { + unsigned int rx_break; + unsigned int stale; + unsigned int count_exhausted; + unsigned int rx_total_snap; + unsigned int count; + unsigned int old_snap_state_1; + unsigned int old_snap_state_2; + unsigned int c_idx; + unsigned int c[dbg_rx_c_MAX + 1]; +}; + +#define dbg_rx_MAX 4000 +static struct dbg_rx dbg_rx[dbg_rx_MAX + 1]; +static int dbg_rx_idx = -1; + +#define BUF_MAX 4095 +#define BUF_SIZE (BUF_MAX + 1) +static unsigned char buf[BUF_SIZE]; +void print_dbg_rx(void) +{ + unsigned char c; + int k; + int j; + int i; + struct dbg_rx *d = &dbg_rx[0]; + unsigned char *bufp; + + pr_err( + " B S E\n" + " r t x old_\n" + " e a h snap_state\n" + " a l s ---------- tot\n" + " k t t 1 2 snap count c_idx --- data\n" + "---- - - - ---- ---- ---- ----- ----- --- --------\n"); + + for (k = 0; k <= dbg_rx_idx; k++, d++) { + bufp = &buf[0]; + bufp += scnprintf(bufp, BUF_SIZE, "%4d %c %c %c %4d %4d %4d %5d %5d --- ", + k, + d->rx_break ? 'B' : ' ', + d->stale ? 'S' : 'H', + d->count_exhausted ? 'E' : ' ', + d->old_snap_state_1, + d->old_snap_state_2, + d->rx_total_snap, + d->count, + d->c_idx + ); + for (j = 0; j < d->c_idx; j++) { + bufp += scnprintf(bufp, + BUF_SIZE - (bufp - &buf[0]), + "%08x ", d->c[j]); + } + for (j = 0; j < d->c_idx; j++) { + for (i = 3; i >= 0; i--) { + c = (d->c[j] >> (8 * i)) & 0xff; + bufp += scnprintf(bufp, + BUF_SIZE - (bufp - &buf[0]), + "%c", + ((c >= 0x20) && (c <= 0x7e)) ? c : '.'); + } + bufp += scnprintf(bufp, + BUF_SIZE - (bufp - &buf[0]), + " "); + } + bufp += scnprintf(bufp, + BUF_SIZE - (bufp - &buf[0]), + "\n"); + pr_err("%s", buf); + } +} + static void handle_rx_dm(struct uart_port *port, unsigned int misr) { struct tty_port *tport = &port->state->port; @@ -110,6 +184,13 @@ static void handle_rx_dm(struct uart_por int res; char *cp; + dbg_rx_idx++; + if (dbg_rx_idx > dbg_rx_MAX) + dbg_rx_idx = 0; + memset(&dbg_rx[dbg_rx_idx], 0, sizeof(dbg_rx[0])); + dbg_rx[dbg_rx_idx].old_snap_state_1 = msm_port->old_snap_state; + dbg_rx[dbg_rx_idx].stale = imr_rx_stale; + if ((msm_read(port, UART_SR) & UART_SR_OVERRUN)) { port->icount.overrun++; tty_insert_flip_char(tport, 0, TTY_OVERRUN); @@ -117,8 +198,14 @@ static void handle_rx_dm(struct uart_por } if (imr_rx_stale) { +#if 1 + int rx_total_snap = msm_read(port, UARTDM_RX_TOTAL_SNAP); + dbg_rx[dbg_rx_idx].rx_total_snap = rx_total_snap; + count = rx_total_snap - msm_port->old_snap_state; +#else count = msm_read(port, UARTDM_RX_TOTAL_SNAP) - msm_port->old_snap_state; +#endif msm_port->old_snap_state = 0; } else { count = msm_read(port, UART_RFWR); @@ -126,6 +213,7 @@ static void handle_rx_dm(struct uart_por count = 4 * count; msm_port->old_snap_state += count; } + dbg_rx[dbg_rx_idx].count = count; /* TODO: Precise error reporting */ @@ -138,12 +226,15 @@ static void handle_rx_dm(struct uart_por if ((sr & UART_SR_RX_READY) == 0) { if (!imr_rx_stale) msm_port->old_snap_state -= count; + dbg_rx[dbg_rx_idx].count_exhausted = 1; break; } c = msm_read(port, UARTDM_RF); + dbg_rx[dbg_rx_idx].c[dbg_rx[dbg_rx_idx].c_idx++] = c; if (sr & UART_SR_RX_BREAK) { + dbg_rx[dbg_rx_idx].rx_break = 1; port->icount.brk++; uart_handle_break(port); if (msm_port->rx_sc_enabled) @@ -193,6 +284,7 @@ static void handle_rx_dm(struct uart_por msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR); msm_write(port, 0xFFFFFF, UARTDM_DMRX); msm_write(port, UART_CR_CMD_STALE_EVENT_ENABLE, UART_CR); + dbg_rx[dbg_rx_idx].old_snap_state_2 = msm_port->old_snap_state; } static void handle_rx(struct uart_port *port) @@ -771,6 +863,9 @@ static int msm_poll_init(struct uart_por struct msm_port *msm_port = UART_TO_MSM(port); unsigned int watermark; + pr_err("enter msm_poll_init()\n"); + pr_err("msm_port->is_uartdm %d\n", msm_port->is_uartdm); + /* Enable single character mode on RX FIFO */ if (msm_port->is_uartdm >= UARTDM_1P4) { msm_write(port, UARTDM_DMEN_RX_SC_ENABLE, UARTDM_DMEN); @@ -1273,6 +1368,21 @@ static int __init msm_console_setup(stru printk(KERN_INFO "msm_serial: console setup on port #%d\n", port->line); +#if 1 +{ + /* zzz debug info */ + + unsigned int version; + + version = msm_read(port, 0xd8); + pr_err("msm_serial: HW_VERSION %d.%d.%d\n", + (version >> 28) & 0xf, + (version >> 16) & 0xfff, + (version ) & 0xffff); + +} +#endif + return uart_set_options(port, co, baud, parity, bits, flow); } Index: b/fs/sync.c =================================================================== --- a/fs/sync.c +++ b/fs/sync.c @@ -99,10 +99,15 @@ static void fdatawait_one_bdev(struct bl * just write metadata (such as inodes or bitmaps) to block device page cache * and do not sync it on their own in ->sync_fs(). */ +void print_dbg_rx(void); +int zzz_print_dbg_rx = 1; SYSCALL_DEFINE0(sync) { int nowait = 0, wait = 1; + if (zzz_print_dbg_rx) + print_dbg_rx(); + wakeup_flusher_threads(0, WB_REASON_SYNC); iterate_supers(sync_inodes_one_sb, NULL); iterate_supers(sync_fs_one_sb, &nowait); Index: b/arch/arm/boot/dts/qcom-msm8974.dtsi =================================================================== --- a/arch/arm/boot/dts/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -227,6 +227,7 @@ serial@f991e000 { compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; + /* compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; */ reg = <0xf991e000 0x1000>; interrupts = <0 108 0x0>; clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>; -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html