Loading drivers/tty/serial/msm_geni_serial.c +58 −25 Original line number Diff line number Diff line Loading @@ -98,7 +98,9 @@ #define UART_PARAM (0x1) /* UART DMA Rx GP_IRQ_BITS */ #define UART_DMA_RX_ERRS (GENMASK(5, 8)) #define UART_DMA_RX_PARITY_ERR BIT(5) #define UART_DMA_RX_ERRS (GENMASK(5, 6)) #define UART_DMA_RX_BREAK (GENMASK(7, 8)) #define UART_OVERSAMPLING (32) #define STALE_TIMEOUT (16) Loading Loading @@ -141,7 +143,8 @@ struct msm_geni_serial_port { int (*handle_rx)(struct uart_port *uport, unsigned int rx_fifo_wc, unsigned int rx_last_byte_valid, unsigned int rx_last); unsigned int rx_last, bool drop_rx); struct device *wrapper_dev; struct se_geni_rsc serial_rsc; dma_addr_t tx_dma; Loading @@ -167,11 +170,13 @@ static struct uart_driver msm_geni_serial_hs_driver; static int handle_rx_console(struct uart_port *uport, unsigned int rx_fifo_wc, unsigned int rx_last_byte_valid, unsigned int rx_last); unsigned int rx_last, bool drop_rx); static int handle_rx_hs(struct uart_port *uport, unsigned int rx_fifo_wc, unsigned int rx_last_byte_valid, unsigned int rx_last); unsigned int rx_last, bool drop_rx); static unsigned int msm_geni_serial_tx_empty(struct uart_port *port); static int msm_geni_serial_power_on(struct uart_port *uport); static void msm_geni_serial_power_off(struct uart_port *uport); Loading Loading @@ -681,7 +686,8 @@ static void msm_geni_serial_console_write(struct console *co, const char *s, static int handle_rx_console(struct uart_port *uport, unsigned int rx_fifo_wc, unsigned int rx_last_byte_valid, unsigned int rx_last) unsigned int rx_last, bool drop_rx) { int i, c; unsigned char *rx_char; Loading @@ -694,6 +700,8 @@ static int handle_rx_console(struct uart_port *uport, *(msm_port->rx_fifo) = geni_read_reg_nolog(uport->membase, SE_GENI_RX_FIFOn); if (drop_rx) continue; rx_char = (unsigned char *)msm_port->rx_fifo; if (i == (rx_fifo_wc - 1)) { Loading @@ -710,6 +718,7 @@ static int handle_rx_console(struct uart_port *uport, tty_insert_flip_char(tport, rx_char[c], flag); } } if (!drop_rx) tty_flip_buffer_push(tport); return 0; } Loading @@ -717,7 +726,8 @@ static int handle_rx_console(struct uart_port *uport, static int handle_rx_console(struct uart_port *uport, unsigned int rx_fifo_wc, unsigned int rx_last_byte_valid, unsigned int rx_last) unsigned int rx_last, bool drop_rx) { return -EPERM; } Loading Loading @@ -1001,7 +1011,8 @@ static void msm_geni_serial_stop_rx(struct uart_port *uport) static int handle_rx_hs(struct uart_port *uport, unsigned int rx_fifo_wc, unsigned int rx_last_byte_valid, unsigned int rx_last) unsigned int rx_last, bool drop_rx) { unsigned char *rx_char; struct tty_port *tport; Loading @@ -1016,6 +1027,8 @@ static int handle_rx_hs(struct uart_port *uport, tport = &uport->state->port; ioread32_rep((uport->membase + SE_GENI_RX_FIFOn), msm_port->rx_fifo, rx_fifo_wc); if (drop_rx) return 0; rx_char = (unsigned char *)msm_port->rx_fifo; ret = tty_insert_flip_string(tport, rx_char, rx_bytes); Loading @@ -1031,7 +1044,7 @@ static int handle_rx_hs(struct uart_port *uport, return ret; } static int msm_geni_serial_handle_rx(struct uart_port *uport) static int msm_geni_serial_handle_rx(struct uart_port *uport, bool drop_rx) { int ret = 0; unsigned int rx_fifo_status; Loading @@ -1050,7 +1063,7 @@ static int msm_geni_serial_handle_rx(struct uart_port *uport) rx_last = rx_fifo_status & RX_LAST; if (rx_fifo_wc) port->handle_rx(uport, rx_fifo_wc, rx_last_byte_valid, rx_last); rx_last, drop_rx); return ret; } Loading Loading @@ -1128,13 +1141,13 @@ static int msm_geni_serial_handle_tx(struct uart_port *uport) } else { msm_port->xmit_size = xmit_size; } exit_handle_tx: if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(uport); exit_handle_tx: return ret; } static int msm_geni_serial_handle_dma_rx(struct uart_port *uport) static int msm_geni_serial_handle_dma_rx(struct uart_port *uport, bool drop_rx) { struct msm_geni_serial_port *msm_port = GET_DEV_PORT(uport); unsigned int rx_bytes = 0; Loading @@ -1160,6 +1173,8 @@ static int msm_geni_serial_handle_dma_rx(struct uart_port *uport) __func__, rx_bytes); goto exit_handle_dma_rx; } if (drop_rx) goto exit_handle_dma_rx; tport = &uport->state->port; ret = tty_insert_flip_string(tport, (unsigned char *)(msm_port->rx_buf), Loading Loading @@ -1211,6 +1226,7 @@ static irqreturn_t msm_geni_serial_isr(int isr, void *dev) unsigned long flags; unsigned int m_irq_en; struct msm_geni_serial_port *msm_port = GET_DEV_PORT(uport); bool drop_rx = false; spin_lock_irqsave(&uport->lock, flags); if (uart_console(uport) && uport->suspended) Loading Loading @@ -1239,21 +1255,29 @@ static irqreturn_t msm_geni_serial_isr(int isr, void *dev) } if (!dma) { if ((m_irq_status & m_irq_en) & (M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN)) msm_geni_serial_handle_tx(uport); if ((s_irq_status & S_GP_IRQ_0_EN) || (s_irq_status & S_GP_IRQ_1_EN) || (s_irq_status & S_GP_IRQ_2_EN) || (s_irq_status & S_GP_IRQ_1_EN)) { if (s_irq_status & S_GP_IRQ_0_EN) uport->icount.parity++; IPC_LOG_MSG(msm_port->ipc_log_misc, "%s.sirq 0x%x parity:%d\n", __func__, s_irq_status, uport->icount.parity); drop_rx = true; } else if ((s_irq_status & S_GP_IRQ_2_EN) || (s_irq_status & S_GP_IRQ_3_EN)) { uport->icount.brk++; IPC_LOG_MSG(msm_port->ipc_log_misc, "%s.sirq 0x%x.\n", __func__, s_irq_status); goto exit_geni_serial_isr; "%s.sirq 0x%x break:%d\n", __func__, s_irq_status, uport->icount.brk); } if ((s_irq_status & S_RX_FIFO_WATERMARK_EN) || (s_irq_status & S_RX_FIFO_LAST_EN)) msm_geni_serial_handle_rx(uport); if ((m_irq_status & m_irq_en) & (M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN)) msm_geni_serial_handle_tx(uport); msm_geni_serial_handle_rx(uport, drop_rx); } else { if (dma_tx_status) { geni_write_reg_nolog(dma_tx_status, uport->membase, Loading @@ -1272,13 +1296,22 @@ static irqreturn_t msm_geni_serial_isr(int isr, void *dev) goto exit_geni_serial_isr; } if (dma_rx_status & UART_DMA_RX_ERRS) { if (dma_rx_status & UART_DMA_RX_PARITY_ERR) uport->icount.parity++; IPC_LOG_MSG(msm_port->ipc_log_misc, "%s.Rx Errors. 0x%x.\n", __func__, dma_rx_status); goto exit_geni_serial_isr; "%s.Rx Errors. 0x%x parity:%d\n", __func__, dma_rx_status, uport->icount.parity); drop_rx = true; } else if (dma_rx_status & UART_DMA_RX_BREAK) { uport->icount.brk++; IPC_LOG_MSG(msm_port->ipc_log_misc, "%s.Rx Errors. 0x%x break:%d\n", __func__, dma_rx_status, uport->icount.brk); } if (dma_rx_status & RX_DMA_DONE) msm_geni_serial_handle_dma_rx(uport); msm_geni_serial_handle_dma_rx(uport, drop_rx); } } Loading Loading
drivers/tty/serial/msm_geni_serial.c +58 −25 Original line number Diff line number Diff line Loading @@ -98,7 +98,9 @@ #define UART_PARAM (0x1) /* UART DMA Rx GP_IRQ_BITS */ #define UART_DMA_RX_ERRS (GENMASK(5, 8)) #define UART_DMA_RX_PARITY_ERR BIT(5) #define UART_DMA_RX_ERRS (GENMASK(5, 6)) #define UART_DMA_RX_BREAK (GENMASK(7, 8)) #define UART_OVERSAMPLING (32) #define STALE_TIMEOUT (16) Loading Loading @@ -141,7 +143,8 @@ struct msm_geni_serial_port { int (*handle_rx)(struct uart_port *uport, unsigned int rx_fifo_wc, unsigned int rx_last_byte_valid, unsigned int rx_last); unsigned int rx_last, bool drop_rx); struct device *wrapper_dev; struct se_geni_rsc serial_rsc; dma_addr_t tx_dma; Loading @@ -167,11 +170,13 @@ static struct uart_driver msm_geni_serial_hs_driver; static int handle_rx_console(struct uart_port *uport, unsigned int rx_fifo_wc, unsigned int rx_last_byte_valid, unsigned int rx_last); unsigned int rx_last, bool drop_rx); static int handle_rx_hs(struct uart_port *uport, unsigned int rx_fifo_wc, unsigned int rx_last_byte_valid, unsigned int rx_last); unsigned int rx_last, bool drop_rx); static unsigned int msm_geni_serial_tx_empty(struct uart_port *port); static int msm_geni_serial_power_on(struct uart_port *uport); static void msm_geni_serial_power_off(struct uart_port *uport); Loading Loading @@ -681,7 +686,8 @@ static void msm_geni_serial_console_write(struct console *co, const char *s, static int handle_rx_console(struct uart_port *uport, unsigned int rx_fifo_wc, unsigned int rx_last_byte_valid, unsigned int rx_last) unsigned int rx_last, bool drop_rx) { int i, c; unsigned char *rx_char; Loading @@ -694,6 +700,8 @@ static int handle_rx_console(struct uart_port *uport, *(msm_port->rx_fifo) = geni_read_reg_nolog(uport->membase, SE_GENI_RX_FIFOn); if (drop_rx) continue; rx_char = (unsigned char *)msm_port->rx_fifo; if (i == (rx_fifo_wc - 1)) { Loading @@ -710,6 +718,7 @@ static int handle_rx_console(struct uart_port *uport, tty_insert_flip_char(tport, rx_char[c], flag); } } if (!drop_rx) tty_flip_buffer_push(tport); return 0; } Loading @@ -717,7 +726,8 @@ static int handle_rx_console(struct uart_port *uport, static int handle_rx_console(struct uart_port *uport, unsigned int rx_fifo_wc, unsigned int rx_last_byte_valid, unsigned int rx_last) unsigned int rx_last, bool drop_rx) { return -EPERM; } Loading Loading @@ -1001,7 +1011,8 @@ static void msm_geni_serial_stop_rx(struct uart_port *uport) static int handle_rx_hs(struct uart_port *uport, unsigned int rx_fifo_wc, unsigned int rx_last_byte_valid, unsigned int rx_last) unsigned int rx_last, bool drop_rx) { unsigned char *rx_char; struct tty_port *tport; Loading @@ -1016,6 +1027,8 @@ static int handle_rx_hs(struct uart_port *uport, tport = &uport->state->port; ioread32_rep((uport->membase + SE_GENI_RX_FIFOn), msm_port->rx_fifo, rx_fifo_wc); if (drop_rx) return 0; rx_char = (unsigned char *)msm_port->rx_fifo; ret = tty_insert_flip_string(tport, rx_char, rx_bytes); Loading @@ -1031,7 +1044,7 @@ static int handle_rx_hs(struct uart_port *uport, return ret; } static int msm_geni_serial_handle_rx(struct uart_port *uport) static int msm_geni_serial_handle_rx(struct uart_port *uport, bool drop_rx) { int ret = 0; unsigned int rx_fifo_status; Loading @@ -1050,7 +1063,7 @@ static int msm_geni_serial_handle_rx(struct uart_port *uport) rx_last = rx_fifo_status & RX_LAST; if (rx_fifo_wc) port->handle_rx(uport, rx_fifo_wc, rx_last_byte_valid, rx_last); rx_last, drop_rx); return ret; } Loading Loading @@ -1128,13 +1141,13 @@ static int msm_geni_serial_handle_tx(struct uart_port *uport) } else { msm_port->xmit_size = xmit_size; } exit_handle_tx: if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(uport); exit_handle_tx: return ret; } static int msm_geni_serial_handle_dma_rx(struct uart_port *uport) static int msm_geni_serial_handle_dma_rx(struct uart_port *uport, bool drop_rx) { struct msm_geni_serial_port *msm_port = GET_DEV_PORT(uport); unsigned int rx_bytes = 0; Loading @@ -1160,6 +1173,8 @@ static int msm_geni_serial_handle_dma_rx(struct uart_port *uport) __func__, rx_bytes); goto exit_handle_dma_rx; } if (drop_rx) goto exit_handle_dma_rx; tport = &uport->state->port; ret = tty_insert_flip_string(tport, (unsigned char *)(msm_port->rx_buf), Loading Loading @@ -1211,6 +1226,7 @@ static irqreturn_t msm_geni_serial_isr(int isr, void *dev) unsigned long flags; unsigned int m_irq_en; struct msm_geni_serial_port *msm_port = GET_DEV_PORT(uport); bool drop_rx = false; spin_lock_irqsave(&uport->lock, flags); if (uart_console(uport) && uport->suspended) Loading Loading @@ -1239,21 +1255,29 @@ static irqreturn_t msm_geni_serial_isr(int isr, void *dev) } if (!dma) { if ((m_irq_status & m_irq_en) & (M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN)) msm_geni_serial_handle_tx(uport); if ((s_irq_status & S_GP_IRQ_0_EN) || (s_irq_status & S_GP_IRQ_1_EN) || (s_irq_status & S_GP_IRQ_2_EN) || (s_irq_status & S_GP_IRQ_1_EN)) { if (s_irq_status & S_GP_IRQ_0_EN) uport->icount.parity++; IPC_LOG_MSG(msm_port->ipc_log_misc, "%s.sirq 0x%x parity:%d\n", __func__, s_irq_status, uport->icount.parity); drop_rx = true; } else if ((s_irq_status & S_GP_IRQ_2_EN) || (s_irq_status & S_GP_IRQ_3_EN)) { uport->icount.brk++; IPC_LOG_MSG(msm_port->ipc_log_misc, "%s.sirq 0x%x.\n", __func__, s_irq_status); goto exit_geni_serial_isr; "%s.sirq 0x%x break:%d\n", __func__, s_irq_status, uport->icount.brk); } if ((s_irq_status & S_RX_FIFO_WATERMARK_EN) || (s_irq_status & S_RX_FIFO_LAST_EN)) msm_geni_serial_handle_rx(uport); if ((m_irq_status & m_irq_en) & (M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN)) msm_geni_serial_handle_tx(uport); msm_geni_serial_handle_rx(uport, drop_rx); } else { if (dma_tx_status) { geni_write_reg_nolog(dma_tx_status, uport->membase, Loading @@ -1272,13 +1296,22 @@ static irqreturn_t msm_geni_serial_isr(int isr, void *dev) goto exit_geni_serial_isr; } if (dma_rx_status & UART_DMA_RX_ERRS) { if (dma_rx_status & UART_DMA_RX_PARITY_ERR) uport->icount.parity++; IPC_LOG_MSG(msm_port->ipc_log_misc, "%s.Rx Errors. 0x%x.\n", __func__, dma_rx_status); goto exit_geni_serial_isr; "%s.Rx Errors. 0x%x parity:%d\n", __func__, dma_rx_status, uport->icount.parity); drop_rx = true; } else if (dma_rx_status & UART_DMA_RX_BREAK) { uport->icount.brk++; IPC_LOG_MSG(msm_port->ipc_log_misc, "%s.Rx Errors. 0x%x break:%d\n", __func__, dma_rx_status, uport->icount.brk); } if (dma_rx_status & RX_DMA_DONE) msm_geni_serial_handle_dma_rx(uport); msm_geni_serial_handle_dma_rx(uport, drop_rx); } } Loading