diff options
Diffstat (limited to 'drivers/tty/serial/fsl_lpuart.c')
-rw-r--r-- | drivers/tty/serial/fsl_lpuart.c | 586 |
1 files changed, 304 insertions, 282 deletions
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index bbcbc91482af..c9519e649e82 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -7,6 +7,7 @@ #include <linux/bitfield.h> #include <linux/bits.h> +#include <linux/circ_buf.h> #include <linux/clk.h> #include <linux/console.h> #include <linux/delay.h> @@ -183,6 +184,7 @@ #define UARTCTRL_SBK 0x00010000 #define UARTCTRL_MA1IE 0x00008000 #define UARTCTRL_MA2IE 0x00004000 +#define UARTCTRL_M7 0x00000800 #define UARTCTRL_IDLECFG GENMASK(10, 8) #define UARTCTRL_LOOPS 0x00000080 #define UARTCTRL_DOZEEN 0x00000040 @@ -243,7 +245,7 @@ #define DRIVER_NAME "fsl-lpuart" #define DEV_NAME "ttyLP" -#define UART_NR 8 +#define UART_NR 12 /* IMX lpuart has four extra unused regs located at the beginning */ #define IMX_REG_OFF 0x10 @@ -316,27 +318,27 @@ static const struct lpuart_soc_data ls1028a_data = { .rx_watermark = 0, }; -static struct lpuart_soc_data imx7ulp_data = { +static const struct lpuart_soc_data imx7ulp_data = { .devtype = IMX7ULP_LPUART, .iotype = UPIO_MEM32, .reg_off = IMX_REG_OFF, .rx_watermark = 1, }; -static struct lpuart_soc_data imx8ulp_data = { +static const struct lpuart_soc_data imx8ulp_data = { .devtype = IMX8ULP_LPUART, .iotype = UPIO_MEM32, .reg_off = IMX_REG_OFF, .rx_watermark = 3, }; -static struct lpuart_soc_data imx8qxp_data = { +static const struct lpuart_soc_data imx8qxp_data = { .devtype = IMX8QXP_LPUART, .iotype = UPIO_MEM32, .reg_off = IMX_REG_OFF, .rx_watermark = 7, /* A lower watermark is ideal for low baud rates. */ }; -static struct lpuart_soc_data imxrt1050_data = { +static const struct lpuart_soc_data imxrt1050_data = { .devtype = IMXRT1050_LPUART, .iotype = UPIO_MEM32, .reg_off = IMX_REG_OFF, @@ -401,6 +403,8 @@ static inline void lpuart32_write(struct uart_port *port, u32 val, case UPIO_MEM32BE: iowrite32be(val, port->membase + off); break; + default: + break; } } @@ -439,41 +443,41 @@ static unsigned int lpuart_get_baud_clk_rate(struct lpuart_port *sport) static void lpuart_stop_tx(struct uart_port *port) { - unsigned char temp; + u8 cr2; - temp = readb(port->membase + UARTCR2); - temp &= ~(UARTCR2_TIE | UARTCR2_TCIE); - writeb(temp, port->membase + UARTCR2); + cr2 = readb(port->membase + UARTCR2); + cr2 &= ~(UARTCR2_TIE | UARTCR2_TCIE); + writeb(cr2, port->membase + UARTCR2); } static void lpuart32_stop_tx(struct uart_port *port) { - unsigned long temp; + u32 ctrl; - temp = lpuart32_read(port, UARTCTRL); - temp &= ~(UARTCTRL_TIE | UARTCTRL_TCIE); - lpuart32_write(port, temp, UARTCTRL); + ctrl = lpuart32_read(port, UARTCTRL); + ctrl &= ~(UARTCTRL_TIE | UARTCTRL_TCIE); + lpuart32_write(port, ctrl, UARTCTRL); } static void lpuart_stop_rx(struct uart_port *port) { - unsigned char temp; + u8 cr2; - temp = readb(port->membase + UARTCR2); - writeb(temp & ~UARTCR2_RE, port->membase + UARTCR2); + cr2 = readb(port->membase + UARTCR2); + writeb(cr2 & ~UARTCR2_RE, port->membase + UARTCR2); } static void lpuart32_stop_rx(struct uart_port *port) { - unsigned long temp; + u32 ctrl; - temp = lpuart32_read(port, UARTCTRL); - lpuart32_write(port, temp & ~UARTCTRL_RE, UARTCTRL); + ctrl = lpuart32_read(port, UARTCTRL); + lpuart32_write(port, ctrl & ~UARTCTRL_RE, UARTCTRL); } static void lpuart_dma_tx(struct lpuart_port *sport) { - struct circ_buf *xmit = &sport->port.state->xmit; + struct tty_port *tport = &sport->port.state->port; struct scatterlist *sgl = sport->tx_sgl; struct device *dev = sport->port.dev; struct dma_chan *chan = sport->dma_tx_chan; @@ -482,18 +486,10 @@ static void lpuart_dma_tx(struct lpuart_port *sport) if (sport->dma_tx_in_progress) return; - sport->dma_tx_bytes = uart_circ_chars_pending(xmit); - - if (xmit->tail < xmit->head || xmit->head == 0) { - sport->dma_tx_nents = 1; - sg_init_one(sgl, xmit->buf + xmit->tail, sport->dma_tx_bytes); - } else { - sport->dma_tx_nents = 2; - sg_init_table(sgl, 2); - sg_set_buf(sgl, xmit->buf + xmit->tail, - UART_XMIT_SIZE - xmit->tail); - sg_set_buf(sgl + 1, xmit->buf, xmit->head); - } + sg_init_table(sgl, ARRAY_SIZE(sport->tx_sgl)); + sport->dma_tx_bytes = kfifo_len(&tport->xmit_fifo); + sport->dma_tx_nents = kfifo_dma_out_prepare(&tport->xmit_fifo, sgl, + ARRAY_SIZE(sport->tx_sgl), sport->dma_tx_bytes); ret = dma_map_sg(chan->device->dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE); @@ -521,14 +517,15 @@ static void lpuart_dma_tx(struct lpuart_port *sport) static bool lpuart_stopped_or_empty(struct uart_port *port) { - return uart_circ_empty(&port->state->xmit) || uart_tx_stopped(port); + return kfifo_is_empty(&port->state->port.xmit_fifo) || + uart_tx_stopped(port); } static void lpuart_dma_tx_complete(void *arg) { struct lpuart_port *sport = arg; struct scatterlist *sgl = &sport->tx_sgl[0]; - struct circ_buf *xmit = &sport->port.state->xmit; + struct tty_port *tport = &sport->port.state->port; struct dma_chan *chan = sport->dma_tx_chan; unsigned long flags; @@ -545,7 +542,7 @@ static void lpuart_dma_tx_complete(void *arg) sport->dma_tx_in_progress = false; uart_port_unlock_irqrestore(&sport->port, flags); - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS) uart_write_wakeup(&sport->port); if (waitqueue_active(&sport->dma_wait)) { @@ -568,8 +565,9 @@ static dma_addr_t lpuart_dma_datareg_addr(struct lpuart_port *sport) return sport->port.mapbase + UARTDATA; case UPIO_MEM32BE: return sport->port.mapbase + UARTDATA + sizeof(u32) - 1; + default: + return sport->port.mapbase + UARTDR; } - return sport->port.mapbase + UARTDR; } static int lpuart_dma_tx_request(struct uart_port *port) @@ -586,7 +584,7 @@ static int lpuart_dma_tx_request(struct uart_port *port) ret = dmaengine_slave_config(sport->dma_tx_chan, &dma_tx_sconfig); if (ret) { - dev_err(sport->port.dev, + dev_err(port->dev, "DMA slave config failed, err = %d\n", ret); return ret; } @@ -604,7 +602,7 @@ static void lpuart_flush_buffer(struct uart_port *port) { struct lpuart_port *sport = container_of(port, struct lpuart_port, port); struct dma_chan *chan = sport->dma_tx_chan; - u32 val; + u32 fifo; if (sport->lpuart_dma_tx_use) { if (sport->dma_tx_in_progress) { @@ -616,13 +614,13 @@ static void lpuart_flush_buffer(struct uart_port *port) } if (lpuart_is_32(sport)) { - val = lpuart32_read(&sport->port, UARTFIFO); - val |= UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH; - lpuart32_write(&sport->port, val, UARTFIFO); + fifo = lpuart32_read(port, UARTFIFO); + fifo |= UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH; + lpuart32_write(port, fifo, UARTFIFO); } else { - val = readb(sport->port.membase + UARTCFIFO); - val |= UARTCFIFO_TXFLUSH | UARTCFIFO_RXFLUSH; - writeb(val, sport->port.membase + UARTCFIFO); + fifo = readb(port->membase + UARTCFIFO); + fifo |= UARTCFIFO_TXFLUSH | UARTCFIFO_RXFLUSH; + writeb(fifo, port->membase + UARTCFIFO); } } @@ -644,38 +642,36 @@ static void lpuart32_wait_bit_set(struct uart_port *port, unsigned int offset, static int lpuart_poll_init(struct uart_port *port) { - struct lpuart_port *sport = container_of(port, - struct lpuart_port, port); unsigned long flags; - unsigned char temp; + u8 fifo; - sport->port.fifosize = 0; + port->fifosize = 0; - uart_port_lock_irqsave(&sport->port, &flags); + uart_port_lock_irqsave(port, &flags); /* Disable Rx & Tx */ - writeb(0, sport->port.membase + UARTCR2); + writeb(0, port->membase + UARTCR2); - temp = readb(sport->port.membase + UARTPFIFO); + fifo = readb(port->membase + UARTPFIFO); /* Enable Rx and Tx FIFO */ - writeb(temp | UARTPFIFO_RXFE | UARTPFIFO_TXFE, - sport->port.membase + UARTPFIFO); + writeb(fifo | UARTPFIFO_RXFE | UARTPFIFO_TXFE, + port->membase + UARTPFIFO); /* flush Tx and Rx FIFO */ writeb(UARTCFIFO_TXFLUSH | UARTCFIFO_RXFLUSH, - sport->port.membase + UARTCFIFO); + port->membase + UARTCFIFO); /* explicitly clear RDRF */ - if (readb(sport->port.membase + UARTSR1) & UARTSR1_RDRF) { - readb(sport->port.membase + UARTDR); - writeb(UARTSFIFO_RXUF, sport->port.membase + UARTSFIFO); + if (readb(port->membase + UARTSR1) & UARTSR1_RDRF) { + readb(port->membase + UARTDR); + writeb(UARTSFIFO_RXUF, port->membase + UARTSFIFO); } - writeb(0, sport->port.membase + UARTTWFIFO); - writeb(1, sport->port.membase + UARTRWFIFO); + writeb(0, port->membase + UARTTWFIFO); + writeb(1, port->membase + UARTRWFIFO); /* Enable Rx and Tx */ - writeb(UARTCR2_RE | UARTCR2_TE, sport->port.membase + UARTCR2); - uart_port_unlock_irqrestore(&sport->port, flags); + writeb(UARTCR2_RE | UARTCR2_TE, port->membase + UARTCR2); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -698,33 +694,32 @@ static int lpuart_poll_get_char(struct uart_port *port) static int lpuart32_poll_init(struct uart_port *port) { unsigned long flags; - struct lpuart_port *sport = container_of(port, struct lpuart_port, port); - u32 temp; + u32 fifo; - sport->port.fifosize = 0; + port->fifosize = 0; - uart_port_lock_irqsave(&sport->port, &flags); + uart_port_lock_irqsave(port, &flags); /* Disable Rx & Tx */ - lpuart32_write(&sport->port, 0, UARTCTRL); + lpuart32_write(port, 0, UARTCTRL); - temp = lpuart32_read(&sport->port, UARTFIFO); + fifo = lpuart32_read(port, UARTFIFO); /* Enable Rx and Tx FIFO */ - lpuart32_write(&sport->port, temp | UARTFIFO_RXFE | UARTFIFO_TXFE, UARTFIFO); + lpuart32_write(port, fifo | UARTFIFO_RXFE | UARTFIFO_TXFE, UARTFIFO); /* flush Tx and Rx FIFO */ - lpuart32_write(&sport->port, UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH, UARTFIFO); + lpuart32_write(port, UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH, UARTFIFO); /* explicitly clear RDRF */ - if (lpuart32_read(&sport->port, UARTSTAT) & UARTSTAT_RDRF) { - lpuart32_read(&sport->port, UARTDATA); - lpuart32_write(&sport->port, UARTFIFO_RXUF, UARTFIFO); + if (lpuart32_read(port, UARTSTAT) & UARTSTAT_RDRF) { + lpuart32_read(port, UARTDATA); + lpuart32_write(port, UARTFIFO_RXUF, UARTFIFO); } /* Enable Rx and Tx */ - lpuart32_write(&sport->port, UARTCTRL_RE | UARTCTRL_TE, UARTCTRL); - uart_port_unlock_irqrestore(&sport->port, flags); + lpuart32_write(port, UARTCTRL_RE | UARTCTRL_TE, UARTCTRL); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -756,8 +751,9 @@ static inline void lpuart_transmit_buffer(struct lpuart_port *sport) static inline void lpuart32_transmit_buffer(struct lpuart_port *sport) { - struct circ_buf *xmit = &sport->port.state->xmit; - unsigned long txcnt; + struct tty_port *tport = &sport->port.state->port; + u32 txcnt; + unsigned char c; if (sport->port.x_char) { lpuart32_write(&sport->port, sport->port.x_char, UARTDATA); @@ -774,18 +770,18 @@ static inline void lpuart32_transmit_buffer(struct lpuart_port *sport) txcnt = lpuart32_read(&sport->port, UARTWATER); txcnt = txcnt >> UARTWATER_TXCNT_OFF; txcnt &= UARTWATER_COUNT_MASK; - while (!uart_circ_empty(xmit) && (txcnt < sport->txfifo_size)) { - lpuart32_write(&sport->port, xmit->buf[xmit->tail], UARTDATA); - uart_xmit_advance(&sport->port, 1); + while (txcnt < sport->txfifo_size && + uart_fifo_get(&sport->port, &c)) { + lpuart32_write(&sport->port, c, UARTDATA); txcnt = lpuart32_read(&sport->port, UARTWATER); txcnt = txcnt >> UARTWATER_TXCNT_OFF; txcnt &= UARTWATER_COUNT_MASK; } - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS) uart_write_wakeup(&sport->port); - if (uart_circ_empty(xmit)) + if (kfifo_is_empty(&tport->xmit_fifo)) lpuart32_stop_tx(&sport->port); } @@ -793,10 +789,10 @@ static void lpuart_start_tx(struct uart_port *port) { struct lpuart_port *sport = container_of(port, struct lpuart_port, port); - unsigned char temp; + u8 cr2; - temp = readb(port->membase + UARTCR2); - writeb(temp | UARTCR2_TIE, port->membase + UARTCR2); + cr2 = readb(port->membase + UARTCR2); + writeb(cr2 | UARTCR2_TIE, port->membase + UARTCR2); if (sport->lpuart_dma_tx_use) { if (!lpuart_stopped_or_empty(port)) @@ -810,14 +806,14 @@ static void lpuart_start_tx(struct uart_port *port) static void lpuart32_start_tx(struct uart_port *port) { struct lpuart_port *sport = container_of(port, struct lpuart_port, port); - unsigned long temp; + u32 ctrl; if (sport->lpuart_dma_tx_use) { if (!lpuart_stopped_or_empty(port)) lpuart_dma_tx(sport); } else { - temp = lpuart32_read(port, UARTCTRL); - lpuart32_write(port, temp | UARTCTRL_TIE, UARTCTRL); + ctrl = lpuart32_read(port, UARTCTRL); + lpuart32_write(port, ctrl | UARTCTRL_TIE, UARTCTRL); if (lpuart32_read(port, UARTSTAT) & UARTSTAT_TDRE) lpuart32_transmit_buffer(sport); @@ -843,8 +839,8 @@ static unsigned int lpuart_tx_empty(struct uart_port *port) { struct lpuart_port *sport = container_of(port, struct lpuart_port, port); - unsigned char sr1 = readb(port->membase + UARTSR1); - unsigned char sfifo = readb(port->membase + UARTSFIFO); + u8 sr1 = readb(port->membase + UARTSR1); + u8 sfifo = readb(port->membase + UARTSFIFO); if (sport->dma_tx_in_progress) return 0; @@ -859,9 +855,9 @@ static unsigned int lpuart32_tx_empty(struct uart_port *port) { struct lpuart_port *sport = container_of(port, struct lpuart_port, port); - unsigned long stat = lpuart32_read(port, UARTSTAT); - unsigned long sfifo = lpuart32_read(port, UARTFIFO); - unsigned long ctrl = lpuart32_read(port, UARTCTRL); + u32 stat = lpuart32_read(port, UARTSTAT); + u32 sfifo = lpuart32_read(port, UARTFIFO); + u32 ctrl = lpuart32_read(port, UARTCTRL); if (sport->dma_tx_in_progress) return 0; @@ -888,7 +884,7 @@ static void lpuart_rxint(struct lpuart_port *sport) { unsigned int flg, ignored = 0, overrun = 0; struct tty_port *port = &sport->port.state->port; - unsigned char rx, sr; + u8 rx, sr; uart_port_lock(&sport->port); @@ -965,7 +961,7 @@ static void lpuart32_rxint(struct lpuart_port *sport) { unsigned int flg, ignored = 0; struct tty_port *port = &sport->port.state->port; - unsigned long rx, sr; + u32 rx, sr; bool is_break; uart_port_lock(&sport->port); @@ -1043,7 +1039,7 @@ out: static irqreturn_t lpuart_int(int irq, void *dev_id) { struct lpuart_port *sport = dev_id; - unsigned char sts; + u8 sts; sts = readb(sport->port.membase + UARTSR1); @@ -1117,7 +1113,7 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport) int count, copied; if (lpuart_is_32(sport)) { - unsigned long sr = lpuart32_read(&sport->port, UARTSTAT); + u32 sr = lpuart32_read(&sport->port, UARTSTAT); if (sr & (UARTSTAT_PE | UARTSTAT_FE)) { /* Clear the error flags */ @@ -1129,10 +1125,10 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport) sport->port.icount.frame++; } } else { - unsigned char sr = readb(sport->port.membase + UARTSR1); + u8 sr = readb(sport->port.membase + UARTSR1); if (sr & (UARTSR1_PE | UARTSR1_FE)) { - unsigned char cr2; + u8 cr2; /* Disable receiver during this operation... */ cr2 = readb(sport->port.membase + UARTCR2); @@ -1283,7 +1279,7 @@ static void lpuart32_dma_idleint(struct lpuart_port *sport) static irqreturn_t lpuart32_int(int irq, void *dev_id) { struct lpuart_port *sport = dev_id; - unsigned long sts, rxcount; + u32 sts, rxcount; sts = lpuart32_read(&sport->port, UARTSTAT); rxcount = lpuart32_read(&sport->port, UARTWATER); @@ -1311,7 +1307,7 @@ static irqreturn_t lpuart32_int(int irq, void *dev_id) */ static void lpuart_timer_func(struct timer_list *t) { - struct lpuart_port *sport = from_timer(sport, t, lpuart_timer); + struct lpuart_port *sport = timer_container_of(sport, t, lpuart_timer); enum dma_status dmastat; struct dma_chan *chan = sport->dma_rx_chan; struct circ_buf *ring = &sport->rx_ring; @@ -1415,12 +1411,12 @@ static inline int lpuart_start_rx_dma(struct lpuart_port *sport) dma_async_issue_pending(chan); if (lpuart_is_32(sport)) { - unsigned long temp = lpuart32_read(&sport->port, UARTBAUD); + u32 baud = lpuart32_read(&sport->port, UARTBAUD); - lpuart32_write(&sport->port, temp | UARTBAUD_RDMAE, UARTBAUD); + lpuart32_write(&sport->port, baud | UARTBAUD_RDMAE, UARTBAUD); if (sport->dma_idle_int) { - unsigned long ctrl = lpuart32_read(&sport->port, UARTCTRL); + u32 ctrl = lpuart32_read(&sport->port, UARTCTRL); lpuart32_write(&sport->port, ctrl | UARTCTRL_ILIE, UARTCTRL); } @@ -1440,7 +1436,7 @@ static void lpuart_dma_rx_free(struct uart_port *port) dmaengine_terminate_sync(chan); if (!sport->dma_idle_int) - del_timer_sync(&sport->lpuart_timer); + timer_delete_sync(&sport->lpuart_timer); dma_unmap_sg(chan->device->dev, &sport->rx_sgl, 1, DMA_FROM_DEVICE); kfree(sport->rx_ring.buf); @@ -1453,12 +1449,9 @@ static void lpuart_dma_rx_free(struct uart_port *port) static int lpuart_config_rs485(struct uart_port *port, struct ktermios *termios, struct serial_rs485 *rs485) { - struct lpuart_port *sport = container_of(port, - struct lpuart_port, port); - - u8 modem = readb(sport->port.membase + UARTMODEM) & + u8 modem = readb(port->membase + UARTMODEM) & ~(UARTMODEM_TXRTSPOL | UARTMODEM_TXRTSE); - writeb(modem, sport->port.membase + UARTMODEM); + writeb(modem, port->membase + UARTMODEM); if (rs485->flags & SER_RS485_ENABLED) { /* Enable auto RS-485 RTS mode */ @@ -1476,19 +1469,29 @@ static int lpuart_config_rs485(struct uart_port *port, struct ktermios *termios, modem &= ~UARTMODEM_TXRTSPOL; } - writeb(modem, sport->port.membase + UARTMODEM); + writeb(modem, port->membase + UARTMODEM); return 0; } static int lpuart32_config_rs485(struct uart_port *port, struct ktermios *termios, struct serial_rs485 *rs485) { - struct lpuart_port *sport = container_of(port, - struct lpuart_port, port); - - unsigned long modem = lpuart32_read(&sport->port, UARTMODIR) + u32 modem = lpuart32_read(port, UARTMODIR) & ~(UARTMODIR_TXRTSPOL | UARTMODIR_TXRTSE); - lpuart32_write(&sport->port, modem, UARTMODIR); + u32 ctrl; + + /* TXRTSE and TXRTSPOL only can be changed when transmitter is disabled. */ + ctrl = lpuart32_read(port, UARTCTRL); + if (ctrl & UARTCTRL_TE) { + /* wait for the transmit engine to complete */ + lpuart32_wait_bit_set(port, UARTSTAT, UARTSTAT_TC); + lpuart32_write(port, ctrl & ~UARTCTRL_TE, UARTCTRL); + + while (lpuart32_read(port, UARTCTRL) & UARTCTRL_TE) + cpu_relax(); + } + + lpuart32_write(port, modem, UARTMODIR); if (rs485->flags & SER_RS485_ENABLED) { /* Enable auto RS-485 RTS mode */ @@ -1506,17 +1509,21 @@ static int lpuart32_config_rs485(struct uart_port *port, struct ktermios *termio modem &= ~UARTMODIR_TXRTSPOL; } - lpuart32_write(&sport->port, modem, UARTMODIR); + lpuart32_write(port, modem, UARTMODIR); + + if (ctrl & UARTCTRL_TE) + lpuart32_write(port, ctrl, UARTCTRL); + return 0; } static unsigned int lpuart_get_mctrl(struct uart_port *port) { unsigned int mctrl = 0; - u8 reg; + u8 cr1; - reg = readb(port->membase + UARTCR1); - if (reg & UARTCR1_LOOPS) + cr1 = readb(port->membase + UARTCR1); + if (cr1 & UARTCR1_LOOPS) mctrl |= TIOCM_LOOP; return mctrl; @@ -1525,10 +1532,10 @@ static unsigned int lpuart_get_mctrl(struct uart_port *port) static unsigned int lpuart32_get_mctrl(struct uart_port *port) { unsigned int mctrl = TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; - u32 reg; + u32 ctrl; - reg = lpuart32_read(port, UARTCTRL); - if (reg & UARTCTRL_LOOPS) + ctrl = lpuart32_read(port, UARTCTRL); + if (ctrl & UARTCTRL_LOOPS) mctrl |= TIOCM_LOOP; return mctrl; @@ -1536,49 +1543,49 @@ static unsigned int lpuart32_get_mctrl(struct uart_port *port) static void lpuart_set_mctrl(struct uart_port *port, unsigned int mctrl) { - u8 reg; + u8 cr1; - reg = readb(port->membase + UARTCR1); + cr1 = readb(port->membase + UARTCR1); /* for internal loopback we need LOOPS=1 and RSRC=0 */ - reg &= ~(UARTCR1_LOOPS | UARTCR1_RSRC); + cr1 &= ~(UARTCR1_LOOPS | UARTCR1_RSRC); if (mctrl & TIOCM_LOOP) - reg |= UARTCR1_LOOPS; + cr1 |= UARTCR1_LOOPS; - writeb(reg, port->membase + UARTCR1); + writeb(cr1, port->membase + UARTCR1); } static void lpuart32_set_mctrl(struct uart_port *port, unsigned int mctrl) { - u32 reg; + u32 ctrl; - reg = lpuart32_read(port, UARTCTRL); + ctrl = lpuart32_read(port, UARTCTRL); /* for internal loopback we need LOOPS=1 and RSRC=0 */ - reg &= ~(UARTCTRL_LOOPS | UARTCTRL_RSRC); + ctrl &= ~(UARTCTRL_LOOPS | UARTCTRL_RSRC); if (mctrl & TIOCM_LOOP) - reg |= UARTCTRL_LOOPS; + ctrl |= UARTCTRL_LOOPS; - lpuart32_write(port, reg, UARTCTRL); + lpuart32_write(port, ctrl, UARTCTRL); } static void lpuart_break_ctl(struct uart_port *port, int break_state) { - unsigned char temp; + u8 cr2; - temp = readb(port->membase + UARTCR2) & ~UARTCR2_SBK; + cr2 = readb(port->membase + UARTCR2) & ~UARTCR2_SBK; if (break_state != 0) - temp |= UARTCR2_SBK; + cr2 |= UARTCR2_SBK; - writeb(temp, port->membase + UARTCR2); + writeb(cr2, port->membase + UARTCR2); } static void lpuart32_break_ctl(struct uart_port *port, int break_state) { - unsigned long temp; + u32 ctrl; - temp = lpuart32_read(port, UARTCTRL); + ctrl = lpuart32_read(port, UARTCTRL); /* * LPUART IP now has two known bugs, one is CTS has higher priority than the @@ -1595,23 +1602,22 @@ static void lpuart32_break_ctl(struct uart_port *port, int break_state) * Disable the transmitter to prevent any data from being sent out * during break, then invert the TX line to send break. */ - temp &= ~UARTCTRL_TE; - lpuart32_write(port, temp, UARTCTRL); - temp |= UARTCTRL_TXINV; - lpuart32_write(port, temp, UARTCTRL); + ctrl &= ~UARTCTRL_TE; + lpuart32_write(port, ctrl, UARTCTRL); + ctrl |= UARTCTRL_TXINV; + lpuart32_write(port, ctrl, UARTCTRL); } else { /* Disable the TXINV to turn off break and re-enable transmitter. */ - temp &= ~UARTCTRL_TXINV; - lpuart32_write(port, temp, UARTCTRL); - temp |= UARTCTRL_TE; - lpuart32_write(port, temp, UARTCTRL); + ctrl &= ~UARTCTRL_TXINV; + lpuart32_write(port, ctrl, UARTCTRL); + ctrl |= UARTCTRL_TE; + lpuart32_write(port, ctrl, UARTCTRL); } } static void lpuart_setup_watermark(struct lpuart_port *sport) { - unsigned char val, cr2; - unsigned char cr2_saved; + u8 fifo, cr2, cr2_saved; cr2 = readb(sport->port.membase + UARTCR2); cr2_saved = cr2; @@ -1619,8 +1625,8 @@ static void lpuart_setup_watermark(struct lpuart_port *sport) UARTCR2_RIE | UARTCR2_RE); writeb(cr2, sport->port.membase + UARTCR2); - val = readb(sport->port.membase + UARTPFIFO); - writeb(val | UARTPFIFO_TXFE | UARTPFIFO_RXFE, + fifo = readb(sport->port.membase + UARTPFIFO); + writeb(fifo | UARTPFIFO_TXFE | UARTPFIFO_RXFE, sport->port.membase + UARTPFIFO); /* flush Tx and Rx FIFO */ @@ -1644,7 +1650,7 @@ static void lpuart_setup_watermark(struct lpuart_port *sport) static void lpuart_setup_watermark_enable(struct lpuart_port *sport) { - unsigned char cr2; + u8 cr2; lpuart_setup_watermark(sport); @@ -1655,8 +1661,7 @@ static void lpuart_setup_watermark_enable(struct lpuart_port *sport) static void lpuart32_setup_watermark(struct lpuart_port *sport) { - unsigned long val, ctrl; - unsigned long ctrl_saved; + u32 val, ctrl, ctrl_saved; ctrl = lpuart32_read(&sport->port, UARTCTRL); ctrl_saved = ctrl; @@ -1691,14 +1696,14 @@ static void lpuart32_setup_watermark(struct lpuart_port *sport) static void lpuart32_setup_watermark_enable(struct lpuart_port *sport) { - u32 temp; + u32 ctrl; lpuart32_setup_watermark(sport); - temp = lpuart32_read(&sport->port, UARTCTRL); - temp |= UARTCTRL_RE | UARTCTRL_TE; - temp |= FIELD_PREP(UARTCTRL_IDLECFG, 0x7); - lpuart32_write(&sport->port, temp, UARTCTRL); + ctrl = lpuart32_read(&sport->port, UARTCTRL); + ctrl |= UARTCTRL_RE | UARTCTRL_TE; + ctrl |= FIELD_PREP(UARTCTRL_IDLECFG, 0x7); + lpuart32_write(&sport->port, ctrl, UARTCTRL); } static void rx_dma_timer_init(struct lpuart_port *sport) @@ -1765,7 +1770,7 @@ err: static void lpuart_rx_dma_startup(struct lpuart_port *sport) { int ret; - unsigned char cr3; + u8 cr3; if (uart_console(&sport->port)) goto err; @@ -1815,16 +1820,16 @@ static void lpuart_hw_setup(struct lpuart_port *sport) static int lpuart_startup(struct uart_port *port) { struct lpuart_port *sport = container_of(port, struct lpuart_port, port); - unsigned char temp; + u8 fifo; /* determine FIFO size and enable FIFO mode */ - temp = readb(sport->port.membase + UARTPFIFO); + fifo = readb(port->membase + UARTPFIFO); - sport->txfifo_size = UARTFIFO_DEPTH((temp >> UARTPFIFO_TXSIZE_OFF) & + sport->txfifo_size = UARTFIFO_DEPTH((fifo >> UARTPFIFO_TXSIZE_OFF) & UARTPFIFO_FIFOSIZE_MASK); - sport->port.fifosize = sport->txfifo_size; + port->fifosize = sport->txfifo_size; - sport->rxfifo_size = UARTFIFO_DEPTH((temp >> UARTPFIFO_RXSIZE_OFF) & + sport->rxfifo_size = UARTFIFO_DEPTH((fifo >> UARTPFIFO_RXSIZE_OFF) & UARTPFIFO_FIFOSIZE_MASK); lpuart_request_dma(sport); @@ -1835,24 +1840,24 @@ static int lpuart_startup(struct uart_port *port) static void lpuart32_hw_disable(struct lpuart_port *sport) { - unsigned long temp; + u32 ctrl; - temp = lpuart32_read(&sport->port, UARTCTRL); - temp &= ~(UARTCTRL_RIE | UARTCTRL_ILIE | UARTCTRL_RE | + ctrl = lpuart32_read(&sport->port, UARTCTRL); + ctrl &= ~(UARTCTRL_RIE | UARTCTRL_ILIE | UARTCTRL_RE | UARTCTRL_TIE | UARTCTRL_TE); - lpuart32_write(&sport->port, temp, UARTCTRL); + lpuart32_write(&sport->port, ctrl, UARTCTRL); } static void lpuart32_configure(struct lpuart_port *sport) { - unsigned long temp; + u32 ctrl; - temp = lpuart32_read(&sport->port, UARTCTRL); + ctrl = lpuart32_read(&sport->port, UARTCTRL); if (!sport->lpuart_dma_rx_use) - temp |= UARTCTRL_RIE | UARTCTRL_ILIE; + ctrl |= UARTCTRL_RIE | UARTCTRL_ILIE; if (!sport->lpuart_dma_tx_use) - temp |= UARTCTRL_TIE; - lpuart32_write(&sport->port, temp, UARTCTRL); + ctrl |= UARTCTRL_TIE; + lpuart32_write(&sport->port, ctrl, UARTCTRL); } static void lpuart32_hw_setup(struct lpuart_port *sport) @@ -1875,16 +1880,16 @@ static void lpuart32_hw_setup(struct lpuart_port *sport) static int lpuart32_startup(struct uart_port *port) { struct lpuart_port *sport = container_of(port, struct lpuart_port, port); - unsigned long temp; + u32 fifo; /* determine FIFO size */ - temp = lpuart32_read(&sport->port, UARTFIFO); + fifo = lpuart32_read(port, UARTFIFO); - sport->txfifo_size = UARTFIFO_DEPTH((temp >> UARTFIFO_TXSIZE_OFF) & + sport->txfifo_size = UARTFIFO_DEPTH((fifo >> UARTFIFO_TXSIZE_OFF) & UARTFIFO_FIFOSIZE_MASK); - sport->port.fifosize = sport->txfifo_size; + port->fifosize = sport->txfifo_size; - sport->rxfifo_size = UARTFIFO_DEPTH((temp >> UARTFIFO_RXSIZE_OFF) & + sport->rxfifo_size = UARTFIFO_DEPTH((fifo >> UARTFIFO_RXSIZE_OFF) & UARTFIFO_FIFOSIZE_MASK); /* @@ -1895,7 +1900,7 @@ static int lpuart32_startup(struct uart_port *port) if (is_layerscape_lpuart(sport)) { sport->rxfifo_size = 16; sport->txfifo_size = 16; - sport->port.fifosize = sport->txfifo_size; + port->fifosize = sport->txfifo_size; } lpuart_request_dma(sport); @@ -1929,16 +1934,16 @@ static void lpuart_dma_shutdown(struct lpuart_port *sport) static void lpuart_shutdown(struct uart_port *port) { struct lpuart_port *sport = container_of(port, struct lpuart_port, port); - unsigned char temp; + u8 cr2; unsigned long flags; uart_port_lock_irqsave(port, &flags); /* disable Rx/Tx and interrupts */ - temp = readb(port->membase + UARTCR2); - temp &= ~(UARTCR2_TE | UARTCR2_RE | + cr2 = readb(port->membase + UARTCR2); + cr2 &= ~(UARTCR2_TE | UARTCR2_RE | UARTCR2_TIE | UARTCR2_TCIE | UARTCR2_RIE); - writeb(temp, port->membase + UARTCR2); + writeb(cr2, port->membase + UARTCR2); uart_port_unlock_irqrestore(port, flags); @@ -1949,14 +1954,14 @@ static void lpuart32_shutdown(struct uart_port *port) { struct lpuart_port *sport = container_of(port, struct lpuart_port, port); - unsigned long temp; + u32 temp; unsigned long flags; uart_port_lock_irqsave(port, &flags); /* clear status */ - temp = lpuart32_read(&sport->port, UARTSTAT); - lpuart32_write(&sport->port, temp, UARTSTAT); + temp = lpuart32_read(port, UARTSTAT); + lpuart32_write(port, temp, UARTSTAT); /* disable Rx/Tx DMA */ temp = lpuart32_read(port, UARTBAUD); @@ -1969,6 +1974,11 @@ static void lpuart32_shutdown(struct uart_port *port) UARTCTRL_TIE | UARTCTRL_TCIE | UARTCTRL_RIE | UARTCTRL_SBK); lpuart32_write(port, temp, UARTCTRL); + /* flush Rx/Tx FIFO */ + temp = lpuart32_read(port, UARTFIFO); + temp |= UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH; + lpuart32_write(port, temp, UARTFIFO); + uart_port_unlock_irqrestore(port, flags); lpuart_dma_shutdown(sport); @@ -1980,17 +1990,17 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios, { struct lpuart_port *sport = container_of(port, struct lpuart_port, port); unsigned long flags; - unsigned char cr1, old_cr1, old_cr2, cr3, cr4, bdh, modem; + u8 cr1, old_cr1, old_cr2, cr3, cr4, bdh, modem; unsigned int baud; unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; unsigned int sbr, brfa; - cr1 = old_cr1 = readb(sport->port.membase + UARTCR1); - old_cr2 = readb(sport->port.membase + UARTCR2); - cr3 = readb(sport->port.membase + UARTCR3); - cr4 = readb(sport->port.membase + UARTCR4); - bdh = readb(sport->port.membase + UARTBDH); - modem = readb(sport->port.membase + UARTMODEM); + cr1 = old_cr1 = readb(port->membase + UARTCR1); + old_cr2 = readb(port->membase + UARTCR2); + cr3 = readb(port->membase + UARTCR3); + cr4 = readb(port->membase + UARTCR4); + bdh = readb(port->membase + UARTBDH); + modem = readb(port->membase + UARTMODEM); /* * only support CS8 and CS7, and for CS7 must enable PE. * supported mode: @@ -2022,7 +2032,7 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios, * When auto RS-485 RTS mode is enabled, * hardware flow control need to be disabled. */ - if (sport->port.rs485.flags & SER_RS485_ENABLED) + if (port->rs485.flags & SER_RS485_ENABLED) termios->c_cflag &= ~CRTSCTS; if (termios->c_cflag & CRTSCTS) @@ -2063,59 +2073,59 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios, * Need to update the Ring buffer length according to the selected * baud rate and restart Rx DMA path. * - * Since timer function acqures sport->port.lock, need to stop before - * acquring same lock because otherwise del_timer_sync() can deadlock. + * Since timer function acqures port->lock, need to stop before + * acquring same lock because otherwise timer_delete_sync() can deadlock. */ if (old && sport->lpuart_dma_rx_use) - lpuart_dma_rx_free(&sport->port); + lpuart_dma_rx_free(port); - uart_port_lock_irqsave(&sport->port, &flags); + uart_port_lock_irqsave(port, &flags); - sport->port.read_status_mask = 0; + port->read_status_mask = 0; if (termios->c_iflag & INPCK) - sport->port.read_status_mask |= UARTSR1_FE | UARTSR1_PE; + port->read_status_mask |= UARTSR1_FE | UARTSR1_PE; if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK)) - sport->port.read_status_mask |= UARTSR1_FE; + port->read_status_mask |= UARTSR1_FE; /* characters to ignore */ - sport->port.ignore_status_mask = 0; + port->ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) - sport->port.ignore_status_mask |= UARTSR1_PE; + port->ignore_status_mask |= UARTSR1_PE; if (termios->c_iflag & IGNBRK) { - sport->port.ignore_status_mask |= UARTSR1_FE; + port->ignore_status_mask |= UARTSR1_FE; /* * if we're ignoring parity and break indicators, * ignore overruns too (for real raw support). */ if (termios->c_iflag & IGNPAR) - sport->port.ignore_status_mask |= UARTSR1_OR; + port->ignore_status_mask |= UARTSR1_OR; } /* update the per-port timeout */ uart_update_timeout(port, termios->c_cflag, baud); /* wait transmit engin complete */ - lpuart_wait_bit_set(&sport->port, UARTSR1, UARTSR1_TC); + lpuart_wait_bit_set(port, UARTSR1, UARTSR1_TC); /* disable transmit and receive */ writeb(old_cr2 & ~(UARTCR2_TE | UARTCR2_RE), - sport->port.membase + UARTCR2); + port->membase + UARTCR2); - sbr = sport->port.uartclk / (16 * baud); - brfa = ((sport->port.uartclk - (16 * sbr * baud)) * 2) / baud; + sbr = port->uartclk / (16 * baud); + brfa = ((port->uartclk - (16 * sbr * baud)) * 2) / baud; bdh &= ~UARTBDH_SBR_MASK; bdh |= (sbr >> 8) & 0x1F; cr4 &= ~UARTCR4_BRFA_MASK; brfa &= UARTCR4_BRFA_MASK; - writeb(cr4 | brfa, sport->port.membase + UARTCR4); - writeb(bdh, sport->port.membase + UARTBDH); - writeb(sbr & 0xFF, sport->port.membase + UARTBDL); - writeb(cr3, sport->port.membase + UARTCR3); - writeb(cr1, sport->port.membase + UARTCR1); - writeb(modem, sport->port.membase + UARTMODEM); + writeb(cr4 | brfa, port->membase + UARTCR4); + writeb(bdh, port->membase + UARTBDH); + writeb(sbr & 0xFF, port->membase + UARTBDL); + writeb(cr3, port->membase + UARTCR3); + writeb(cr1, port->membase + UARTCR1); + writeb(modem, port->membase + UARTMODEM); /* restore control register */ - writeb(old_cr2, sport->port.membase + UARTCR2); + writeb(old_cr2, port->membase + UARTCR2); if (old && sport->lpuart_dma_rx_use) { if (!lpuart_start_rx_dma(sport)) @@ -2124,14 +2134,14 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios, sport->lpuart_dma_rx_use = false; } - uart_port_unlock_irqrestore(&sport->port, flags); + uart_port_unlock_irqrestore(port, flags); } static void __lpuart32_serial_setbrg(struct uart_port *port, unsigned int baudrate, bool use_rx_dma, bool use_tx_dma) { - u32 sbr, osr, baud_diff, tmp_osr, tmp_sbr, tmp_diff, tmp; + u32 sbr, osr, baud_diff, tmp_osr, tmp_sbr, tmp_diff, baud; u32 clk = port->uartclk; /* @@ -2160,9 +2170,9 @@ static void __lpuart32_serial_setbrg(struct uart_port *port, tmp_diff = clk / (tmp_osr * tmp_sbr) - baudrate; /* select best values between sbr and sbr+1 */ - tmp = clk / (tmp_osr * (tmp_sbr + 1)); - if (tmp_diff > (baudrate - tmp)) { - tmp_diff = baudrate - tmp; + baud = clk / (tmp_osr * (tmp_sbr + 1)); + if (tmp_diff > (baudrate - baud)) { + tmp_diff = baudrate - baud; tmp_sbr++; } @@ -2184,23 +2194,23 @@ static void __lpuart32_serial_setbrg(struct uart_port *port, dev_warn(port->dev, "unacceptable baud rate difference of more than 3%%\n"); - tmp = lpuart32_read(port, UARTBAUD); + baud = lpuart32_read(port, UARTBAUD); if ((osr > 3) && (osr < 8)) - tmp |= UARTBAUD_BOTHEDGE; + baud |= UARTBAUD_BOTHEDGE; - tmp &= ~(UARTBAUD_OSR_MASK << UARTBAUD_OSR_SHIFT); - tmp |= ((osr-1) & UARTBAUD_OSR_MASK) << UARTBAUD_OSR_SHIFT; + baud &= ~(UARTBAUD_OSR_MASK << UARTBAUD_OSR_SHIFT); + baud |= ((osr-1) & UARTBAUD_OSR_MASK) << UARTBAUD_OSR_SHIFT; - tmp &= ~UARTBAUD_SBR_MASK; - tmp |= sbr & UARTBAUD_SBR_MASK; + baud &= ~UARTBAUD_SBR_MASK; + baud |= sbr & UARTBAUD_SBR_MASK; if (!use_rx_dma) - tmp &= ~UARTBAUD_RDMAE; + baud &= ~UARTBAUD_RDMAE; if (!use_tx_dma) - tmp &= ~UARTBAUD_TDMAE; + baud &= ~UARTBAUD_TDMAE; - lpuart32_write(port, tmp, UARTBAUD); + lpuart32_write(port, baud, UARTBAUD); } static void lpuart32_serial_setbrg(struct lpuart_port *sport, @@ -2218,17 +2228,18 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios, { struct lpuart_port *sport = container_of(port, struct lpuart_port, port); unsigned long flags; - unsigned long ctrl, old_ctrl, bd, modem; + u32 ctrl, old_ctrl, bd, modem; unsigned int baud; unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; - ctrl = old_ctrl = lpuart32_read(&sport->port, UARTCTRL); - bd = lpuart32_read(&sport->port, UARTBAUD); - modem = lpuart32_read(&sport->port, UARTMODIR); + ctrl = old_ctrl = lpuart32_read(port, UARTCTRL); + bd = lpuart32_read(port, UARTBAUD); + modem = lpuart32_read(port, UARTMODIR); sport->is_cs7 = false; /* - * only support CS8 and CS7, and for CS7 must enable PE. + * only support CS8 and CS7 * supported mode: + * - (7,n,1) (imx only) * - (7,e/o,1) * - (8,n,1) * - (8,m/s,1) @@ -2243,7 +2254,7 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios, if ((termios->c_cflag & CSIZE) == CS8 || (termios->c_cflag & CSIZE) == CS7) - ctrl = old_ctrl & ~UARTCTRL_M; + ctrl = old_ctrl & ~(UARTCTRL_M | UARTCTRL_M7); if (termios->c_cflag & CMSPAR) { if ((termios->c_cflag & CSIZE) != CS8) { @@ -2257,7 +2268,7 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios, * When auto RS-485 RTS mode is enabled, * hardware flow control need to be disabled. */ - if (sport->port.rs485.flags & SER_RS485_ENABLED) + if (port->rs485.flags & SER_RS485_ENABLED) termios->c_cflag &= ~CRTSCTS; if (termios->c_cflag & CRTSCTS) @@ -2270,9 +2281,18 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios, else bd &= ~UARTBAUD_SBNS; - /* parity must be enabled when CS7 to match 8-bits format */ - if ((termios->c_cflag & CSIZE) == CS7) - termios->c_cflag |= PARENB; + /* + * imx support 7-bits format, no limitation on parity when CS7 + * for layerscape, parity must be enabled when CS7 to match 8-bits format + */ + if ((termios->c_cflag & CSIZE) == CS7 && !(termios->c_cflag & PARENB)) { + if (is_imx7ulp_lpuart(sport) || + is_imx8ulp_lpuart(sport) || + is_imx8qxp_lpuart(sport)) + ctrl |= UARTCTRL_M7; + else + termios->c_cflag |= PARENB; + } if ((termios->c_cflag & PARENB)) { if (termios->c_cflag & CMSPAR) { @@ -2298,59 +2318,61 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios, * Need to update the Ring buffer length according to the selected * baud rate and restart Rx DMA path. * - * Since timer function acqures sport->port.lock, need to stop before - * acquring same lock because otherwise del_timer_sync() can deadlock. + * Since timer function acqures port->lock, need to stop before + * acquring same lock because otherwise timer_delete_sync() can deadlock. */ if (old && sport->lpuart_dma_rx_use) - lpuart_dma_rx_free(&sport->port); + lpuart_dma_rx_free(port); - uart_port_lock_irqsave(&sport->port, &flags); + uart_port_lock_irqsave(port, &flags); - sport->port.read_status_mask = 0; + port->read_status_mask = 0; if (termios->c_iflag & INPCK) - sport->port.read_status_mask |= UARTSTAT_FE | UARTSTAT_PE; + port->read_status_mask |= UARTSTAT_FE | UARTSTAT_PE; if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK)) - sport->port.read_status_mask |= UARTSTAT_FE; + port->read_status_mask |= UARTSTAT_FE; /* characters to ignore */ - sport->port.ignore_status_mask = 0; + port->ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) - sport->port.ignore_status_mask |= UARTSTAT_PE; + port->ignore_status_mask |= UARTSTAT_PE; if (termios->c_iflag & IGNBRK) { - sport->port.ignore_status_mask |= UARTSTAT_FE; + port->ignore_status_mask |= UARTSTAT_FE; /* * if we're ignoring parity and break indicators, * ignore overruns too (for real raw support). */ if (termios->c_iflag & IGNPAR) - sport->port.ignore_status_mask |= UARTSTAT_OR; + port->ignore_status_mask |= UARTSTAT_OR; } /* update the per-port timeout */ uart_update_timeout(port, termios->c_cflag, baud); /* + * disable CTS to ensure the transmit engine is not blocked by the flow + * control when there is dirty data in TX FIFO + */ + lpuart32_write(port, modem & ~UARTMODIR_TXCTSE, UARTMODIR); + + /* * LPUART Transmission Complete Flag may never be set while queuing a break * character, so skip waiting for transmission complete when UARTCTRL_SBK is * asserted. */ - if (!(old_ctrl & UARTCTRL_SBK)) { - lpuart32_write(&sport->port, 0, UARTMODIR); - lpuart32_wait_bit_set(&sport->port, UARTSTAT, UARTSTAT_TC); - } + if (!(old_ctrl & UARTCTRL_SBK)) + lpuart32_wait_bit_set(port, UARTSTAT, UARTSTAT_TC); /* disable transmit and receive */ - lpuart32_write(&sport->port, old_ctrl & ~(UARTCTRL_TE | UARTCTRL_RE), + lpuart32_write(port, old_ctrl & ~(UARTCTRL_TE | UARTCTRL_RE), UARTCTRL); - lpuart32_write(&sport->port, bd, UARTBAUD); + lpuart32_write(port, bd, UARTBAUD); lpuart32_serial_setbrg(sport, baud); - /* disable CTS before enabling UARTCTRL_TE to avoid pending idle preamble */ - lpuart32_write(&sport->port, modem & ~UARTMODIR_TXCTSE, UARTMODIR); /* restore control register */ - lpuart32_write(&sport->port, ctrl, UARTCTRL); + lpuart32_write(port, ctrl, UARTCTRL); /* re-enable the CTS if needed */ - lpuart32_write(&sport->port, modem, UARTMODIR); + lpuart32_write(port, modem, UARTMODIR); if ((ctrl & (UARTCTRL_PE | UARTCTRL_M)) == UARTCTRL_PE) sport->is_cs7 = true; @@ -2362,7 +2384,7 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios, sport->lpuart_dma_rx_use = false; } - uart_port_unlock_irqrestore(&sport->port, flags); + uart_port_unlock_irqrestore(port, flags); } static const char *lpuart_type(struct uart_port *port) @@ -2475,7 +2497,7 @@ static void lpuart_console_write(struct console *co, const char *s, unsigned int count) { struct lpuart_port *sport = lpuart_ports[co->index]; - unsigned char old_cr2, cr2; + u8 old_cr2, cr2; unsigned long flags; int locked = 1; @@ -2505,7 +2527,7 @@ static void lpuart32_console_write(struct console *co, const char *s, unsigned int count) { struct lpuart_port *sport = lpuart_ports[co->index]; - unsigned long old_cr, cr; + u32 old_cr, cr; unsigned long flags; int locked = 1; @@ -2539,7 +2561,7 @@ static void __init lpuart_console_get_options(struct lpuart_port *sport, int *baud, int *parity, int *bits) { - unsigned char cr, bdh, bdl, brfa; + u8 cr, bdh, bdl, brfa; unsigned int sbr, uartclk, baud_raw; cr = readb(sport->port.membase + UARTCR2); @@ -2588,7 +2610,7 @@ static void __init lpuart32_console_get_options(struct lpuart_port *sport, int *baud, int *parity, int *bits) { - unsigned long cr, bd; + u32 cr, bd; unsigned int sbr, uartclk, baud_raw; cr = lpuart32_read(&sport->port, UARTCTRL); @@ -2794,13 +2816,13 @@ static int lpuart_global_reset(struct lpuart_port *sport) { struct uart_port *port = &sport->port; void __iomem *global_addr; - unsigned long ctrl, bd; + u32 ctrl, bd; unsigned int val = 0; int ret; ret = clk_prepare_enable(sport->ipg_clk); if (ret) { - dev_err(sport->port.dev, "failed to enable uart ipg clk: %d\n", ret); + dev_err(port->dev, "failed to enable uart ipg clk: %d\n", ret); return ret; } @@ -2811,10 +2833,10 @@ static int lpuart_global_reset(struct lpuart_port *sport) */ ctrl = lpuart32_read(port, UARTCTRL); if (ctrl & UARTCTRL_TE) { - bd = lpuart32_read(&sport->port, UARTBAUD); + bd = lpuart32_read(port, UARTBAUD); if (read_poll_timeout(lpuart32_tx_empty, val, val, 1, 100000, false, port)) { - dev_warn(sport->port.dev, + dev_warn(port->dev, "timeout waiting for transmit engine to complete\n"); clk_disable_unprepare(sport->ipg_clk); return 0; @@ -2884,8 +2906,7 @@ static int lpuart_probe(struct platform_device *pdev) sport->ipg_clk = devm_clk_get(&pdev->dev, "ipg"); if (IS_ERR(sport->ipg_clk)) { ret = PTR_ERR(sport->ipg_clk); - dev_err(&pdev->dev, "failed to get uart ipg clk: %d\n", ret); - return ret; + return dev_err_probe(&pdev->dev, ret, "failed to get uart ipg clk\n"); } sport->baud_clk = NULL; @@ -2893,8 +2914,7 @@ static int lpuart_probe(struct platform_device *pdev) sport->baud_clk = devm_clk_get(&pdev->dev, "baud"); if (IS_ERR(sport->baud_clk)) { ret = PTR_ERR(sport->baud_clk); - dev_err(&pdev->dev, "failed to get uart baud clk: %d\n", ret); - return ret; + return dev_err_probe(&pdev->dev, ret, "failed to get uart baud clk\n"); } } @@ -2930,6 +2950,7 @@ static int lpuart_probe(struct platform_device *pdev) pm_runtime_set_autosuspend_delay(&pdev->dev, UART_AUTOSUSPEND_TIMEOUT); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); + pm_runtime_mark_last_busy(&pdev->dev); ret = lpuart_global_reset(sport); if (ret) @@ -2944,7 +2965,7 @@ static int lpuart_probe(struct platform_device *pdev) goto failed_attach_port; ret = devm_request_irq(&pdev->dev, sport->port.irq, handler, 0, - DRIVER_NAME, sport); + dev_name(&pdev->dev), sport); if (ret) goto failed_irq_request; @@ -3001,7 +3022,7 @@ static int lpuart_runtime_resume(struct device *dev) static void serial_lpuart_enable_wakeup(struct lpuart_port *sport, bool on) { - unsigned int val, baud; + u32 val, baud; if (lpuart_is_32(sport)) { val = lpuart32_read(&sport->port, UARTCTRL); @@ -3066,7 +3087,7 @@ static int lpuart_suspend_noirq(struct device *dev) static int lpuart_resume_noirq(struct device *dev) { struct lpuart_port *sport = dev_get_drvdata(dev); - unsigned int val; + u32 stat; pinctrl_pm_select_default_state(dev); @@ -3075,8 +3096,8 @@ static int lpuart_resume_noirq(struct device *dev) /* clear the wakeup flags */ if (lpuart_is_32(sport)) { - val = lpuart32_read(&sport->port, UARTSTAT); - lpuart32_write(&sport->port, val, UARTSTAT); + stat = lpuart32_read(&sport->port, UARTSTAT); + lpuart32_write(&sport->port, stat, UARTSTAT); } } @@ -3086,7 +3107,8 @@ static int lpuart_resume_noirq(struct device *dev) static int lpuart_suspend(struct device *dev) { struct lpuart_port *sport = dev_get_drvdata(dev); - unsigned long temp, flags; + u32 temp; + unsigned long flags; uart_suspend_port(&lpuart_reg, &sport->port); @@ -3166,7 +3188,7 @@ static void lpuart_console_fixup(struct lpuart_port *sport) * in VLLS mode, or restore console setting here. */ if (is_imx7ulp_lpuart(sport) && lpuart_uport_is_active(sport) && - console_suspend_enabled && uart_console(&sport->port)) { + console_suspend_enabled && uart_console(uport)) { mutex_lock(&port->mutex); memset(&termios, 0, sizeof(struct ktermios)); @@ -3212,7 +3234,7 @@ static const struct dev_pm_ops lpuart_pm_ops = { static struct platform_driver lpuart_driver = { .probe = lpuart_probe, - .remove_new = lpuart_remove, + .remove = lpuart_remove, .driver = { .name = "fsl-lpuart", .of_match_table = lpuart_dt_ids, |