Loading drivers/tty/serial/msm_geni_serial.c +36 −1 Original line number Diff line number Diff line Loading @@ -777,6 +777,7 @@ static void msm_geni_serial_console_write(struct console *co, const char *s, bool locked = true; unsigned long flags; unsigned int geni_status; int irq_en; /* Max 1 port supported as of now */ WARN_ON(co->index < 0 || co->index >= GENI_UART_CONS_PORTS); Loading Loading @@ -806,12 +807,22 @@ static void msm_geni_serial_console_write(struct console *co, const char *s, } writel_relaxed(M_CMD_CANCEL_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); } else if ((geni_status & M_GENI_CMD_ACTIVE) && !port->cur_tx_remaining) } else if ((geni_status & M_GENI_CMD_ACTIVE) && !port->cur_tx_remaining) { /* It seems we can interrupt existing transfers unless all data * has been sent, in which case we need to look for done first. */ msm_geni_serial_poll_cancel_tx(uport); /* Enable WM interrupt for every new console write op */ if (uart_circ_chars_pending(&uport->state->xmit)) { irq_en = geni_read_reg_nolog(uport->membase, SE_GENI_M_IRQ_EN); geni_write_reg_nolog(irq_en | M_TX_FIFO_WATERMARK_EN, uport->membase, SE_GENI_M_IRQ_EN); } } __msm_geni_serial_console_write(uport, s, count); if (port->cur_tx_remaining) Loading Loading @@ -1310,6 +1321,7 @@ static int msm_geni_serial_handle_tx(struct uart_port *uport, bool done, unsigned int fifo_width_bytes = (uart_console(uport) ? 1 : (msm_port->tx_fifo_width >> 3)); int temp_tail = 0; int irq_en; tx_fifo_status = geni_read_reg_nolog(uport->membase, SE_GENI_TX_FIFO_STATUS); Loading Loading @@ -1340,6 +1352,12 @@ static int msm_geni_serial_handle_tx(struct uart_port *uport, bool done, if (!msm_port->cur_tx_remaining) { msm_geni_serial_setup_tx(uport, pending); msm_port->cur_tx_remaining = pending; /* Re-enable WM interrupt when starting new transfer */ irq_en = geni_read_reg_nolog(uport->membase, SE_GENI_M_IRQ_EN); if (!(irq_en & M_TX_FIFO_WATERMARK_EN)) geni_write_reg_nolog(irq_en | M_TX_FIFO_WATERMARK_EN, uport->membase, SE_GENI_M_IRQ_EN); } bytes_remaining = xmit_size; Loading Loading @@ -1367,7 +1385,24 @@ static int msm_geni_serial_handle_tx(struct uart_port *uport, bool done, wmb(); } xmit->tail = temp_tail; /* * The tx fifo watermark is level triggered and latched. Though we had * cleared it in qcom_geni_serial_isr it will have already reasserted * so we must clear it again here after our writes. */ geni_write_reg_nolog(M_TX_FIFO_WATERMARK_EN, uport->membase, SE_GENI_M_IRQ_CLEAR); exit_handle_tx: if (!msm_port->cur_tx_remaining) { irq_en = geni_read_reg_nolog(uport->membase, SE_GENI_M_IRQ_EN); /* Clear WM interrupt post each transfer completion */ if (irq_en & M_TX_FIFO_WATERMARK_EN) geni_write_reg_nolog(irq_en & ~M_TX_FIFO_WATERMARK_EN, uport->membase, SE_GENI_M_IRQ_EN); } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(uport); return 0; Loading Loading
drivers/tty/serial/msm_geni_serial.c +36 −1 Original line number Diff line number Diff line Loading @@ -777,6 +777,7 @@ static void msm_geni_serial_console_write(struct console *co, const char *s, bool locked = true; unsigned long flags; unsigned int geni_status; int irq_en; /* Max 1 port supported as of now */ WARN_ON(co->index < 0 || co->index >= GENI_UART_CONS_PORTS); Loading Loading @@ -806,12 +807,22 @@ static void msm_geni_serial_console_write(struct console *co, const char *s, } writel_relaxed(M_CMD_CANCEL_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); } else if ((geni_status & M_GENI_CMD_ACTIVE) && !port->cur_tx_remaining) } else if ((geni_status & M_GENI_CMD_ACTIVE) && !port->cur_tx_remaining) { /* It seems we can interrupt existing transfers unless all data * has been sent, in which case we need to look for done first. */ msm_geni_serial_poll_cancel_tx(uport); /* Enable WM interrupt for every new console write op */ if (uart_circ_chars_pending(&uport->state->xmit)) { irq_en = geni_read_reg_nolog(uport->membase, SE_GENI_M_IRQ_EN); geni_write_reg_nolog(irq_en | M_TX_FIFO_WATERMARK_EN, uport->membase, SE_GENI_M_IRQ_EN); } } __msm_geni_serial_console_write(uport, s, count); if (port->cur_tx_remaining) Loading Loading @@ -1310,6 +1321,7 @@ static int msm_geni_serial_handle_tx(struct uart_port *uport, bool done, unsigned int fifo_width_bytes = (uart_console(uport) ? 1 : (msm_port->tx_fifo_width >> 3)); int temp_tail = 0; int irq_en; tx_fifo_status = geni_read_reg_nolog(uport->membase, SE_GENI_TX_FIFO_STATUS); Loading Loading @@ -1340,6 +1352,12 @@ static int msm_geni_serial_handle_tx(struct uart_port *uport, bool done, if (!msm_port->cur_tx_remaining) { msm_geni_serial_setup_tx(uport, pending); msm_port->cur_tx_remaining = pending; /* Re-enable WM interrupt when starting new transfer */ irq_en = geni_read_reg_nolog(uport->membase, SE_GENI_M_IRQ_EN); if (!(irq_en & M_TX_FIFO_WATERMARK_EN)) geni_write_reg_nolog(irq_en | M_TX_FIFO_WATERMARK_EN, uport->membase, SE_GENI_M_IRQ_EN); } bytes_remaining = xmit_size; Loading Loading @@ -1367,7 +1385,24 @@ static int msm_geni_serial_handle_tx(struct uart_port *uport, bool done, wmb(); } xmit->tail = temp_tail; /* * The tx fifo watermark is level triggered and latched. Though we had * cleared it in qcom_geni_serial_isr it will have already reasserted * so we must clear it again here after our writes. */ geni_write_reg_nolog(M_TX_FIFO_WATERMARK_EN, uport->membase, SE_GENI_M_IRQ_CLEAR); exit_handle_tx: if (!msm_port->cur_tx_remaining) { irq_en = geni_read_reg_nolog(uport->membase, SE_GENI_M_IRQ_EN); /* Clear WM interrupt post each transfer completion */ if (irq_en & M_TX_FIFO_WATERMARK_EN) geni_write_reg_nolog(irq_en & ~M_TX_FIFO_WATERMARK_EN, uport->membase, SE_GENI_M_IRQ_EN); } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(uport); return 0; Loading