From 52008ebd62adc4f7da2518d638555c765c63388e Mon Sep 17 00:00:00 2001 From: Liang Chen Date: Thu, 29 Apr 2021 16:11:43 +0800 Subject: [PATCH 001/227] dt-bindings: serial: snps-dw-apb-uart: add description for rk3568 add "rockchip,rk3568-uart", "snps,dw-apb-uart" for uart nodes on a rk3568 platform to snps-dw-apb-uart.yaml. Signed-off-by: Liang Chen Acked-by: Rob Herring Link: https://lore.kernel.org/r/20210429081151.17558-3-cl@rock-chips.com Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml index 87ef1e218152..97debbf68748 100644 --- a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml +++ b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml @@ -31,6 +31,7 @@ properties: - rockchip,rk3328-uart - rockchip,rk3368-uart - rockchip,rk3399-uart + - rockchip,rk3568-uart - rockchip,rv1108-uart - const: snps,dw-apb-uart - items: From fcb10ee27fb91b25b68d7745db9817ecea9f1038 Mon Sep 17 00:00:00 2001 From: Sherry Sun Date: Tue, 27 Apr 2021 10:12:26 +0800 Subject: [PATCH 002/227] tty: serial: fsl_lpuart: fix the potential risk of division or modulo by zero We should be very careful about the register values that will be used for division or modulo operations, althrough the possibility that the UARTBAUD register value is zero is very low, but we had better to deal with the "bad data" of hardware in advance to avoid division or modulo by zero leading to undefined kernel behavior. Signed-off-by: Sherry Sun Link: https://lore.kernel.org/r/20210427021226.27468-1-sherry.sun@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 794035041744..777d54b593f8 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -2414,6 +2414,9 @@ lpuart32_console_get_options(struct lpuart_port *sport, int *baud, bd = lpuart32_read(&sport->port, UARTBAUD); bd &= UARTBAUD_SBR_MASK; + if (!bd) + return; + sbr = bd; uartclk = lpuart_get_baud_clk_rate(sport); /* From ccf08fd1204bcb5311cc10aea037c71c6e74720a Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 12 May 2021 16:12:47 +0200 Subject: [PATCH 003/227] serial: fsl_lpuart: don't modify arbitrary data on lpuart32 lpuart_rx_dma_startup() is used for both the 8 bit and the 32 bit version of the LPUART. Modify the UARTCR only for the 8 bit version. Fixes: f4eef224a09f ("serial: fsl_lpuart: add sysrq support when using dma") Signed-off-by: Michael Walle Link: https://lore.kernel.org/r/20210512141255.18277-2-michael@walle.cc Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 777d54b593f8..120527cb8a81 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1625,7 +1625,7 @@ static void lpuart_rx_dma_startup(struct lpuart_port *sport) sport->lpuart_dma_rx_use = true; rx_dma_timer_init(sport); - if (sport->port.has_sysrq) { + if (sport->port.has_sysrq && !lpuart_is_32(sport)) { cr3 = readb(sport->port.membase + UARTCR3); cr3 |= UARTCR3_FEIE; writeb(cr3, sport->port.membase + UARTCR3); From ec22c3eec5439fb012a41d49b015c13ca9b91b6c Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 12 May 2021 16:12:48 +0200 Subject: [PATCH 004/227] serial: fsl_lpuart: use UARTDATA_MASK macro Use the corresponding macro instead of the magic number. While at it, drop the useless cast to "unsigned char". Signed-off-by: Michael Walle Link: https://lore.kernel.org/r/20210512141255.18277-3-michael@walle.cc Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 120527cb8a81..cabfc1c5d701 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -928,9 +928,9 @@ static void lpuart32_rxint(struct lpuart_port *sport) */ sr = lpuart32_read(&sport->port, UARTSTAT); rx = lpuart32_read(&sport->port, UARTDATA); - rx &= 0x3ff; + rx &= UARTDATA_MASK; - if (uart_handle_sysrq_char(&sport->port, (unsigned char)rx)) + if (uart_handle_sysrq_char(&sport->port, rx)) continue; if (sr & (UARTSTAT_PE | UARTSTAT_OR | UARTSTAT_FE)) { From 0d84f62220eda0eb167b01433f5ce8ebf51654a8 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 12 May 2021 16:12:49 +0200 Subject: [PATCH 005/227] serial: fsl_lpuart: don't restore interrupt state in ISR >From commit 75f4e830fa9c ("serial: do not restore interrupt state in sysrq helper"): Since commit 81e2073c175b ("genirq: Disable interrupts for force threaded handlers") interrupt handlers that are not explicitly requested as threaded are always called with interrupts disabled and there is no need to save the interrupt state when taking the port lock. Apply this also to fsl_lpuart in prepartion for sysrq handling with uart_unlock_and_check_sysrq(). Signed-off-by: Michael Walle Link: https://lore.kernel.org/r/20210512141255.18277-4-michael@walle.cc Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index cabfc1c5d701..7f705ee04205 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -824,21 +824,18 @@ static unsigned int lpuart32_tx_empty(struct uart_port *port) static void lpuart_txint(struct lpuart_port *sport) { - unsigned long flags; - - spin_lock_irqsave(&sport->port.lock, flags); + spin_lock(&sport->port.lock); lpuart_transmit_buffer(sport); - spin_unlock_irqrestore(&sport->port.lock, flags); + spin_unlock(&sport->port.lock); } static void lpuart_rxint(struct lpuart_port *sport) { unsigned int flg, ignored = 0, overrun = 0; struct tty_port *port = &sport->port.state->port; - unsigned long flags; unsigned char rx, sr; - spin_lock_irqsave(&sport->port.lock, flags); + spin_lock(&sport->port.lock); while (!(readb(sport->port.membase + UARTSFIFO) & UARTSFIFO_RXEMPT)) { flg = TTY_NORMAL; @@ -896,28 +893,25 @@ out: writeb(UARTSFIFO_RXOF, sport->port.membase + UARTSFIFO); } - spin_unlock_irqrestore(&sport->port.lock, flags); + spin_unlock(&sport->port.lock); tty_flip_buffer_push(port); } static void lpuart32_txint(struct lpuart_port *sport) { - unsigned long flags; - - spin_lock_irqsave(&sport->port.lock, flags); + spin_lock(&sport->port.lock); lpuart32_transmit_buffer(sport); - spin_unlock_irqrestore(&sport->port.lock, flags); + spin_unlock(&sport->port.lock); } static void lpuart32_rxint(struct lpuart_port *sport) { unsigned int flg, ignored = 0; struct tty_port *port = &sport->port.state->port; - unsigned long flags; unsigned long rx, sr; - spin_lock_irqsave(&sport->port.lock, flags); + spin_lock(&sport->port.lock); while (!(lpuart32_read(&sport->port, UARTFIFO) & UARTFIFO_RXEMPT)) { flg = TTY_NORMAL; @@ -965,7 +959,7 @@ static void lpuart32_rxint(struct lpuart_port *sport) } out: - spin_unlock_irqrestore(&sport->port.lock, flags); + spin_unlock(&sport->port.lock); tty_flip_buffer_push(port); } From 5697df7322fe0a95e56393f63ca8e0f256be92f9 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 12 May 2021 16:12:50 +0200 Subject: [PATCH 006/227] serial: fsl_lpuart: split sysrq handling Instead of uart_handle_sysrq_char() use uart_prepare_sysrq_char() and uart_unlock_and_check_sysrq(). This will call handle_sysrq() without holding the port lock, which in turn let us drop the spin_trylock hack. Suggested-by: Johan Hovold Signed-off-by: Michael Walle Link: https://lore.kernel.org/r/20210512141255.18277-5-michael@walle.cc Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 7f705ee04205..72caa7a193a8 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -847,7 +847,7 @@ static void lpuart_rxint(struct lpuart_port *sport) sr = readb(sport->port.membase + UARTSR1); rx = readb(sport->port.membase + UARTDR); - if (uart_handle_sysrq_char(&sport->port, (unsigned char)rx)) + if (uart_prepare_sysrq_char(&sport->port, rx)) continue; if (sr & (UARTSR1_PE | UARTSR1_OR | UARTSR1_FE)) { @@ -893,7 +893,7 @@ out: writeb(UARTSFIFO_RXOF, sport->port.membase + UARTSFIFO); } - spin_unlock(&sport->port.lock); + uart_unlock_and_check_sysrq(&sport->port); tty_flip_buffer_push(port); } @@ -924,7 +924,7 @@ static void lpuart32_rxint(struct lpuart_port *sport) rx = lpuart32_read(&sport->port, UARTDATA); rx &= UARTDATA_MASK; - if (uart_handle_sysrq_char(&sport->port, rx)) + if (uart_prepare_sysrq_char(&sport->port, rx)) continue; if (sr & (UARTSTAT_PE | UARTSTAT_OR | UARTSTAT_FE)) { @@ -959,7 +959,7 @@ static void lpuart32_rxint(struct lpuart_port *sport) } out: - spin_unlock(&sport->port.lock); + uart_unlock_and_check_sysrq(&sport->port); tty_flip_buffer_push(port); } @@ -2272,7 +2272,7 @@ lpuart_console_write(struct console *co, const char *s, unsigned int count) unsigned long flags; int locked = 1; - if (sport->port.sysrq || oops_in_progress) + if (oops_in_progress) locked = spin_trylock_irqsave(&sport->port.lock, flags); else spin_lock_irqsave(&sport->port.lock, flags); @@ -2302,7 +2302,7 @@ lpuart32_console_write(struct console *co, const char *s, unsigned int count) unsigned long flags; int locked = 1; - if (sport->port.sysrq || oops_in_progress) + if (oops_in_progress) locked = spin_trylock_irqsave(&sport->port.lock, flags); else spin_lock_irqsave(&sport->port.lock, flags); From 5541a9bacfe54fb2038531fb276724fcec6c29c4 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 12 May 2021 16:12:51 +0200 Subject: [PATCH 007/227] serial: fsl_lpuart: handle break and make sysrq work Although there is already sysrq characters handling, a break condition was never detected. Add support for it. The LPUART can't distinguish between a framing error and a break condition. We assume it is a break if the received data is all zero. Signed-off-by: Michael Walle Link: https://lore.kernel.org/r/20210512141255.18277-6-michael@walle.cc Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 72caa7a193a8..baa96e61ab14 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -910,6 +910,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; + bool is_break; spin_lock(&sport->port.lock); @@ -924,14 +925,27 @@ static void lpuart32_rxint(struct lpuart_port *sport) rx = lpuart32_read(&sport->port, UARTDATA); rx &= UARTDATA_MASK; + /* + * The LPUART can't distinguish between a break and a framing error, + * thus we assume it is a break if the received data is zero. + */ + is_break = (sr & UARTSTAT_FE) && !rx; + + if (is_break && uart_handle_break(&sport->port)) + continue; + if (uart_prepare_sysrq_char(&sport->port, rx)) continue; if (sr & (UARTSTAT_PE | UARTSTAT_OR | UARTSTAT_FE)) { - if (sr & UARTSTAT_PE) - sport->port.icount.parity++; - else if (sr & UARTSTAT_FE) + if (sr & UARTSTAT_PE) { + if (is_break) + sport->port.icount.brk++; + else + sport->port.icount.parity++; + } else if (sr & UARTSTAT_FE) { sport->port.icount.frame++; + } if (sr & UARTSTAT_OR) sport->port.icount.overrun++; @@ -944,15 +958,17 @@ static void lpuart32_rxint(struct lpuart_port *sport) sr &= sport->port.read_status_mask; - if (sr & UARTSTAT_PE) - flg = TTY_PARITY; - else if (sr & UARTSTAT_FE) + if (sr & UARTSTAT_PE) { + if (is_break) + flg = TTY_BREAK; + else + flg = TTY_PARITY; + } else if (sr & UARTSTAT_FE) { flg = TTY_FRAME; + } if (sr & UARTSTAT_OR) flg = TTY_OVERRUN; - - sport->port.sysrq = 0; } tty_insert_flip_char(port, rx, flg); From e60c2991f18bf221fa9908ff10cb24eaedaa9bae Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 12 May 2021 16:12:52 +0200 Subject: [PATCH 008/227] serial: fsl_lpuart: remove RTSCTS handling from get_mctrl() The wrong code in set_mctrl() was already removed in commit 2b30efe2e88a ("tty: serial: lpuart: Remove unnecessary code from set_mctrl"), but the code in get_mctrl() wasn't removed. It will not return the state of the RTS or CTS line but whether automatic flow control is enabled, which is wrong for the get_mctrl(). Thus remove it. Fixes: 2b30efe2e88a ("tty: serial: lpuart: Remove unnecessary code from set_mctrl") Signed-off-by: Michael Walle Link: https://lore.kernel.org/r/20210512141255.18277-7-michael@walle.cc Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index baa96e61ab14..080b462c61dc 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1418,17 +1418,7 @@ static unsigned int lpuart_get_mctrl(struct uart_port *port) static unsigned int lpuart32_get_mctrl(struct uart_port *port) { - unsigned int temp = 0; - unsigned long reg; - - reg = lpuart32_read(port, UARTMODIR); - if (reg & UARTMODIR_TXCTSE) - temp |= TIOCM_CTS; - - if (reg & UARTMODIR_RXRTSE) - temp |= TIOCM_RTS; - - return temp; + return 0; } static void lpuart_set_mctrl(struct uart_port *port, unsigned int mctrl) From fa3540735425cb7f95a8d83e74dfdc84170d139b Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 12 May 2021 16:12:53 +0200 Subject: [PATCH 009/227] serial: fsl_lpuart: remove manual RTSCTS control from 8-bit LPUART The LPUART doesn't have the ability to control the RTS or CTS line manually. Instead it will set it automatically when data is send or handle it when data is received. Thus drop the wrong code in set_mctrl. For the 32 bit version this was already done in the commit 2b30efe2e88a ("tty: serial: lpuart: Remove unnecessary code from set_mctrl"). Keep the 8-bit version in sync and remove it there, too. Signed-off-by: Michael Walle Link: https://lore.kernel.org/r/20210512141255.18277-8-michael@walle.cc Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 080b462c61dc..895766599b84 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1403,17 +1403,7 @@ static int lpuart32_config_rs485(struct uart_port *port, static unsigned int lpuart_get_mctrl(struct uart_port *port) { - unsigned int temp = 0; - unsigned char reg; - - reg = readb(port->membase + UARTMODEM); - if (reg & UARTMODEM_TXCTSE) - temp |= TIOCM_CTS; - - if (reg & UARTMODEM_RXRTSE) - temp |= TIOCM_RTS; - - return temp; + return 0; } static unsigned int lpuart32_get_mctrl(struct uart_port *port) @@ -1423,23 +1413,7 @@ static unsigned int lpuart32_get_mctrl(struct uart_port *port) static void lpuart_set_mctrl(struct uart_port *port, unsigned int mctrl) { - unsigned char temp; - struct lpuart_port *sport = container_of(port, - struct lpuart_port, port); - /* Make sure RXRTSE bit is not set when RS485 is enabled */ - if (!(sport->port.rs485.flags & SER_RS485_ENABLED)) { - temp = readb(sport->port.membase + UARTMODEM) & - ~(UARTMODEM_RXRTSE | UARTMODEM_TXCTSE); - - if (mctrl & TIOCM_RTS) - temp |= UARTMODEM_RXRTSE; - - if (mctrl & TIOCM_CTS) - temp |= UARTMODEM_TXCTSE; - - writeb(temp, port->membase + UARTMODEM); - } } static void lpuart32_set_mctrl(struct uart_port *port, unsigned int mctrl) From 8a0c810d94f02d7aa2074658ee6d0ec0a39f0555 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 12 May 2021 16:12:54 +0200 Subject: [PATCH 010/227] serial: fsl_lpuart: add loopback support The LPUART can loop the RX and TX signal. Add support for it. Please note, this was only tested on the 32 bit version of the LPUART. Signed-off-by: Michael Walle Link: https://lore.kernel.org/r/20210512141255.18277-9-michael@walle.cc Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 36 +++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 895766599b84..0d4eb0219728 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1403,22 +1403,54 @@ static int lpuart32_config_rs485(struct uart_port *port, static unsigned int lpuart_get_mctrl(struct uart_port *port) { - return 0; + unsigned int mctrl = 0; + u8 reg; + + reg = readb(port->membase + UARTCR1); + if (reg & UARTCR1_LOOPS) + mctrl |= TIOCM_LOOP; + + return mctrl; } static unsigned int lpuart32_get_mctrl(struct uart_port *port) { - return 0; + unsigned int mctrl = 0; + u32 reg; + + reg = lpuart32_read(port, UARTCTRL); + if (reg & UARTCTRL_LOOPS) + mctrl |= TIOCM_LOOP; + + return mctrl; } static void lpuart_set_mctrl(struct uart_port *port, unsigned int mctrl) { + u8 reg; + reg = readb(port->membase + UARTCR1); + + /* for internal loopback we need LOOPS=1 and RSRC=0 */ + reg &= ~(UARTCR1_LOOPS | UARTCR1_RSRC); + if (mctrl & TIOCM_LOOP) + reg |= UARTCR1_LOOPS; + + writeb(reg, port->membase + UARTCR1); } static void lpuart32_set_mctrl(struct uart_port *port, unsigned int mctrl) { + u32 reg; + reg = lpuart32_read(port, UARTCTRL); + + /* for internal loopback we need LOOPS=1 and RSRC=0 */ + reg &= ~(UARTCTRL_LOOPS | UARTCTRL_RSRC); + if (mctrl & TIOCM_LOOP) + reg |= UARTCTRL_LOOPS; + + lpuart32_write(port, reg, UARTCTRL); } static void lpuart_break_ctl(struct uart_port *port, int break_state) From 8cac2f6eb8548245e6f8fb893fc7f2a714952654 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 12 May 2021 16:12:55 +0200 Subject: [PATCH 011/227] serial: fsl_lpuart: disable DMA for console and fix sysrq SYSRQ doesn't work with DMA. This is because there is no error indication whether a symbol had a framing error or not. Actually, this is not completely correct, there is a bit in the data register which is set in this case, but we'd have to read change the DMA access to 16 bit and we'd need to post process the data, thus make the DMA pointless in the first place. Signed-off-by: Michael Walle Link: https://lore.kernel.org/r/20210512141255.18277-10-michael@walle.cc Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 0d4eb0219728..508128ddfa01 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1587,6 +1587,9 @@ static void lpuart_tx_dma_startup(struct lpuart_port *sport) u32 uartbaud; int ret; + if (uart_console(&sport->port)) + goto err; + if (!sport->dma_tx_chan) goto err; @@ -1616,6 +1619,9 @@ static void lpuart_rx_dma_startup(struct lpuart_port *sport) int ret; unsigned char cr3; + if (uart_console(&sport->port)) + goto err; + if (!sport->dma_rx_chan) goto err; From 7a9a2363d7eebb3494653a3aa903198991494cd3 Mon Sep 17 00:00:00 2001 From: Tian Tao Date: Tue, 27 Apr 2021 08:49:35 +0800 Subject: [PATCH 012/227] tty: serial: samsung_tty: remove set but not used variables The value of 'ret' is not used which reported by svace, so just return instead of break. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Tian Tao Link: https://lore.kernel.org/r/1619484575-26098-1-git-send-email-tiantao6@hisilicon.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung_tty.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c index d9e4b67a12a0..9fbc61151c2e 100644 --- a/drivers/tty/serial/samsung_tty.c +++ b/drivers/tty/serial/samsung_tty.c @@ -2220,8 +2220,7 @@ static int s3c24xx_serial_probe(struct platform_device *pdev) default: dev_warn(&pdev->dev, "unsupported reg-io-width (%d)\n", prop); - ret = -EINVAL; - break; + return -EINVAL; } } } From 991a350dff134d8e23bebc36ec16304bbd16f85f Mon Sep 17 00:00:00 2001 From: Zev Weiss Date: Sun, 9 May 2021 20:42:29 -0500 Subject: [PATCH 013/227] serial: 8250_aspeed_vuart: factor out aspeed_vuart_{read, write}b() helper functions This is a small prepatory step for changing the way this driver does its I/O accesses. Reviewed-by: Andrew Jeffery Signed-off-by: Zev Weiss Link: https://lore.kernel.org/r/20210510014231.647-2-zev@bewilderbeest.net Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_aspeed_vuart.c | 38 +++++++++++++-------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/drivers/tty/serial/8250/8250_aspeed_vuart.c b/drivers/tty/serial/8250/8250_aspeed_vuart.c index 61550f24a2d3..9e8b2e8e32b6 100644 --- a/drivers/tty/serial/8250/8250_aspeed_vuart.c +++ b/drivers/tty/serial/8250/8250_aspeed_vuart.c @@ -64,14 +64,24 @@ static const int unthrottle_timeout = HZ/10; * different system (though most of them use 3f8/4). */ +static inline u8 aspeed_vuart_readb(struct aspeed_vuart *vuart, u8 reg) +{ + return readb(vuart->regs + reg); +} + +static inline void aspeed_vuart_writeb(struct aspeed_vuart *vuart, u8 val, u8 reg) +{ + writeb(val, vuart->regs + reg); +} + static ssize_t lpc_address_show(struct device *dev, struct device_attribute *attr, char *buf) { struct aspeed_vuart *vuart = dev_get_drvdata(dev); u16 addr; - addr = (readb(vuart->regs + ASPEED_VUART_ADDRH) << 8) | - (readb(vuart->regs + ASPEED_VUART_ADDRL)); + addr = (aspeed_vuart_readb(vuart, ASPEED_VUART_ADDRH) << 8) | + (aspeed_vuart_readb(vuart, ASPEED_VUART_ADDRL)); return snprintf(buf, PAGE_SIZE - 1, "0x%x\n", addr); } @@ -81,8 +91,8 @@ static int aspeed_vuart_set_lpc_address(struct aspeed_vuart *vuart, u32 addr) if (addr > U16_MAX) return -EINVAL; - writeb(addr >> 8, vuart->regs + ASPEED_VUART_ADDRH); - writeb(addr >> 0, vuart->regs + ASPEED_VUART_ADDRL); + aspeed_vuart_writeb(vuart, addr >> 8, ASPEED_VUART_ADDRH); + aspeed_vuart_writeb(vuart, addr >> 0, ASPEED_VUART_ADDRL); return 0; } @@ -111,7 +121,7 @@ static ssize_t sirq_show(struct device *dev, struct aspeed_vuart *vuart = dev_get_drvdata(dev); u8 reg; - reg = readb(vuart->regs + ASPEED_VUART_GCRB); + reg = aspeed_vuart_readb(vuart, ASPEED_VUART_GCRB); reg &= ASPEED_VUART_GCRB_HOST_SIRQ_MASK; reg >>= ASPEED_VUART_GCRB_HOST_SIRQ_SHIFT; @@ -128,10 +138,10 @@ static int aspeed_vuart_set_sirq(struct aspeed_vuart *vuart, u32 sirq) sirq <<= ASPEED_VUART_GCRB_HOST_SIRQ_SHIFT; sirq &= ASPEED_VUART_GCRB_HOST_SIRQ_MASK; - reg = readb(vuart->regs + ASPEED_VUART_GCRB); + reg = aspeed_vuart_readb(vuart, ASPEED_VUART_GCRB); reg &= ~ASPEED_VUART_GCRB_HOST_SIRQ_MASK; reg |= sirq; - writeb(reg, vuart->regs + ASPEED_VUART_GCRB); + aspeed_vuart_writeb(vuart, reg, ASPEED_VUART_GCRB); return 0; } @@ -159,7 +169,7 @@ static ssize_t sirq_polarity_show(struct device *dev, struct aspeed_vuart *vuart = dev_get_drvdata(dev); u8 reg; - reg = readb(vuart->regs + ASPEED_VUART_GCRA); + reg = aspeed_vuart_readb(vuart, ASPEED_VUART_GCRA); reg &= ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY; return snprintf(buf, PAGE_SIZE - 1, "%u\n", reg ? 1 : 0); @@ -168,14 +178,14 @@ static ssize_t sirq_polarity_show(struct device *dev, static void aspeed_vuart_set_sirq_polarity(struct aspeed_vuart *vuart, bool polarity) { - u8 reg = readb(vuart->regs + ASPEED_VUART_GCRA); + u8 reg = aspeed_vuart_readb(vuart, ASPEED_VUART_GCRA); if (polarity) reg |= ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY; else reg &= ~ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY; - writeb(reg, vuart->regs + ASPEED_VUART_GCRA); + aspeed_vuart_writeb(vuart, reg, ASPEED_VUART_GCRA); } static ssize_t sirq_polarity_store(struct device *dev, @@ -210,14 +220,14 @@ static const struct attribute_group aspeed_vuart_attr_group = { static void aspeed_vuart_set_enabled(struct aspeed_vuart *vuart, bool enabled) { - u8 reg = readb(vuart->regs + ASPEED_VUART_GCRA); + u8 reg = aspeed_vuart_readb(vuart, ASPEED_VUART_GCRA); if (enabled) reg |= ASPEED_VUART_GCRA_VUART_EN; else reg &= ~ASPEED_VUART_GCRA_VUART_EN; - writeb(reg, vuart->regs + ASPEED_VUART_GCRA); + aspeed_vuart_writeb(vuart, reg, ASPEED_VUART_GCRA); } static void aspeed_vuart_set_host_tx_discard(struct aspeed_vuart *vuart, @@ -225,7 +235,7 @@ static void aspeed_vuart_set_host_tx_discard(struct aspeed_vuart *vuart, { u8 reg; - reg = readb(vuart->regs + ASPEED_VUART_GCRA); + reg = aspeed_vuart_readb(vuart, ASPEED_VUART_GCRA); /* If the DISABLE_HOST_TX_DISCARD bit is set, discard is disabled */ if (!discard) @@ -233,7 +243,7 @@ static void aspeed_vuart_set_host_tx_discard(struct aspeed_vuart *vuart, else reg &= ~ASPEED_VUART_GCRA_DISABLE_HOST_TX_DISCARD; - writeb(reg, vuart->regs + ASPEED_VUART_GCRA); + aspeed_vuart_writeb(vuart, reg, ASPEED_VUART_GCRA); } static int aspeed_vuart_startup(struct uart_port *uart_port) From c9805fbf9d89c32c7ea4a6c5c3a66244aab06584 Mon Sep 17 00:00:00 2001 From: Zev Weiss Date: Sun, 9 May 2021 20:42:30 -0500 Subject: [PATCH 014/227] serial: 8250_aspeed_vuart: initialize vuart->port in aspeed_vuart_probe() Previously this had only been initialized if we hit the throttling path in aspeed_vuart_handle_irq(); moving it to the probe function is a slight consistency improvement and avoids redundant reinitialization in the interrupt handler. It also serves as preparation for converting the driver's I/O accesses to use port->port.membase instead of its own vuart->regs. Signed-off-by: Zev Weiss Link: https://lore.kernel.org/r/20210510014231.647-3-zev@bewilderbeest.net Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_aspeed_vuart.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/8250/8250_aspeed_vuart.c b/drivers/tty/serial/8250/8250_aspeed_vuart.c index 9e8b2e8e32b6..249164dc397b 100644 --- a/drivers/tty/serial/8250/8250_aspeed_vuart.c +++ b/drivers/tty/serial/8250/8250_aspeed_vuart.c @@ -349,11 +349,9 @@ static int aspeed_vuart_handle_irq(struct uart_port *port) struct aspeed_vuart *vuart = port->private_data; __aspeed_vuart_set_throttle(up, true); - if (!timer_pending(&vuart->unthrottle_timer)) { - vuart->port = up; + if (!timer_pending(&vuart->unthrottle_timer)) mod_timer(&vuart->unthrottle_timer, jiffies + unthrottle_timeout); - } } else { count = min(space, 256); @@ -511,6 +509,7 @@ static int aspeed_vuart_probe(struct platform_device *pdev) goto err_clk_disable; vuart->line = rc; + vuart->port = serial8250_get_port(vuart->line); rc = of_parse_phandle_with_fixed_args( np, "aspeed,sirq-polarity-sense", 2, 0, From 54da3e381c2b55289b220601f403f17df7b20597 Mon Sep 17 00:00:00 2001 From: Zev Weiss Date: Sun, 9 May 2021 20:42:31 -0500 Subject: [PATCH 015/227] serial: 8250_aspeed_vuart: use UPF_IOREMAP to set up register mapping Previously this driver's use of devm_ioremap_resource() led to duplicated calls to __release_region() when unbinding it (one from serial8250_release_std_resource() and one from devres_release_all()), the second of which resulted in a warning message: # echo 1e787000.serial > /sys/bus/platform/drivers/aspeed-vuart/unbind [33091.774200] Trying to free nonexistent resource <000000001e787000-000000001e78703f> With this change the driver uses the generic serial8250 code's UPF_IOREMAP to take care of the register mapping automatically instead of doing its own devm_ioremap_resource(), thus avoiding the duplicate __release_region() on unbind. In doing this we eliminate vuart->regs, since it merely duplicates vuart->port->port.membase, which we now use for our I/O accesses. Reported-by: Andrew Jeffery Signed-off-by: Zev Weiss Link: https://lore.kernel.org/r/20210510014231.647-4-zev@bewilderbeest.net Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_aspeed_vuart.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/8250/8250_aspeed_vuart.c b/drivers/tty/serial/8250/8250_aspeed_vuart.c index 249164dc397b..2bf1d8582d9a 100644 --- a/drivers/tty/serial/8250/8250_aspeed_vuart.c +++ b/drivers/tty/serial/8250/8250_aspeed_vuart.c @@ -34,7 +34,6 @@ struct aspeed_vuart { struct device *dev; - void __iomem *regs; struct clk *clk; int line; struct timer_list unthrottle_timer; @@ -66,12 +65,12 @@ static const int unthrottle_timeout = HZ/10; static inline u8 aspeed_vuart_readb(struct aspeed_vuart *vuart, u8 reg) { - return readb(vuart->regs + reg); + return readb(vuart->port->port.membase + reg); } static inline void aspeed_vuart_writeb(struct aspeed_vuart *vuart, u8 val, u8 reg) { - writeb(val, vuart->regs + reg); + writeb(val, vuart->port->port.membase + reg); } static ssize_t lpc_address_show(struct device *dev, @@ -429,13 +428,9 @@ static int aspeed_vuart_probe(struct platform_device *pdev) timer_setup(&vuart->unthrottle_timer, aspeed_vuart_unthrottle_exp, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - vuart->regs = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(vuart->regs)) - return PTR_ERR(vuart->regs); memset(&port, 0, sizeof(port)); port.port.private_data = vuart; - port.port.membase = vuart->regs; port.port.mapbase = res->start; port.port.mapsize = resource_size(res); port.port.startup = aspeed_vuart_startup; @@ -492,7 +487,7 @@ static int aspeed_vuart_probe(struct platform_device *pdev) port.port.iotype = UPIO_MEM; port.port.type = PORT_16550A; port.port.uartclk = clk; - port.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF + port.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_FIXED_PORT | UPF_FIXED_TYPE | UPF_NO_THRE_TEST; if (of_property_read_bool(np, "no-loopback-test")) From 8f082dcf2c3dadef0fd118207d47215c917b8a1e Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Thu, 6 May 2021 21:20:48 +0800 Subject: [PATCH 016/227] dt-bindings: serial: Change to reference the kernel-defined serial.yaml The /schemas/serial.yaml from dt-schema only has the property $nodename, whereas the kernel-defined /schemas/serial/serial.yaml contains more useful properties, support for more complex application scenarios. For example: 1) The property "current-speed" in fsl-lx2160a.dtsi 2) The subnode "bluetooth" in hi3660-hikey960.dts Reviewed-by: Rob Herring Signed-off-by: Zhen Lei Link: https://lore.kernel.org/r/20210506132049.1513-2-thunder.leizhen@huawei.com Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/8250.yaml | 2 +- .../devicetree/bindings/serial/brcm,bcm7271-uart.yaml | 2 +- Documentation/devicetree/bindings/serial/ingenic,uart.yaml | 2 +- Documentation/devicetree/bindings/serial/pl011.yaml | 4 ++-- Documentation/devicetree/bindings/serial/qca,ar9330-uart.yaml | 4 ++-- Documentation/devicetree/bindings/serial/renesas,em-uart.yaml | 2 +- Documentation/devicetree/bindings/serial/samsung_uart.yaml | 2 +- Documentation/devicetree/bindings/serial/sifive-serial.yaml | 4 ++-- .../devicetree/bindings/serial/snps-dw-apb-uart.yaml | 2 +- Documentation/devicetree/bindings/serial/st,stm32-uart.yaml | 3 +-- 10 files changed, 13 insertions(+), 14 deletions(-) diff --git a/Documentation/devicetree/bindings/serial/8250.yaml b/Documentation/devicetree/bindings/serial/8250.yaml index 41f57c448621..a0bf061b80fe 100644 --- a/Documentation/devicetree/bindings/serial/8250.yaml +++ b/Documentation/devicetree/bindings/serial/8250.yaml @@ -10,7 +10,7 @@ maintainers: - devicetree@vger.kernel.org allOf: - - $ref: /schemas/serial.yaml# + - $ref: serial.yaml# - if: anyOf: - required: diff --git a/Documentation/devicetree/bindings/serial/brcm,bcm7271-uart.yaml b/Documentation/devicetree/bindings/serial/brcm,bcm7271-uart.yaml index 46c62745f901..6d176588df47 100644 --- a/Documentation/devicetree/bindings/serial/brcm,bcm7271-uart.yaml +++ b/Documentation/devicetree/bindings/serial/brcm,bcm7271-uart.yaml @@ -10,7 +10,7 @@ maintainers: - Al Cooper allOf: - - $ref: /schemas/serial.yaml# + - $ref: serial.yaml# description: |+ The Broadcom UART is based on the basic 8250 UART but with diff --git a/Documentation/devicetree/bindings/serial/ingenic,uart.yaml b/Documentation/devicetree/bindings/serial/ingenic,uart.yaml index 7748d8c3bab8..b432d4dff730 100644 --- a/Documentation/devicetree/bindings/serial/ingenic,uart.yaml +++ b/Documentation/devicetree/bindings/serial/ingenic,uart.yaml @@ -10,7 +10,7 @@ maintainers: - Paul Cercueil allOf: - - $ref: /schemas/serial.yaml# + - $ref: serial.yaml# properties: $nodename: diff --git a/Documentation/devicetree/bindings/serial/pl011.yaml b/Documentation/devicetree/bindings/serial/pl011.yaml index 1f8e9f2644b6..142187337c76 100644 --- a/Documentation/devicetree/bindings/serial/pl011.yaml +++ b/Documentation/devicetree/bindings/serial/pl011.yaml @@ -10,7 +10,7 @@ maintainers: - Rob Herring allOf: - - $ref: /schemas/serial.yaml# + - $ref: serial.yaml# # Need a custom select here or 'arm,primecell' will match on lots of nodes select: @@ -103,7 +103,7 @@ dependencies: poll-rate-ms: [ auto-poll ] poll-timeout-ms: [ auto-poll ] -additionalProperties: false +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/serial/qca,ar9330-uart.yaml b/Documentation/devicetree/bindings/serial/qca,ar9330-uart.yaml index a344369285b6..a644e5af12b2 100644 --- a/Documentation/devicetree/bindings/serial/qca,ar9330-uart.yaml +++ b/Documentation/devicetree/bindings/serial/qca,ar9330-uart.yaml @@ -10,7 +10,7 @@ maintainers: - Oleksij Rempel allOf: - - $ref: /schemas/serial.yaml# + - $ref: serial.yaml# properties: compatible: @@ -35,7 +35,7 @@ required: - clocks - clock-names -additionalProperties: false +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/serial/renesas,em-uart.yaml b/Documentation/devicetree/bindings/serial/renesas,em-uart.yaml index 82aefdb0d45e..e98ec48fee46 100644 --- a/Documentation/devicetree/bindings/serial/renesas,em-uart.yaml +++ b/Documentation/devicetree/bindings/serial/renesas,em-uart.yaml @@ -35,7 +35,7 @@ required: - clocks - clock-names -additionalProperties: false +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/serial/samsung_uart.yaml b/Documentation/devicetree/bindings/serial/samsung_uart.yaml index 97ec8a093bf3..0c24e7b1f15e 100644 --- a/Documentation/devicetree/bindings/serial/samsung_uart.yaml +++ b/Documentation/devicetree/bindings/serial/samsung_uart.yaml @@ -82,7 +82,7 @@ required: unevaluatedProperties: false allOf: - - $ref: /schemas/serial.yaml# + - $ref: serial.yaml# - if: properties: diff --git a/Documentation/devicetree/bindings/serial/sifive-serial.yaml b/Documentation/devicetree/bindings/serial/sifive-serial.yaml index 5fa94dacbba9..09aae43f65a7 100644 --- a/Documentation/devicetree/bindings/serial/sifive-serial.yaml +++ b/Documentation/devicetree/bindings/serial/sifive-serial.yaml @@ -12,7 +12,7 @@ maintainers: - Palmer Dabbelt allOf: - - $ref: /schemas/serial.yaml# + - $ref: serial.yaml# properties: compatible: @@ -49,7 +49,7 @@ required: - interrupts - clocks -additionalProperties: false +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml index 97debbf68748..88bf4adf1067 100644 --- a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml +++ b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml @@ -10,7 +10,7 @@ maintainers: - Rob Herring allOf: - - $ref: /schemas/serial.yaml# + - $ref: serial.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/serial/st,stm32-uart.yaml b/Documentation/devicetree/bindings/serial/st,stm32-uart.yaml index 71a6426bc558..f50f4ca893a0 100644 --- a/Documentation/devicetree/bindings/serial/st,stm32-uart.yaml +++ b/Documentation/devicetree/bindings/serial/st,stm32-uart.yaml @@ -112,8 +112,7 @@ required: - interrupts - clocks -additionalProperties: - type: object +unevaluatedProperties: false examples: - | From e27671f66321f97b62424aebacd6d9b678b0c5be Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Thu, 6 May 2021 21:20:49 +0800 Subject: [PATCH 017/227] dt-bindings: serial: Add label property in serial.yaml When there is more than one serial port present, the property 'label' allows a custom name to be used for briefly describe the usage or position of each serial port. Without this "label" property, many dtbs_check warnings similar to the following are reported: arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dt.yaml: \ serial@ffd74000: Additional properties are not allowed ('label' was unexpected) From schema: Documentation/devicetree/bindings/serial/pl011.yaml Reviewed-by: Rob Herring Signed-off-by: Zhen Lei Link: https://lore.kernel.org/r/20210506132049.1513-3-thunder.leizhen@huawei.com Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/serial.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/serial/serial.yaml b/Documentation/devicetree/bindings/serial/serial.yaml index 2fdf4ed198da..c75ba3fb6465 100644 --- a/Documentation/devicetree/bindings/serial/serial.yaml +++ b/Documentation/devicetree/bindings/serial/serial.yaml @@ -23,6 +23,8 @@ properties: $nodename: pattern: "^serial(@.*)?$" + label: true + cts-gpios: maxItems: 1 description: From 71581242164f112520025ad465cba48c52f65bd1 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 23 Apr 2021 09:13:17 +0100 Subject: [PATCH 018/227] serial: qcom_geni_serial: redundant initialization to variable line The variable line being initialized with a value that is never read and it is being updated later with a new value. The initialization is redundant and can be removed. Reviewed-by: Jiri Slaby Signed-off-by: Colin Ian King Addresses-Coverity: ("Unused value") Link: https://lore.kernel.org/r/20210423081317.318352-1-colin.king@canonical.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/qcom_geni_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 23d729ed3bf6..463f84a66f6e 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -1338,7 +1338,7 @@ static const struct uart_ops qcom_geni_uart_pops = { static int qcom_geni_serial_probe(struct platform_device *pdev) { int ret = 0; - int line = -1; + int line; struct qcom_geni_serial_port *port; struct uart_port *uport; struct resource *res; From f5b08386dee439c7a9e60ce0a4a4a705f3a60dff Mon Sep 17 00:00:00 2001 From: Jim Quinlan Date: Fri, 23 Apr 2021 11:32:04 -0700 Subject: [PATCH 019/227] serial: 8250: of: Check for CONFIG_SERIAL_8250_BCM7271 Our SoC's have always had a NS16650A UART core and older SoC's would have a compatible string of: 'compatible = ""ns16550a"' and use the 8250_of driver. Our newer SoC's have added enhancements to the base core to add support for DMA and accurate high speed baud rates and use this newer 8250_bcm7271 driver. The Device Tree node for our enhanced UARTs has a compatible string of: 'compatible = "brcm,bcm7271-uart", "ns16550a"''. With both drivers running and the link order setup so that the 8250_bcm7217 driver is initialized before the 8250_of driver, we should bind the 8250_bcm7271 driver to the enhanced UART, or for upstream kernels that don't have the 8250_bcm7271 driver, we bind to the 8250_of driver. The problem is that when both the 8250_of and 8250_bcm7271 drivers were running, occasionally the 8250_of driver would be bound to the enhanced UART instead of the 8250_bcm7271 driver. This was happening because we use SCMI based clocks which come up late in initialization and cause probe DEFER's when the two drivers get their clocks. Occasionally the SCMI clock would become ready between the 8250_bcm7271 probe and the 8250_of probe and the 8250_of driver would be bound. To fix this we decided to config only our 8250_bcm7271 driver and added "ns16665a0" to the compatible string so the driver would work on our older system. This commit has of_platform_serial_probe() check specifically for the "brcm,bcm7271-uart" and whether its companion driver is enabled. If it is the case, and the clock provider is not ready, we want to make sure that when the 8250_bcm7271.c driver returns EPROBE_DEFER, we are not getting the UART registered via 8250_of.c. Reviewed-by: Andy Shevchenko Signed-off-by: Jim Quinlan Signed-off-by: Al Cooper Signed-off-by: Florian Fainelli Link: https://lore.kernel.org/r/20210423183206.3917725-1-f.fainelli@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_of.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c index 0b077b45d6a9..bce28729dd7b 100644 --- a/drivers/tty/serial/8250/8250_of.c +++ b/drivers/tty/serial/8250/8250_of.c @@ -192,6 +192,10 @@ static int of_platform_serial_probe(struct platform_device *ofdev) u32 tx_threshold; int ret; + if (IS_ENABLED(CONFIG_SERIAL_8250_BCM7271) && + of_device_is_compatible(ofdev->dev.of_node, "brcm,bcm7271-uart")) + return -ENODEV; + port_type = (unsigned long)of_device_get_match_data(&ofdev->dev); if (port_type == PORT_UNKNOWN) return -EINVAL; From 021212f5335229ed12e3d31f9b7d30bd3bb66f7d Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 26 Apr 2021 11:11:06 +0100 Subject: [PATCH 020/227] serial: meson: remove redundant initialization of variable id The variable id being initialized with a value that is never read and it is being updated later with a new value. The initialization is redundant and can be removed. Since id is just being used in a for-loop inside a local scope, move the declaration of id to that scope. Reviewed-by: Kevin Hilman Reviewed-by: Martin Blumenstingl Signed-off-by: Colin Ian King Addresses-Coverity: ("Unused value") Link: https://lore.kernel.org/r/20210426101106.9122-1-colin.king@canonical.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/meson_uart.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index 529cd0289056..d7f55031b2cf 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -716,12 +716,13 @@ static int meson_uart_probe(struct platform_device *pdev) struct resource *res_mem, *res_irq; struct uart_port *port; int ret = 0; - int id = -1; if (pdev->dev.of_node) pdev->id = of_alias_get_id(pdev->dev.of_node, "serial"); if (pdev->id < 0) { + int id; + for (id = AML_UART_PORT_OFFSET; id < AML_UART_PORT_NUM; id++) { if (!meson_ports[id]) { pdev->id = id; From 89e78001295cb9eb0e86ae15b46cbbc0e45e2c8d Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Wed, 28 Apr 2021 09:30:40 +0200 Subject: [PATCH 021/227] serial: 8250: Use 'hlist_for_each_entry' to simplify code Use 'hlist_for_each_entry' instead of hand writing it. This saves a few lines of code. The comment about warning generated by some gcc version is also removed. The way 'hlist_for_each_entry' is written should prevent such a warning to be emitted. Reviewed-by: Andy Shevchenko Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/14024ddeb2b3a8c5b0138b5ba5083f54d00164a9.1619594713.git.christophe.jaillet@wanadoo.fr Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_core.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index cae61d1ebec5..081b773a54c9 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -172,7 +172,6 @@ static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up) static int serial_link_irq_chain(struct uart_8250_port *up) { struct hlist_head *h; - struct hlist_node *n; struct irq_info *i; int ret; @@ -180,13 +179,11 @@ static int serial_link_irq_chain(struct uart_8250_port *up) h = &irq_lists[up->port.irq % NR_IRQ_HASH]; - hlist_for_each(n, h) { - i = hlist_entry(n, struct irq_info, node); + hlist_for_each_entry(i, h, node) if (i->irq == up->port.irq) break; - } - if (n == NULL) { + if (i == NULL) { i = kzalloc(sizeof(struct irq_info), GFP_KERNEL); if (i == NULL) { mutex_unlock(&hash_mutex); @@ -220,25 +217,18 @@ static int serial_link_irq_chain(struct uart_8250_port *up) static void serial_unlink_irq_chain(struct uart_8250_port *up) { - /* - * yes, some broken gcc emit "warning: 'i' may be used uninitialized" - * but no, we are not going to take a patch that assigns NULL below. - */ struct irq_info *i; - struct hlist_node *n; struct hlist_head *h; mutex_lock(&hash_mutex); h = &irq_lists[up->port.irq % NR_IRQ_HASH]; - hlist_for_each(n, h) { - i = hlist_entry(n, struct irq_info, node); + hlist_for_each_entry(i, h, node) if (i->irq == up->port.irq) break; - } - BUG_ON(n == NULL); + BUG_ON(i == NULL); BUG_ON(i->head == NULL); if (list_empty(i->head)) From 26f7591632d74f637f346f5d642d8ebe6b433fc9 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Wed, 28 Apr 2021 09:30:52 +0200 Subject: [PATCH 022/227] serial: 8250: Add an empty line and remove some useless {} This fixes the following checkpatch.pl warnings: WARNING: Missing a blank line after declarations WARNING: braces {} are not necessary for any arm of this statement Reviewed-by: Andy Shevchenko Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/257ffd691b4a062ad017333c9430d69da6dbd29a.1619594713.git.christophe.jaillet@wanadoo.fr Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 081b773a54c9..1082e76c4d37 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -321,9 +321,9 @@ static int univ8250_setup_irq(struct uart_8250_port *up) * hardware interrupt, we use a timer-based system. The original * driver used to do this with IRQ0. */ - if (!port->irq) { + if (!port->irq) mod_timer(&up->timer, jiffies + uart_poll_timeout(port)); - } else + else retval = serial_link_irq_chain(up); return retval; @@ -752,6 +752,7 @@ void serial8250_suspend_port(int line) if (!console_suspend_enabled && uart_console(port) && port->type != PORT_8250) { unsigned char canary = 0xa5; + serial_out(up, UART_SCR, canary); if (serial_in(up, UART_SCR) == canary) up->canary = canary; From d7e325aaa8c3593b5a572b583ecad79e95f32e7f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 29 Apr 2021 10:19:22 +0300 Subject: [PATCH 023/227] serial: 8250_omap: fix a timeout loop condition This loop ends on -1 so the error message will never be printed. Fixes: 4bcf59a5dea0 ("serial: 8250: 8250_omap: Account for data in flight during DMA teardown") Reviewed-by: Alexander Sverdlin Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/YIpd+kOpXKMpEXPf@mwanda Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_omap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 8ac11eaeca51..c06631ced414 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -813,7 +813,7 @@ static void __dma_rx_do_complete(struct uart_8250_port *p) poll_count--) cpu_relax(); - if (!poll_count) + if (poll_count == -1) dev_err(p->port.dev, "teardown incomplete\n"); } } From ed5aecd3da2eabd8a6c9f5593df2c4f00985fca2 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:18:54 +0200 Subject: [PATCH 024/227] tty: remove broken r3964 line discipline Noone stepped up in the past two years since it was marked as BROKEN by commit c7084edc3f6d (tty: mark Siemens R3964 line discipline as BROKEN). Remove the line discipline for good. Three remarks: * we remove also the uapi header (as noone is able to use that interface anyway) * we do *not* remove the N_R3964 constant definition from tty.h, so it remains reserved. * in_interrupt() check is now removed from vt's con_put_char. Noone else calls tty_operations::put_char from interrupt context. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210505091928.22010-2-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/configs/ppc6xx_defconfig | 1 - drivers/char/Kconfig | 13 - drivers/tty/Makefile | 1 - drivers/tty/n_r3964.c | 1283 ------------------------- drivers/tty/vt/vt.c | 2 - include/linux/n_r3964.h | 175 ---- include/uapi/linux/n_r3964.h | 99 -- 7 files changed, 1574 deletions(-) delete mode 100644 drivers/tty/n_r3964.c delete mode 100644 include/linux/n_r3964.h delete mode 100644 include/uapi/linux/n_r3964.h diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig index 1fd9d1260f9e..ee09f7bb6ea9 100644 --- a/arch/powerpc/configs/ppc6xx_defconfig +++ b/arch/powerpc/configs/ppc6xx_defconfig @@ -621,7 +621,6 @@ CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_VIRTIO=m CONFIG_NVRAM=y CONFIG_DTLK=m -CONFIG_R3964=m CONFIG_CARDMAN_4000=m CONFIG_CARDMAN_4040=m CONFIG_IPWIRELESS=m diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index b151e0fcdeb5..52d0dd49a683 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -218,19 +218,6 @@ config XILINX_HWICAP If unsure, say N. -config R3964 - tristate "Siemens R3964 line discipline" - depends on TTY && BROKEN - help - This driver allows synchronous communication with devices using the - Siemens R3964 packet protocol. Unless you are dealing with special - hardware like PLCs, you are unlikely to need this. - - To compile this driver as a module, choose M here: the - module will be called n_r3964. - - If unsure, say N. - config APPLICOM tristate "Applicom intelligent fieldbus card support" depends on PCI diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile index c7054f5117c3..a2bd75fbaaa4 100644 --- a/drivers/tty/Makefile +++ b/drivers/tty/Makefile @@ -9,7 +9,6 @@ obj-$(CONFIG_AUDIT) += tty_audit.o obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o obj-$(CONFIG_N_HDLC) += n_hdlc.o obj-$(CONFIG_N_GSM) += n_gsm.o -obj-$(CONFIG_R3964) += n_r3964.o obj-y += vt/ obj-$(CONFIG_HVC_DRIVER) += hvc/ diff --git a/drivers/tty/n_r3964.c b/drivers/tty/n_r3964.c deleted file mode 100644 index 2eb76ea1d88d..000000000000 --- a/drivers/tty/n_r3964.c +++ /dev/null @@ -1,1283 +0,0 @@ -// SPDX-License-Identifier: GPL-1.0+ -/* r3964 linediscipline for linux - * - * ----------------------------------------------------------- - * Copyright by - * Philips Automation Projects - * Kassel (Germany) - * ----------------------------------------------------------- - * Author: - * L. Haag - * - * $Log: n_r3964.c,v $ - * Revision 1.10 2001/03/18 13:02:24 dwmw2 - * Fix timer usage, use spinlocks properly. - * - * Revision 1.9 2001/03/18 12:52:14 dwmw2 - * Merge changes in 2.4.2 - * - * Revision 1.8 2000/03/23 14:14:54 dwmw2 - * Fix race in sleeping in r3964_read() - * - * Revision 1.7 1999/28/08 11:41:50 dwmw2 - * Port to 2.3 kernel - * - * Revision 1.6 1998/09/30 00:40:40 dwmw2 - * Fixed compilation on 2.0.x kernels - * Updated to newly registered tty-ldisc number 9 - * - * Revision 1.5 1998/09/04 21:57:36 dwmw2 - * Signal handling bug fixes, port to 2.1.x. - * - * Revision 1.4 1998/04/02 20:26:59 lhaag - * select, blocking, ... - * - * Revision 1.3 1998/02/12 18:58:43 root - * fixed some memory leaks - * calculation of checksum characters - * - * Revision 1.2 1998/02/07 13:03:34 root - * ioctl read_telegram - * - * Revision 1.1 1998/02/06 19:21:03 root - * Initial revision - * - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* used in new tty drivers */ -#include /* used in new tty drivers */ -#include -#include -#include -#include -#include - -/*#define DEBUG_QUEUE*/ - -/* Log successful handshake and protocol operations */ -/*#define DEBUG_PROTO_S*/ - -/* Log handshake and protocol errors: */ -/*#define DEBUG_PROTO_E*/ - -/* Log Linediscipline operations (open, close, read, write...): */ -/*#define DEBUG_LDISC*/ - -/* Log module and memory operations (init, cleanup; kmalloc, kfree): */ -/*#define DEBUG_MODUL*/ - -/* Macro helpers for debug output: */ -#define TRACE(format, args...) printk("r3964: " format "\n" , ## args) - -#ifdef DEBUG_MODUL -#define TRACE_M(format, args...) printk("r3964: " format "\n" , ## args) -#else -#define TRACE_M(fmt, arg...) do {} while (0) -#endif -#ifdef DEBUG_PROTO_S -#define TRACE_PS(format, args...) printk("r3964: " format "\n" , ## args) -#else -#define TRACE_PS(fmt, arg...) do {} while (0) -#endif -#ifdef DEBUG_PROTO_E -#define TRACE_PE(format, args...) printk("r3964: " format "\n" , ## args) -#else -#define TRACE_PE(fmt, arg...) do {} while (0) -#endif -#ifdef DEBUG_LDISC -#define TRACE_L(format, args...) printk("r3964: " format "\n" , ## args) -#else -#define TRACE_L(fmt, arg...) do {} while (0) -#endif -#ifdef DEBUG_QUEUE -#define TRACE_Q(format, args...) printk("r3964: " format "\n" , ## args) -#else -#define TRACE_Q(fmt, arg...) do {} while (0) -#endif -static void add_tx_queue(struct r3964_info *, struct r3964_block_header *); -static void remove_from_tx_queue(struct r3964_info *pInfo, int error_code); -static void put_char(struct r3964_info *pInfo, unsigned char ch); -static void trigger_transmit(struct r3964_info *pInfo); -static void retry_transmit(struct r3964_info *pInfo); -static void transmit_block(struct r3964_info *pInfo); -static void receive_char(struct r3964_info *pInfo, const unsigned char c); -static void receive_error(struct r3964_info *pInfo, const char flag); -static void on_timeout(struct timer_list *t); -static int enable_signals(struct r3964_info *pInfo, struct pid *pid, int arg); -static int read_telegram(struct r3964_info *pInfo, struct pid *pid, - unsigned char __user * buf); -static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg, - int error_code, struct r3964_block_header *pBlock); -static struct r3964_message *remove_msg(struct r3964_info *pInfo, - struct r3964_client_info *pClient); -static void remove_client_block(struct r3964_info *pInfo, - struct r3964_client_info *pClient); - -static int r3964_open(struct tty_struct *tty); -static void r3964_close(struct tty_struct *tty); -static ssize_t r3964_read(struct tty_struct *tty, struct file *file, - void *cookie, unsigned char *buf, size_t nr); -static ssize_t r3964_write(struct tty_struct *tty, struct file *file, - const unsigned char *buf, size_t nr); -static int r3964_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg); -#ifdef CONFIG_COMPAT -static int r3964_compat_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg); -#endif -static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old); -static __poll_t r3964_poll(struct tty_struct *tty, struct file *file, - struct poll_table_struct *wait); -static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count); - -static struct tty_ldisc_ops tty_ldisc_N_R3964 = { - .owner = THIS_MODULE, - .name = "R3964", - .open = r3964_open, - .close = r3964_close, - .read = r3964_read, - .write = r3964_write, - .ioctl = r3964_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = r3964_compat_ioctl, -#endif - .set_termios = r3964_set_termios, - .poll = r3964_poll, - .receive_buf = r3964_receive_buf, -}; - -static void dump_block(const unsigned char *block, unsigned int length) -{ - unsigned int i, j; - char linebuf[16 * 3 + 1]; - - for (i = 0; i < length; i += 16) { - for (j = 0; (j < 16) && (j + i < length); j++) { - sprintf(linebuf + 3 * j, "%02x ", block[i + j]); - } - linebuf[3 * j] = '\0'; - TRACE_PS("%s", linebuf); - } -} - -/************************************************************* - * Driver initialisation - *************************************************************/ - -/************************************************************* - * Module support routines - *************************************************************/ - -static void __exit r3964_exit(void) -{ - int status; - - TRACE_M("cleanup_module()"); - - status = tty_unregister_ldisc(N_R3964); - - if (status != 0) { - printk(KERN_ERR "r3964: error unregistering linediscipline: " - "%d\n", status); - } else { - TRACE_L("linediscipline successfully unregistered"); - } -} - -static int __init r3964_init(void) -{ - int status; - - printk("r3964: Philips r3964 Driver $Revision: 1.10 $\n"); - - /* - * Register the tty line discipline - */ - - status = tty_register_ldisc(N_R3964, &tty_ldisc_N_R3964); - if (status == 0) { - TRACE_L("line discipline %d registered", N_R3964); - TRACE_L("flags=%x num=%x", tty_ldisc_N_R3964.flags, - tty_ldisc_N_R3964.num); - TRACE_L("open=%p", tty_ldisc_N_R3964.open); - TRACE_L("tty_ldisc_N_R3964 = %p", &tty_ldisc_N_R3964); - } else { - printk(KERN_ERR "r3964: error registering line discipline: " - "%d\n", status); - } - return status; -} - -module_init(r3964_init); -module_exit(r3964_exit); - -/************************************************************* - * Protocol implementation routines - *************************************************************/ - -static void add_tx_queue(struct r3964_info *pInfo, - struct r3964_block_header *pHeader) -{ - unsigned long flags; - - spin_lock_irqsave(&pInfo->lock, flags); - - pHeader->next = NULL; - - if (pInfo->tx_last == NULL) { - pInfo->tx_first = pInfo->tx_last = pHeader; - } else { - pInfo->tx_last->next = pHeader; - pInfo->tx_last = pHeader; - } - - spin_unlock_irqrestore(&pInfo->lock, flags); - - TRACE_Q("add_tx_queue %p, length %d, tx_first = %p", - pHeader, pHeader->length, pInfo->tx_first); -} - -static void remove_from_tx_queue(struct r3964_info *pInfo, int error_code) -{ - struct r3964_block_header *pHeader; - unsigned long flags; -#ifdef DEBUG_QUEUE - struct r3964_block_header *pDump; -#endif - - pHeader = pInfo->tx_first; - - if (pHeader == NULL) - return; - -#ifdef DEBUG_QUEUE - printk("r3964: remove_from_tx_queue: %p, length %u - ", - pHeader, pHeader->length); - for (pDump = pHeader; pDump; pDump = pDump->next) - printk("%p ", pDump); - printk("\n"); -#endif - - if (pHeader->owner) { - if (error_code) { - add_msg(pHeader->owner, R3964_MSG_ACK, 0, - error_code, NULL); - } else { - add_msg(pHeader->owner, R3964_MSG_ACK, pHeader->length, - error_code, NULL); - } - wake_up_interruptible(&pInfo->tty->read_wait); - } - - spin_lock_irqsave(&pInfo->lock, flags); - - pInfo->tx_first = pHeader->next; - if (pInfo->tx_first == NULL) { - pInfo->tx_last = NULL; - } - - spin_unlock_irqrestore(&pInfo->lock, flags); - - kfree(pHeader); - TRACE_M("remove_from_tx_queue - kfree %p", pHeader); - - TRACE_Q("remove_from_tx_queue: tx_first = %p, tx_last = %p", - pInfo->tx_first, pInfo->tx_last); -} - -static void add_rx_queue(struct r3964_info *pInfo, - struct r3964_block_header *pHeader) -{ - unsigned long flags; - - spin_lock_irqsave(&pInfo->lock, flags); - - pHeader->next = NULL; - - if (pInfo->rx_last == NULL) { - pInfo->rx_first = pInfo->rx_last = pHeader; - } else { - pInfo->rx_last->next = pHeader; - pInfo->rx_last = pHeader; - } - pInfo->blocks_in_rx_queue++; - - spin_unlock_irqrestore(&pInfo->lock, flags); - - TRACE_Q("add_rx_queue: %p, length = %d, rx_first = %p, count = %d", - pHeader, pHeader->length, - pInfo->rx_first, pInfo->blocks_in_rx_queue); -} - -static void remove_from_rx_queue(struct r3964_info *pInfo, - struct r3964_block_header *pHeader) -{ - unsigned long flags; - struct r3964_block_header *pFind; - - if (pHeader == NULL) - return; - - TRACE_Q("remove_from_rx_queue: rx_first = %p, rx_last = %p, count = %d", - pInfo->rx_first, pInfo->rx_last, pInfo->blocks_in_rx_queue); - TRACE_Q("remove_from_rx_queue: %p, length %u", - pHeader, pHeader->length); - - spin_lock_irqsave(&pInfo->lock, flags); - - if (pInfo->rx_first == pHeader) { - /* Remove the first block in the linked list: */ - pInfo->rx_first = pHeader->next; - - if (pInfo->rx_first == NULL) { - pInfo->rx_last = NULL; - } - pInfo->blocks_in_rx_queue--; - } else { - /* Find block to remove: */ - for (pFind = pInfo->rx_first; pFind; pFind = pFind->next) { - if (pFind->next == pHeader) { - /* Got it. */ - pFind->next = pHeader->next; - pInfo->blocks_in_rx_queue--; - if (pFind->next == NULL) { - /* Oh, removed the last one! */ - pInfo->rx_last = pFind; - } - break; - } - } - } - - spin_unlock_irqrestore(&pInfo->lock, flags); - - kfree(pHeader); - TRACE_M("remove_from_rx_queue - kfree %p", pHeader); - - TRACE_Q("remove_from_rx_queue: rx_first = %p, rx_last = %p, count = %d", - pInfo->rx_first, pInfo->rx_last, pInfo->blocks_in_rx_queue); -} - -static void put_char(struct r3964_info *pInfo, unsigned char ch) -{ - struct tty_struct *tty = pInfo->tty; - /* FIXME: put_char should not be called from an IRQ */ - tty_put_char(tty, ch); - pInfo->bcc ^= ch; -} - -static void flush(struct r3964_info *pInfo) -{ - struct tty_struct *tty = pInfo->tty; - - if (tty == NULL || tty->ops->flush_chars == NULL) - return; - tty->ops->flush_chars(tty); -} - -static void trigger_transmit(struct r3964_info *pInfo) -{ - unsigned long flags; - - spin_lock_irqsave(&pInfo->lock, flags); - - if ((pInfo->state == R3964_IDLE) && (pInfo->tx_first != NULL)) { - pInfo->state = R3964_TX_REQUEST; - pInfo->nRetry = 0; - pInfo->flags &= ~R3964_ERROR; - mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ); - - spin_unlock_irqrestore(&pInfo->lock, flags); - - TRACE_PS("trigger_transmit - sent STX"); - - put_char(pInfo, STX); - flush(pInfo); - - pInfo->bcc = 0; - } else { - spin_unlock_irqrestore(&pInfo->lock, flags); - } -} - -static void retry_transmit(struct r3964_info *pInfo) -{ - if (pInfo->nRetry < R3964_MAX_RETRIES) { - TRACE_PE("transmission failed. Retry #%d", pInfo->nRetry); - pInfo->bcc = 0; - put_char(pInfo, STX); - flush(pInfo); - pInfo->state = R3964_TX_REQUEST; - pInfo->nRetry++; - mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ); - } else { - TRACE_PE("transmission failed after %d retries", - R3964_MAX_RETRIES); - - remove_from_tx_queue(pInfo, R3964_TX_FAIL); - - put_char(pInfo, NAK); - flush(pInfo); - pInfo->state = R3964_IDLE; - - trigger_transmit(pInfo); - } -} - -static void transmit_block(struct r3964_info *pInfo) -{ - struct tty_struct *tty = pInfo->tty; - struct r3964_block_header *pBlock = pInfo->tx_first; - int room = 0; - - if (tty == NULL || pBlock == NULL) { - return; - } - - room = tty_write_room(tty); - - TRACE_PS("transmit_block %p, room %d, length %d", - pBlock, room, pBlock->length); - - while (pInfo->tx_position < pBlock->length) { - if (room < 2) - break; - - if (pBlock->data[pInfo->tx_position] == DLE) { - /* send additional DLE char: */ - put_char(pInfo, DLE); - } - put_char(pInfo, pBlock->data[pInfo->tx_position++]); - - room--; - } - - if ((pInfo->tx_position == pBlock->length) && (room >= 3)) { - put_char(pInfo, DLE); - put_char(pInfo, ETX); - if (pInfo->flags & R3964_BCC) { - put_char(pInfo, pInfo->bcc); - } - pInfo->state = R3964_WAIT_FOR_TX_ACK; - mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ); - } - flush(pInfo); -} - -static void on_receive_block(struct r3964_info *pInfo) -{ - unsigned int length; - struct r3964_client_info *pClient; - struct r3964_block_header *pBlock; - - length = pInfo->rx_position; - - /* compare byte checksum characters: */ - if (pInfo->flags & R3964_BCC) { - if (pInfo->bcc != pInfo->last_rx) { - TRACE_PE("checksum error - got %x but expected %x", - pInfo->last_rx, pInfo->bcc); - pInfo->flags |= R3964_CHECKSUM; - } - } - - /* check for errors (parity, overrun,...): */ - if (pInfo->flags & R3964_ERROR) { - TRACE_PE("on_receive_block - transmission failed error %x", - pInfo->flags & R3964_ERROR); - - put_char(pInfo, NAK); - flush(pInfo); - if (pInfo->nRetry < R3964_MAX_RETRIES) { - pInfo->state = R3964_WAIT_FOR_RX_REPEAT; - pInfo->nRetry++; - mod_timer(&pInfo->tmr, jiffies + R3964_TO_RX_PANIC); - } else { - TRACE_PE("on_receive_block - failed after max retries"); - pInfo->state = R3964_IDLE; - } - return; - } - - /* received block; submit DLE: */ - put_char(pInfo, DLE); - flush(pInfo); - del_timer_sync(&pInfo->tmr); - TRACE_PS(" rx success: got %d chars", length); - - /* prepare struct r3964_block_header: */ - pBlock = kmalloc(length + sizeof(struct r3964_block_header), - GFP_KERNEL); - TRACE_M("on_receive_block - kmalloc %p", pBlock); - - if (pBlock == NULL) - return; - - pBlock->length = length; - pBlock->data = ((unsigned char *)pBlock) + - sizeof(struct r3964_block_header); - pBlock->locks = 0; - pBlock->next = NULL; - pBlock->owner = NULL; - - memcpy(pBlock->data, pInfo->rx_buf, length); - - /* queue block into rx_queue: */ - add_rx_queue(pInfo, pBlock); - - /* notify attached client processes: */ - for (pClient = pInfo->firstClient; pClient; pClient = pClient->next) { - if (pClient->sig_flags & R3964_SIG_DATA) { - add_msg(pClient, R3964_MSG_DATA, length, R3964_OK, - pBlock); - } - } - wake_up_interruptible(&pInfo->tty->read_wait); - - pInfo->state = R3964_IDLE; - - trigger_transmit(pInfo); -} - -static void receive_char(struct r3964_info *pInfo, const unsigned char c) -{ - switch (pInfo->state) { - case R3964_TX_REQUEST: - if (c == DLE) { - TRACE_PS("TX_REQUEST - got DLE"); - - pInfo->state = R3964_TRANSMITTING; - pInfo->tx_position = 0; - - transmit_block(pInfo); - } else if (c == STX) { - if (pInfo->nRetry == 0) { - TRACE_PE("TX_REQUEST - init conflict"); - if (pInfo->priority == R3964_SLAVE) { - goto start_receiving; - } - } else { - TRACE_PE("TX_REQUEST - secondary init " - "conflict!? Switching to SLAVE mode " - "for next rx."); - goto start_receiving; - } - } else { - TRACE_PE("TX_REQUEST - char != DLE: %x", c); - retry_transmit(pInfo); - } - break; - case R3964_TRANSMITTING: - if (c == NAK) { - TRACE_PE("TRANSMITTING - got NAK"); - retry_transmit(pInfo); - } else { - TRACE_PE("TRANSMITTING - got invalid char"); - - pInfo->state = R3964_WAIT_ZVZ_BEFORE_TX_RETRY; - mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ); - } - break; - case R3964_WAIT_FOR_TX_ACK: - if (c == DLE) { - TRACE_PS("WAIT_FOR_TX_ACK - got DLE"); - remove_from_tx_queue(pInfo, R3964_OK); - - pInfo->state = R3964_IDLE; - trigger_transmit(pInfo); - } else { - retry_transmit(pInfo); - } - break; - case R3964_WAIT_FOR_RX_REPEAT: - case R3964_IDLE: - if (c == STX) { - /* Prevent rx_queue from overflow: */ - if (pInfo->blocks_in_rx_queue >= - R3964_MAX_BLOCKS_IN_RX_QUEUE) { - TRACE_PE("IDLE - got STX but no space in " - "rx_queue!"); - pInfo->state = R3964_WAIT_FOR_RX_BUF; - mod_timer(&pInfo->tmr, - jiffies + R3964_TO_NO_BUF); - break; - } -start_receiving: - /* Ok, start receiving: */ - TRACE_PS("IDLE - got STX"); - pInfo->rx_position = 0; - pInfo->last_rx = 0; - pInfo->flags &= ~R3964_ERROR; - pInfo->state = R3964_RECEIVING; - mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ); - pInfo->nRetry = 0; - put_char(pInfo, DLE); - flush(pInfo); - pInfo->bcc = 0; - } - break; - case R3964_RECEIVING: - if (pInfo->rx_position < RX_BUF_SIZE) { - pInfo->bcc ^= c; - - if (c == DLE) { - if (pInfo->last_rx == DLE) { - pInfo->last_rx = 0; - goto char_to_buf; - } - pInfo->last_rx = DLE; - break; - } else if ((c == ETX) && (pInfo->last_rx == DLE)) { - if (pInfo->flags & R3964_BCC) { - pInfo->state = R3964_WAIT_FOR_BCC; - mod_timer(&pInfo->tmr, - jiffies + R3964_TO_ZVZ); - } else { - on_receive_block(pInfo); - } - } else { - pInfo->last_rx = c; -char_to_buf: - pInfo->rx_buf[pInfo->rx_position++] = c; - mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ); - } - } - /* else: overflow-msg? BUF_SIZE>MTU; should not happen? */ - break; - case R3964_WAIT_FOR_BCC: - pInfo->last_rx = c; - on_receive_block(pInfo); - break; - } -} - -static void receive_error(struct r3964_info *pInfo, const char flag) -{ - switch (flag) { - case TTY_NORMAL: - break; - case TTY_BREAK: - TRACE_PE("received break"); - pInfo->flags |= R3964_BREAK; - break; - case TTY_PARITY: - TRACE_PE("parity error"); - pInfo->flags |= R3964_PARITY; - break; - case TTY_FRAME: - TRACE_PE("frame error"); - pInfo->flags |= R3964_FRAME; - break; - case TTY_OVERRUN: - TRACE_PE("frame overrun"); - pInfo->flags |= R3964_OVERRUN; - break; - default: - TRACE_PE("receive_error - unknown flag %d", flag); - pInfo->flags |= R3964_UNKNOWN; - break; - } -} - -static void on_timeout(struct timer_list *t) -{ - struct r3964_info *pInfo = from_timer(pInfo, t, tmr); - - switch (pInfo->state) { - case R3964_TX_REQUEST: - TRACE_PE("TX_REQUEST - timeout"); - retry_transmit(pInfo); - break; - case R3964_WAIT_ZVZ_BEFORE_TX_RETRY: - put_char(pInfo, NAK); - flush(pInfo); - retry_transmit(pInfo); - break; - case R3964_WAIT_FOR_TX_ACK: - TRACE_PE("WAIT_FOR_TX_ACK - timeout"); - retry_transmit(pInfo); - break; - case R3964_WAIT_FOR_RX_BUF: - TRACE_PE("WAIT_FOR_RX_BUF - timeout"); - put_char(pInfo, NAK); - flush(pInfo); - pInfo->state = R3964_IDLE; - break; - case R3964_RECEIVING: - TRACE_PE("RECEIVING - timeout after %d chars", - pInfo->rx_position); - put_char(pInfo, NAK); - flush(pInfo); - pInfo->state = R3964_IDLE; - break; - case R3964_WAIT_FOR_RX_REPEAT: - TRACE_PE("WAIT_FOR_RX_REPEAT - timeout"); - pInfo->state = R3964_IDLE; - break; - case R3964_WAIT_FOR_BCC: - TRACE_PE("WAIT_FOR_BCC - timeout"); - put_char(pInfo, NAK); - flush(pInfo); - pInfo->state = R3964_IDLE; - break; - } -} - -static struct r3964_client_info *findClient(struct r3964_info *pInfo, - struct pid *pid) -{ - struct r3964_client_info *pClient; - - for (pClient = pInfo->firstClient; pClient; pClient = pClient->next) { - if (pClient->pid == pid) { - return pClient; - } - } - return NULL; -} - -static int enable_signals(struct r3964_info *pInfo, struct pid *pid, int arg) -{ - struct r3964_client_info *pClient; - struct r3964_client_info **ppClient; - struct r3964_message *pMsg; - - if ((arg & R3964_SIG_ALL) == 0) { - /* Remove client from client list */ - for (ppClient = &pInfo->firstClient; *ppClient; - ppClient = &(*ppClient)->next) { - pClient = *ppClient; - - if (pClient->pid == pid) { - TRACE_PS("removing client %d from client list", - pid_nr(pid)); - *ppClient = pClient->next; - while (pClient->msg_count) { - pMsg = remove_msg(pInfo, pClient); - if (pMsg) { - kfree(pMsg); - TRACE_M("enable_signals - msg " - "kfree %p", pMsg); - } - } - put_pid(pClient->pid); - kfree(pClient); - TRACE_M("enable_signals - kfree %p", pClient); - return 0; - } - } - return -EINVAL; - } else { - pClient = findClient(pInfo, pid); - if (pClient) { - /* update signal options */ - pClient->sig_flags = arg; - } else { - /* add client to client list */ - pClient = kmalloc(sizeof(struct r3964_client_info), - GFP_KERNEL); - TRACE_M("enable_signals - kmalloc %p", pClient); - if (pClient == NULL) - return -ENOMEM; - - TRACE_PS("add client %d to client list", pid_nr(pid)); - spin_lock_init(&pClient->lock); - pClient->sig_flags = arg; - pClient->pid = get_pid(pid); - pClient->next = pInfo->firstClient; - pClient->first_msg = NULL; - pClient->last_msg = NULL; - pClient->next_block_to_read = NULL; - pClient->msg_count = 0; - pInfo->firstClient = pClient; - } - } - - return 0; -} - -static int read_telegram(struct r3964_info *pInfo, struct pid *pid, - unsigned char __user * buf) -{ - struct r3964_client_info *pClient; - struct r3964_block_header *block; - - if (!buf) { - return -EINVAL; - } - - pClient = findClient(pInfo, pid); - if (pClient == NULL) { - return -EINVAL; - } - - block = pClient->next_block_to_read; - if (!block) { - return 0; - } else { - if (copy_to_user(buf, block->data, block->length)) - return -EFAULT; - - remove_client_block(pInfo, pClient); - return block->length; - } - - return -EINVAL; -} - -static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg, - int error_code, struct r3964_block_header *pBlock) -{ - struct r3964_message *pMsg; - unsigned long flags; - - if (pClient->msg_count < R3964_MAX_MSG_COUNT - 1) { -queue_the_message: - - pMsg = kmalloc(sizeof(struct r3964_message), - error_code ? GFP_ATOMIC : GFP_KERNEL); - TRACE_M("add_msg - kmalloc %p", pMsg); - if (pMsg == NULL) { - return; - } - - spin_lock_irqsave(&pClient->lock, flags); - - pMsg->msg_id = msg_id; - pMsg->arg = arg; - pMsg->error_code = error_code; - pMsg->block = pBlock; - pMsg->next = NULL; - - if (pClient->last_msg == NULL) { - pClient->first_msg = pClient->last_msg = pMsg; - } else { - pClient->last_msg->next = pMsg; - pClient->last_msg = pMsg; - } - - pClient->msg_count++; - - if (pBlock != NULL) { - pBlock->locks++; - } - spin_unlock_irqrestore(&pClient->lock, flags); - } else { - if ((pClient->last_msg->msg_id == R3964_MSG_ACK) - && (pClient->last_msg->error_code == R3964_OVERFLOW)) { - pClient->last_msg->arg++; - TRACE_PE("add_msg - inc prev OVERFLOW-msg"); - } else { - msg_id = R3964_MSG_ACK; - arg = 0; - error_code = R3964_OVERFLOW; - pBlock = NULL; - TRACE_PE("add_msg - queue OVERFLOW-msg"); - goto queue_the_message; - } - } - /* Send SIGIO signal to client process: */ - if (pClient->sig_flags & R3964_USE_SIGIO) { - kill_pid(pClient->pid, SIGIO, 1); - } -} - -static struct r3964_message *remove_msg(struct r3964_info *pInfo, - struct r3964_client_info *pClient) -{ - struct r3964_message *pMsg = NULL; - unsigned long flags; - - if (pClient->first_msg) { - spin_lock_irqsave(&pClient->lock, flags); - - pMsg = pClient->first_msg; - pClient->first_msg = pMsg->next; - if (pClient->first_msg == NULL) { - pClient->last_msg = NULL; - } - - pClient->msg_count--; - if (pMsg->block) { - remove_client_block(pInfo, pClient); - pClient->next_block_to_read = pMsg->block; - } - spin_unlock_irqrestore(&pClient->lock, flags); - } - return pMsg; -} - -static void remove_client_block(struct r3964_info *pInfo, - struct r3964_client_info *pClient) -{ - struct r3964_block_header *block; - - TRACE_PS("remove_client_block PID %d", pid_nr(pClient->pid)); - - block = pClient->next_block_to_read; - if (block) { - block->locks--; - if (block->locks == 0) { - remove_from_rx_queue(pInfo, block); - } - } - pClient->next_block_to_read = NULL; -} - -/************************************************************* - * Line discipline routines - *************************************************************/ - -static int r3964_open(struct tty_struct *tty) -{ - struct r3964_info *pInfo; - - TRACE_L("open"); - TRACE_L("tty=%p, PID=%d, disc_data=%p", - tty, current->pid, tty->disc_data); - - pInfo = kmalloc(sizeof(struct r3964_info), GFP_KERNEL); - TRACE_M("r3964_open - info kmalloc %p", pInfo); - - if (!pInfo) { - printk(KERN_ERR "r3964: failed to alloc info structure\n"); - return -ENOMEM; - } - - pInfo->rx_buf = kmalloc(RX_BUF_SIZE, GFP_KERNEL); - TRACE_M("r3964_open - rx_buf kmalloc %p", pInfo->rx_buf); - - if (!pInfo->rx_buf) { - printk(KERN_ERR "r3964: failed to alloc receive buffer\n"); - kfree(pInfo); - TRACE_M("r3964_open - info kfree %p", pInfo); - return -ENOMEM; - } - - pInfo->tx_buf = kmalloc(TX_BUF_SIZE, GFP_KERNEL); - TRACE_M("r3964_open - tx_buf kmalloc %p", pInfo->tx_buf); - - if (!pInfo->tx_buf) { - printk(KERN_ERR "r3964: failed to alloc transmit buffer\n"); - kfree(pInfo->rx_buf); - TRACE_M("r3964_open - rx_buf kfree %p", pInfo->rx_buf); - kfree(pInfo); - TRACE_M("r3964_open - info kfree %p", pInfo); - return -ENOMEM; - } - - spin_lock_init(&pInfo->lock); - mutex_init(&pInfo->read_lock); - pInfo->tty = tty; - pInfo->priority = R3964_MASTER; - pInfo->rx_first = pInfo->rx_last = NULL; - pInfo->tx_first = pInfo->tx_last = NULL; - pInfo->rx_position = 0; - pInfo->tx_position = 0; - pInfo->last_rx = 0; - pInfo->blocks_in_rx_queue = 0; - pInfo->firstClient = NULL; - pInfo->state = R3964_IDLE; - pInfo->flags = R3964_DEBUG; - pInfo->nRetry = 0; - - tty->disc_data = pInfo; - tty->receive_room = 65536; - - timer_setup(&pInfo->tmr, on_timeout, 0); - - return 0; -} - -static void r3964_close(struct tty_struct *tty) -{ - struct r3964_info *pInfo = tty->disc_data; - struct r3964_client_info *pClient, *pNext; - struct r3964_message *pMsg; - struct r3964_block_header *pHeader, *pNextHeader; - unsigned long flags; - - TRACE_L("close"); - - /* - * Make sure that our task queue isn't activated. If it - * is, take it out of the linked list. - */ - del_timer_sync(&pInfo->tmr); - - /* Remove client-structs and message queues: */ - pClient = pInfo->firstClient; - while (pClient) { - pNext = pClient->next; - while (pClient->msg_count) { - pMsg = remove_msg(pInfo, pClient); - if (pMsg) { - kfree(pMsg); - TRACE_M("r3964_close - msg kfree %p", pMsg); - } - } - put_pid(pClient->pid); - kfree(pClient); - TRACE_M("r3964_close - client kfree %p", pClient); - pClient = pNext; - } - /* Remove jobs from tx_queue: */ - spin_lock_irqsave(&pInfo->lock, flags); - pHeader = pInfo->tx_first; - pInfo->tx_first = pInfo->tx_last = NULL; - spin_unlock_irqrestore(&pInfo->lock, flags); - - while (pHeader) { - pNextHeader = pHeader->next; - kfree(pHeader); - pHeader = pNextHeader; - } - - /* Free buffers: */ - kfree(pInfo->rx_buf); - TRACE_M("r3964_close - rx_buf kfree %p", pInfo->rx_buf); - kfree(pInfo->tx_buf); - TRACE_M("r3964_close - tx_buf kfree %p", pInfo->tx_buf); - kfree(pInfo); - TRACE_M("r3964_close - info kfree %p", pInfo); -} - -static ssize_t r3964_read(struct tty_struct *tty, struct file *file, - unsigned char *kbuf, size_t nr, - void **cookie, unsigned long offset) -{ - struct r3964_info *pInfo = tty->disc_data; - struct r3964_client_info *pClient; - struct r3964_message *pMsg; - struct r3964_client_message theMsg; - int ret; - - TRACE_L("read()"); - - /* - * Internal serialization of reads. - */ - if (file->f_flags & O_NONBLOCK) { - if (!mutex_trylock(&pInfo->read_lock)) - return -EAGAIN; - } else { - if (mutex_lock_interruptible(&pInfo->read_lock)) - return -ERESTARTSYS; - } - - pClient = findClient(pInfo, task_pid(current)); - if (pClient) { - pMsg = remove_msg(pInfo, pClient); - if (pMsg == NULL) { - /* no messages available. */ - if (tty_io_nonblock(tty, file)) { - ret = -EAGAIN; - goto unlock; - } - /* block until there is a message: */ - wait_event_interruptible(tty->read_wait, - (pMsg = remove_msg(pInfo, pClient))); - } - - /* If we still haven't got a message, we must have been signalled */ - - if (!pMsg) { - ret = -EINTR; - goto unlock; - } - - /* deliver msg to client process: */ - theMsg.msg_id = pMsg->msg_id; - theMsg.arg = pMsg->arg; - theMsg.error_code = pMsg->error_code; - ret = sizeof(struct r3964_client_message); - - kfree(pMsg); - TRACE_M("r3964_read - msg kfree %p", pMsg); - - memcpy(kbuf, &theMsg, ret); - - TRACE_PS("read - return %d", ret); - goto unlock; - } - ret = -EPERM; -unlock: - mutex_unlock(&pInfo->read_lock); - return ret; -} - -static ssize_t r3964_write(struct tty_struct *tty, struct file *file, - const unsigned char *data, size_t count) -{ - struct r3964_info *pInfo = tty->disc_data; - struct r3964_block_header *pHeader; - struct r3964_client_info *pClient; - unsigned char *new_data; - - TRACE_L("write request, %d characters", count); -/* - * Verify the pointers - */ - - if (!pInfo) - return -EIO; - -/* - * Ensure that the caller does not wish to send too much. - */ - if (count > R3964_MTU) { - if (pInfo->flags & R3964_DEBUG) { - TRACE_L(KERN_WARNING "r3964_write: truncating user " - "packet from %u to mtu %d", count, R3964_MTU); - } - count = R3964_MTU; - } -/* - * Allocate a buffer for the data and copy it from the buffer with header prepended - */ - new_data = kmalloc(count + sizeof(struct r3964_block_header), - GFP_KERNEL); - TRACE_M("r3964_write - kmalloc %p", new_data); - if (new_data == NULL) { - if (pInfo->flags & R3964_DEBUG) { - printk(KERN_ERR "r3964_write: no memory\n"); - } - return -ENOSPC; - } - - pHeader = (struct r3964_block_header *)new_data; - pHeader->data = new_data + sizeof(struct r3964_block_header); - pHeader->length = count; - pHeader->locks = 0; - pHeader->owner = NULL; - - pClient = findClient(pInfo, task_pid(current)); - if (pClient) { - pHeader->owner = pClient; - } - - memcpy(pHeader->data, data, count); /* We already verified this */ - - if (pInfo->flags & R3964_DEBUG) { - dump_block(pHeader->data, count); - } - -/* - * Add buffer to transmit-queue: - */ - add_tx_queue(pInfo, pHeader); - trigger_transmit(pInfo); - - return 0; -} - -static int r3964_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct r3964_info *pInfo = tty->disc_data; - if (pInfo == NULL) - return -EINVAL; - switch (cmd) { - case R3964_ENABLE_SIGNALS: - return enable_signals(pInfo, task_pid(current), arg); - case R3964_SETPRIORITY: - if (arg < R3964_MASTER || arg > R3964_SLAVE) - return -EINVAL; - pInfo->priority = arg & 0xff; - return 0; - case R3964_USE_BCC: - if (arg) - pInfo->flags |= R3964_BCC; - else - pInfo->flags &= ~R3964_BCC; - return 0; - case R3964_READ_TELEGRAM: - return read_telegram(pInfo, task_pid(current), - (unsigned char __user *)arg); - default: - return -ENOIOCTLCMD; - } -} - -#ifdef CONFIG_COMPAT -static int r3964_compat_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) -{ - switch (cmd) { - case R3964_ENABLE_SIGNALS: - case R3964_SETPRIORITY: - case R3964_USE_BCC: - return r3964_ioctl(tty, file, cmd, arg); - default: - return -ENOIOCTLCMD; - } -} -#endif - -static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old) -{ - TRACE_L("set_termios"); -} - -/* Called without the kernel lock held - fine */ -static __poll_t r3964_poll(struct tty_struct *tty, struct file *file, - struct poll_table_struct *wait) -{ - struct r3964_info *pInfo = tty->disc_data; - struct r3964_client_info *pClient; - struct r3964_message *pMsg = NULL; - unsigned long flags; - __poll_t result = EPOLLOUT; - - TRACE_L("POLL"); - - pClient = findClient(pInfo, task_pid(current)); - if (pClient) { - poll_wait(file, &tty->read_wait, wait); - spin_lock_irqsave(&pInfo->lock, flags); - pMsg = pClient->first_msg; - spin_unlock_irqrestore(&pInfo->lock, flags); - if (pMsg) - result |= EPOLLIN | EPOLLRDNORM; - } else { - result = -EINVAL; - } - return result; -} - -static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) -{ - struct r3964_info *pInfo = tty->disc_data; - const unsigned char *p; - char *f, flags = TTY_NORMAL; - int i; - - for (i = count, p = cp, f = fp; i; i--, p++) { - if (f) - flags = *f++; - if (flags == TTY_NORMAL) { - receive_char(pInfo, *p); - } else { - receive_error(pInfo, flags); - } - - } -} - -MODULE_LICENSE("GPL"); -MODULE_ALIAS_LDISC(N_R3964); diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 01645e87b3d5..e5040bdadcd6 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -3260,8 +3260,6 @@ static int con_write(struct tty_struct *tty, const unsigned char *buf, int count static int con_put_char(struct tty_struct *tty, unsigned char ch) { - if (in_interrupt()) - return 0; /* n_r3964 calls put_char() from interrupt context */ return do_con_write(tty, &ch, 1); } diff --git a/include/linux/n_r3964.h b/include/linux/n_r3964.h deleted file mode 100644 index 90a803aa42e8..000000000000 --- a/include/linux/n_r3964.h +++ /dev/null @@ -1,175 +0,0 @@ -/* r3964 linediscipline for linux - * - * ----------------------------------------------------------- - * Copyright by - * Philips Automation Projects - * Kassel (Germany) - * ----------------------------------------------------------- - * This software may be used and distributed according to the terms of - * the GNU General Public License, incorporated herein by reference. - * - * Author: - * L. Haag - * - * $Log: r3964.h,v $ - * Revision 1.4 2005/12/21 19:54:24 Kurt Huwig - * Fixed HZ usage on 2.6 kernels - * Removed unnecessary include - * - * Revision 1.3 2001/03/18 13:02:24 dwmw2 - * Fix timer usage, use spinlocks properly. - * - * Revision 1.2 2001/03/18 12:53:15 dwmw2 - * Merge changes in 2.4.2 - * - * Revision 1.1.1.1 1998/10/13 16:43:14 dwmw2 - * This'll screw the version control - * - * Revision 1.6 1998/09/30 00:40:38 dwmw2 - * Updated to use kernel's N_R3964 if available - * - * Revision 1.4 1998/04/02 20:29:44 lhaag - * select, blocking, ... - * - * Revision 1.3 1998/02/12 18:58:43 root - * fixed some memory leaks - * calculation of checksum characters - * - * Revision 1.2 1998/02/07 13:03:17 root - * ioctl read_telegram - * - * Revision 1.1 1998/02/06 19:19:43 root - * Initial revision - * - * - */ -#ifndef __LINUX_N_R3964_H__ -#define __LINUX_N_R3964_H__ - - -#include -#include - -/* - * Common ascii handshake characters: - */ - -#define STX 0x02 -#define ETX 0x03 -#define DLE 0x10 -#define NAK 0x15 - -/* - * Timeouts (from milliseconds to jiffies) - */ - -#define R3964_TO_QVZ ((550)*HZ/1000) -#define R3964_TO_ZVZ ((220)*HZ/1000) -#define R3964_TO_NO_BUF ((400)*HZ/1000) -#define R3964_NO_TX_ROOM ((100)*HZ/1000) -#define R3964_TO_RX_PANIC ((4000)*HZ/1000) -#define R3964_MAX_RETRIES 5 - - -enum { R3964_IDLE, - R3964_TX_REQUEST, R3964_TRANSMITTING, - R3964_WAIT_ZVZ_BEFORE_TX_RETRY, R3964_WAIT_FOR_TX_ACK, - R3964_WAIT_FOR_RX_BUF, - R3964_RECEIVING, R3964_WAIT_FOR_BCC, R3964_WAIT_FOR_RX_REPEAT - }; - -/* - * All open file-handles are 'clients' and are stored in a linked list: - */ - -struct r3964_message; - -struct r3964_client_info { - spinlock_t lock; - struct pid *pid; - unsigned int sig_flags; - - struct r3964_client_info *next; - - struct r3964_message *first_msg; - struct r3964_message *last_msg; - struct r3964_block_header *next_block_to_read; - int msg_count; -}; - - - -struct r3964_block_header; - -/* internal version of client_message: */ -struct r3964_message { - int msg_id; - int arg; - int error_code; - struct r3964_block_header *block; - struct r3964_message *next; -}; - -/* - * Header of received block in rx_buf/tx_buf: - */ - -struct r3964_block_header -{ - unsigned int length; /* length in chars without header */ - unsigned char *data; /* usually data is located - immediately behind this struct */ - unsigned int locks; /* only used in rx_buffer */ - - struct r3964_block_header *next; - struct r3964_client_info *owner; /* =NULL in rx_buffer */ -}; - -/* - * If rx_buf hasn't enough space to store R3964_MTU chars, - * we will reject all incoming STX-requests by sending NAK. - */ - -#define RX_BUF_SIZE 4000 -#define TX_BUF_SIZE 4000 -#define R3964_MAX_BLOCKS_IN_RX_QUEUE 100 - -#define R3964_PARITY 0x0001 -#define R3964_FRAME 0x0002 -#define R3964_OVERRUN 0x0004 -#define R3964_UNKNOWN 0x0008 -#define R3964_BREAK 0x0010 -#define R3964_CHECKSUM 0x0020 -#define R3964_ERROR 0x003f -#define R3964_BCC 0x4000 -#define R3964_DEBUG 0x8000 - - -struct r3964_info { - spinlock_t lock; - struct tty_struct *tty; - unsigned char priority; - unsigned char *rx_buf; /* ring buffer */ - unsigned char *tx_buf; - - struct r3964_block_header *rx_first; - struct r3964_block_header *rx_last; - struct r3964_block_header *tx_first; - struct r3964_block_header *tx_last; - unsigned int tx_position; - unsigned int rx_position; - unsigned char last_rx; - unsigned char bcc; - unsigned int blocks_in_rx_queue; - - struct mutex read_lock; /* serialize r3964_read */ - - struct r3964_client_info *firstClient; - unsigned int state; - unsigned int flags; - - struct timer_list tmr; - int nRetry; -}; - -#endif diff --git a/include/uapi/linux/n_r3964.h b/include/uapi/linux/n_r3964.h deleted file mode 100644 index 6bbd18520f30..000000000000 --- a/include/uapi/linux/n_r3964.h +++ /dev/null @@ -1,99 +0,0 @@ -/* SPDX-License-Identifier: GPL-1.0+ WITH Linux-syscall-note */ -/* r3964 linediscipline for linux - * - * ----------------------------------------------------------- - * Copyright by - * Philips Automation Projects - * Kassel (Germany) - * ----------------------------------------------------------- - * This software may be used and distributed according to the terms of - * the GNU General Public License, incorporated herein by reference. - * - * Author: - * L. Haag - * - * $Log: r3964.h,v $ - * Revision 1.4 2005/12/21 19:54:24 Kurt Huwig - * Fixed HZ usage on 2.6 kernels - * Removed unnecessary include - * - * Revision 1.3 2001/03/18 13:02:24 dwmw2 - * Fix timer usage, use spinlocks properly. - * - * Revision 1.2 2001/03/18 12:53:15 dwmw2 - * Merge changes in 2.4.2 - * - * Revision 1.1.1.1 1998/10/13 16:43:14 dwmw2 - * This'll screw the version control - * - * Revision 1.6 1998/09/30 00:40:38 dwmw2 - * Updated to use kernel's N_R3964 if available - * - * Revision 1.4 1998/04/02 20:29:44 lhaag - * select, blocking, ... - * - * Revision 1.3 1998/02/12 18:58:43 root - * fixed some memory leaks - * calculation of checksum characters - * - * Revision 1.2 1998/02/07 13:03:17 root - * ioctl read_telegram - * - * Revision 1.1 1998/02/06 19:19:43 root - * Initial revision - * - * - */ - -#ifndef _UAPI__LINUX_N_R3964_H__ -#define _UAPI__LINUX_N_R3964_H__ - -/* line disciplines for r3964 protocol */ - - -/* - * Ioctl-commands - */ - -#define R3964_ENABLE_SIGNALS 0x5301 -#define R3964_SETPRIORITY 0x5302 -#define R3964_USE_BCC 0x5303 -#define R3964_READ_TELEGRAM 0x5304 - -/* Options for R3964_SETPRIORITY */ -#define R3964_MASTER 0 -#define R3964_SLAVE 1 - -/* Options for R3964_ENABLE_SIGNALS */ -#define R3964_SIG_ACK 0x0001 -#define R3964_SIG_DATA 0x0002 -#define R3964_SIG_ALL 0x000f -#define R3964_SIG_NONE 0x0000 -#define R3964_USE_SIGIO 0x1000 - -/* - * r3964 operation states: - */ - -/* types for msg_id: */ -enum {R3964_MSG_ACK=1, R3964_MSG_DATA }; - -#define R3964_MAX_MSG_COUNT 32 - -/* error codes for client messages */ -#define R3964_OK 0 /* no error. */ -#define R3964_TX_FAIL -1 /* transmission error, block NOT sent */ -#define R3964_OVERFLOW -2 /* msg queue overflow */ - -/* the client gets this struct when calling read(fd,...): */ -struct r3964_client_message { - int msg_id; - int arg; - int error_code; -}; - -#define R3964_MTU 256 - - - -#endif /* _UAPI__LINUX_N_R3964_H__ */ From 7fb8a8affdf1971e89b5977e074e402190dcd6dc Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:18:55 +0200 Subject: [PATCH 025/227] n_tty: remove n_tty_receive_char wrapper The wrapper was meant as an optimization in commits eb3e4668bd9e (n_tty: Un-inline slow-path n_tty_receive_char()) and e60d27c4d8b3 (n_tty: Factor LNEXT processing from per-char i/o path). But the current compiler (gcc 10) inlines it anyway (as expected). Actually, I'm not sure it ever didn't. It would need to be marked with the noinline attribute. So remove this useless wrapper. And if we ever introduce something similar, we need confirming numbers first. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210505091928.22010-3-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 9686c5d10571..0a8c9440f5d2 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1401,7 +1401,7 @@ handle_newline: } static inline void -n_tty_receive_char_inline(struct tty_struct *tty, unsigned char c) +n_tty_receive_char(struct tty_struct *tty, unsigned char c) { struct n_tty_data *ldata = tty->disc_data; @@ -1423,11 +1423,6 @@ n_tty_receive_char_inline(struct tty_struct *tty, unsigned char c) put_tty_queue(c, ldata); } -static void n_tty_receive_char(struct tty_struct *tty, unsigned char c) -{ - n_tty_receive_char_inline(tty, c); -} - static inline void n_tty_receive_char_fast(struct tty_struct *tty, unsigned char c) { @@ -1577,7 +1572,7 @@ n_tty_receive_buf_standard(struct tty_struct *tty, const unsigned char *cp, continue; } if (!test_bit(c, ldata->char_map)) - n_tty_receive_char_inline(tty, c); + n_tty_receive_char(tty, c); else if (n_tty_receive_char_special(tty, c) && count) { if (fp) flag = *fp++; From 89bb4a3622f99ea736eab185db9b46b4fa4c29c0 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:18:56 +0200 Subject: [PATCH 026/227] n_tty: remove n_tty_receive_char_fast n_tty_receive_char_fast is a copy of n_tty_receive_char with one exception: PARMRK is not doubled in the former. Unify these two and double PARMRK depending on a newly added parameter (bool parmrk_dbl). I don't think the theoretical speedup is worth the code duplication. Which is directly connected with maintenance burden. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210505091928.22010-4-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 0a8c9440f5d2..0adc79bae839 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1400,8 +1400,8 @@ handle_newline: return 0; } -static inline void -n_tty_receive_char(struct tty_struct *tty, unsigned char c) +static void n_tty_receive_char(struct tty_struct *tty, unsigned char c, + bool parmrk_dbl) { struct n_tty_data *ldata = tty->disc_data; @@ -1418,31 +1418,11 @@ n_tty_receive_char(struct tty_struct *tty, unsigned char c) commit_echoes(tty); } /* PARMRK doubling check */ - if (c == (unsigned char) '\377' && I_PARMRK(tty)) + if (parmrk_dbl && c == (unsigned char) '\377' && I_PARMRK(tty)) put_tty_queue(c, ldata); put_tty_queue(c, ldata); } -static inline void -n_tty_receive_char_fast(struct tty_struct *tty, unsigned char c) -{ - struct n_tty_data *ldata = tty->disc_data; - - if (tty->stopped && !tty->flow_stopped && I_IXON(tty) && I_IXANY(tty)) { - start_tty(tty); - process_echoes(tty); - } - if (L_ECHO(tty)) { - finish_erasing(ldata); - /* Record the column of first canon char. */ - if (ldata->canon_head == ldata->read_head) - echo_set_canon_col(ldata); - echo_char(c, tty); - commit_echoes(tty); - } - put_tty_queue(c, ldata); -} - static void n_tty_receive_char_closing(struct tty_struct *tty, unsigned char c) { if (I_ISTRIP(tty)) @@ -1494,7 +1474,7 @@ n_tty_receive_char_lnext(struct tty_struct *tty, unsigned char c, char flag) c &= 0x7f; if (I_IUCLC(tty) && L_IEXTEN(tty)) c = tolower(c); - n_tty_receive_char(tty, c); + n_tty_receive_char(tty, c, true); } else n_tty_receive_char_flagged(tty, c, flag); } @@ -1572,7 +1552,7 @@ n_tty_receive_buf_standard(struct tty_struct *tty, const unsigned char *cp, continue; } if (!test_bit(c, ldata->char_map)) - n_tty_receive_char(tty, c); + n_tty_receive_char(tty, c, true); else if (n_tty_receive_char_special(tty, c) && count) { if (fp) flag = *fp++; @@ -1598,7 +1578,7 @@ n_tty_receive_buf_fast(struct tty_struct *tty, const unsigned char *cp, unsigned char c = *cp++; if (!test_bit(c, ldata->char_map)) - n_tty_receive_char_fast(tty, c); + n_tty_receive_char(tty, c, false); else if (n_tty_receive_char_special(tty, c) && count) { if (fp) flag = *fp++; From 1ed2dfedd215def180351697f5b4bcde468c5197 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:18:57 +0200 Subject: [PATCH 027/227] n_tty: drop n_tty_receive_buf_fast After the previous patches, n_tty_receive_buf_standard and n_tty_receive_buf_fast differ only in handling of tty line and input controls. Unlike n_tty_receive_buf_fast, n_tty_receive_buf_standard handles them all (I_ISTRIP, I_IUCLC, L_IEXTEN, L_EXTPROC, and I_PARMRK). So remove n_tty_receive_buf_fast and let n_tty_receive_buf_standard do the handling. Actually most of the tests are only moved from __receive_buf to n_tty_receive_buf_standard. Again, the code duplication is not worth the theoretical speedup. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210505091928.22010-5-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 36 +++--------------------------------- 1 file changed, 3 insertions(+), 33 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 0adc79bae839..5d83fb5412fd 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1530,9 +1530,8 @@ n_tty_receive_buf_closing(struct tty_struct *tty, const unsigned char *cp, } } -static void -n_tty_receive_buf_standard(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) +static void n_tty_receive_buf_standard(struct tty_struct *tty, + const unsigned char *cp, char *fp, int count) { struct n_tty_data *ldata = tty->disc_data; char flag = TTY_NORMAL; @@ -1564,32 +1563,6 @@ n_tty_receive_buf_standard(struct tty_struct *tty, const unsigned char *cp, } } -static void -n_tty_receive_buf_fast(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) -{ - struct n_tty_data *ldata = tty->disc_data; - char flag = TTY_NORMAL; - - while (count--) { - if (fp) - flag = *fp++; - if (likely(flag == TTY_NORMAL)) { - unsigned char c = *cp++; - - if (!test_bit(c, ldata->char_map)) - n_tty_receive_char(tty, c, false); - else if (n_tty_receive_char_special(tty, c) && count) { - if (fp) - flag = *fp++; - n_tty_receive_char_lnext(tty, *cp++, flag); - count--; - } - } else - n_tty_receive_char_flagged(tty, *cp++, flag); - } -} - static void __receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) { @@ -1612,10 +1585,7 @@ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp, count--; } - if (!preops && !I_PARMRK(tty)) - n_tty_receive_buf_fast(tty, cp, fp, count); - else - n_tty_receive_buf_standard(tty, cp, fp, count); + n_tty_receive_buf_standard(tty, cp, fp, count); flush_echoes(tty); if (tty->ops->flush_chars) From 95aafe3278e7f16910eeef59c0664b1d23dcdda0 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:18:58 +0200 Subject: [PATCH 028/227] n_tty: drop parmrk_dbl from n_tty_receive_char After the previous cleanup patches, parmrk_dbl parameter is always true -- I_PARMRK is checked only in n_tty_receive_char now. So remove parmrk_dbl completely. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210505091928.22010-6-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 5d83fb5412fd..f0db3f41df83 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1400,8 +1400,7 @@ handle_newline: return 0; } -static void n_tty_receive_char(struct tty_struct *tty, unsigned char c, - bool parmrk_dbl) +static void n_tty_receive_char(struct tty_struct *tty, unsigned char c) { struct n_tty_data *ldata = tty->disc_data; @@ -1418,7 +1417,7 @@ static void n_tty_receive_char(struct tty_struct *tty, unsigned char c, commit_echoes(tty); } /* PARMRK doubling check */ - if (parmrk_dbl && c == (unsigned char) '\377' && I_PARMRK(tty)) + if (c == (unsigned char) '\377' && I_PARMRK(tty)) put_tty_queue(c, ldata); put_tty_queue(c, ldata); } @@ -1474,7 +1473,7 @@ n_tty_receive_char_lnext(struct tty_struct *tty, unsigned char c, char flag) c &= 0x7f; if (I_IUCLC(tty) && L_IEXTEN(tty)) c = tolower(c); - n_tty_receive_char(tty, c, true); + n_tty_receive_char(tty, c); } else n_tty_receive_char_flagged(tty, c, flag); } @@ -1551,7 +1550,7 @@ static void n_tty_receive_buf_standard(struct tty_struct *tty, continue; } if (!test_bit(c, ldata->char_map)) - n_tty_receive_char(tty, c, true); + n_tty_receive_char(tty, c); else if (n_tty_receive_char_special(tty, c) && count) { if (fp) flag = *fp++; From 67a620d58b47b6683da7f8152baa4384f74b19f8 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:18:59 +0200 Subject: [PATCH 029/227] n_tty: move lnext handling Move lnext handling from __receive_buf to n_tty_receive_buf_standard. It simplifies the handling as it needs not fetching 'flag' and decrement 'count' in __receive_buf. Instead, all this is left up to the loop in n_tty_receive_buf_standard which already does that. This way, no need to repeat the action when n_tty_receive_char_special returns true -- ldata->lnext is set there in that case, so the 'if (ldata->lnext)' check is sufficient. The next patch will switch n_tty_receive_char_special to return 'void'. The result is much simplified code flow. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210505091928.22010-7-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index f0db3f41df83..d40844b7a4fb 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1538,6 +1538,12 @@ static void n_tty_receive_buf_standard(struct tty_struct *tty, while (count--) { if (fp) flag = *fp++; + + if (ldata->lnext) { + n_tty_receive_char_lnext(tty, *cp++, flag); + continue; + } + if (likely(flag == TTY_NORMAL)) { unsigned char c = *cp++; @@ -1551,12 +1557,8 @@ static void n_tty_receive_buf_standard(struct tty_struct *tty, } if (!test_bit(c, ldata->char_map)) n_tty_receive_char(tty, c); - else if (n_tty_receive_char_special(tty, c) && count) { - if (fp) - flag = *fp++; - n_tty_receive_char_lnext(tty, *cp++, flag); - count--; - } + else + n_tty_receive_char_special(tty, c); } else n_tty_receive_char_flagged(tty, *cp++, flag); } @@ -1575,15 +1577,6 @@ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp, else if (tty->closing && !L_EXTPROC(tty)) n_tty_receive_buf_closing(tty, cp, fp, count); else { - if (ldata->lnext) { - char flag = TTY_NORMAL; - - if (fp) - flag = *fp++; - n_tty_receive_char_lnext(tty, *cp++, flag); - count--; - } - n_tty_receive_buf_standard(tty, cp, fp, count); flush_echoes(tty); From 16765365a062f6d25d087cdd0fca3e01c9a03403 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:19:00 +0200 Subject: [PATCH 030/227] n_tty: make n_tty_receive_char_special return void After the previous patch, noone cares about the return value of n_tty_receive_char_special. ldata->lnext is checked instead. So switch return type of n_tty_receive_char_special to void. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210505091928.22010-8-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index d40844b7a4fb..b8f981499465 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1260,12 +1260,8 @@ n_tty_receive_signal_char(struct tty_struct *tty, int signal, unsigned char c) * n_tty_receive_buf()/producer path: * caller holds non-exclusive termios_rwsem * publishes canon_head if canonical mode is active - * - * Returns 1 if LNEXT was received, else returns 0 */ - -static int -n_tty_receive_char_special(struct tty_struct *tty, unsigned char c) +static void n_tty_receive_char_special(struct tty_struct *tty, unsigned char c) { struct n_tty_data *ldata = tty->disc_data; @@ -1273,24 +1269,24 @@ n_tty_receive_char_special(struct tty_struct *tty, unsigned char c) if (c == START_CHAR(tty)) { start_tty(tty); process_echoes(tty); - return 0; + return; } if (c == STOP_CHAR(tty)) { stop_tty(tty); - return 0; + return; } } if (L_ISIG(tty)) { if (c == INTR_CHAR(tty)) { n_tty_receive_signal_char(tty, SIGINT, c); - return 0; + return; } else if (c == QUIT_CHAR(tty)) { n_tty_receive_signal_char(tty, SIGQUIT, c); - return 0; + return; } else if (c == SUSP_CHAR(tty)) { n_tty_receive_signal_char(tty, SIGTSTP, c); - return 0; + return; } } @@ -1301,7 +1297,7 @@ n_tty_receive_char_special(struct tty_struct *tty, unsigned char c) if (c == '\r') { if (I_IGNCR(tty)) - return 0; + return; if (I_ICRNL(tty)) c = '\n'; } else if (c == '\n' && I_INLCR(tty)) @@ -1312,7 +1308,7 @@ n_tty_receive_char_special(struct tty_struct *tty, unsigned char c) (c == WERASE_CHAR(tty) && L_IEXTEN(tty))) { eraser(c, tty); commit_echoes(tty); - return 0; + return; } if (c == LNEXT_CHAR(tty) && L_IEXTEN(tty)) { ldata->lnext = 1; @@ -1324,7 +1320,7 @@ n_tty_receive_char_special(struct tty_struct *tty, unsigned char c) commit_echoes(tty); } } - return 1; + return; } if (c == REPRINT_CHAR(tty) && L_ECHO(tty) && L_IEXTEN(tty)) { size_t tail = ldata->canon_head; @@ -1337,7 +1333,7 @@ n_tty_receive_char_special(struct tty_struct *tty, unsigned char c) tail++; } commit_echoes(tty); - return 0; + return; } if (c == '\n') { if (L_ECHO(tty) || L_ECHONL(tty)) { @@ -1375,7 +1371,7 @@ handle_newline: smp_store_release(&ldata->canon_head, ldata->read_head); kill_fasync(&tty->fasync, SIGIO, POLL_IN); wake_up_interruptible_poll(&tty->read_wait, EPOLLIN); - return 0; + return; } } @@ -1397,7 +1393,6 @@ handle_newline: put_tty_queue(c, ldata); put_tty_queue(c, ldata); - return 0; } static void n_tty_receive_char(struct tty_struct *tty, unsigned char c) From 3a7d530a0cf9b82fce3596627259a67c511ec917 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:19:01 +0200 Subject: [PATCH 031/227] n_tty: do only one cp dereference in n_tty_receive_buf_standard It might be confusing for readers: there are three distinct dereferences and increments of 'cp' in n_tty_receive_buf_standard. Do it on a single place, along with/before the 'fp' dereference. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210505091928.22010-9-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index b8f981499465..e7c9dce14f88 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1531,17 +1531,17 @@ static void n_tty_receive_buf_standard(struct tty_struct *tty, char flag = TTY_NORMAL; while (count--) { + unsigned char c = *cp++; + if (fp) flag = *fp++; if (ldata->lnext) { - n_tty_receive_char_lnext(tty, *cp++, flag); + n_tty_receive_char_lnext(tty, c, flag); continue; } if (likely(flag == TTY_NORMAL)) { - unsigned char c = *cp++; - if (I_ISTRIP(tty)) c &= 0x7f; if (I_IUCLC(tty) && L_IEXTEN(tty)) @@ -1555,7 +1555,7 @@ static void n_tty_receive_buf_standard(struct tty_struct *tty, else n_tty_receive_char_special(tty, c); } else - n_tty_receive_char_flagged(tty, *cp++, flag); + n_tty_receive_char_flagged(tty, c, flag); } } From e8f2a139ffb600f47c3ddb286e5bd9a71041c35a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:19:02 +0200 Subject: [PATCH 032/227] n_tty: invert TTY_NORMAL condition in n_tty_receive_buf_standard Handle !TTY_NORMAL as a short path and 'continue' the loop. Do the rest as a normal code flow. This decreases the indentation level by one and makes the code flow more understandable. IOW, we avoid if (cond) { LONG CODE; } else single_line(); by if (!cond) { single_line(); continue; } LONG CODE; While at it, invert also the 'if (!test_bit) A else B' into 'if (test_bit) B else A'. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210505091928.22010-10-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index e7c9dce14f88..01883e5c8bbd 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1541,21 +1541,24 @@ static void n_tty_receive_buf_standard(struct tty_struct *tty, continue; } - if (likely(flag == TTY_NORMAL)) { - if (I_ISTRIP(tty)) - c &= 0x7f; - if (I_IUCLC(tty) && L_IEXTEN(tty)) - c = tolower(c); - if (L_EXTPROC(tty)) { - put_tty_queue(c, ldata); - continue; - } - if (!test_bit(c, ldata->char_map)) - n_tty_receive_char(tty, c); - else - n_tty_receive_char_special(tty, c); - } else + if (unlikely(flag != TTY_NORMAL)) { n_tty_receive_char_flagged(tty, c, flag); + continue; + } + + if (I_ISTRIP(tty)) + c &= 0x7f; + if (I_IUCLC(tty) && L_IEXTEN(tty)) + c = tolower(c); + if (L_EXTPROC(tty)) { + put_tty_queue(c, ldata); + continue; + } + + if (test_bit(c, ldata->char_map)) + n_tty_receive_char_special(tty, c); + else + n_tty_receive_char(tty, c); } } From fc0df90b781145525c8d4ccaeccb6dcb8f810ce7 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:19:03 +0200 Subject: [PATCH 033/227] n_tty: remove superfluous return from n_tty_receive_signal_char A return at the end of a void-returning function is superfluous. Get rid of it. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210505091928.22010-11-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 01883e5c8bbd..0d93be26c678 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1245,7 +1245,6 @@ n_tty_receive_signal_char(struct tty_struct *tty, int signal, unsigned char c) commit_echoes(tty); } else process_echoes(tty); - return; } /** From 0f3dcf3b5d76669123bf99fec812b8b0acd60375 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:19:04 +0200 Subject: [PATCH 034/227] tty: make fp of tty_ldisc_ops::receive_buf{,2} const Char pointer (cp) passed to tty_ldisc_ops::receive_buf{,2} is const. There is no reason for flag pointer (fp) not to be too. So switch it in the definition and all uses. Signed-off-by: Jiri Slaby Cc: William Hubbs Cc: Chris Brannon Cc: Kirk Reiser Cc: Samuel Thibault Cc: Marcel Holtmann Cc: Johan Hedberg Cc: Luiz Augusto von Dentz Cc: Dmitry Torokhov Cc: Arnd Bergmann Cc: "David S. Miller" Cc: Jakub Kicinski Cc: Wolfgang Grandegger Cc: Marc Kleine-Budde Cc: Andreas Koensgen Cc: Paul Mackerras Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Peter Ujfalusi Link: https://lore.kernel.org/r/20210505091928.22010-12-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/accessibility/speakup/spk_ttyio.c | 3 ++- drivers/bluetooth/hci_ldisc.c | 2 +- drivers/input/serio/serport.c | 3 ++- drivers/misc/ti-st/st_core.c | 2 +- drivers/net/caif/caif_serial.c | 2 +- drivers/net/can/slcan.c | 3 ++- drivers/net/hamradio/6pack.c | 2 +- drivers/net/hamradio/mkiss.c | 2 +- drivers/net/ppp/ppp_async.c | 6 +++--- drivers/net/ppp/ppp_synctty.c | 6 +++--- drivers/net/slip/slip.c | 2 +- drivers/tty/n_gsm.c | 2 +- drivers/tty/n_hdlc.c | 2 +- drivers/tty/n_null.c | 2 +- drivers/tty/n_tty.c | 16 ++++++++-------- drivers/tty/tty_buffer.c | 4 ++-- include/linux/tty.h | 2 +- include/linux/tty_ldisc.h | 4 ++-- net/nfc/nci/uart.c | 2 +- sound/soc/codecs/cx20442.c | 4 ++-- sound/soc/ti/ams-delta.c | 4 ++-- 21 files changed, 39 insertions(+), 36 deletions(-) diff --git a/drivers/accessibility/speakup/spk_ttyio.c b/drivers/accessibility/speakup/spk_ttyio.c index 2e39fcf492d8..b7fd094700d9 100644 --- a/drivers/accessibility/speakup/spk_ttyio.c +++ b/drivers/accessibility/speakup/spk_ttyio.c @@ -72,7 +72,8 @@ static void spk_ttyio_ldisc_close(struct tty_struct *tty) } static int spk_ttyio_receive_buf2(struct tty_struct *tty, - const unsigned char *cp, char *fp, int count) + const unsigned char *cp, + const char *fp, int count) { struct spk_ldisc_data *ldisc_data = tty->disc_data; struct spk_synth *synth = ldisc_data->synth; diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 71a4ca505e09..e785851a92c1 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -593,7 +593,7 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty) * Return Value: None */ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, - char *flags, int count) + const char *flags, int count) { struct hci_uart *hu = tty->disc_data; diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index 33e9d9bfd036..ff3715315592 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c @@ -114,7 +114,8 @@ static void serport_ldisc_close(struct tty_struct *tty) * 'interrupt' routine. */ -static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) +static void serport_ldisc_receive(struct tty_struct *tty, + const unsigned char *cp, const char *fp, int count) { struct serport *serport = (struct serport*) tty->disc_data; unsigned long flags; diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index 071844b58073..239a75502cd6 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -798,7 +798,7 @@ static void st_tty_close(struct tty_struct *tty) } static void st_tty_receive(struct tty_struct *tty, const unsigned char *data, - char *tty_flags, int count) + const char *tty_flags, int count) { #ifdef VERBOSE print_hex_dump(KERN_DEBUG, ">in>", DUMP_PREFIX_NONE, diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index da6fffb4d5a8..fb3ca4e11fe5 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c @@ -159,7 +159,7 @@ static inline void debugfs_tx(struct ser_device *ser, const u8 *data, int size) #endif static void ldisc_receive(struct tty_struct *tty, const u8 *data, - char *flags, int count) + const char *flags, int count) { struct sk_buff *skb = NULL; struct ser_device *ser; diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index 31ba6664503d..7dc3e79cb5c4 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -467,7 +467,8 @@ static void slc_setup(struct net_device *dev) */ static void slcan_receive_buf(struct tty_struct *tty, - const unsigned char *cp, char *fp, int count) + const unsigned char *cp, const char *fp, + int count) { struct slcan *sl = (struct slcan *) tty->disc_data; diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 80f41945709f..c0a80f04dd8e 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -428,7 +428,7 @@ out: * and sent on to some IP layer for further processing. */ static void sixpack_receive_buf(struct tty_struct *tty, - const unsigned char *cp, char *fp, int count) + const unsigned char *cp, const char *fp, int count) { struct sixpack *sp; int count1; diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 65154224d5b8..fc05ded48178 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -871,7 +871,7 @@ static int mkiss_ioctl(struct tty_struct *tty, struct file *file, * and sent on to the AX.25 layer for further processing. */ static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) + const char *fp, int count) { struct mkiss *ax = mkiss_get(tty); diff --git a/drivers/net/ppp/ppp_async.c b/drivers/net/ppp/ppp_async.c index 8b41aa3fb64e..9f08bd19551f 100644 --- a/drivers/net/ppp/ppp_async.c +++ b/drivers/net/ppp/ppp_async.c @@ -98,7 +98,7 @@ static int ppp_async_send(struct ppp_channel *chan, struct sk_buff *skb); static int ppp_async_push(struct asyncppp *ap); static void ppp_async_flush_output(struct asyncppp *ap); static void ppp_async_input(struct asyncppp *ap, const unsigned char *buf, - char *flags, int count); + const char *flags, int count); static int ppp_async_ioctl(struct ppp_channel *chan, unsigned int cmd, unsigned long arg); static void ppp_async_process(struct tasklet_struct *t); @@ -340,7 +340,7 @@ ppp_asynctty_poll(struct tty_struct *tty, struct file *file, poll_table *wait) /* May sleep, don't call from interrupt level or with interrupts disabled */ static void ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf, - char *cflags, int count) + const char *cflags, int count) { struct asyncppp *ap = ap_get(tty); unsigned long flags; @@ -829,7 +829,7 @@ process_input_packet(struct asyncppp *ap) static void ppp_async_input(struct asyncppp *ap, const unsigned char *buf, - char *flags, int count) + const char *flags, int count) { struct sk_buff *skb; int c, i, j, n, s, f; diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c index 576b6a93bf23..c82c4e6df4cb 100644 --- a/drivers/net/ppp/ppp_synctty.c +++ b/drivers/net/ppp/ppp_synctty.c @@ -94,7 +94,7 @@ static void ppp_sync_process(struct tasklet_struct *t); static int ppp_sync_push(struct syncppp *ap); static void ppp_sync_flush_output(struct syncppp *ap); static void ppp_sync_input(struct syncppp *ap, const unsigned char *buf, - char *flags, int count); + const char *flags, int count); static const struct ppp_channel_ops sync_ops = { .start_xmit = ppp_sync_send, @@ -333,7 +333,7 @@ ppp_sync_poll(struct tty_struct *tty, struct file *file, poll_table *wait) /* May sleep, don't call from interrupt level or with interrupts disabled */ static void ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf, - char *cflags, int count) + const char *cflags, int count) { struct syncppp *ap = sp_get(tty); unsigned long flags; @@ -665,7 +665,7 @@ ppp_sync_flush_output(struct syncppp *ap) */ static void ppp_sync_input(struct syncppp *ap, const unsigned char *buf, - char *flags, int count) + const char *flags, int count) { struct sk_buff *skb; unsigned char *p; diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c index 1ab124eba8eb..4dda49e61745 100644 --- a/drivers/net/slip/slip.c +++ b/drivers/net/slip/slip.c @@ -685,7 +685,7 @@ static void sl_setup(struct net_device *dev) */ static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) + const char *fp, int count) { struct slip *sl = tty->disc_data; diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 5fea02cfb0cc..477403ecc445 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2424,7 +2424,7 @@ static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm) } static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) + const char *fp, int count) { struct gsm_mux *gsm = tty->disc_data; char flags = TTY_NORMAL; diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index b0f33e8ac819..62b1d1a6e0f1 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c @@ -358,7 +358,7 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty) * interpreted as one HDLC frame. */ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data, - char *flags, int count) + const char *flags, int count) { register struct n_hdlc *n_hdlc = tty->disc_data; register struct n_hdlc_buf *buf; diff --git a/drivers/tty/n_null.c b/drivers/tty/n_null.c index b8f67b5f1ef8..2ff373d2f98d 100644 --- a/drivers/tty/n_null.c +++ b/drivers/tty/n_null.c @@ -33,7 +33,7 @@ static ssize_t n_null_write(struct tty_struct *tty, struct file *file, } static void n_null_receivebuf(struct tty_struct *tty, - const unsigned char *cp, char *fp, + const unsigned char *cp, const char *fp, int cnt) { } diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 0d93be26c678..c32318da5190 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1474,7 +1474,7 @@ n_tty_receive_char_lnext(struct tty_struct *tty, unsigned char c, char flag) static void n_tty_receive_buf_real_raw(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) + const char *fp, int count) { struct n_tty_data *ldata = tty->disc_data; size_t n, head; @@ -1494,7 +1494,7 @@ n_tty_receive_buf_real_raw(struct tty_struct *tty, const unsigned char *cp, static void n_tty_receive_buf_raw(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) + const char *fp, int count) { struct n_tty_data *ldata = tty->disc_data; char flag = TTY_NORMAL; @@ -1511,7 +1511,7 @@ n_tty_receive_buf_raw(struct tty_struct *tty, const unsigned char *cp, static void n_tty_receive_buf_closing(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) + const char *fp, int count) { char flag = TTY_NORMAL; @@ -1524,7 +1524,7 @@ n_tty_receive_buf_closing(struct tty_struct *tty, const unsigned char *cp, } static void n_tty_receive_buf_standard(struct tty_struct *tty, - const unsigned char *cp, char *fp, int count) + const unsigned char *cp, const char *fp, int count) { struct n_tty_data *ldata = tty->disc_data; char flag = TTY_NORMAL; @@ -1562,7 +1562,7 @@ static void n_tty_receive_buf_standard(struct tty_struct *tty, } static void __receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) + const char *fp, int count) { struct n_tty_data *ldata = tty->disc_data; bool preops = I_ISTRIP(tty) || (I_IUCLC(tty) && L_IEXTEN(tty)); @@ -1629,7 +1629,7 @@ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp, */ static int n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count, int flow) + const char *fp, int count, int flow) { struct n_tty_data *ldata = tty->disc_data; int room, n, rcvd = 0, overflow; @@ -1698,13 +1698,13 @@ n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp, } static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) + const char *fp, int count) { n_tty_receive_buf_common(tty, cp, fp, count, 0); } static int n_tty_receive_buf2(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) + const char *fp, int count) { return n_tty_receive_buf_common(tty, cp, fp, count, 1); } diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 9733469a14b2..55b1f1711341 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -455,7 +455,7 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string); * Returns the number of bytes processed */ int tty_ldisc_receive_buf(struct tty_ldisc *ld, const unsigned char *p, - char *f, int count) + const char *f, int count) { if (ld->ops->receive_buf2) count = ld->ops->receive_buf2(ld->tty, p, f, count); @@ -472,7 +472,7 @@ static int receive_buf(struct tty_port *port, struct tty_buffer *head, int count) { unsigned char *p = char_buf_ptr(head, head->read); - char *f = NULL; + const char *f = NULL; int n; if (~head->flags & TTYB_NORMAL) diff --git a/include/linux/tty.h b/include/linux/tty.h index e5d6b1f28823..5aad2220266c 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -628,7 +628,7 @@ extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc); extern int tty_unregister_ldisc(int disc); extern int tty_set_ldisc(struct tty_struct *tty, int disc); extern int tty_ldisc_receive_buf(struct tty_ldisc *ld, const unsigned char *p, - char *f, int count); + const char *f, int count); /* n_tty.c */ extern void n_tty_inherit_ops(struct tty_ldisc_ops *ops); diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h index 31284b55bd4f..c20ca6a75b4c 100644 --- a/include/linux/tty_ldisc.h +++ b/include/linux/tty_ldisc.h @@ -201,11 +201,11 @@ struct tty_ldisc_ops { * The following routines are called from below. */ void (*receive_buf)(struct tty_struct *, const unsigned char *cp, - char *fp, int count); + const char *fp, int count); void (*write_wakeup)(struct tty_struct *); void (*dcd_change)(struct tty_struct *, unsigned int); int (*receive_buf2)(struct tty_struct *, const unsigned char *cp, - char *fp, int count); + const char *fp, int count); struct module *owner; diff --git a/net/nfc/nci/uart.c b/net/nfc/nci/uart.c index 1248faf4d6df..98102ef64004 100644 --- a/net/nfc/nci/uart.c +++ b/net/nfc/nci/uart.c @@ -308,7 +308,7 @@ static int nci_uart_default_recv_buf(struct nci_uart *nu, const u8 *data, * Return Value: None */ static void nci_uart_tty_receive(struct tty_struct *tty, const u8 *data, - char *flags, int count) + const char *flags, int count) { struct nci_uart *nu = (void *)tty->disc_data; diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index 61dfa86d444d..ec8d6e74b467 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c @@ -259,8 +259,8 @@ static int v253_hangup(struct tty_struct *tty) } /* Line discipline .receive_buf() */ -static void v253_receive(struct tty_struct *tty, - const unsigned char *cp, char *fp, int count) +static void v253_receive(struct tty_struct *tty, const unsigned char *cp, + const char *fp, int count) { struct snd_soc_component *component = tty->disc_data; struct cx20442_priv *cx20442; diff --git a/sound/soc/ti/ams-delta.c b/sound/soc/ti/ams-delta.c index aba0017e870b..55a6736a378e 100644 --- a/sound/soc/ti/ams-delta.c +++ b/sound/soc/ti/ams-delta.c @@ -337,8 +337,8 @@ static int cx81801_hangup(struct tty_struct *tty) } /* Line discipline .receive_buf() */ -static void cx81801_receive(struct tty_struct *tty, - const unsigned char *cp, char *fp, int count) +static void cx81801_receive(struct tty_struct *tty, const unsigned char *cp, + const char *fp, int count) { struct snd_soc_component *component = tty->disc_data; const unsigned char *c; From 6e94dbc7a4e49a028b81302d755bba1a518f973b Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:19:05 +0200 Subject: [PATCH 035/227] tty: cumulate and document tty_struct::flow* members Group the flow flags under a single struct called flow. The new struct contains 'stopped' and 'tco_stopped' bools which used to be bits in a bitfield. The struct also contains the lock protecting them to potentially share the same cache line. Note that commit c545b66c6922b (tty: Serialize tcflow() with other tty flow control changes) added a padding to the original bitfield. It was for the bitfield to occupy a whole 64b word to avoid interferring stores on Alpha (cannot we evaporate this arch with weird implications to C code yet?). But it doesn't work as expected as the padding (tty_struct::unused) is aligned to a 8B boundary too and occupies some bytes from the next word. So make it reliable by: 1) setting __aligned of the struct -- that aligns the start, and 2) making 'unsigned long unused[0]' as the last member of the struct -- pads the end. This is also the perfect time to start the documentation of tty_struct where all this lives. So we start by documenting what these bools actually serve for. And why we do all the alignment dances. Only the few up-to-date information from the Theodore's comment made it into this new Kerneldoc comment. Signed-off-by: Jiri Slaby Cc: "David S. Miller" Cc: Jakub Kicinski Cc: Jonathan Corbet Cc: Arnd Bergmann Cc: Ulf Hansson Cc: Heiko Carstens Cc: Vasily Gorbik Cc: Christian Borntraeger Cc: Shawn Guo Cc: Sascha Hauer Cc: Vineet Gupta Cc: "Maciej W. Rozycki" Link: https://lore.kernel.org/r/20210505091928.22010-13-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- Documentation/networking/caif/caif.rst | 4 +-- drivers/char/pcmcia/synclink_cs.c | 8 +++--- drivers/mmc/core/sdio_uart.c | 2 +- drivers/net/caif/caif_serial.c | 4 +-- drivers/s390/char/tty3270.c | 2 +- drivers/staging/fwserial/fwserial.c | 2 +- drivers/tty/amiserial.c | 8 +++--- drivers/tty/moxa.c | 4 +-- drivers/tty/mxser.c | 12 ++++---- drivers/tty/n_tty.c | 8 +++--- drivers/tty/pty.c | 4 +-- drivers/tty/serial/arc_uart.c | 2 +- drivers/tty/serial/dz.c | 2 +- drivers/tty/synclink_gt.c | 6 ++-- drivers/tty/tty_io.c | 24 ++++++++-------- drivers/tty/tty_ioctl.c | 16 +++++------ drivers/tty/tty_port.c | 2 +- drivers/tty/vt/keyboard.c | 2 +- drivers/tty/vt/vt.c | 4 +-- include/linux/serial_core.h | 2 +- include/linux/tty.h | 38 +++++++++++++++----------- include/linux/tty_driver.h | 4 +-- 22 files changed, 83 insertions(+), 77 deletions(-) diff --git a/Documentation/networking/caif/caif.rst b/Documentation/networking/caif/caif.rst index 81a14373d780..d922d419c513 100644 --- a/Documentation/networking/caif/caif.rst +++ b/Documentation/networking/caif/caif.rst @@ -69,9 +69,9 @@ There are debugfs parameters provided for serial communication. - 0x01 - tty->warned is on. - 0x04 - tty->packed is on. - - 0x08 - tty->flow_stopped is on. + - 0x08 - tty->flow.tco_stopped is on. - 0x10 - tty->hw_stopped is on. - - 0x20 - tty->stopped is on. + - 0x20 - tty->flow.stopped is on. * last_tx_msg: Binary blob Prints the last transmitted frame. diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 3287a7627ed0..b4707bc3aee8 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -985,7 +985,7 @@ static void tx_done(MGSLPC_INFO *info, struct tty_struct *tty) else #endif { - if (tty && (tty->stopped || tty->hw_stopped)) { + if (tty && (tty->flow.stopped || tty->hw_stopped)) { tx_stop(info); return; } @@ -1005,7 +1005,7 @@ static void tx_ready(MGSLPC_INFO *info, struct tty_struct *tty) if (!info->tx_active) return; } else { - if (tty && (tty->stopped || tty->hw_stopped)) { + if (tty && (tty->flow.stopped || tty->hw_stopped)) { tx_stop(info); return; } @@ -1525,7 +1525,7 @@ static void mgslpc_flush_chars(struct tty_struct *tty) if (mgslpc_paranoia_check(info, tty->name, "mgslpc_flush_chars")) return; - if (info->tx_count <= 0 || tty->stopped || + if (info->tx_count <= 0 || tty->flow.stopped || tty->hw_stopped || !info->tx_buf) return; @@ -1594,7 +1594,7 @@ static int mgslpc_write(struct tty_struct * tty, ret += c; } start: - if (info->tx_count && !tty->stopped && !tty->hw_stopped) { + if (info->tx_count && !tty->flow.stopped && !tty->hw_stopped) { spin_lock_irqsave(&info->lock, flags); if (!info->tx_active) tx_start(info, tty); diff --git a/drivers/mmc/core/sdio_uart.c b/drivers/mmc/core/sdio_uart.c index be4067281caa..dbcac2b7f2fe 100644 --- a/drivers/mmc/core/sdio_uart.c +++ b/drivers/mmc/core/sdio_uart.c @@ -439,7 +439,7 @@ static void sdio_uart_transmit_chars(struct sdio_uart_port *port) tty = tty_port_tty_get(&port->port); if (tty == NULL || !kfifo_len(xmit) || - tty->stopped || tty->hw_stopped) { + tty->flow.stopped || tty->hw_stopped) { sdio_uart_stop_tx(port); tty_kref_put(tty); return; diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index fb3ca4e11fe5..3996cf7dc9ba 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c @@ -87,8 +87,8 @@ static void ldisc_tx_wakeup(struct tty_struct *tty); static inline void update_tty_status(struct ser_device *ser) { ser->tty_status = - ser->tty->stopped << 5 | - ser->tty->flow_stopped << 3 | + ser->tty->flow.stopped << 5 | + ser->tty->flow.tco_stopped << 3 | ser->tty->packet << 2; } static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty) diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index 307a80f85c07..1b68564799fa 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -1640,7 +1640,7 @@ tty3270_do_write(struct tty3270 *tp, struct tty_struct *tty, int i_msg, i; spin_lock_bh(&tp->view.lock); - for (i_msg = 0; !tty->stopped && i_msg < count; i_msg++) { + for (i_msg = 0; !tty->flow.stopped && i_msg < count; i_msg++) { if (tp->esc_state != 0) { /* Continue escape sequence. */ tty3270_escape_sequence(tp, buf[i_msg]); diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index 1ee6382cafc4..4245532d2fe0 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c @@ -722,7 +722,7 @@ static int fwtty_tx(struct fwtty_port *port, bool drain) /* try to write as many dma transactions out as possible */ n = -EAGAIN; - while (!tty->stopped && !tty->hw_stopped && + while (!tty->flow.stopped && !tty->hw_stopped && !test_bit(STOP_TX, &port->flags)) { txn = kmem_cache_alloc(fwtty_txn_cache, GFP_ATOMIC); if (!txn) { diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index ca48ce5a0862..a4b8876091d2 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -148,7 +148,7 @@ static __inline__ void rtsdtr_ctrl(int bits) * ------------------------------------------------------------ * rs_stop() and rs_start() * - * This routines are called before setting or resetting tty->stopped. + * This routines are called before setting or resetting tty->flow.stopped. * They enable or disable transmitter interrupts, as necessary. * ------------------------------------------------------------ */ @@ -309,7 +309,7 @@ static void transmit_chars(struct serial_state *info) return; } if (info->xmit.head == info->xmit.tail - || info->tport.tty->stopped + || info->tport.tty->flow.stopped || info->tport.tty->hw_stopped) { info->IER &= ~UART_IER_THRI; custom.intena = IF_TBE; @@ -768,7 +768,7 @@ static void rs_flush_chars(struct tty_struct *tty) unsigned long flags; if (info->xmit.head == info->xmit.tail - || tty->stopped + || tty->flow.stopped || tty->hw_stopped || !info->xmit.buf) return; @@ -812,7 +812,7 @@ static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count local_irq_restore(flags); if (info->xmit.head != info->xmit.tail - && !tty->stopped + && !tty->flow.stopped && !tty->hw_stopped && !(info->IER & UART_IER_THRI)) { info->IER |= UART_IER_THRI; diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index 4d4f15b5cd29..847ad3dac107 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c @@ -1221,7 +1221,7 @@ static int moxa_write_room(struct tty_struct *tty) { struct moxa_port *ch; - if (tty->stopped) + if (tty->flow.stopped) return 0; ch = tty->driver_data; if (ch == NULL) @@ -1374,7 +1374,7 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle, clear_bit(EMPTYWAIT, &p->statusflags); tty_wakeup(tty); } - if (test_bit(LOWWAIT, &p->statusflags) && !tty->stopped && + if (test_bit(LOWWAIT, &p->statusflags) && !tty->flow.stopped && MoxaPortTxQueue(p) <= WAKEUP_CHARS) { clear_bit(LOWWAIT, &p->statusflags); tty_wakeup(tty); diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 16a852ecbe8a..85271e109014 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -1118,7 +1118,7 @@ static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int cou total += c; } - if (info->xmit_cnt && !tty->stopped) { + if (info->xmit_cnt && !tty->flow.stopped) { if (!tty->hw_stopped || (info->type == PORT_16550A) || (info->board->chip_flag)) { @@ -1149,7 +1149,7 @@ static int mxser_put_char(struct tty_struct *tty, unsigned char ch) info->xmit_head &= SERIAL_XMIT_SIZE - 1; info->xmit_cnt++; spin_unlock_irqrestore(&info->slock, flags); - if (!tty->stopped) { + if (!tty->flow.stopped) { if (!tty->hw_stopped || (info->type == PORT_16550A) || info->board->chip_flag) { @@ -1169,7 +1169,7 @@ static void mxser_flush_chars(struct tty_struct *tty) struct mxser_port *info = tty->driver_data; unsigned long flags; - if (info->xmit_cnt <= 0 || tty->stopped || !info->port.xmit_buf || + if (info->xmit_cnt <= 0 || tty->flow.stopped || !info->port.xmit_buf || (tty->hw_stopped && info->type != PORT_16550A && !info->board->chip_flag)) return; @@ -1917,7 +1917,7 @@ static void mxser_unthrottle(struct tty_struct *tty) /* * mxser_stop() and mxser_start() * - * This routines are called before setting or resetting tty->stopped. + * This routines are called before setting or resetting tty->flow.stopped. * They enable or disable transmitter interrupts, as necessary. */ static void mxser_stop(struct tty_struct *tty) @@ -1963,7 +1963,7 @@ static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termi /* Handle sw stopped */ if ((old_termios->c_iflag & IXON) && !I_IXON(tty)) { - tty->stopped = 0; + tty->flow.stopped = 0; if (info->board->chip_flag) { spin_lock_irqsave(&info->slock, flags); @@ -2175,7 +2175,7 @@ static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port if (port->port.xmit_buf == NULL) return; - if (port->xmit_cnt <= 0 || tty->stopped || + if (port->xmit_cnt <= 0 || tty->flow.stopped || (tty->hw_stopped && (port->type != PORT_16550A) && (!port->board->chip_flag))) { diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index c32318da5190..3566bb577eb0 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1289,7 +1289,7 @@ static void n_tty_receive_char_special(struct tty_struct *tty, unsigned char c) } } - if (tty->stopped && !tty->flow_stopped && I_IXON(tty) && I_IXANY(tty)) { + if (tty->flow.stopped && !tty->flow.tco_stopped && I_IXON(tty) && I_IXANY(tty)) { start_tty(tty); process_echoes(tty); } @@ -1398,7 +1398,7 @@ static void n_tty_receive_char(struct tty_struct *tty, unsigned char c) { struct n_tty_data *ldata = tty->disc_data; - if (tty->stopped && !tty->flow_stopped && I_IXON(tty) && I_IXANY(tty)) { + if (tty->flow.stopped && !tty->flow.tco_stopped && I_IXON(tty) && I_IXANY(tty)) { start_tty(tty); process_echoes(tty); } @@ -1427,7 +1427,7 @@ static void n_tty_receive_char_closing(struct tty_struct *tty, unsigned char c) if (c == STOP_CHAR(tty)) stop_tty(tty); else if (c == START_CHAR(tty) || - (tty->stopped && !tty->flow_stopped && I_IXANY(tty) && + (tty->flow.stopped && !tty->flow.tco_stopped && I_IXANY(tty) && c != INTR_CHAR(tty) && c != QUIT_CHAR(tty) && c != SUSP_CHAR(tty))) { start_tty(tty); @@ -1797,7 +1797,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) * Fix tty hang when I_IXON(tty) is cleared, but the tty * been stopped by STOP_CHAR(tty) before it. */ - if (!I_IXON(tty) && old && (old->c_iflag & IXON) && !tty->flow_stopped) { + if (!I_IXON(tty) && old && (old->c_iflag & IXON) && !tty->flow.tco_stopped) { start_tty(tty); process_echoes(tty); } diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 9b5d4ae5d8f2..017f28150a32 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -113,7 +113,7 @@ static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c) struct tty_struct *to = tty->link; unsigned long flags; - if (tty->stopped) + if (tty->flow.stopped) return 0; if (c > 0) { @@ -138,7 +138,7 @@ static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c) static int pty_write_room(struct tty_struct *tty) { - if (tty->stopped) + if (tty->flow.stopped) return 0; return tty_buffer_space_avail(tty->link->port); } diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c index 1a9444b6b57e..596217d10d5c 100644 --- a/drivers/tty/serial/arc_uart.c +++ b/drivers/tty/serial/arc_uart.c @@ -149,7 +149,7 @@ static unsigned int arc_serial_tx_empty(struct uart_port *port) /* * Driver internal routine, used by both tty(serial core) as well as tx-isr * -Called under spinlock in either cases - * -also tty->stopped has already been checked + * -also tty->flow.stopped has already been checked * = by uart_start( ) before calling us * = tx_ist checks that too before calling */ diff --git a/drivers/tty/serial/dz.c b/drivers/tty/serial/dz.c index 4552742c3859..6d91e9b6284d 100644 --- a/drivers/tty/serial/dz.c +++ b/drivers/tty/serial/dz.c @@ -115,7 +115,7 @@ static void dz_out(struct dz_port *dport, unsigned offset, u16 value) * rs_stop () and rs_start () * * These routines are called before setting or resetting - * tty->stopped. They enable or disable transmitter interrupts, + * tty->flow.stopped. They enable or disable transmitter interrupts, * as necessary. * ------------------------------------------------------------ */ diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index 5523cf7bd1c2..1555dccc28af 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -768,7 +768,7 @@ static int write(struct tty_struct *tty, if (!info->tx_buf || (count > info->max_frame_size)) return -EIO; - if (!count || tty->stopped || tty->hw_stopped) + if (!count || tty->flow.stopped || tty->hw_stopped) return 0; spin_lock_irqsave(&info->lock, flags); @@ -889,7 +889,7 @@ static void flush_chars(struct tty_struct *tty) return; DBGINFO(("%s flush_chars entry tx_count=%d\n", info->device_name, info->tx_count)); - if (info->tx_count <= 0 || tty->stopped || + if (info->tx_count <= 0 || tty->flow.stopped || tty->hw_stopped || !info->tx_buf) return; @@ -2241,7 +2241,7 @@ static void isr_txeom(struct slgt_info *info, unsigned short status) else #endif { - if (info->port.tty && (info->port.tty->stopped || info->port.tty->hw_stopped)) { + if (info->port.tty && (info->port.tty->flow.stopped || info->port.tty->hw_stopped)) { tx_stop(info); return; } diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 5b5e99604989..9734be2eb00e 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -778,14 +778,14 @@ EXPORT_SYMBOL(tty_hung_up_p); * but not always. * * Locking: - * flow_lock + * flow.lock */ void __stop_tty(struct tty_struct *tty) { - if (tty->stopped) + if (tty->flow.stopped) return; - tty->stopped = 1; + tty->flow.stopped = true; if (tty->ops->stop) tty->ops->stop(tty); } @@ -794,9 +794,9 @@ void stop_tty(struct tty_struct *tty) { unsigned long flags; - spin_lock_irqsave(&tty->flow_lock, flags); + spin_lock_irqsave(&tty->flow.lock, flags); __stop_tty(tty); - spin_unlock_irqrestore(&tty->flow_lock, flags); + spin_unlock_irqrestore(&tty->flow.lock, flags); } EXPORT_SYMBOL(stop_tty); @@ -809,14 +809,14 @@ EXPORT_SYMBOL(stop_tty); * start method is invoked and the line discipline woken. * * Locking: - * flow_lock + * flow.lock */ void __start_tty(struct tty_struct *tty) { - if (!tty->stopped || tty->flow_stopped) + if (!tty->flow.stopped || tty->flow.tco_stopped) return; - tty->stopped = 0; + tty->flow.stopped = false; if (tty->ops->start) tty->ops->start(tty); tty_wakeup(tty); @@ -826,9 +826,9 @@ void start_tty(struct tty_struct *tty) { unsigned long flags; - spin_lock_irqsave(&tty->flow_lock, flags); + spin_lock_irqsave(&tty->flow.lock, flags); __start_tty(tty); - spin_unlock_irqrestore(&tty->flow_lock, flags); + spin_unlock_irqrestore(&tty->flow.lock, flags); } EXPORT_SYMBOL(start_tty); @@ -1172,7 +1172,7 @@ ssize_t redirected_tty_write(struct kiocb *iocb, struct iov_iter *iter) int tty_send_xchar(struct tty_struct *tty, char ch) { - int was_stopped = tty->stopped; + bool was_stopped = tty->flow.stopped; if (tty->ops->send_xchar) { down_read(&tty->termios_rwsem); @@ -3141,7 +3141,7 @@ struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx) INIT_WORK(&tty->hangup_work, do_tty_hangup); mutex_init(&tty->atomic_write_lock); spin_lock_init(&tty->ctrl_lock); - spin_lock_init(&tty->flow_lock); + spin_lock_init(&tty->flow.lock); spin_lock_init(&tty->files_lock); INIT_LIST_HEAD(&tty->tty_files); INIT_WORK(&tty->SAK_work, do_SAK_work); diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 41f7449d0464..07c88ccfb17a 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -846,20 +846,20 @@ int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, return retval; switch (arg) { case TCOOFF: - spin_lock_irq(&tty->flow_lock); - if (!tty->flow_stopped) { - tty->flow_stopped = 1; + spin_lock_irq(&tty->flow.lock); + if (!tty->flow.tco_stopped) { + tty->flow.tco_stopped = true; __stop_tty(tty); } - spin_unlock_irq(&tty->flow_lock); + spin_unlock_irq(&tty->flow.lock); break; case TCOON: - spin_lock_irq(&tty->flow_lock); - if (tty->flow_stopped) { - tty->flow_stopped = 0; + spin_lock_irq(&tty->flow.lock); + if (tty->flow.tco_stopped) { + tty->flow.tco_stopped = false; __start_tty(tty); } - spin_unlock_irq(&tty->flow_lock); + spin_unlock_irq(&tty->flow.lock); break; case TCIOFF: if (STOP_CHAR(tty) != __DISABLED_CHAR) diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 303c198fbf5c..0eb523207828 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -587,7 +587,7 @@ int tty_port_close_start(struct tty_port *port, if (tty_port_initialized(port)) { /* Don't block on a stalled port, just pull the chain */ - if (tty->flow_stopped) + if (tty->flow.tco_stopped) tty_driver_flush_buffer(tty); if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) tty_wait_until_sent(tty, port->closing_wait); diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index 5d2309742718..4b0d69042ceb 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c @@ -515,7 +515,7 @@ static void fn_hold(struct vc_data *vc) * these routines are also activated by ^S/^Q. * (And SCROLLOCK can also be set by the ioctl KDSKBLED.) */ - if (tty->stopped) + if (tty->flow.stopped) start_tty(tty); else stop_tty(tty); diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index e5040bdadcd6..38c677fb6505 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -2888,7 +2888,7 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co param.vc = vc; - while (!tty->stopped && count) { + while (!tty->flow.stopped && count) { int orig = *buf; buf++; n++; @@ -3265,7 +3265,7 @@ static int con_put_char(struct tty_struct *tty, unsigned char ch) static int con_write_room(struct tty_struct *tty) { - if (tty->stopped) + if (tty->flow.stopped) return 0; return 32768; /* No limit, really; we're not buffering */ } diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index d7ed00f1594e..7445c8fd88c0 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -428,7 +428,7 @@ int uart_resume_port(struct uart_driver *reg, struct uart_port *port); static inline int uart_tx_stopped(struct uart_port *port) { struct tty_struct *tty = port->state->port.tty; - if ((tty && tty->stopped) || port->hw_stopped) + if ((tty && tty->flow.stopped) || port->hw_stopped) return 1; return 0; } diff --git a/include/linux/tty.h b/include/linux/tty.h index 5aad2220266c..df3a69b2e1ea 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -243,20 +243,22 @@ struct tty_port { #define TTY_PORT_KOPENED 5 /* device exclusively opened by kernel */ -/* - * Where all of the state associated with a tty is kept while the tty - * is open. Since the termios state should be kept even if the tty - * has been closed --- for things like the baud rate, etc --- it is - * not stored here, but rather a pointer to the real state is stored - * here. Possible the winsize structure should have the same - * treatment, but (1) the default 80x24 is usually right and (2) it's - * most often used by a windowing system, which will set the correct - * size each time the window is created or resized anyway. - * - TYT, 9/14/92 - */ - struct tty_operations; +/** + * struct tty_struct - state associated with a tty while open + * + * @flow.lock: lock for flow members + * @flow.stopped: tty stopped/started by tty_stop/tty_start + * @flow.tco_stopped: tty stopped/started by TCOOFF/TCOON ioctls (it has + * precedense over @flow.stopped) + * @flow.unused: alignment for Alpha, so that no members other than @flow.* are + * modified by the same 64b word store. The @flow's __aligned is + * there for the very same reason. + * + * All of the state associated with a tty while the tty is open. Persistent + * storage for tty devices is referenced here as @port in struct tty_port. + */ struct tty_struct { int magic; struct kref kref; @@ -275,7 +277,6 @@ struct tty_struct { struct rw_semaphore termios_rwsem; struct mutex winsize_mutex; spinlock_t ctrl_lock; - spinlock_t flow_lock; /* Termios values are protected by the termios rwsem */ struct ktermios termios, termios_locked; char name[64]; @@ -288,9 +289,14 @@ struct tty_struct { unsigned long flags; int count; struct winsize winsize; /* winsize_mutex */ - unsigned long stopped:1, /* flow_lock */ - flow_stopped:1, - unused:BITS_PER_LONG - 2; + + struct { + spinlock_t lock; + bool stopped; + bool tco_stopped; + unsigned long unused[0]; + } __aligned(sizeof(unsigned long)) flow; + int hw_stopped; unsigned long ctrl_status:8, /* ctrl_lock */ packet:1, diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index 2f719b471d52..653fa5af3a22 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -153,7 +153,7 @@ * This routine notifies the tty driver that it should stop * outputting characters to the tty device. * - * Called with ->flow_lock held. Serialized with start() method. + * Called with ->flow.lock held. Serialized with start() method. * * Optional: * @@ -164,7 +164,7 @@ * This routine notifies the tty driver that it resume sending * characters to the tty device. * - * Called with ->flow_lock held. Serialized with stop() method. + * Called with ->flow.lock held. Serialized with stop() method. * * Optional: * From 64d608db38ffc0c7a25455387096e0aad9410397 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:19:06 +0200 Subject: [PATCH 036/227] tty: cumulate and document tty_struct::ctrl* members Group the ctrl members under a single struct called ctrl. The new struct contains 'pgrp', 'session', 'pktstatus', and 'packet'. 'pktstatus' and 'packet' used to be bits in a bitfield. The struct also contains the lock protecting them to share the same cache line. Note that commit c545b66c6922b (tty: Serialize tcflow() with other tty flow control changes) added a padding to the original bitfield. It was for the bitfield to occupy a whole 64b word to avoid interferring stores on Alpha (cannot we evaporate this arch with weird implications to C code yet?). But it doesn't work as expected as the padding (tty_struct::ctrl_unused) is aligned to a 8B boundary too and occupies some bytes from the next word. So make it reliable by: 1) setting __aligned of the struct -- that aligns the start, and 2) making 'unsigned long unused[0]' as the last member of the struct -- pads the end. Add a kerneldoc comment for this grouped members. Signed-off-by: Jiri Slaby Cc: "David S. Miller" Cc: Jakub Kicinski Cc: netdev@vger.kernel.org Link: https://lore.kernel.org/r/20210505091928.22010-14-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/net/caif/caif_serial.c | 2 +- drivers/tty/n_tty.c | 30 ++++++------ drivers/tty/pty.c | 62 ++++++++++++------------- drivers/tty/tty_io.c | 44 +++++++++--------- drivers/tty/tty_jobctrl.c | 84 +++++++++++++++++----------------- drivers/tty/vt/vt.c | 4 +- include/linux/tty.h | 26 +++++++---- 7 files changed, 130 insertions(+), 122 deletions(-) diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index 3996cf7dc9ba..b0566588ce33 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c @@ -89,7 +89,7 @@ static inline void update_tty_status(struct ser_device *ser) ser->tty_status = ser->tty->flow.stopped << 5 | ser->tty->flow.tco_stopped << 3 | - ser->tty->packet << 2; + ser->tty->ctrl.packet << 2; } static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty) { diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 3566bb577eb0..8ce712eec026 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -342,10 +342,10 @@ static void n_tty_packet_mode_flush(struct tty_struct *tty) { unsigned long flags; - if (tty->link->packet) { - spin_lock_irqsave(&tty->ctrl_lock, flags); - tty->ctrl_status |= TIOCPKT_FLUSHREAD; - spin_unlock_irqrestore(&tty->ctrl_lock, flags); + if (tty->link->ctrl.packet) { + spin_lock_irqsave(&tty->ctrl.lock, flags); + tty->ctrl.pktstatus |= TIOCPKT_FLUSHREAD; + spin_unlock_irqrestore(&tty->ctrl.lock, flags); wake_up_interruptible(&tty->link->read_wait); } } @@ -361,7 +361,7 @@ static void n_tty_packet_mode_flush(struct tty_struct *tty) * Holds termios_rwsem to exclude producer/consumer while * buffer indices are reset. * - * Locking: ctrl_lock, exclusive termios_rwsem + * Locking: ctrl.lock, exclusive termios_rwsem */ static void n_tty_flush_buffer(struct tty_struct *tty) @@ -1103,7 +1103,7 @@ static void eraser(unsigned char c, struct tty_struct *tty) * buffer is 'output'. The signal is processed first to alert any current * readers or writers to discontinue and exit their i/o loops. * - * Locking: ctrl_lock + * Locking: ctrl.lock */ static void __isig(int sig, struct tty_struct *tty) @@ -2025,7 +2025,7 @@ static bool canon_copy_from_read_buf(struct tty_struct *tty, * * Locking: redirected write test is safe * current->signal->tty check is safe - * ctrl_lock to safely reference tty->pgrp + * ctrl.lock to safely reference tty->ctrl.pgrp */ static int job_control(struct tty_struct *tty, struct file *file) @@ -2072,7 +2072,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, int minimum, time; ssize_t retval = 0; long timeout; - int packet; + bool packet; size_t tail; /* @@ -2128,20 +2128,20 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, } } - packet = tty->packet; + packet = tty->ctrl.packet; tail = ldata->read_tail; add_wait_queue(&tty->read_wait, &wait); while (nr) { /* First test for status change. */ - if (packet && tty->link->ctrl_status) { + if (packet && tty->link->ctrl.pktstatus) { unsigned char cs; if (kb != kbuf) break; - spin_lock_irq(&tty->link->ctrl_lock); - cs = tty->link->ctrl_status; - tty->link->ctrl_status = 0; - spin_unlock_irq(&tty->link->ctrl_lock); + spin_lock_irq(&tty->link->ctrl.lock); + cs = tty->link->ctrl.pktstatus; + tty->link->ctrl.pktstatus = 0; + spin_unlock_irq(&tty->link->ctrl.lock); *kb++ = cs; nr--; break; @@ -2368,7 +2368,7 @@ static __poll_t n_tty_poll(struct tty_struct *tty, struct file *file, if (input_available_p(tty, 1)) mask |= EPOLLIN | EPOLLRDNORM; } - if (tty->packet && tty->link->ctrl_status) + if (tty->ctrl.packet && tty->link->ctrl.pktstatus) mask |= EPOLLPRI | EPOLLIN | EPOLLRDNORM; if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) mask |= EPOLLHUP; diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 017f28150a32..3e7b5c811f9b 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -57,9 +57,9 @@ static void pty_close(struct tty_struct *tty, struct file *filp) set_bit(TTY_IO_ERROR, &tty->flags); wake_up_interruptible(&tty->read_wait); wake_up_interruptible(&tty->write_wait); - spin_lock_irq(&tty->ctrl_lock); - tty->packet = 0; - spin_unlock_irq(&tty->ctrl_lock); + spin_lock_irq(&tty->ctrl.lock); + tty->ctrl.packet = false; + spin_unlock_irq(&tty->ctrl.lock); /* Review - krefs on tty_link ?? */ if (!tty->link) return; @@ -185,16 +185,16 @@ static int pty_set_pktmode(struct tty_struct *tty, int __user *arg) if (get_user(pktmode, arg)) return -EFAULT; - spin_lock_irq(&tty->ctrl_lock); + spin_lock_irq(&tty->ctrl.lock); if (pktmode) { - if (!tty->packet) { - tty->link->ctrl_status = 0; + if (!tty->ctrl.packet) { + tty->link->ctrl.pktstatus = 0; smp_mb(); - tty->packet = 1; + tty->ctrl.packet = true; } } else - tty->packet = 0; - spin_unlock_irq(&tty->ctrl_lock); + tty->ctrl.packet = false; + spin_unlock_irq(&tty->ctrl.lock); return 0; } @@ -202,7 +202,7 @@ static int pty_set_pktmode(struct tty_struct *tty, int __user *arg) /* Get the packet mode of a pty */ static int pty_get_pktmode(struct tty_struct *tty, int __user *arg) { - int pktmode = tty->packet; + int pktmode = tty->ctrl.packet; return put_user(pktmode, arg); } @@ -232,11 +232,11 @@ static void pty_flush_buffer(struct tty_struct *tty) return; tty_buffer_flush(to, NULL); - if (to->packet) { - spin_lock_irq(&tty->ctrl_lock); - tty->ctrl_status |= TIOCPKT_FLUSHWRITE; + if (to->ctrl.packet) { + spin_lock_irq(&tty->ctrl.lock); + tty->ctrl.pktstatus |= TIOCPKT_FLUSHWRITE; wake_up_interruptible(&to->read_wait); - spin_unlock_irq(&tty->ctrl_lock); + spin_unlock_irq(&tty->ctrl.lock); } } @@ -266,7 +266,7 @@ static void pty_set_termios(struct tty_struct *tty, struct ktermios *old_termios) { /* See if packet mode change of state. */ - if (tty->link && tty->link->packet) { + if (tty->link && tty->link->ctrl.packet) { int extproc = (old_termios->c_lflag & EXTPROC) | L_EXTPROC(tty); int old_flow = ((old_termios->c_iflag & IXON) && (old_termios->c_cc[VSTOP] == '\023') && @@ -275,17 +275,17 @@ static void pty_set_termios(struct tty_struct *tty, STOP_CHAR(tty) == '\023' && START_CHAR(tty) == '\021'); if ((old_flow != new_flow) || extproc) { - spin_lock_irq(&tty->ctrl_lock); + spin_lock_irq(&tty->ctrl.lock); if (old_flow != new_flow) { - tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP); + tty->ctrl.pktstatus &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP); if (new_flow) - tty->ctrl_status |= TIOCPKT_DOSTOP; + tty->ctrl.pktstatus |= TIOCPKT_DOSTOP; else - tty->ctrl_status |= TIOCPKT_NOSTOP; + tty->ctrl.pktstatus |= TIOCPKT_NOSTOP; } if (extproc) - tty->ctrl_status |= TIOCPKT_IOCTL; - spin_unlock_irq(&tty->ctrl_lock); + tty->ctrl.pktstatus |= TIOCPKT_IOCTL; + spin_unlock_irq(&tty->ctrl.lock); wake_up_interruptible(&tty->link->read_wait); } } @@ -346,11 +346,11 @@ static void pty_start(struct tty_struct *tty) { unsigned long flags; - if (tty->link && tty->link->packet) { - spin_lock_irqsave(&tty->ctrl_lock, flags); - tty->ctrl_status &= ~TIOCPKT_STOP; - tty->ctrl_status |= TIOCPKT_START; - spin_unlock_irqrestore(&tty->ctrl_lock, flags); + if (tty->link && tty->link->ctrl.packet) { + spin_lock_irqsave(&tty->ctrl.lock, flags); + tty->ctrl.pktstatus &= ~TIOCPKT_STOP; + tty->ctrl.pktstatus |= TIOCPKT_START; + spin_unlock_irqrestore(&tty->ctrl.lock, flags); wake_up_interruptible_poll(&tty->link->read_wait, EPOLLIN); } } @@ -359,11 +359,11 @@ static void pty_stop(struct tty_struct *tty) { unsigned long flags; - if (tty->link && tty->link->packet) { - spin_lock_irqsave(&tty->ctrl_lock, flags); - tty->ctrl_status &= ~TIOCPKT_START; - tty->ctrl_status |= TIOCPKT_STOP; - spin_unlock_irqrestore(&tty->ctrl_lock, flags); + if (tty->link && tty->link->ctrl.packet) { + spin_lock_irqsave(&tty->ctrl.lock, flags); + tty->ctrl.pktstatus &= ~TIOCPKT_START; + tty->ctrl.pktstatus |= TIOCPKT_STOP; + spin_unlock_irqrestore(&tty->ctrl.lock, flags); wake_up_interruptible_poll(&tty->link->read_wait, EPOLLIN); } } diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 9734be2eb00e..362845dc1c19 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -638,15 +638,15 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session) tty_ldisc_hangup(tty, cons_filp != NULL); - spin_lock_irq(&tty->ctrl_lock); + spin_lock_irq(&tty->ctrl.lock); clear_bit(TTY_THROTTLED, &tty->flags); clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); - put_pid(tty->session); - put_pid(tty->pgrp); - tty->session = NULL; - tty->pgrp = NULL; - tty->ctrl_status = 0; - spin_unlock_irq(&tty->ctrl_lock); + put_pid(tty->ctrl.session); + put_pid(tty->ctrl.pgrp); + tty->ctrl.session = NULL; + tty->ctrl.pgrp = NULL; + tty->ctrl.pktstatus = 0; + spin_unlock_irq(&tty->ctrl.lock); /* * If one of the devices matches a console pointer, we @@ -1559,8 +1559,8 @@ static void release_one_tty(struct work_struct *work) list_del_init(&tty->tty_files); spin_unlock(&tty->files_lock); - put_pid(tty->pgrp); - put_pid(tty->session); + put_pid(tty->ctrl.pgrp); + put_pid(tty->ctrl.session); free_tty_struct(tty); } @@ -1861,9 +1861,9 @@ int tty_release(struct inode *inode, struct file *filp) */ if (!tty->count) { read_lock(&tasklist_lock); - session_clear_tty(tty->session); + session_clear_tty(tty->ctrl.session); if (o_tty) - session_clear_tty(o_tty->session); + session_clear_tty(o_tty->ctrl.session); read_unlock(&tasklist_lock); } @@ -2250,16 +2250,16 @@ static int __tty_fasync(int fd, struct file *filp, int on) enum pid_type type; struct pid *pid; - spin_lock_irqsave(&tty->ctrl_lock, flags); - if (tty->pgrp) { - pid = tty->pgrp; + spin_lock_irqsave(&tty->ctrl.lock, flags); + if (tty->ctrl.pgrp) { + pid = tty->ctrl.pgrp; type = PIDTYPE_PGID; } else { pid = task_pid(current); type = PIDTYPE_TGID; } get_pid(pid); - spin_unlock_irqrestore(&tty->ctrl_lock, flags); + spin_unlock_irqrestore(&tty->ctrl.lock, flags); __f_setown(filp, pid, type, 0); put_pid(pid); retval = 0; @@ -2381,7 +2381,7 @@ EXPORT_SYMBOL(tty_do_resize); * * Locking: * Driver dependent. The default do_resize method takes the - * tty termios mutex and ctrl_lock. The console takes its own lock + * tty termios mutex and ctrl.lock. The console takes its own lock * then calls into the default method. */ @@ -3039,9 +3039,9 @@ void __do_SAK(struct tty_struct *tty) if (!tty) return; - spin_lock_irqsave(&tty->ctrl_lock, flags); - session = get_pid(tty->session); - spin_unlock_irqrestore(&tty->ctrl_lock, flags); + spin_lock_irqsave(&tty->ctrl.lock, flags); + session = get_pid(tty->ctrl.session); + spin_unlock_irqrestore(&tty->ctrl.lock, flags); tty_ldisc_flush(tty); @@ -3129,8 +3129,8 @@ struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx) kfree(tty); return NULL; } - tty->session = NULL; - tty->pgrp = NULL; + tty->ctrl.session = NULL; + tty->ctrl.pgrp = NULL; mutex_init(&tty->legacy_mutex); mutex_init(&tty->throttle_mutex); init_rwsem(&tty->termios_rwsem); @@ -3140,7 +3140,7 @@ struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx) init_waitqueue_head(&tty->read_wait); INIT_WORK(&tty->hangup_work, do_tty_hangup); mutex_init(&tty->atomic_write_lock); - spin_lock_init(&tty->ctrl_lock); + spin_lock_init(&tty->ctrl.lock); spin_lock_init(&tty->flow.lock); spin_lock_init(&tty->files_lock); INIT_LIST_HEAD(&tty->tty_files); diff --git a/drivers/tty/tty_jobctrl.c b/drivers/tty/tty_jobctrl.c index 7813dc910a19..6119b5e48610 100644 --- a/drivers/tty/tty_jobctrl.c +++ b/drivers/tty/tty_jobctrl.c @@ -28,7 +28,7 @@ static int is_ignored(int sig) * not in the foreground, send a SIGTTOU. If the signal is blocked or * ignored, go ahead and perform the operation. (POSIX 7.2) * - * Locking: ctrl_lock + * Locking: ctrl.lock */ int __tty_check_change(struct tty_struct *tty, int sig) { @@ -42,9 +42,9 @@ int __tty_check_change(struct tty_struct *tty, int sig) rcu_read_lock(); pgrp = task_pgrp(current); - spin_lock_irqsave(&tty->ctrl_lock, flags); - tty_pgrp = tty->pgrp; - spin_unlock_irqrestore(&tty->ctrl_lock, flags); + spin_lock_irqsave(&tty->ctrl.lock, flags); + tty_pgrp = tty->ctrl.pgrp; + spin_unlock_irqrestore(&tty->ctrl.lock, flags); if (tty_pgrp && pgrp != tty_pgrp) { if (is_ignored(sig)) { @@ -99,16 +99,16 @@ static void __proc_set_tty(struct tty_struct *tty) { unsigned long flags; - spin_lock_irqsave(&tty->ctrl_lock, flags); + spin_lock_irqsave(&tty->ctrl.lock, flags); /* * The session and fg pgrp references will be non-NULL if * tiocsctty() is stealing the controlling tty */ - put_pid(tty->session); - put_pid(tty->pgrp); - tty->pgrp = get_pid(task_pgrp(current)); - tty->session = get_pid(task_session(current)); - spin_unlock_irqrestore(&tty->ctrl_lock, flags); + put_pid(tty->ctrl.session); + put_pid(tty->ctrl.pgrp); + tty->ctrl.pgrp = get_pid(task_pgrp(current)); + tty->ctrl.session = get_pid(task_session(current)); + spin_unlock_irqrestore(&tty->ctrl.lock, flags); if (current->signal->tty) { tty_debug(tty, "current tty %s not NULL!!\n", current->signal->tty->name); @@ -135,7 +135,7 @@ void tty_open_proc_set_tty(struct file *filp, struct tty_struct *tty) spin_lock_irq(¤t->sighand->siglock); if (current->signal->leader && !current->signal->tty && - tty->session == NULL) { + tty->ctrl.session == NULL) { /* * Don't let a process that only has write access to the tty * obtain the privileges associated with having a tty as @@ -200,8 +200,8 @@ int tty_signal_session_leader(struct tty_struct *tty, int exit_session) struct pid *tty_pgrp = NULL; read_lock(&tasklist_lock); - if (tty->session) { - do_each_pid_task(tty->session, PIDTYPE_SID, p) { + if (tty->ctrl.session) { + do_each_pid_task(tty->ctrl.session, PIDTYPE_SID, p) { spin_lock_irq(&p->sighand->siglock); if (p->signal->tty == tty) { p->signal->tty = NULL; @@ -218,13 +218,14 @@ int tty_signal_session_leader(struct tty_struct *tty, int exit_session) __group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p); __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p); put_pid(p->signal->tty_old_pgrp); /* A noop */ - spin_lock(&tty->ctrl_lock); - tty_pgrp = get_pid(tty->pgrp); - if (tty->pgrp) - p->signal->tty_old_pgrp = get_pid(tty->pgrp); - spin_unlock(&tty->ctrl_lock); + spin_lock(&tty->ctrl.lock); + tty_pgrp = get_pid(tty->ctrl.pgrp); + if (tty->ctrl.pgrp) + p->signal->tty_old_pgrp = + get_pid(tty->ctrl.pgrp); + spin_unlock(&tty->ctrl.lock); spin_unlock_irq(&p->sighand->siglock); - } while_each_pid_task(tty->session, PIDTYPE_SID, p); + } while_each_pid_task(tty->ctrl.session, PIDTYPE_SID, p); } read_unlock(&tasklist_lock); @@ -309,12 +310,12 @@ void disassociate_ctty(int on_exit) unsigned long flags; tty_lock(tty); - spin_lock_irqsave(&tty->ctrl_lock, flags); - put_pid(tty->session); - put_pid(tty->pgrp); - tty->session = NULL; - tty->pgrp = NULL; - spin_unlock_irqrestore(&tty->ctrl_lock, flags); + spin_lock_irqsave(&tty->ctrl.lock, flags); + put_pid(tty->ctrl.session); + put_pid(tty->ctrl.pgrp); + tty->ctrl.session = NULL; + tty->ctrl.pgrp = NULL; + spin_unlock_irqrestore(&tty->ctrl.lock, flags); tty_unlock(tty); tty_kref_put(tty); } @@ -363,7 +364,8 @@ static int tiocsctty(struct tty_struct *tty, struct file *file, int arg) tty_lock(tty); read_lock(&tasklist_lock); - if (current->signal->leader && (task_session(current) == tty->session)) + if (current->signal->leader && + task_session(current) == tty->ctrl.session) goto unlock; /* @@ -375,7 +377,7 @@ static int tiocsctty(struct tty_struct *tty, struct file *file, int arg) goto unlock; } - if (tty->session) { + if (tty->ctrl.session) { /* * This tty is already the controlling * tty for another session group! @@ -384,7 +386,7 @@ static int tiocsctty(struct tty_struct *tty, struct file *file, int arg) /* * Steal it away */ - session_clear_tty(tty->session); + session_clear_tty(tty->ctrl.session); } else { ret = -EPERM; goto unlock; @@ -416,9 +418,9 @@ struct pid *tty_get_pgrp(struct tty_struct *tty) unsigned long flags; struct pid *pgrp; - spin_lock_irqsave(&tty->ctrl_lock, flags); - pgrp = get_pid(tty->pgrp); - spin_unlock_irqrestore(&tty->ctrl_lock, flags); + spin_lock_irqsave(&tty->ctrl.lock, flags); + pgrp = get_pid(tty->ctrl.pgrp); + spin_unlock_irqrestore(&tty->ctrl.lock, flags); return pgrp; } @@ -499,10 +501,10 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t if (pgrp_nr < 0) return -EINVAL; - spin_lock_irq(&real_tty->ctrl_lock); + spin_lock_irq(&real_tty->ctrl.lock); if (!current->signal->tty || (current->signal->tty != real_tty) || - (real_tty->session != task_session(current))) { + (real_tty->ctrl.session != task_session(current))) { retval = -ENOTTY; goto out_unlock_ctrl; } @@ -515,12 +517,12 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t if (session_of_pgrp(pgrp) != task_session(current)) goto out_unlock; retval = 0; - put_pid(real_tty->pgrp); - real_tty->pgrp = get_pid(pgrp); + put_pid(real_tty->ctrl.pgrp); + real_tty->ctrl.pgrp = get_pid(pgrp); out_unlock: rcu_read_unlock(); out_unlock_ctrl: - spin_unlock_irq(&real_tty->ctrl_lock); + spin_unlock_irq(&real_tty->ctrl.lock); return retval; } @@ -545,16 +547,16 @@ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t _ if (tty == real_tty && current->signal->tty != real_tty) return -ENOTTY; - spin_lock_irqsave(&real_tty->ctrl_lock, flags); - if (!real_tty->session) + spin_lock_irqsave(&real_tty->ctrl.lock, flags); + if (!real_tty->ctrl.session) goto err; - sid = pid_vnr(real_tty->session); - spin_unlock_irqrestore(&real_tty->ctrl_lock, flags); + sid = pid_vnr(real_tty->ctrl.session); + spin_unlock_irqrestore(&real_tty->ctrl.lock, flags); return put_user(sid, p); err: - spin_unlock_irqrestore(&real_tty->ctrl_lock, flags); + spin_unlock_irqrestore(&real_tty->ctrl.lock, flags); return -ENOTTY; } diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 38c677fb6505..706f066eb711 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -1189,7 +1189,7 @@ static inline int resize_screen(struct vc_data *vc, int width, int height, * information and perform any necessary signal handling. * * Caller must hold the console semaphore. Takes the termios rwsem and - * ctrl_lock of the tty IFF a tty is passed. + * ctrl.lock of the tty IFF a tty is passed. */ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, @@ -1355,7 +1355,7 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int rows) * the actual work. * * Takes the console sem and the called methods then take the tty - * termios_rwsem and the tty ctrl_lock in that order. + * termios_rwsem and the tty ctrl.lock in that order. */ static int vt_resize(struct tty_struct *tty, struct winsize *ws) { diff --git a/include/linux/tty.h b/include/linux/tty.h index df3a69b2e1ea..283ac5f29052 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -255,6 +255,13 @@ struct tty_operations; * @flow.unused: alignment for Alpha, so that no members other than @flow.* are * modified by the same 64b word store. The @flow's __aligned is * there for the very same reason. + * @ctrl.lock: lock for ctrl members + * @ctrl.pgrp: process group of this tty (setpgrp(2)) + * @ctrl.session: session of this tty (setsid(2)). Writes are protected by both + * @ctrl.lock and legacy mutex, readers must use at least one of + * them. + * @ctrl.pktstatus: packet mode status (bitwise OR of TIOCPKT_* constants) + * @ctrl.packet: packet mode enabled * * All of the state associated with a tty while the tty is open. Persistent * storage for tty devices is referenced here as @port in struct tty_port. @@ -276,16 +283,9 @@ struct tty_struct { struct mutex throttle_mutex; struct rw_semaphore termios_rwsem; struct mutex winsize_mutex; - spinlock_t ctrl_lock; /* Termios values are protected by the termios rwsem */ struct ktermios termios, termios_locked; char name[64]; - struct pid *pgrp; /* Protected by ctrl lock */ - /* - * Writes protected by both ctrl lock and legacy mutex, readers must use - * at least one of them. - */ - struct pid *session; unsigned long flags; int count; struct winsize winsize; /* winsize_mutex */ @@ -297,10 +297,16 @@ struct tty_struct { unsigned long unused[0]; } __aligned(sizeof(unsigned long)) flow; + struct { + spinlock_t lock; + struct pid *pgrp; + struct pid *session; + unsigned char pktstatus; + bool packet; + unsigned long unused[0]; + } __aligned(sizeof(unsigned long)) ctrl; + int hw_stopped; - unsigned long ctrl_status:8, /* ctrl_lock */ - packet:1, - unused_ctrl:BITS_PER_LONG - 9; unsigned int receive_room; /* Bytes free for queue */ int flow_change; From fbadf70a8053b3dce78a45997ae55651693a2a81 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:19:07 +0200 Subject: [PATCH 037/227] tty: set tty_ldisc_ops::num statically There is no reason to pass the ldisc number to tty_register_ldisc separately. Just set it in the already defined tty_ldisc_ops in all the ldiscs. This simplifies tty_register_ldisc a bit too (no need to set the num member there). Signed-off-by: Jiri Slaby Cc: William Hubbs Cc: Chris Brannon Cc: Kirk Reiser Cc: Samuel Thibault Cc: Marcel Holtmann Cc: Johan Hedberg Cc: Luiz Augusto von Dentz Cc: Dmitry Torokhov Cc: Arnd Bergmann Cc: "David S. Miller" Cc: Jakub Kicinski Cc: Wolfgang Grandegger Cc: Marc Kleine-Budde Cc: Andreas Koensgen Cc: Paul Mackerras Cc: Rodolfo Giometti Cc: Peter Ujfalusi Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Link: https://lore.kernel.org/r/20210505091928.22010-15-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/accessibility/speakup/spk_ttyio.c | 3 ++- drivers/bluetooth/hci_ldisc.c | 3 ++- drivers/input/serio/serport.c | 3 ++- drivers/misc/ti-st/st_core.c | 3 ++- drivers/net/caif/caif_serial.c | 3 ++- drivers/net/can/slcan.c | 3 ++- drivers/net/hamradio/6pack.c | 4 +++- drivers/net/hamradio/mkiss.c | 3 ++- drivers/net/ppp/ppp_async.c | 3 ++- drivers/net/ppp/ppp_synctty.c | 3 ++- drivers/net/slip/slip.c | 3 ++- drivers/pps/clients/pps-ldisc.c | 3 ++- drivers/tty/n_gsm.c | 3 ++- drivers/tty/n_hdlc.c | 3 ++- drivers/tty/n_null.c | 3 ++- drivers/tty/n_tty.c | 3 ++- drivers/tty/tty_ldisc.c | 7 +++---- include/linux/tty.h | 2 +- net/nfc/nci/uart.c | 3 ++- sound/soc/ti/ams-delta.c | 3 ++- 20 files changed, 41 insertions(+), 23 deletions(-) diff --git a/drivers/accessibility/speakup/spk_ttyio.c b/drivers/accessibility/speakup/spk_ttyio.c index b7fd094700d9..8faa27bae6bf 100644 --- a/drivers/accessibility/speakup/spk_ttyio.c +++ b/drivers/accessibility/speakup/spk_ttyio.c @@ -105,6 +105,7 @@ static int spk_ttyio_receive_buf2(struct tty_struct *tty, static struct tty_ldisc_ops spk_ttyio_ldisc_ops = { .owner = THIS_MODULE, + .num = N_SPEAKUP, .name = "speakup_ldisc", .open = spk_ttyio_ldisc_open, .close = spk_ttyio_ldisc_close, @@ -212,7 +213,7 @@ static int spk_ttyio_initialise_ldisc(struct spk_synth *synth) void spk_ttyio_register_ldisc(void) { - if (tty_register_ldisc(N_SPEAKUP, &spk_ttyio_ldisc_ops)) + if (tty_register_ldisc(&spk_ttyio_ldisc_ops)) pr_warn("speakup: Error registering line discipline. Most synths won't work.\n"); } diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index e785851a92c1..ee32006e8fc9 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -821,6 +821,7 @@ static __poll_t hci_uart_tty_poll(struct tty_struct *tty, static struct tty_ldisc_ops hci_uart_ldisc = { .owner = THIS_MODULE, + .num = N_HCI, .name = "n_hci", .open = hci_uart_tty_open, .close = hci_uart_tty_close, @@ -840,7 +841,7 @@ static int __init hci_uart_init(void) BT_INFO("HCI UART driver ver %s", VERSION); /* Register the tty discipline */ - err = tty_register_ldisc(N_HCI, &hci_uart_ldisc); + err = tty_register_ldisc(&hci_uart_ldisc); if (err) { BT_ERR("HCI line discipline registration failed. (%d)", err); return err; diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index ff3715315592..870b1d2606fc 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c @@ -274,6 +274,7 @@ static void serport_ldisc_write_wakeup(struct tty_struct * tty) static struct tty_ldisc_ops serport_ldisc = { .owner = THIS_MODULE, + .num = N_MOUSE, .name = "input", .open = serport_ldisc_open, .close = serport_ldisc_close, @@ -294,7 +295,7 @@ static struct tty_ldisc_ops serport_ldisc = { static int __init serport_init(void) { int retval; - retval = tty_register_ldisc(N_MOUSE, &serport_ldisc); + retval = tty_register_ldisc(&serport_ldisc); if (retval) printk(KERN_ERR "serport.c: Error registering line discipline.\n"); diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index 239a75502cd6..a4f5d02940c7 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -845,6 +845,7 @@ static void st_tty_flush_buffer(struct tty_struct *tty) } static struct tty_ldisc_ops st_ldisc_ops = { + .num = N_TI_WL, .name = "n_st", .open = st_tty_open, .close = st_tty_close, @@ -860,7 +861,7 @@ int st_core_init(struct st_data_s **core_data) struct st_data_s *st_gdata; long err; - err = tty_register_ldisc(N_TI_WL, &st_ldisc_ops); + err = tty_register_ldisc(&st_ldisc_ops); if (err) { pr_err("error registering %d line discipline %ld", N_TI_WL, err); diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index b0566588ce33..2407a0f6656d 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c @@ -382,6 +382,7 @@ static void ldisc_close(struct tty_struct *tty) /* The line discipline structure. */ static struct tty_ldisc_ops caif_ldisc = { .owner = THIS_MODULE, + .num = N_CAIF, .name = "n_caif", .open = ldisc_open, .close = ldisc_close, @@ -431,7 +432,7 @@ static int __init caif_ser_init(void) { int ret; - ret = tty_register_ldisc(N_CAIF, &caif_ldisc); + ret = tty_register_ldisc(&caif_ldisc); if (ret < 0) pr_err("cannot register CAIF ldisc=%d err=%d\n", N_CAIF, ret); diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index 7dc3e79cb5c4..e3f528c82242 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -698,6 +698,7 @@ static int slcan_ioctl(struct tty_struct *tty, struct file *file, static struct tty_ldisc_ops slc_ldisc = { .owner = THIS_MODULE, + .num = N_SLCAN, .name = "slcan", .open = slcan_open, .close = slcan_close, @@ -722,7 +723,7 @@ static int __init slcan_init(void) return -ENOMEM; /* Fill in our line protocol discipline, and register it */ - status = tty_register_ldisc(N_SLCAN, &slc_ldisc); + status = tty_register_ldisc(&slc_ldisc); if (status) { printk(KERN_ERR "slcan: can't register line discipline\n"); kfree(slcan_devs); diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index c0a80f04dd8e..4db1d3c4d771 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -744,6 +744,7 @@ static int sixpack_ioctl(struct tty_struct *tty, struct file *file, static struct tty_ldisc_ops sp_ldisc = { .owner = THIS_MODULE, + .num = N_6PACK, .name = "6pack", .open = sixpack_open, .close = sixpack_close, @@ -766,7 +767,8 @@ static int __init sixpack_init_driver(void) printk(msg_banner); /* Register the provided line protocol discipline */ - if ((status = tty_register_ldisc(N_6PACK, &sp_ldisc)) != 0) + status = tty_register_ldisc(&sp_ldisc); + if (status) printk(msg_regfail, status); return status; diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index fc05ded48178..1eb87a5a9394 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -933,6 +933,7 @@ out: static struct tty_ldisc_ops ax_ldisc = { .owner = THIS_MODULE, + .num = N_AX25, .name = "mkiss", .open = mkiss_open, .close = mkiss_close, @@ -952,7 +953,7 @@ static int __init mkiss_init_driver(void) printk(banner); - status = tty_register_ldisc(N_AX25, &ax_ldisc); + status = tty_register_ldisc(&ax_ldisc); if (status != 0) printk(msg_regfail, status); diff --git a/drivers/net/ppp/ppp_async.c b/drivers/net/ppp/ppp_async.c index 9f08bd19551f..4bfb66c40c86 100644 --- a/drivers/net/ppp/ppp_async.c +++ b/drivers/net/ppp/ppp_async.c @@ -372,6 +372,7 @@ ppp_asynctty_wakeup(struct tty_struct *tty) static struct tty_ldisc_ops ppp_ldisc = { .owner = THIS_MODULE, + .num = N_PPP, .name = "ppp", .open = ppp_asynctty_open, .close = ppp_asynctty_close, @@ -389,7 +390,7 @@ ppp_async_init(void) { int err; - err = tty_register_ldisc(N_PPP, &ppp_ldisc); + err = tty_register_ldisc(&ppp_ldisc); if (err != 0) printk(KERN_ERR "PPP_async: error %d registering line disc.\n", err); diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c index c82c4e6df4cb..0942d3ee48e0 100644 --- a/drivers/net/ppp/ppp_synctty.c +++ b/drivers/net/ppp/ppp_synctty.c @@ -365,6 +365,7 @@ ppp_sync_wakeup(struct tty_struct *tty) static struct tty_ldisc_ops ppp_sync_ldisc = { .owner = THIS_MODULE, + .num = N_SYNC_PPP, .name = "pppsync", .open = ppp_sync_open, .close = ppp_sync_close, @@ -382,7 +383,7 @@ ppp_sync_init(void) { int err; - err = tty_register_ldisc(N_SYNC_PPP, &ppp_sync_ldisc); + err = tty_register_ldisc(&ppp_sync_ldisc); if (err != 0) printk(KERN_ERR "PPP_sync: error %d registering line disc.\n", err); diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c index 4dda49e61745..938ac0ec0305 100644 --- a/drivers/net/slip/slip.c +++ b/drivers/net/slip/slip.c @@ -1263,6 +1263,7 @@ static int sl_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) static struct tty_ldisc_ops sl_ldisc = { .owner = THIS_MODULE, + .num = N_SLIP, .name = "slip", .open = slip_open, .close = slip_close, @@ -1298,7 +1299,7 @@ static int __init slip_init(void) return -ENOMEM; /* Fill in our line protocol discipline, and register it */ - status = tty_register_ldisc(N_SLIP, &sl_ldisc); + status = tty_register_ldisc(&sl_ldisc); if (status != 0) { printk(KERN_ERR "SLIP: can't register line discipline (err = %d)\n", status); kfree(slip_devs); diff --git a/drivers/pps/clients/pps-ldisc.c b/drivers/pps/clients/pps-ldisc.c index bf26cc56b863..2a88e678d0b8 100644 --- a/drivers/pps/clients/pps-ldisc.c +++ b/drivers/pps/clients/pps-ldisc.c @@ -112,12 +112,13 @@ static int __init pps_tty_init(void) /* Init PPS_TTY data */ pps_ldisc_ops.owner = THIS_MODULE; + pps_ldisc_ops.num = N_PPS; pps_ldisc_ops.name = "pps_tty"; pps_ldisc_ops.dcd_change = pps_tty_dcd_change; pps_ldisc_ops.open = pps_tty_open; pps_ldisc_ops.close = pps_tty_close; - err = tty_register_ldisc(N_PPS, &pps_ldisc_ops); + err = tty_register_ldisc(&pps_ldisc_ops); if (err) pr_err("can't register PPS line discipline\n"); else diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 477403ecc445..654e439ff6c8 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2857,6 +2857,7 @@ static int gsm_create_network(struct gsm_dlci *dlci, struct gsm_netconfig *nc) /* Line discipline for real tty */ static struct tty_ldisc_ops tty_ldisc_packet = { .owner = THIS_MODULE, + .num = N_GSM0710, .name = "n_gsm", .open = gsmld_open, .close = gsmld_close, @@ -3242,7 +3243,7 @@ static const struct tty_operations gsmtty_ops = { static int __init gsm_init(void) { /* Fill in our line protocol discipline, and register it */ - int status = tty_register_ldisc(N_GSM0710, &tty_ldisc_packet); + int status = tty_register_ldisc(&tty_ldisc_packet); if (status != 0) { pr_err("n_gsm: can't register line discipline (err = %d)\n", status); diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index 62b1d1a6e0f1..2256039911f5 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c @@ -788,6 +788,7 @@ static struct n_hdlc_buf *n_hdlc_buf_get(struct n_hdlc_buf_list *buf_list) static struct tty_ldisc_ops n_hdlc_ldisc = { .owner = THIS_MODULE, + .num = N_HDLC, .name = "hdlc", .open = n_hdlc_tty_open, .close = n_hdlc_tty_close, @@ -807,7 +808,7 @@ static int __init n_hdlc_init(void) /* range check maxframe arg */ maxframe = clamp(maxframe, 4096, MAX_HDLC_FRAME_SIZE); - status = tty_register_ldisc(N_HDLC, &n_hdlc_ldisc); + status = tty_register_ldisc(&n_hdlc_ldisc); if (!status) pr_info("N_HDLC line discipline registered with maxframe=%d\n", maxframe); diff --git a/drivers/tty/n_null.c b/drivers/tty/n_null.c index 2ff373d2f98d..ee229c812dce 100644 --- a/drivers/tty/n_null.c +++ b/drivers/tty/n_null.c @@ -40,6 +40,7 @@ static void n_null_receivebuf(struct tty_struct *tty, static struct tty_ldisc_ops null_ldisc = { .owner = THIS_MODULE, + .num = N_NULL, .name = "n_null", .open = n_null_open, .close = n_null_close, @@ -50,7 +51,7 @@ static struct tty_ldisc_ops null_ldisc = { static int __init n_null_init(void) { - BUG_ON(tty_register_ldisc(N_NULL, &null_ldisc)); + BUG_ON(tty_register_ldisc(&null_ldisc)); return 0; } diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 8ce712eec026..2fe27905c398 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -2424,6 +2424,7 @@ static int n_tty_ioctl(struct tty_struct *tty, struct file *file, static struct tty_ldisc_ops n_tty_ops = { .owner = THIS_MODULE, + .num = N_TTY, .name = "n_tty", .open = n_tty_open, .close = n_tty_close, @@ -2455,5 +2456,5 @@ EXPORT_SYMBOL_GPL(n_tty_inherit_ops); void __init n_tty_init(void) { - tty_register_ldisc(N_TTY, &n_tty_ops); + tty_register_ldisc(&n_tty_ops); } diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 03f414172f34..9aff04bee4cd 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -59,17 +59,16 @@ static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS]; * takes tty_ldiscs_lock to guard against ldisc races */ -int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc) +int tty_register_ldisc(struct tty_ldisc_ops *new_ldisc) { unsigned long flags; int ret = 0; - if (disc < N_TTY || disc >= NR_LDISCS) + if (new_ldisc->num < N_TTY || new_ldisc->num >= NR_LDISCS) return -EINVAL; raw_spin_lock_irqsave(&tty_ldiscs_lock, flags); - tty_ldiscs[disc] = new_ldisc; - new_ldisc->num = disc; + tty_ldiscs[new_ldisc->num] = new_ldisc; new_ldisc->refcount = 0; raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags); diff --git a/include/linux/tty.h b/include/linux/tty.h index 283ac5f29052..95c632299fb4 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -636,7 +636,7 @@ static inline int tty_port_users(struct tty_port *port) return port->count + port->blocked_open; } -extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc); +extern int tty_register_ldisc(struct tty_ldisc_ops *new_ldisc); extern int tty_unregister_ldisc(int disc); extern int tty_set_ldisc(struct tty_struct *tty, int disc); extern int tty_ldisc_receive_buf(struct tty_ldisc *ld, const unsigned char *p, diff --git a/net/nfc/nci/uart.c b/net/nfc/nci/uart.c index 98102ef64004..648c26b4bad8 100644 --- a/net/nfc/nci/uart.c +++ b/net/nfc/nci/uart.c @@ -442,6 +442,7 @@ EXPORT_SYMBOL_GPL(nci_uart_set_config); static struct tty_ldisc_ops nci_uart_ldisc = { .owner = THIS_MODULE, + .num = N_NCI, .name = "n_nci", .open = nci_uart_tty_open, .close = nci_uart_tty_close, @@ -456,7 +457,7 @@ static struct tty_ldisc_ops nci_uart_ldisc = { static int __init nci_uart_init(void) { - return tty_register_ldisc(N_NCI, &nci_uart_ldisc); + return tty_register_ldisc(&nci_uart_ldisc); } static void __exit nci_uart_exit(void) diff --git a/sound/soc/ti/ams-delta.c b/sound/soc/ti/ams-delta.c index 55a6736a378e..fcbb791bf27a 100644 --- a/sound/soc/ti/ams-delta.c +++ b/sound/soc/ti/ams-delta.c @@ -396,6 +396,7 @@ static void cx81801_wakeup(struct tty_struct *tty) static struct tty_ldisc_ops cx81801_ops = { .name = "cx81801", + .num = N_V253, .owner = THIS_MODULE, .open = cx81801_open, .close = cx81801_close, @@ -503,7 +504,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) } /* Register optional line discipline for over the modem control */ - ret = tty_register_ldisc(N_V253, &cx81801_ops); + ret = tty_register_ldisc(&cx81801_ops); if (ret) { dev_warn(card->dev, "Failed to register line discipline, " From 839e0f226d1c1d216ac3841b4710810080392c16 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:19:08 +0200 Subject: [PATCH 038/227] n_gsm: use goto-failpaths in gsm_init Use the classic failpath handling using gotos in gsm_init. That way, tty_unregister_ldisc needs not be repeated on two places. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210505091928.22010-16-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_gsm.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 654e439ff6c8..cce2ef04caeb 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -3252,9 +3252,9 @@ static int __init gsm_init(void) gsm_tty_driver = alloc_tty_driver(256); if (!gsm_tty_driver) { - tty_unregister_ldisc(N_GSM0710); pr_err("gsm_init: tty allocation failed.\n"); - return -EINVAL; + status = -ENOMEM; + goto err_unreg_ldisc; } gsm_tty_driver->driver_name = "gsmtty"; gsm_tty_driver->name = "gsmtty"; @@ -3270,14 +3270,18 @@ static int __init gsm_init(void) tty_set_operations(gsm_tty_driver, &gsmtty_ops); if (tty_register_driver(gsm_tty_driver)) { - put_tty_driver(gsm_tty_driver); - tty_unregister_ldisc(N_GSM0710); pr_err("gsm_init: tty registration failed.\n"); - return -EBUSY; + status = -EBUSY; + goto err_put_driver; } pr_debug("gsm_init: loaded as %d,%d.\n", gsm_tty_driver->major, gsm_tty_driver->minor_start); return 0; +err_put_driver: + put_tty_driver(gsm_tty_driver); +err_unreg_ldisc: + tty_unregister_ldisc(N_GSM0710); + return status; } static void __exit gsm_exit(void) From f81ee8b8b8421dc06d13f197bb53191559cc51da Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:19:09 +0200 Subject: [PATCH 039/227] tty: make tty_ldisc_ops a param in tty_unregister_ldisc Make tty_unregister_ldisc symmetric to tty_register_ldisc by accepting struct tty_ldisc_ops as a parameter instead of ldisc number. This avoids checking of the ldisc number bounds in tty_unregister_ldisc. Signed-off-by: Jiri Slaby Cc: William Hubbs Cc: Chris Brannon Cc: Kirk Reiser Cc: Samuel Thibault Cc: Marcel Holtmann Cc: Johan Hedberg Cc: Luiz Augusto von Dentz Cc: Dmitry Torokhov Cc: Arnd Bergmann Cc: "David S. Miller" Cc: Jakub Kicinski Cc: Wolfgang Grandegger Cc: Marc Kleine-Budde Cc: Andreas Koensgen Cc: Paul Mackerras Cc: Rodolfo Giometti Cc: Peter Ujfalusi Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Link: https://lore.kernel.org/r/20210505091928.22010-17-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/accessibility/speakup/spk_ttyio.c | 2 +- drivers/bluetooth/hci_ldisc.c | 2 +- drivers/input/serio/serport.c | 2 +- drivers/misc/ti-st/st_core.c | 6 +++--- drivers/net/caif/caif_serial.c | 2 +- drivers/net/can/slcan.c | 2 +- drivers/net/hamradio/6pack.c | 2 +- drivers/net/hamradio/mkiss.c | 2 +- drivers/net/ppp/ppp_async.c | 2 +- drivers/net/ppp/ppp_synctty.c | 2 +- drivers/net/slip/slip.c | 2 +- drivers/pps/clients/pps-ldisc.c | 2 +- drivers/tty/n_gsm.c | 4 ++-- drivers/tty/n_hdlc.c | 3 +-- drivers/tty/n_null.c | 2 +- drivers/tty/tty_ldisc.c | 9 +++------ include/linux/tty.h | 2 +- net/nfc/nci/uart.c | 2 +- sound/soc/ti/ams-delta.c | 2 +- 19 files changed, 24 insertions(+), 28 deletions(-) diff --git a/drivers/accessibility/speakup/spk_ttyio.c b/drivers/accessibility/speakup/spk_ttyio.c index 8faa27bae6bf..0b7f1a87eaeb 100644 --- a/drivers/accessibility/speakup/spk_ttyio.c +++ b/drivers/accessibility/speakup/spk_ttyio.c @@ -219,7 +219,7 @@ void spk_ttyio_register_ldisc(void) void spk_ttyio_unregister_ldisc(void) { - if (tty_unregister_ldisc(N_SPEAKUP)) + if (tty_unregister_ldisc(&spk_ttyio_ldisc_ops)) pr_warn("speakup: Couldn't unregister ldisc\n"); } diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index ee32006e8fc9..31e0c804363c 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -917,7 +917,7 @@ static void __exit hci_uart_exit(void) #endif /* Release tty registration of line discipline */ - err = tty_unregister_ldisc(N_HCI); + err = tty_unregister_ldisc(&hci_uart_ldisc); if (err) BT_ERR("Can't unregister HCI line discipline (%d)", err); } diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index 870b1d2606fc..7fbbe00e3553 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c @@ -304,7 +304,7 @@ static int __init serport_init(void) static void __exit serport_exit(void) { - tty_unregister_ldisc(N_MOUSE); + tty_unregister_ldisc(&serport_ldisc); } module_init(serport_init); diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index a4f5d02940c7..174ae8e52805 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -872,7 +872,7 @@ int st_core_init(struct st_data_s **core_data) st_gdata = kzalloc(sizeof(struct st_data_s), GFP_KERNEL); if (!st_gdata) { pr_err("memory allocation failed"); - err = tty_unregister_ldisc(N_TI_WL); + err = tty_unregister_ldisc(&st_ldisc_ops); if (err) pr_err("unable to un-register ldisc %ld", err); err = -ENOMEM; @@ -892,7 +892,7 @@ int st_core_init(struct st_data_s **core_data) if (err) { pr_err("error during st_ll initialization(%ld)", err); kfree(st_gdata); - err = tty_unregister_ldisc(N_TI_WL); + err = tty_unregister_ldisc(&st_ldisc_ops); if (err) pr_err("unable to un-register ldisc"); return err; @@ -919,7 +919,7 @@ void st_core_exit(struct st_data_s *st_gdata) kfree_skb(st_gdata->rx_skb); kfree_skb(st_gdata->tx_skb); /* TTY ldisc cleanup */ - err = tty_unregister_ldisc(N_TI_WL); + err = tty_unregister_ldisc(&st_ldisc_ops); if (err) pr_err("unable to un-register ldisc %ld", err); /* free the global data pointer */ diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index 2407a0f6656d..d0c24dba4a86 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c @@ -447,7 +447,7 @@ static void __exit caif_ser_exit(void) spin_unlock(&ser_lock); ser_release(NULL); cancel_work_sync(&ser_release_work); - tty_unregister_ldisc(N_CAIF); + tty_unregister_ldisc(&caif_ldisc); debugfs_remove_recursive(debugfsdir); } diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index e3f528c82242..03a2dbd3c367 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -784,7 +784,7 @@ static void __exit slcan_exit(void) kfree(slcan_devs); slcan_devs = NULL; - i = tty_unregister_ldisc(N_SLCAN); + i = tty_unregister_ldisc(&slc_ldisc); if (i) printk(KERN_ERR "slcan: can't unregister ldisc (err %d)\n", i); } diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 4db1d3c4d771..aac24f9caceb 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -781,7 +781,7 @@ static void __exit sixpack_exit_driver(void) { int ret; - if ((ret = tty_unregister_ldisc(N_6PACK))) + if ((ret = tty_unregister_ldisc(&sp_ldisc))) printk(msg_unregfail, ret); } diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 1eb87a5a9394..750c6afc9302 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -967,7 +967,7 @@ static void __exit mkiss_exit_driver(void) { int ret; - if ((ret = tty_unregister_ldisc(N_AX25))) + if ((ret = tty_unregister_ldisc(&ax_ldisc))) printk(msg_unregfail, ret); } diff --git a/drivers/net/ppp/ppp_async.c b/drivers/net/ppp/ppp_async.c index 4bfb66c40c86..b2d454d01eba 100644 --- a/drivers/net/ppp/ppp_async.c +++ b/drivers/net/ppp/ppp_async.c @@ -1016,7 +1016,7 @@ static void async_lcp_peek(struct asyncppp *ap, unsigned char *data, static void __exit ppp_async_cleanup(void) { - if (tty_unregister_ldisc(N_PPP) != 0) + if (tty_unregister_ldisc(&ppp_ldisc) != 0) printk(KERN_ERR "failed to unregister PPP line discipline\n"); } diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c index 0942d3ee48e0..ca403bde56fb 100644 --- a/drivers/net/ppp/ppp_synctty.c +++ b/drivers/net/ppp/ppp_synctty.c @@ -727,7 +727,7 @@ err: static void __exit ppp_sync_cleanup(void) { - if (tty_unregister_ldisc(N_SYNC_PPP) != 0) + if (tty_unregister_ldisc(&ppp_sync_ldisc) != 0) printk(KERN_ERR "failed to unregister Sync PPP line discipline\n"); } diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c index 938ac0ec0305..867efff40a0e 100644 --- a/drivers/net/slip/slip.c +++ b/drivers/net/slip/slip.c @@ -1360,7 +1360,7 @@ static void __exit slip_exit(void) kfree(slip_devs); slip_devs = NULL; - i = tty_unregister_ldisc(N_SLIP); + i = tty_unregister_ldisc(&sl_ldisc); if (i != 0) printk(KERN_ERR "SLIP: can't unregister line discipline (err = %d)\n", i); } diff --git a/drivers/pps/clients/pps-ldisc.c b/drivers/pps/clients/pps-ldisc.c index 2a88e678d0b8..91b947f37774 100644 --- a/drivers/pps/clients/pps-ldisc.c +++ b/drivers/pps/clients/pps-ldisc.c @@ -131,7 +131,7 @@ static void __exit pps_tty_cleanup(void) { int err; - err = tty_unregister_ldisc(N_PPS); + err = tty_unregister_ldisc(&pps_ldisc_ops); if (err) pr_err("can't unregister PPS line discipline\n"); else diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index cce2ef04caeb..db7d4a30af91 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -3280,13 +3280,13 @@ static int __init gsm_init(void) err_put_driver: put_tty_driver(gsm_tty_driver); err_unreg_ldisc: - tty_unregister_ldisc(N_GSM0710); + tty_unregister_ldisc(&tty_ldisc_packet); return status; } static void __exit gsm_exit(void) { - int status = tty_unregister_ldisc(N_GSM0710); + int status = tty_unregister_ldisc(&tty_ldisc_packet); if (status != 0) pr_err("n_gsm: can't unregister line discipline (err = %d)\n", status); diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index 2256039911f5..c2afbfe0a1d5 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c @@ -822,8 +822,7 @@ static int __init n_hdlc_init(void) static void __exit n_hdlc_exit(void) { - /* Release tty registration of line discipline */ - int status = tty_unregister_ldisc(N_HDLC); + int status = tty_unregister_ldisc(&n_hdlc_ldisc); if (status) pr_err("N_HDLC: can't unregister line discipline (err = %d)\n", diff --git a/drivers/tty/n_null.c b/drivers/tty/n_null.c index ee229c812dce..f913b665af72 100644 --- a/drivers/tty/n_null.c +++ b/drivers/tty/n_null.c @@ -57,7 +57,7 @@ static int __init n_null_init(void) static void __exit n_null_exit(void) { - tty_unregister_ldisc(N_NULL); + tty_unregister_ldisc(&null_ldisc); } module_init(n_null_init); diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 9aff04bee4cd..d02deeb5e584 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -87,19 +87,16 @@ EXPORT_SYMBOL(tty_register_ldisc); * takes tty_ldiscs_lock to guard against ldisc races */ -int tty_unregister_ldisc(int disc) +int tty_unregister_ldisc(struct tty_ldisc_ops *ldisc) { unsigned long flags; int ret = 0; - if (disc < N_TTY || disc >= NR_LDISCS) - return -EINVAL; - raw_spin_lock_irqsave(&tty_ldiscs_lock, flags); - if (tty_ldiscs[disc]->refcount) + if (tty_ldiscs[ldisc->num]->refcount) ret = -EBUSY; else - tty_ldiscs[disc] = NULL; + tty_ldiscs[ldisc->num] = NULL; raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags); return ret; diff --git a/include/linux/tty.h b/include/linux/tty.h index 95c632299fb4..6a72d0ff6391 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -637,7 +637,7 @@ static inline int tty_port_users(struct tty_port *port) } extern int tty_register_ldisc(struct tty_ldisc_ops *new_ldisc); -extern int tty_unregister_ldisc(int disc); +extern int tty_unregister_ldisc(struct tty_ldisc_ops *ldisc); extern int tty_set_ldisc(struct tty_struct *tty, int disc); extern int tty_ldisc_receive_buf(struct tty_ldisc *ld, const unsigned char *p, const char *f, int count); diff --git a/net/nfc/nci/uart.c b/net/nfc/nci/uart.c index 648c26b4bad8..502e7a3f8948 100644 --- a/net/nfc/nci/uart.c +++ b/net/nfc/nci/uart.c @@ -462,7 +462,7 @@ static int __init nci_uart_init(void) static void __exit nci_uart_exit(void) { - tty_unregister_ldisc(N_NCI); + tty_unregister_ldisc(&nci_uart_ldisc); } module_init(nci_uart_init); diff --git a/sound/soc/ti/ams-delta.c b/sound/soc/ti/ams-delta.c index fcbb791bf27a..e89548e48364 100644 --- a/sound/soc/ti/ams-delta.c +++ b/sound/soc/ti/ams-delta.c @@ -583,7 +583,7 @@ static int ams_delta_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); - if (tty_unregister_ldisc(N_V253) != 0) + if (tty_unregister_ldisc(&cx81801_ops) != 0) dev_warn(&pdev->dev, "failed to unregister V253 line discipline\n"); From 19475209331168cdb8070a011650535f1c54a730 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:19:10 +0200 Subject: [PATCH 040/227] tty: drop tty_ldisc_ops::refcount The refcount is checked only in tty_unregister_ldisc and EBUSY returned if it is nonzero. But none of the tty_unregister_ldisc callers act anyhow if this (or any other) error is returned. So remove tty_ldisc_ops::refcount completely and make tty_unregister_ldisc return 'void' in the next patches. That means we assume tty_unregister_ldisc is not called while the ldisc might be in use. That relies on try_module_get in get_ldops and module_put in put_ldops. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210505091928.22010-18-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 2 +- drivers/tty/tty_ldisc.c | 14 +++----------- include/linux/tty_ldisc.h | 2 -- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 2fe27905c398..0ec93f1a61f5 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -2450,7 +2450,7 @@ void n_tty_inherit_ops(struct tty_ldisc_ops *ops) { *ops = n_tty_ops; ops->owner = NULL; - ops->refcount = ops->flags = 0; + ops->flags = 0; } EXPORT_SYMBOL_GPL(n_tty_inherit_ops); diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index d02deeb5e584..98e8316fd28a 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -69,7 +69,6 @@ int tty_register_ldisc(struct tty_ldisc_ops *new_ldisc) raw_spin_lock_irqsave(&tty_ldiscs_lock, flags); tty_ldiscs[new_ldisc->num] = new_ldisc; - new_ldisc->refcount = 0; raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags); return ret; @@ -90,16 +89,12 @@ EXPORT_SYMBOL(tty_register_ldisc); int tty_unregister_ldisc(struct tty_ldisc_ops *ldisc) { unsigned long flags; - int ret = 0; raw_spin_lock_irqsave(&tty_ldiscs_lock, flags); - if (tty_ldiscs[ldisc->num]->refcount) - ret = -EBUSY; - else - tty_ldiscs[ldisc->num] = NULL; + tty_ldiscs[ldisc->num] = NULL; raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags); - return ret; + return 0; } EXPORT_SYMBOL(tty_unregister_ldisc); @@ -113,10 +108,8 @@ static struct tty_ldisc_ops *get_ldops(int disc) ldops = tty_ldiscs[disc]; if (ldops) { ret = ERR_PTR(-EAGAIN); - if (try_module_get(ldops->owner)) { - ldops->refcount++; + if (try_module_get(ldops->owner)) ret = ldops; - } } raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags); return ret; @@ -127,7 +120,6 @@ static void put_ldops(struct tty_ldisc_ops *ldops) unsigned long flags; raw_spin_lock_irqsave(&tty_ldiscs_lock, flags); - ldops->refcount--; module_put(ldops->owner); raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags); } diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h index c20ca6a75b4c..fbe9de278629 100644 --- a/include/linux/tty_ldisc.h +++ b/include/linux/tty_ldisc.h @@ -208,8 +208,6 @@ struct tty_ldisc_ops { const char *fp, int count); struct module *owner; - - int refcount; }; struct tty_ldisc { From 357a6a875f1c4772f2102639bf19619780889f31 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:19:11 +0200 Subject: [PATCH 041/227] tty: no checking of tty_unregister_ldisc tty_unregister_ldisc now returns 0 = success. No need to check the return value. In fact, the users only warned if an error occured and didn't do anything useful anyway -- the ldisc module was unloaded in any case. Signed-off-by: Jiri Slaby Cc: William Hubbs Cc: Chris Brannon Cc: Kirk Reiser Cc: Samuel Thibault Cc: Marcel Holtmann Cc: Johan Hedberg Cc: Luiz Augusto von Dentz Cc: Arnd Bergmann Cc: Wolfgang Grandegger Cc: Marc Kleine-Budde Cc: "David S. Miller" Cc: Jakub Kicinski Cc: Andreas Koensgen Cc: Paul Mackerras Cc: Rodolfo Giometti Cc: Peter Ujfalusi Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Link: https://lore.kernel.org/r/20210505091928.22010-19-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/accessibility/speakup/spk_ttyio.c | 3 +-- drivers/bluetooth/hci_ldisc.c | 7 +------ drivers/misc/ti-st/st_core.c | 12 +++--------- drivers/net/can/slcan.c | 4 +--- drivers/net/hamradio/6pack.c | 8 +------- drivers/net/hamradio/mkiss.c | 8 +------- drivers/net/ppp/ppp_async.c | 3 +-- drivers/net/ppp/ppp_synctty.c | 3 +-- drivers/net/slip/slip.c | 4 +--- drivers/pps/clients/pps-ldisc.c | 8 +------- drivers/tty/n_gsm.c | 5 +---- drivers/tty/n_hdlc.c | 8 +------- sound/soc/ti/ams-delta.c | 4 +--- 13 files changed, 15 insertions(+), 62 deletions(-) diff --git a/drivers/accessibility/speakup/spk_ttyio.c b/drivers/accessibility/speakup/spk_ttyio.c index 0b7f1a87eaeb..0d1f397cd896 100644 --- a/drivers/accessibility/speakup/spk_ttyio.c +++ b/drivers/accessibility/speakup/spk_ttyio.c @@ -219,8 +219,7 @@ void spk_ttyio_register_ldisc(void) void spk_ttyio_unregister_ldisc(void) { - if (tty_unregister_ldisc(&spk_ttyio_ldisc_ops)) - pr_warn("speakup: Couldn't unregister ldisc\n"); + tty_unregister_ldisc(&spk_ttyio_ldisc_ops); } static int spk_ttyio_out(struct spk_synth *in_synth, const char ch) diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 31e0c804363c..5ed2cfa7da1d 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -883,8 +883,6 @@ static int __init hci_uart_init(void) static void __exit hci_uart_exit(void) { - int err; - #ifdef CONFIG_BT_HCIUART_H4 h4_deinit(); #endif @@ -916,10 +914,7 @@ static void __exit hci_uart_exit(void) mrvl_deinit(); #endif - /* Release tty registration of line discipline */ - err = tty_unregister_ldisc(&hci_uart_ldisc); - if (err) - BT_ERR("Can't unregister HCI line discipline (%d)", err); + tty_unregister_ldisc(&hci_uart_ldisc); } module_init(hci_uart_init); diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index 174ae8e52805..85315e726644 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -872,9 +872,7 @@ int st_core_init(struct st_data_s **core_data) st_gdata = kzalloc(sizeof(struct st_data_s), GFP_KERNEL); if (!st_gdata) { pr_err("memory allocation failed"); - err = tty_unregister_ldisc(&st_ldisc_ops); - if (err) - pr_err("unable to un-register ldisc %ld", err); + tty_unregister_ldisc(&st_ldisc_ops); err = -ENOMEM; return err; } @@ -892,9 +890,7 @@ int st_core_init(struct st_data_s **core_data) if (err) { pr_err("error during st_ll initialization(%ld)", err); kfree(st_gdata); - err = tty_unregister_ldisc(&st_ldisc_ops); - if (err) - pr_err("unable to un-register ldisc"); + tty_unregister_ldisc(&st_ldisc_ops); return err; } @@ -919,9 +915,7 @@ void st_core_exit(struct st_data_s *st_gdata) kfree_skb(st_gdata->rx_skb); kfree_skb(st_gdata->tx_skb); /* TTY ldisc cleanup */ - err = tty_unregister_ldisc(&st_ldisc_ops); - if (err) - pr_err("unable to un-register ldisc %ld", err); + tty_unregister_ldisc(&st_ldisc_ops); /* free the global data pointer */ kfree(st_gdata); } diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index 03a2dbd3c367..d42ec7d1bc14 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -784,9 +784,7 @@ static void __exit slcan_exit(void) kfree(slcan_devs); slcan_devs = NULL; - i = tty_unregister_ldisc(&slc_ldisc); - if (i) - printk(KERN_ERR "slcan: can't unregister ldisc (err %d)\n", i); + tty_unregister_ldisc(&slc_ldisc); } module_init(slcan_init); diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index aac24f9caceb..686c38c46113 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -774,15 +774,9 @@ static int __init sixpack_init_driver(void) return status; } -static const char msg_unregfail[] = KERN_ERR \ - "6pack: can't unregister line discipline (err = %d)\n"; - static void __exit sixpack_exit_driver(void) { - int ret; - - if ((ret = tty_unregister_ldisc(&sp_ldisc))) - printk(msg_unregfail, ret); + tty_unregister_ldisc(&sp_ldisc); } /* encode an AX.25 packet into 6pack */ diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 750c6afc9302..e3294a0a9800 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -960,15 +960,9 @@ static int __init mkiss_init_driver(void) return status; } -static const char msg_unregfail[] = KERN_ERR \ - "mkiss: can't unregister line discipline (err = %d)\n"; - static void __exit mkiss_exit_driver(void) { - int ret; - - if ((ret = tty_unregister_ldisc(&ax_ldisc))) - printk(msg_unregfail, ret); + tty_unregister_ldisc(&ax_ldisc); } MODULE_AUTHOR("Ralf Baechle DL5RB "); diff --git a/drivers/net/ppp/ppp_async.c b/drivers/net/ppp/ppp_async.c index b2d454d01eba..29a93d6bfe37 100644 --- a/drivers/net/ppp/ppp_async.c +++ b/drivers/net/ppp/ppp_async.c @@ -1016,8 +1016,7 @@ static void async_lcp_peek(struct asyncppp *ap, unsigned char *data, static void __exit ppp_async_cleanup(void) { - if (tty_unregister_ldisc(&ppp_ldisc) != 0) - printk(KERN_ERR "failed to unregister PPP line discipline\n"); + tty_unregister_ldisc(&ppp_ldisc); } module_init(ppp_async_init); diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c index ca403bde56fb..af3e048695b6 100644 --- a/drivers/net/ppp/ppp_synctty.c +++ b/drivers/net/ppp/ppp_synctty.c @@ -727,8 +727,7 @@ err: static void __exit ppp_sync_cleanup(void) { - if (tty_unregister_ldisc(&ppp_sync_ldisc) != 0) - printk(KERN_ERR "failed to unregister Sync PPP line discipline\n"); + tty_unregister_ldisc(&ppp_sync_ldisc); } module_init(ppp_sync_init); diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c index 867efff40a0e..dc84cb844319 100644 --- a/drivers/net/slip/slip.c +++ b/drivers/net/slip/slip.c @@ -1360,9 +1360,7 @@ static void __exit slip_exit(void) kfree(slip_devs); slip_devs = NULL; - i = tty_unregister_ldisc(&sl_ldisc); - if (i != 0) - printk(KERN_ERR "SLIP: can't unregister line discipline (err = %d)\n", i); + tty_unregister_ldisc(&sl_ldisc); } module_init(slip_init); diff --git a/drivers/pps/clients/pps-ldisc.c b/drivers/pps/clients/pps-ldisc.c index 91b947f37774..d73c4c2ed4e1 100644 --- a/drivers/pps/clients/pps-ldisc.c +++ b/drivers/pps/clients/pps-ldisc.c @@ -129,13 +129,7 @@ static int __init pps_tty_init(void) static void __exit pps_tty_cleanup(void) { - int err; - - err = tty_unregister_ldisc(&pps_ldisc_ops); - if (err) - pr_err("can't unregister PPS line discipline\n"); - else - pr_info("PPS line discipline removed\n"); + tty_unregister_ldisc(&pps_ldisc_ops); } module_init(pps_tty_init); diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index db7d4a30af91..157b26ef6259 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -3286,10 +3286,7 @@ err_unreg_ldisc: static void __exit gsm_exit(void) { - int status = tty_unregister_ldisc(&tty_ldisc_packet); - if (status != 0) - pr_err("n_gsm: can't unregister line discipline (err = %d)\n", - status); + tty_unregister_ldisc(&tty_ldisc_packet); tty_unregister_driver(gsm_tty_driver); put_tty_driver(gsm_tty_driver); } diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index c2afbfe0a1d5..d899ee4e0116 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c @@ -822,13 +822,7 @@ static int __init n_hdlc_init(void) static void __exit n_hdlc_exit(void) { - int status = tty_unregister_ldisc(&n_hdlc_ldisc); - - if (status) - pr_err("N_HDLC: can't unregister line discipline (err = %d)\n", - status); - else - pr_info("N_HDLC: line discipline unregistered\n"); + tty_unregister_ldisc(&n_hdlc_ldisc); } module_init(n_hdlc_init); diff --git a/sound/soc/ti/ams-delta.c b/sound/soc/ti/ams-delta.c index e89548e48364..ecd24d412a9b 100644 --- a/sound/soc/ti/ams-delta.c +++ b/sound/soc/ti/ams-delta.c @@ -583,9 +583,7 @@ static int ams_delta_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); - if (tty_unregister_ldisc(&cx81801_ops) != 0) - dev_warn(&pdev->dev, - "failed to unregister V253 line discipline\n"); + tty_unregister_ldisc(&cx81801_ops); snd_soc_unregister_card(card); card->dev = NULL; From f6f19595a7efdaa0c196d7fa2b343b5588f94470 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:19:12 +0200 Subject: [PATCH 042/227] tty: return void from tty_unregister_ldisc Now that noone checks the return value of tty_unregister_ldisc, make the function return 'void'. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210505091928.22010-20-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 4 +--- include/linux/tty.h | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 98e8316fd28a..8edd73ab9148 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -86,15 +86,13 @@ EXPORT_SYMBOL(tty_register_ldisc); * takes tty_ldiscs_lock to guard against ldisc races */ -int tty_unregister_ldisc(struct tty_ldisc_ops *ldisc) +void tty_unregister_ldisc(struct tty_ldisc_ops *ldisc) { unsigned long flags; raw_spin_lock_irqsave(&tty_ldiscs_lock, flags); tty_ldiscs[ldisc->num] = NULL; raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags); - - return 0; } EXPORT_SYMBOL(tty_unregister_ldisc); diff --git a/include/linux/tty.h b/include/linux/tty.h index 6a72d0ff6391..e18a4f1ac39d 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -637,7 +637,7 @@ static inline int tty_port_users(struct tty_port *port) } extern int tty_register_ldisc(struct tty_ldisc_ops *new_ldisc); -extern int tty_unregister_ldisc(struct tty_ldisc_ops *ldisc); +extern void tty_unregister_ldisc(struct tty_ldisc_ops *ldisc); extern int tty_set_ldisc(struct tty_struct *tty, int disc); extern int tty_ldisc_receive_buf(struct tty_ldisc *ld, const unsigned char *p, const char *f, int count); From 303e8ebf5dcb802b016b2802825dbc7928f9a50a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:19:13 +0200 Subject: [PATCH 043/227] ti-st: use goto-failpath in st_core_init Use the classic failpath handling using gotos in st_core_init. That way, tty_unregister_ldisc needs not be repeated on two places. Signed-off-by: Jiri Slaby Cc: Arnd Bergmann Link: https://lore.kernel.org/r/20210505091928.22010-21-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ti-st/st_core.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index 85315e726644..05c015140cad 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -872,9 +872,8 @@ int st_core_init(struct st_data_s **core_data) st_gdata = kzalloc(sizeof(struct st_data_s), GFP_KERNEL); if (!st_gdata) { pr_err("memory allocation failed"); - tty_unregister_ldisc(&st_ldisc_ops); err = -ENOMEM; - return err; + goto err_unreg_ldisc; } /* Initialize ST TxQ and Tx waitQ queue head. All BT/FM/GPS module skb's @@ -889,15 +888,18 @@ int st_core_init(struct st_data_s **core_data) err = st_ll_init(st_gdata); if (err) { pr_err("error during st_ll initialization(%ld)", err); - kfree(st_gdata); - tty_unregister_ldisc(&st_ldisc_ops); - return err; + goto err_free_gdata; } INIT_WORK(&st_gdata->work_write_wakeup, work_fn_write_wakeup); *core_data = st_gdata; return 0; +err_free_gdata: + kfree(st_gdata); +err_unreg_ldisc: + tty_unregister_ldisc(&st_ldisc_ops); + return err; } void st_core_exit(struct st_data_s *st_gdata) From 0f29b503bd0b48ec6f14243f3626ac411c879555 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:19:14 +0200 Subject: [PATCH 044/227] ti-st: use tty_write_room Don't access tty->ops->write_room directly, use tty_write_room helper instead. Signed-off-by: Jiri Slaby Cc: Arnd Bergmann Link: https://lore.kernel.org/r/20210505091928.22010-22-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ti-st/st_core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index 05c015140cad..7f6976a9f508 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -52,13 +52,12 @@ static void remove_channel_from_table(struct st_data_s *st_gdata, */ int st_get_uart_wr_room(struct st_data_s *st_gdata) { - struct tty_struct *tty; if (unlikely(st_gdata == NULL || st_gdata->tty == NULL)) { pr_err("tty unavailable to perform write"); return -1; } - tty = st_gdata->tty; - return tty->ops->write_room(tty); + + return tty_write_room(st_gdata->tty); } /* From 03b3b1a2405ccd71570cd5ec1fe4abd7bb4891cb Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:19:15 +0200 Subject: [PATCH 045/227] tty: make tty_operations::write_room return uint Line disciplines expect a positive value or zero returned from tty->ops->write_room (invoked by tty_write_room). So make this assumption explicit by using unsigned int as a return value. Both of tty->ops->write_room and tty_write_room. Signed-off-by: Jiri Slaby Acked-by: Laurentiu Tudor Acked-by: Alex Elder Acked-by: Max Filippov # xtensa Acked-by: David Sterba Acked-By: Anton Ivanov Acked-by: Geert Uytterhoeven Cc: Richard Henderson Cc: Ivan Kokshaysky Cc: Matt Turner Cc: "James E.J. Bottomley" Cc: Helge Deller Cc: Jeff Dike Cc: Richard Weinberger Cc: Chris Zankel Cc: Arnd Bergmann Cc: Samuel Iglesias Gonsalvez Cc: Jens Taprogge Cc: Karsten Keil Cc: Scott Branden Cc: Ulf Hansson Cc: "David S. Miller" Cc: Jakub Kicinski Cc: Heiko Carstens Cc: Vasily Gorbik Cc: Christian Borntraeger Cc: David Lin Cc: Johan Hovold Cc: Jiri Kosina Cc: Shawn Guo Cc: Sascha Hauer Cc: Oliver Neukum Cc: Felipe Balbi Cc: Mathias Nyman Cc: Marcel Holtmann Cc: Johan Hedberg Cc: Luiz Augusto von Dentz Link: https://lore.kernel.org/r/20210505091928.22010-23-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- arch/alpha/kernel/srmcons.c | 2 +- arch/m68k/emu/nfcon.c | 2 +- arch/parisc/kernel/pdc_cons.c | 2 +- arch/um/drivers/line.c | 6 +++--- arch/um/drivers/line.h | 2 +- arch/xtensa/platforms/iss/console.c | 2 +- drivers/char/pcmcia/synclink_cs.c | 2 +- drivers/char/ttyprintk.c | 2 +- drivers/ipack/devices/ipoctal.c | 2 +- drivers/isdn/capi/capi.c | 6 +++--- drivers/misc/bcm-vk/bcm_vk_tty.c | 2 +- drivers/mmc/core/sdio_uart.c | 2 +- drivers/net/usb/hso.c | 4 ++-- drivers/s390/char/con3215.c | 2 +- drivers/s390/char/sclp_tty.c | 4 ++-- drivers/s390/char/sclp_vt220.c | 4 ++-- drivers/s390/char/tty3270.c | 2 +- drivers/staging/fwserial/fwserial.c | 6 +++--- drivers/staging/gdm724x/gdm_tty.c | 2 +- drivers/staging/greybus/uart.c | 2 +- drivers/tty/amiserial.c | 2 +- drivers/tty/ehv_bytechan.c | 4 ++-- drivers/tty/goldfish.c | 2 +- drivers/tty/hvc/hvc_console.c | 2 +- drivers/tty/hvc/hvcs.c | 2 +- drivers/tty/hvc/hvsi.c | 4 ++-- drivers/tty/ipwireless/tty.c | 2 +- drivers/tty/mips_ejtag_fdc.c | 4 ++-- drivers/tty/moxa.c | 8 ++++---- drivers/tty/mxser.c | 2 +- drivers/tty/n_gsm.c | 2 +- drivers/tty/nozomi.c | 4 ++-- drivers/tty/pty.c | 2 +- drivers/tty/serial/kgdb_nmi.c | 2 +- drivers/tty/serial/serial_core.c | 4 ++-- drivers/tty/synclink_gt.c | 6 +++--- drivers/tty/tty_ioctl.c | 2 +- drivers/tty/ttynull.c | 2 +- drivers/tty/vcc.c | 4 ++-- drivers/tty/vt/vt.c | 2 +- drivers/usb/class/cdc-acm.c | 2 +- drivers/usb/gadget/function/u_serial.c | 6 +++--- drivers/usb/host/xhci-dbgtty.c | 4 ++-- drivers/usb/serial/usb-serial.c | 2 +- include/linux/tty.h | 2 +- include/linux/tty_driver.h | 4 ++-- net/bluetooth/rfcomm/tty.c | 2 +- 47 files changed, 71 insertions(+), 71 deletions(-) diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c index 438b10c44d73..2110b7e7f988 100644 --- a/arch/alpha/kernel/srmcons.c +++ b/arch/alpha/kernel/srmcons.c @@ -142,7 +142,7 @@ srmcons_write(struct tty_struct *tty, return count; } -static int +static unsigned int srmcons_write_room(struct tty_struct *tty) { return 512; diff --git a/arch/m68k/emu/nfcon.c b/arch/m68k/emu/nfcon.c index 57e8c8fb5eba..92636c89d65b 100644 --- a/arch/m68k/emu/nfcon.c +++ b/arch/m68k/emu/nfcon.c @@ -85,7 +85,7 @@ static int nfcon_tty_put_char(struct tty_struct *tty, unsigned char ch) return 1; } -static int nfcon_tty_write_room(struct tty_struct *tty) +static unsigned int nfcon_tty_write_room(struct tty_struct *tty) { return 64; } diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c index 7ed404c60a9e..fe2ed0bbd07e 100644 --- a/arch/parisc/kernel/pdc_cons.c +++ b/arch/parisc/kernel/pdc_cons.c @@ -103,7 +103,7 @@ static int pdc_console_tty_write(struct tty_struct *tty, const unsigned char *bu return count; } -static int pdc_console_tty_write_room(struct tty_struct *tty) +static unsigned int pdc_console_tty_write_room(struct tty_struct *tty) { return 32768; /* no limit, no buffer used */ } diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 1c70a31e7c5b..2b8810ba5470 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -32,7 +32,7 @@ static irqreturn_t line_interrupt(int irq, void *data) * * Should be called while holding line->lock (this does not modify data). */ -static int write_room(struct line *line) +static unsigned int write_room(struct line *line) { int n; @@ -47,11 +47,11 @@ static int write_room(struct line *line) return n - 1; } -int line_write_room(struct tty_struct *tty) +unsigned int line_write_room(struct tty_struct *tty) { struct line *line = tty->driver_data; unsigned long flags; - int room; + unsigned int room; spin_lock_irqsave(&line->lock, flags); room = write_room(line); diff --git a/arch/um/drivers/line.h b/arch/um/drivers/line.h index 01d21e76144f..861edf329569 100644 --- a/arch/um/drivers/line.h +++ b/arch/um/drivers/line.h @@ -70,7 +70,7 @@ extern void line_set_termios(struct tty_struct *tty, struct ktermios * old); extern int line_chars_in_buffer(struct tty_struct *tty); extern void line_flush_buffer(struct tty_struct *tty); extern void line_flush_chars(struct tty_struct *tty); -extern int line_write_room(struct tty_struct *tty); +extern unsigned int line_write_room(struct tty_struct *tty); extern void line_throttle(struct tty_struct *tty); extern void line_unthrottle(struct tty_struct *tty); diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c index a3dda25a4e45..98ac3a7fdb0a 100644 --- a/arch/xtensa/platforms/iss/console.c +++ b/arch/xtensa/platforms/iss/console.c @@ -100,7 +100,7 @@ static void rs_flush_chars(struct tty_struct *tty) { } -static int rs_write_room(struct tty_struct *tty) +static unsigned int rs_write_room(struct tty_struct *tty) { /* Let's say iss can always accept 2K characters.. */ return 2 * 1024; diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index b4707bc3aee8..e4b2c68f44f5 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -1609,7 +1609,7 @@ cleanup: /* Return the count of free bytes in transmit buffer */ -static int mgslpc_write_room(struct tty_struct *tty) +static unsigned int mgslpc_write_room(struct tty_struct *tty) { MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data; int ret; diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c index 93f5d11c830b..e93b0af92339 100644 --- a/drivers/char/ttyprintk.c +++ b/drivers/char/ttyprintk.c @@ -132,7 +132,7 @@ static int tpk_write(struct tty_struct *tty, /* * TTY operations write_room function. */ -static int tpk_write_room(struct tty_struct *tty) +static unsigned int tpk_write_room(struct tty_struct *tty) { return TPK_MAX_ROOM; } diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c index 3940714e4397..ea0f1aeaaa06 100644 --- a/drivers/ipack/devices/ipoctal.c +++ b/drivers/ipack/devices/ipoctal.c @@ -460,7 +460,7 @@ static int ipoctal_write_tty(struct tty_struct *tty, return char_copied; } -static int ipoctal_write_room(struct tty_struct *tty) +static unsigned int ipoctal_write_room(struct tty_struct *tty) { struct ipoctal_channel *channel = tty->driver_data; diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index fdf87acccd06..c50c454006b3 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -1175,14 +1175,14 @@ static void capinc_tty_flush_chars(struct tty_struct *tty) handle_minor_recv(mp); } -static int capinc_tty_write_room(struct tty_struct *tty) +static unsigned int capinc_tty_write_room(struct tty_struct *tty) { struct capiminor *mp = tty->driver_data; - int room; + unsigned int room; room = CAPINC_MAX_SENDQUEUE-skb_queue_len(&mp->outqueue); room *= CAPI_MAX_BLKSIZE; - pr_debug("capinc_tty_write_room = %d\n", room); + pr_debug("capinc_tty_write_room = %u\n", room); return room; } diff --git a/drivers/misc/bcm-vk/bcm_vk_tty.c b/drivers/misc/bcm-vk/bcm_vk_tty.c index 4d02692ecfc7..dae9eeed84a2 100644 --- a/drivers/misc/bcm-vk/bcm_vk_tty.c +++ b/drivers/misc/bcm-vk/bcm_vk_tty.c @@ -214,7 +214,7 @@ static int bcm_vk_tty_write(struct tty_struct *tty, return count; } -static int bcm_vk_tty_write_room(struct tty_struct *tty) +static unsigned int bcm_vk_tty_write_room(struct tty_struct *tty) { struct bcm_vk *vk = dev_get_drvdata(tty->dev); diff --git a/drivers/mmc/core/sdio_uart.c b/drivers/mmc/core/sdio_uart.c index dbcac2b7f2fe..c8f4eca7aad4 100644 --- a/drivers/mmc/core/sdio_uart.c +++ b/drivers/mmc/core/sdio_uart.c @@ -797,7 +797,7 @@ static int sdio_uart_write(struct tty_struct *tty, const unsigned char *buf, return ret; } -static int sdio_uart_write_room(struct tty_struct *tty) +static unsigned int sdio_uart_write_room(struct tty_struct *tty) { struct sdio_uart_port *port = tty->driver_data; return FIFO_SIZE - kfifo_len(&port->xmit_fifo); diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 3ef4b2841402..bb8bb85308ab 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1357,10 +1357,10 @@ out: } /* how much room is there for writing */ -static int hso_serial_write_room(struct tty_struct *tty) +static unsigned int hso_serial_write_room(struct tty_struct *tty) { struct hso_serial *serial = tty->driver_data; - int room; + unsigned int room; unsigned long flags; spin_lock_irqsave(&serial->serial_lock, flags); diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 1fd5bca9fa20..c9fd4a05931a 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -924,7 +924,7 @@ static void tty3215_close(struct tty_struct *tty, struct file * filp) /* * Returns the amount of free space in the output buffer. */ -static int tty3215_write_room(struct tty_struct *tty) +static unsigned int tty3215_write_room(struct tty_struct *tty) { struct raw3215_info *raw = tty->driver_data; diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index 4456ceb23bd2..ea1e43fd16bc 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c @@ -86,12 +86,12 @@ sclp_tty_close(struct tty_struct *tty, struct file *filp) * a string of newlines. Every newline creates a new message which * needs 82 bytes. */ -static int +static unsigned int sclp_tty_write_room (struct tty_struct *tty) { unsigned long flags; struct list_head *l; - int count; + unsigned int count; spin_lock_irqsave(&sclp_tty_lock, flags); count = 0; diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index 7f4445b0f819..b621adee35f0 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -609,12 +609,12 @@ sclp_vt220_flush_chars(struct tty_struct *tty) * to change as output buffers get emptied, or if the output flow * control is acted. */ -static int +static unsigned int sclp_vt220_write_room(struct tty_struct *tty) { unsigned long flags; struct list_head *l; - int count; + unsigned int count; spin_lock_irqsave(&sclp_vt220_lock, flags); count = 0; diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index 1b68564799fa..82d4c961ed06 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -1071,7 +1071,7 @@ static void tty3270_cleanup(struct tty_struct *tty) /* * We always have room. */ -static int +static unsigned int tty3270_write_room(struct tty_struct *tty) { return INT_MAX; diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index 4245532d2fe0..a151cd76d24e 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c @@ -1113,16 +1113,16 @@ static int fwtty_write(struct tty_struct *tty, const unsigned char *buf, int c) return (n < 0) ? 0 : n; } -static int fwtty_write_room(struct tty_struct *tty) +static unsigned int fwtty_write_room(struct tty_struct *tty) { struct fwtty_port *port = tty->driver_data; - int n; + unsigned int n; spin_lock_bh(&port->lock); n = dma_fifo_avail(&port->tx_fifo); spin_unlock_bh(&port->lock); - fwtty_dbg(port, "%d\n", n); + fwtty_dbg(port, "%u\n", n); return n; } diff --git a/drivers/staging/gdm724x/gdm_tty.c b/drivers/staging/gdm724x/gdm_tty.c index 0ccc8c24e754..279de2cd9c4a 100644 --- a/drivers/staging/gdm724x/gdm_tty.c +++ b/drivers/staging/gdm724x/gdm_tty.c @@ -183,7 +183,7 @@ static int gdm_tty_write(struct tty_struct *tty, const unsigned char *buf, return len; } -static int gdm_tty_write_room(struct tty_struct *tty) +static unsigned int gdm_tty_write_room(struct tty_struct *tty) { struct gdm *gdm = tty->driver_data; diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c index b1e63f7798b0..529eccb99b6c 100644 --- a/drivers/staging/greybus/uart.c +++ b/drivers/staging/greybus/uart.c @@ -440,7 +440,7 @@ static int gb_tty_write(struct tty_struct *tty, const unsigned char *buf, return count; } -static int gb_tty_write_room(struct tty_struct *tty) +static unsigned int gb_tty_write_room(struct tty_struct *tty) { struct gb_tty *gb_tty = tty->driver_data; unsigned long flags; diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index a4b8876091d2..ee1f4d72cd5e 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -827,7 +827,7 @@ static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count return ret; } -static int rs_write_room(struct tty_struct *tty) +static unsigned int rs_write_room(struct tty_struct *tty) { struct serial_state *info = tty->driver_data; diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index 3c6dd06ec5fb..445e5ff9b36d 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c @@ -536,11 +536,11 @@ static void ehv_bc_tty_close(struct tty_struct *ttys, struct file *filp) * how much write room the driver can guarantee will be sent OR BUFFERED. This * driver MUST honor the return value. */ -static int ehv_bc_tty_write_room(struct tty_struct *ttys) +static unsigned int ehv_bc_tty_write_room(struct tty_struct *ttys) { struct ehv_bc_data *bc = ttys->driver_data; unsigned long flags; - int count; + unsigned int count; spin_lock_irqsave(&bc->lock, flags); count = CIRC_SPACE(bc->head, bc->tail, BUF_SIZE); diff --git a/drivers/tty/goldfish.c b/drivers/tty/goldfish.c index cd23a4b05c8f..e4f9a60dcc18 100644 --- a/drivers/tty/goldfish.c +++ b/drivers/tty/goldfish.c @@ -193,7 +193,7 @@ static int goldfish_tty_write(struct tty_struct *tty, const unsigned char *buf, return count; } -static int goldfish_tty_write_room(struct tty_struct *tty) +static unsigned int goldfish_tty_write_room(struct tty_struct *tty) { return 0x10000; } diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index cdcc64ea2554..a3725eb69cd3 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c @@ -586,7 +586,7 @@ static void hvc_set_winsz(struct work_struct *work) * how much write room the driver can guarantee will be sent OR BUFFERED. This * driver MUST honor the return value. */ -static int hvc_write_room(struct tty_struct *tty) +static unsigned int hvc_write_room(struct tty_struct *tty) { struct hvc_struct *hp = tty->driver_data; diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index 197988c55e0c..f43f2f94d8bd 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c @@ -1376,7 +1376,7 @@ static int hvcs_write(struct tty_struct *tty, * absolutely WILL BUFFER if we can't send it. This driver MUST honor the * return value, hence the reason for hvcs_struct buffering. */ -static int hvcs_write_room(struct tty_struct *tty) +static unsigned int hvcs_write_room(struct tty_struct *tty) { struct hvcs_struct *hvcsd = tty->driver_data; diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index e8c58f9bd263..0a56f44e6b12 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c @@ -890,7 +890,7 @@ out: spin_unlock_irqrestore(&hp->lock, flags); } -static int hvsi_write_room(struct tty_struct *tty) +static unsigned int hvsi_write_room(struct tty_struct *tty) { struct hvsi_struct *hp = tty->driver_data; @@ -929,7 +929,7 @@ static int hvsi_write(struct tty_struct *tty, * will see there is no room in outbuf and return. */ while ((count > 0) && (hvsi_write_room(tty) > 0)) { - int chunksize = min(count, hvsi_write_room(tty)); + int chunksize = min_t(int, count, hvsi_write_room(tty)); BUG_ON(hp->n_outbuf < 0); memcpy(hp->outbuf + hp->n_outbuf, source, chunksize); diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c index 99bb2f149ff5..ab562838313b 100644 --- a/drivers/tty/ipwireless/tty.c +++ b/drivers/tty/ipwireless/tty.c @@ -228,7 +228,7 @@ static int ipw_write(struct tty_struct *linux_tty, return count; } -static int ipw_write_room(struct tty_struct *linux_tty) +static unsigned int ipw_write_room(struct tty_struct *linux_tty) { struct ipw_tty *tty = linux_tty->driver_data; int room; diff --git a/drivers/tty/mips_ejtag_fdc.c b/drivers/tty/mips_ejtag_fdc.c index a8e19b4833bf..f427e8e154d7 100644 --- a/drivers/tty/mips_ejtag_fdc.c +++ b/drivers/tty/mips_ejtag_fdc.c @@ -840,11 +840,11 @@ static int mips_ejtag_fdc_tty_write(struct tty_struct *tty, return total; } -static int mips_ejtag_fdc_tty_write_room(struct tty_struct *tty) +static unsigned int mips_ejtag_fdc_tty_write_room(struct tty_struct *tty) { struct mips_ejtag_fdc_tty_port *dport = tty->driver_data; struct mips_ejtag_fdc_tty *priv = dport->driver; - int room; + unsigned int room; /* Report the space in the xmit buffer */ spin_lock(&dport->xmit_lock); diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index 847ad3dac107..e4fe9315de29 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c @@ -188,7 +188,7 @@ module_param(ttymajor, int, 0); static int moxa_open(struct tty_struct *, struct file *); static void moxa_close(struct tty_struct *, struct file *); static int moxa_write(struct tty_struct *, const unsigned char *, int); -static int moxa_write_room(struct tty_struct *); +static unsigned int moxa_write_room(struct tty_struct *); static void moxa_flush_buffer(struct tty_struct *); static int moxa_chars_in_buffer(struct tty_struct *); static void moxa_set_termios(struct tty_struct *, struct ktermios *); @@ -218,7 +218,7 @@ static int MoxaPortWriteData(struct tty_struct *, const unsigned char *, int); static int MoxaPortReadData(struct moxa_port *); static int MoxaPortTxQueue(struct moxa_port *); static int MoxaPortRxQueue(struct moxa_port *); -static int MoxaPortTxFree(struct moxa_port *); +static unsigned int MoxaPortTxFree(struct moxa_port *); static void MoxaPortTxDisable(struct moxa_port *); static void MoxaPortTxEnable(struct moxa_port *); static int moxa_get_serial_info(struct tty_struct *, struct serial_struct *); @@ -1217,7 +1217,7 @@ static int moxa_write(struct tty_struct *tty, return len; } -static int moxa_write_room(struct tty_struct *tty) +static unsigned int moxa_write_room(struct tty_struct *tty) { struct moxa_port *ch; @@ -1992,7 +1992,7 @@ static int MoxaPortTxQueue(struct moxa_port *port) return (wptr - rptr) & mask; } -static int MoxaPortTxFree(struct moxa_port *port) +static unsigned int MoxaPortTxFree(struct moxa_port *port) { void __iomem *ofsAddr = port->tableAddr; u16 rptr, wptr, mask; diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 85271e109014..5851a45d828c 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -1183,7 +1183,7 @@ static void mxser_flush_chars(struct tty_struct *tty) spin_unlock_irqrestore(&info->slock, flags); } -static int mxser_write_room(struct tty_struct *tty) +static unsigned int mxser_write_room(struct tty_struct *tty) { struct mxser_port *info = tty->driver_data; int ret; diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 157b26ef6259..06f0c6d39620 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -3056,7 +3056,7 @@ static int gsmtty_write(struct tty_struct *tty, const unsigned char *buf, return sent; } -static int gsmtty_write_room(struct tty_struct *tty) +static unsigned int gsmtty_write_room(struct tty_struct *tty) { struct gsm_dlci *dlci = tty->driver_data; if (dlci->state == DLCI_CLOSED) diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index 9a2d78ace49b..c55475a9a184 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c @@ -1636,10 +1636,10 @@ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer, * If the port is unplugged report lots of room and let the bits * dribble away so we don't block anything. */ -static int ntty_write_room(struct tty_struct *tty) +static unsigned int ntty_write_room(struct tty_struct *tty) { struct port *port = tty->driver_data; - int room = 4096; + unsigned int room = 4096; const struct nozomi *dc = get_dc_by_tty(tty); if (dc) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 3e7b5c811f9b..eb8556b19592 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -136,7 +136,7 @@ static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c) * the other device. */ -static int pty_write_room(struct tty_struct *tty) +static unsigned int pty_write_room(struct tty_struct *tty) { if (tty->flow.stopped) return 0; diff --git a/drivers/tty/serial/kgdb_nmi.c b/drivers/tty/serial/kgdb_nmi.c index db059b66438e..b193bbc666d4 100644 --- a/drivers/tty/serial/kgdb_nmi.c +++ b/drivers/tty/serial/kgdb_nmi.c @@ -298,7 +298,7 @@ static void kgdb_nmi_tty_hangup(struct tty_struct *tty) tty_port_hangup(&priv->port); } -static int kgdb_nmi_tty_write_room(struct tty_struct *tty) +static unsigned int kgdb_nmi_tty_write_room(struct tty_struct *tty) { /* Actually, we can handle any amount as we use polled writes. */ return 2048; diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 87f7127b57e6..cb46a65a5dd8 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -616,12 +616,12 @@ static int uart_write(struct tty_struct *tty, return ret; } -static int uart_write_room(struct tty_struct *tty) +static unsigned int uart_write_room(struct tty_struct *tty) { struct uart_state *state = tty->driver_data; struct uart_port *port; unsigned long flags; - int ret; + unsigned int ret; port = uart_port_lock(state, flags); ret = uart_circ_chars_free(&state->xmit); diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index 1555dccc28af..583aa8342112 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -868,15 +868,15 @@ exit: DBGINFO(("%s wait_until_sent exit\n", info->device_name)); } -static int write_room(struct tty_struct *tty) +static unsigned int write_room(struct tty_struct *tty) { struct slgt_info *info = tty->driver_data; - int ret; + unsigned int ret; if (sanity_check(info, tty->name, "write_room")) return 0; ret = (info->tx_active) ? 0 : HDLC_MAX_FRAME_SIZE; - DBGINFO(("%s write_room=%d\n", info->device_name, ret)); + DBGINFO(("%s write_room=%u\n", info->device_name, ret)); return ret; } diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 07c88ccfb17a..d8834784b586 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -73,7 +73,7 @@ EXPORT_SYMBOL(tty_chars_in_buffer); * returned and data may be lost as there will be no flow control. */ -int tty_write_room(struct tty_struct *tty) +unsigned int tty_write_room(struct tty_struct *tty) { if (tty->ops->write_room) return tty->ops->write_room(tty); diff --git a/drivers/tty/ttynull.c b/drivers/tty/ttynull.c index 17f05b7eb6d3..af3311a24917 100644 --- a/drivers/tty/ttynull.c +++ b/drivers/tty/ttynull.c @@ -35,7 +35,7 @@ static int ttynull_write(struct tty_struct *tty, const unsigned char *buf, return count; } -static int ttynull_write_room(struct tty_struct *tty) +static unsigned int ttynull_write_room(struct tty_struct *tty) { return 65536; } diff --git a/drivers/tty/vcc.c b/drivers/tty/vcc.c index 0a3a71e14df4..d82ce3bb82c3 100644 --- a/drivers/tty/vcc.c +++ b/drivers/tty/vcc.c @@ -870,10 +870,10 @@ static int vcc_write(struct tty_struct *tty, const unsigned char *buf, return total_sent ? total_sent : rv; } -static int vcc_write_room(struct tty_struct *tty) +static unsigned int vcc_write_room(struct tty_struct *tty) { struct vcc_port *port; - u64 num; + unsigned int num; port = vcc_get_ne(tty->index); if (unlikely(!port)) { diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 706f066eb711..96c130714930 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -3263,7 +3263,7 @@ static int con_put_char(struct tty_struct *tty, unsigned char ch) return do_con_write(tty, &ch, 1); } -static int con_write_room(struct tty_struct *tty) +static unsigned int con_write_room(struct tty_struct *tty) { if (tty->flow.stopped) return 0; diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index ca7a61190dd9..76b7fd234238 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -838,7 +838,7 @@ static int acm_tty_write(struct tty_struct *tty, return count; } -static int acm_tty_write_room(struct tty_struct *tty) +static unsigned int acm_tty_write_room(struct tty_struct *tty) { struct acm *acm = tty->driver_data; /* diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index 1e59204ec7aa..676a920d9d6b 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -774,18 +774,18 @@ static void gs_flush_chars(struct tty_struct *tty) spin_unlock_irqrestore(&port->port_lock, flags); } -static int gs_write_room(struct tty_struct *tty) +static unsigned int gs_write_room(struct tty_struct *tty) { struct gs_port *port = tty->driver_data; unsigned long flags; - int room = 0; + unsigned int room = 0; spin_lock_irqsave(&port->port_lock, flags); if (port->port_usb) room = kfifo_avail(&port->port_write_buf); spin_unlock_irqrestore(&port->port_lock, flags); - pr_vdebug("gs_write_room: (%d,%p) room=%d\n", + pr_vdebug("gs_write_room: (%d,%p) room=%u\n", port->port_num, tty, room); return room; diff --git a/drivers/usb/host/xhci-dbgtty.c b/drivers/usb/host/xhci-dbgtty.c index ae4e4ab638b5..cd3ab35dd689 100644 --- a/drivers/usb/host/xhci-dbgtty.c +++ b/drivers/usb/host/xhci-dbgtty.c @@ -240,11 +240,11 @@ static void dbc_tty_flush_chars(struct tty_struct *tty) spin_unlock_irqrestore(&port->port_lock, flags); } -static int dbc_tty_write_room(struct tty_struct *tty) +static unsigned int dbc_tty_write_room(struct tty_struct *tty) { struct dbc_port *port = tty->driver_data; unsigned long flags; - int room = 0; + unsigned int room; spin_lock_irqsave(&port->port_lock, flags); room = kfifo_avail(&port->write_fifo); diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 98b33b1b5357..055096831daf 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -376,7 +376,7 @@ exit: return retval; } -static int serial_write_room(struct tty_struct *tty) +static unsigned int serial_write_room(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; diff --git a/include/linux/tty.h b/include/linux/tty.h index e18a4f1ac39d..d18fc34d3054 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -459,7 +459,7 @@ extern void tty_write_message(struct tty_struct *tty, char *msg); extern int tty_send_xchar(struct tty_struct *tty, char ch); extern int tty_put_char(struct tty_struct *tty, unsigned char c); extern int tty_chars_in_buffer(struct tty_struct *tty); -extern int tty_write_room(struct tty_struct *tty); +extern unsigned int tty_write_room(struct tty_struct *tty); extern void tty_driver_flush_buffer(struct tty_struct *tty); extern void tty_throttle(struct tty_struct *tty); extern void tty_unthrottle(struct tty_struct *tty); diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index 653fa5af3a22..ea5b15c72764 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -89,7 +89,7 @@ * * Note: Do not call this function directly, call tty_driver_flush_chars * - * int (*write_room)(struct tty_struct *tty); + * unsigned int (*write_room)(struct tty_struct *tty); * * This routine returns the numbers of characters the tty driver * will accept for queuing to be written. This number is subject @@ -256,7 +256,7 @@ struct tty_operations { const unsigned char *buf, int count); int (*put_char)(struct tty_struct *tty, unsigned char ch); void (*flush_chars)(struct tty_struct *tty); - int (*write_room)(struct tty_struct *tty); + unsigned int (*write_room)(struct tty_struct *tty); int (*chars_in_buffer)(struct tty_struct *tty); int (*ioctl)(struct tty_struct *tty, unsigned int cmd, unsigned long arg); diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index a58584949a95..a5e3d957f20f 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -807,7 +807,7 @@ static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, in return sent; } -static int rfcomm_tty_write_room(struct tty_struct *tty) +static unsigned int rfcomm_tty_write_room(struct tty_struct *tty) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; int room = 0; From 9a33fbf9d23034d7e89849c587b0aed0e4cf794d Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:19:17 +0200 Subject: [PATCH 046/227] tty: make tty_buffer_space_avail return uint tty_buffer_space_avail returns values >= 0, so make it clear by the return type. Signed-off-by: Jiri Slaby Cc: Joel Stanley Link: https://lore.kernel.org/r/20210505091928.22010-25-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_aspeed_vuart.c | 4 ++-- drivers/tty/tty_buffer.c | 2 +- include/linux/tty_flip.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/8250/8250_aspeed_vuart.c b/drivers/tty/serial/8250/8250_aspeed_vuart.c index 2bf1d8582d9a..a28a394ba32a 100644 --- a/drivers/tty/serial/8250/8250_aspeed_vuart.c +++ b/drivers/tty/serial/8250/8250_aspeed_vuart.c @@ -329,7 +329,7 @@ static int aspeed_vuart_handle_irq(struct uart_port *port) { struct uart_8250_port *up = up_to_u8250p(port); unsigned int iir, lsr; - int space, count; + unsigned int space, count; iir = serial_port_in(port, UART_IIR); @@ -353,7 +353,7 @@ static int aspeed_vuart_handle_irq(struct uart_port *port) jiffies + unthrottle_timeout); } else { - count = min(space, 256); + count = min(space, 256U); do { serial8250_read_char(up, lsr); diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 55b1f1711341..585a19f65284 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -88,7 +88,7 @@ EXPORT_SYMBOL_GPL(tty_buffer_unlock_exclusive); * pre-allocate if memory guarantee is required). */ -int tty_buffer_space_avail(struct tty_port *port) +unsigned int tty_buffer_space_avail(struct tty_port *port) { int space = port->buf.mem_limit - atomic_read(&port->buf.mem_used); return max(space, 0); diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h index 767f62086bd9..d6729281ec50 100644 --- a/include/linux/tty_flip.h +++ b/include/linux/tty_flip.h @@ -3,7 +3,7 @@ #define _LINUX_TTY_FLIP_H extern int tty_buffer_set_limit(struct tty_port *port, int limit); -extern int tty_buffer_space_avail(struct tty_port *port); +extern unsigned int tty_buffer_space_avail(struct tty_port *port); extern int tty_buffer_request_room(struct tty_port *port, size_t size); extern int tty_insert_flip_string_flags(struct tty_port *port, const unsigned char *chars, const char *flags, size_t size); From fa7501e57e9bf869cb6718a2699f05fc2807cbf1 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:19:18 +0200 Subject: [PATCH 047/227] tty: remove tty_operations::chars_in_buffer for non-buffering The only user of tty_ops::chars_in_buffer is tty_chars_in_buffer. And it considers tty_ops::chars_in_buffer optional. In case it's NULL, zero is returned. So remove all those chars_in_buffer from tty_ops which return zero. (Zero means such driver doesn't buffer.) Signed-off-by: Jiri Slaby Cc: Richard Henderson Acked-by: Max Filippov # xtensa Cc: Ivan Kokshaysky Cc: Matt Turner Cc: "James E.J. Bottomley" Cc: Helge Deller Cc: Chris Zankel Cc: Heiko Carstens Cc: Vasily Gorbik Cc: Christian Borntraeger Link: https://lore.kernel.org/r/20210505091928.22010-26-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- arch/alpha/kernel/srmcons.c | 7 ------- arch/parisc/kernel/pdc_cons.c | 6 ------ arch/xtensa/platforms/iss/console.c | 7 ------- drivers/s390/char/tty3270.c | 12 ------------ drivers/tty/pty.c | 17 ----------------- drivers/tty/vt/vt.c | 6 ------ 6 files changed, 55 deletions(-) diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c index 2110b7e7f988..fc03471a0b0f 100644 --- a/arch/alpha/kernel/srmcons.c +++ b/arch/alpha/kernel/srmcons.c @@ -148,12 +148,6 @@ srmcons_write_room(struct tty_struct *tty) return 512; } -static int -srmcons_chars_in_buffer(struct tty_struct *tty) -{ - return 0; -} - static int srmcons_open(struct tty_struct *tty, struct file *filp) { @@ -200,7 +194,6 @@ static const struct tty_operations srmcons_ops = { .close = srmcons_close, .write = srmcons_write, .write_room = srmcons_write_room, - .chars_in_buffer= srmcons_chars_in_buffer, }; static int __init diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c index fe2ed0bbd07e..39ccad063533 100644 --- a/arch/parisc/kernel/pdc_cons.c +++ b/arch/parisc/kernel/pdc_cons.c @@ -108,17 +108,11 @@ static unsigned int pdc_console_tty_write_room(struct tty_struct *tty) return 32768; /* no limit, no buffer used */ } -static int pdc_console_tty_chars_in_buffer(struct tty_struct *tty) -{ - return 0; /* no buffer */ -} - static const struct tty_operations pdc_console_tty_ops = { .open = pdc_console_tty_open, .close = pdc_console_tty_close, .write = pdc_console_tty_write, .write_room = pdc_console_tty_write_room, - .chars_in_buffer = pdc_console_tty_chars_in_buffer, }; static void pdc_console_poll(struct timer_list *unused) diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c index 98ac3a7fdb0a..21184488c277 100644 --- a/arch/xtensa/platforms/iss/console.c +++ b/arch/xtensa/platforms/iss/console.c @@ -106,12 +106,6 @@ static unsigned int rs_write_room(struct tty_struct *tty) return 2 * 1024; } -static int rs_chars_in_buffer(struct tty_struct *tty) -{ - /* the iss doesn't buffer characters */ - return 0; -} - static void rs_hangup(struct tty_struct *tty) { /* Stub, once again.. */ @@ -135,7 +129,6 @@ static const struct tty_operations serial_ops = { .put_char = rs_put_char, .flush_chars = rs_flush_chars, .write_room = rs_write_room, - .chars_in_buffer = rs_chars_in_buffer, .hangup = rs_hangup, .wait_until_sent = rs_wait_until_sent, .proc_show = rs_proc_show, diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index 82d4c961ed06..ba1fbce63fee 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -1756,17 +1756,6 @@ tty3270_flush_chars(struct tty_struct *tty) } } -/* - * Returns the number of characters in the output buffer. This is - * used in tty_wait_until_sent to wait until all characters have - * appeared on the screen. - */ -static int -tty3270_chars_in_buffer(struct tty_struct *tty) -{ - return 0; -} - static void tty3270_flush_buffer(struct tty_struct *tty) { @@ -1892,7 +1881,6 @@ static const struct tty_operations tty3270_ops = { .put_char = tty3270_put_char, .flush_chars = tty3270_flush_chars, .write_room = tty3270_write_room, - .chars_in_buffer = tty3270_chars_in_buffer, .flush_buffer = tty3270_flush_buffer, .throttle = tty3270_throttle, .unthrottle = tty3270_unthrottle, diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index eb8556b19592..5ada7e9381eb 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -143,19 +143,6 @@ static unsigned int pty_write_room(struct tty_struct *tty) return tty_buffer_space_avail(tty->link->port); } -/** - * pty_chars_in_buffer - characters currently in our tx queue - * @tty: our tty - * - * Report how much we have in the transmit queue. As everything is - * instantly at the other end this is easy to implement. - */ - -static int pty_chars_in_buffer(struct tty_struct *tty) -{ - return 0; -} - /* Set the lock flag on a pty */ static int pty_set_lock(struct tty_struct *tty, int __user *arg) { @@ -525,7 +512,6 @@ static const struct tty_operations master_pty_ops_bsd = { .write = pty_write, .write_room = pty_write_room, .flush_buffer = pty_flush_buffer, - .chars_in_buffer = pty_chars_in_buffer, .unthrottle = pty_unthrottle, .ioctl = pty_bsd_ioctl, .compat_ioctl = pty_bsd_compat_ioctl, @@ -541,7 +527,6 @@ static const struct tty_operations slave_pty_ops_bsd = { .write = pty_write, .write_room = pty_write_room, .flush_buffer = pty_flush_buffer, - .chars_in_buffer = pty_chars_in_buffer, .unthrottle = pty_unthrottle, .set_termios = pty_set_termios, .cleanup = pty_cleanup, @@ -776,7 +761,6 @@ static const struct tty_operations ptm_unix98_ops = { .write = pty_write, .write_room = pty_write_room, .flush_buffer = pty_flush_buffer, - .chars_in_buffer = pty_chars_in_buffer, .unthrottle = pty_unthrottle, .ioctl = pty_unix98_ioctl, .compat_ioctl = pty_unix98_compat_ioctl, @@ -794,7 +778,6 @@ static const struct tty_operations pty_unix98_ops = { .write = pty_write, .write_room = pty_write_room, .flush_buffer = pty_flush_buffer, - .chars_in_buffer = pty_chars_in_buffer, .unthrottle = pty_unthrottle, .set_termios = pty_set_termios, .start = pty_start, diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 96c130714930..b838f656f4cd 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -3270,11 +3270,6 @@ static unsigned int con_write_room(struct tty_struct *tty) return 32768; /* No limit, really; we're not buffering */ } -static int con_chars_in_buffer(struct tty_struct *tty) -{ - return 0; /* we're not buffering */ -} - /* * con_throttle and con_unthrottle are only used for * paste_selection(), which has to stuff in a large number of @@ -3521,7 +3516,6 @@ static const struct tty_operations con_ops = { .write_room = con_write_room, .put_char = con_put_char, .flush_chars = con_flush_chars, - .chars_in_buffer = con_chars_in_buffer, .ioctl = vt_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = vt_compat_ioctl, From fff4ef17a9400fcd276b5c3a00ce5793f6c465e6 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:19:19 +0200 Subject: [PATCH 048/227] tty: make tty_operations::chars_in_buffer return uint tty_operations::chars_in_buffer is another hook which is expected to return values >= 0. So make it explicit by the return type too -- use unsigned int. Signed-off-by: Jiri Slaby Acked-By: Anton Ivanov Acked-by: David Sterba Cc: Jeff Dike Cc: Richard Weinberger Cc: Arnd Bergmann Cc: Samuel Iglesias Gonsalvez Cc: Jens Taprogge Cc: Karsten Keil Cc: Ulf Hansson Cc: "David S. Miller" Cc: Jakub Kicinski Cc: Heiko Carstens Cc: Vasily Gorbik Cc: Christian Borntraeger Cc: David Lin Cc: Johan Hovold Cc: Alex Elder Cc: Jiri Kosina Cc: Shawn Guo Cc: Sascha Hauer Cc: Oliver Neukum Cc: Felipe Balbi Cc: Mathias Nyman Cc: Marcel Holtmann Cc: Johan Hedberg Cc: Luiz Augusto von Dentz Link: https://lore.kernel.org/r/20210505091928.22010-27-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- arch/um/drivers/line.c | 4 ++-- arch/um/drivers/line.h | 2 +- drivers/char/pcmcia/synclink_cs.c | 6 +++--- drivers/ipack/devices/ipoctal.c | 2 +- drivers/isdn/capi/capi.c | 2 +- drivers/mmc/core/sdio_uart.c | 2 +- drivers/net/usb/hso.c | 4 ++-- drivers/s390/char/con3215.c | 2 +- drivers/s390/char/sclp_rw.c | 4 ++-- drivers/s390/char/sclp_rw.h | 2 +- drivers/s390/char/sclp_tty.c | 5 ++--- drivers/s390/char/sclp_vt220.c | 5 ++--- drivers/staging/fwserial/fwserial.c | 6 +++--- drivers/staging/greybus/uart.c | 4 ++-- drivers/tty/amiserial.c | 2 +- drivers/tty/goldfish.c | 2 +- drivers/tty/hvc/hvc_console.c | 2 +- drivers/tty/hvc/hvcs.c | 2 +- drivers/tty/hvc/hvsi.c | 2 +- drivers/tty/ipwireless/tty.c | 2 +- drivers/tty/mips_ejtag_fdc.c | 4 ++-- drivers/tty/moxa.c | 10 +++++----- drivers/tty/mxser.c | 2 +- drivers/tty/n_gsm.c | 2 +- drivers/tty/nozomi.c | 2 +- drivers/tty/serial/serial_core.c | 4 ++-- drivers/tty/synclink_gt.c | 6 +++--- drivers/tty/tty_ioctl.c | 2 +- drivers/tty/vcc.c | 4 ++-- drivers/usb/class/cdc-acm.c | 2 +- drivers/usb/gadget/function/u_serial.c | 6 +++--- drivers/usb/host/xhci-dbgtty.c | 4 ++-- drivers/usb/serial/usb-serial.c | 2 +- include/linux/tty.h | 2 +- include/linux/tty_driver.h | 2 +- net/bluetooth/rfcomm/tty.c | 2 +- 36 files changed, 58 insertions(+), 60 deletions(-) diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 2b8810ba5470..159434851417 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -60,11 +60,11 @@ unsigned int line_write_room(struct tty_struct *tty) return room; } -int line_chars_in_buffer(struct tty_struct *tty) +unsigned int line_chars_in_buffer(struct tty_struct *tty) { struct line *line = tty->driver_data; unsigned long flags; - int ret; + unsigned int ret; spin_lock_irqsave(&line->lock, flags); /* write_room subtracts 1 for the needed NULL, so we readd it.*/ diff --git a/arch/um/drivers/line.h b/arch/um/drivers/line.h index 861edf329569..3325e2bc64e4 100644 --- a/arch/um/drivers/line.h +++ b/arch/um/drivers/line.h @@ -67,7 +67,7 @@ extern int line_setup(char **conf, unsigned nlines, char **def, extern int line_write(struct tty_struct *tty, const unsigned char *buf, int len); extern void line_set_termios(struct tty_struct *tty, struct ktermios * old); -extern int line_chars_in_buffer(struct tty_struct *tty); +extern unsigned int line_chars_in_buffer(struct tty_struct *tty); extern void line_flush_buffer(struct tty_struct *tty); extern void line_flush_chars(struct tty_struct *tty); extern unsigned int line_write_room(struct tty_struct *tty); diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index e4b2c68f44f5..9f7420bc5026 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -1637,10 +1637,10 @@ static unsigned int mgslpc_write_room(struct tty_struct *tty) /* Return the count of bytes in transmit buffer */ -static int mgslpc_chars_in_buffer(struct tty_struct *tty) +static unsigned int mgslpc_chars_in_buffer(struct tty_struct *tty) { MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data; - int rc; + unsigned int rc; if (debug_level >= DEBUG_LEVEL_INFO) printk("%s(%d):mgslpc_chars_in_buffer(%s)\n", @@ -1655,7 +1655,7 @@ static int mgslpc_chars_in_buffer(struct tty_struct *tty) rc = info->tx_count; if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgslpc_chars_in_buffer(%s)=%d\n", + printk("%s(%d):mgslpc_chars_in_buffer(%s)=%u\n", __FILE__, __LINE__, info->device_name, rc); return rc; diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c index ea0f1aeaaa06..0a3b89c17d08 100644 --- a/drivers/ipack/devices/ipoctal.c +++ b/drivers/ipack/devices/ipoctal.c @@ -467,7 +467,7 @@ static unsigned int ipoctal_write_room(struct tty_struct *tty) return PAGE_SIZE - channel->nb_bytes; } -static int ipoctal_chars_in_buffer(struct tty_struct *tty) +static unsigned int ipoctal_chars_in_buffer(struct tty_struct *tty) { struct ipoctal_channel *channel = tty->driver_data; diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index c50c454006b3..dae80197ad9c 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -1186,7 +1186,7 @@ static unsigned int capinc_tty_write_room(struct tty_struct *tty) return room; } -static int capinc_tty_chars_in_buffer(struct tty_struct *tty) +static unsigned int capinc_tty_chars_in_buffer(struct tty_struct *tty) { struct capiminor *mp = tty->driver_data; diff --git a/drivers/mmc/core/sdio_uart.c b/drivers/mmc/core/sdio_uart.c index c8f4eca7aad4..c36242b86b1d 100644 --- a/drivers/mmc/core/sdio_uart.c +++ b/drivers/mmc/core/sdio_uart.c @@ -803,7 +803,7 @@ static unsigned int sdio_uart_write_room(struct tty_struct *tty) return FIFO_SIZE - kfifo_len(&port->xmit_fifo); } -static int sdio_uart_chars_in_buffer(struct tty_struct *tty) +static unsigned int sdio_uart_chars_in_buffer(struct tty_struct *tty) { struct sdio_uart_port *port = tty->driver_data; return kfifo_len(&port->xmit_fifo); diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index bb8bb85308ab..c7563ed3ac31 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1404,11 +1404,11 @@ static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old) } /* how many characters in the buffer */ -static int hso_serial_chars_in_buffer(struct tty_struct *tty) +static unsigned int hso_serial_chars_in_buffer(struct tty_struct *tty) { struct hso_serial *serial = tty->driver_data; - int chars; unsigned long flags; + unsigned int chars; /* sanity check */ if (serial == NULL) diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index c9fd4a05931a..8821927ef875 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -980,7 +980,7 @@ static void tty3215_flush_chars(struct tty_struct *tty) /* * Returns the number of characters in the output buffer */ -static int tty3215_chars_in_buffer(struct tty_struct *tty) +static unsigned int tty3215_chars_in_buffer(struct tty_struct *tty) { struct raw3215_info *raw = tty->driver_data; diff --git a/drivers/s390/char/sclp_rw.c b/drivers/s390/char/sclp_rw.c index d6c84e354df5..5a1bf6eaa9d9 100644 --- a/drivers/s390/char/sclp_rw.c +++ b/drivers/s390/char/sclp_rw.c @@ -325,10 +325,10 @@ sclp_buffer_space(struct sclp_buffer *buffer) /* * Return number of characters in buffer */ -int +unsigned int sclp_chars_in_buffer(struct sclp_buffer *buffer) { - int count; + unsigned int count; count = buffer->char_sum; if (buffer->current_line != NULL) diff --git a/drivers/s390/char/sclp_rw.h b/drivers/s390/char/sclp_rw.h index 93d706e4935c..b4506be79246 100644 --- a/drivers/s390/char/sclp_rw.h +++ b/drivers/s390/char/sclp_rw.h @@ -86,7 +86,7 @@ void *sclp_unmake_buffer(struct sclp_buffer *); int sclp_buffer_space(struct sclp_buffer *); int sclp_write(struct sclp_buffer *buffer, const unsigned char *, int); int sclp_emit_buffer(struct sclp_buffer *,void (*)(struct sclp_buffer *,int)); -int sclp_chars_in_buffer(struct sclp_buffer *); +unsigned int sclp_chars_in_buffer(struct sclp_buffer *); #ifdef CONFIG_SCLP_CONSOLE void sclp_console_pm_event(enum sclp_pm_event sclp_pm_event); diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index ea1e43fd16bc..162127ff7845 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c @@ -280,16 +280,15 @@ sclp_tty_flush_chars(struct tty_struct *tty) * characters in the write buffer (will not be written as long as there is a * final line feed missing). */ -static int +static unsigned int sclp_tty_chars_in_buffer(struct tty_struct *tty) { unsigned long flags; struct list_head *l; struct sclp_buffer *t; - int count; + unsigned int count = 0; spin_lock_irqsave(&sclp_tty_lock, flags); - count = 0; if (sclp_ttybuf != NULL) count = sclp_chars_in_buffer(sclp_ttybuf); list_for_each(l, &sclp_tty_outqueue) { diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index b621adee35f0..24eb3a0b0a9a 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -629,16 +629,15 @@ sclp_vt220_write_room(struct tty_struct *tty) /* * Return number of buffered chars. */ -static int +static unsigned int sclp_vt220_chars_in_buffer(struct tty_struct *tty) { unsigned long flags; struct list_head *l; struct sclp_vt220_request *r; - int count; + unsigned int count = 0; spin_lock_irqsave(&sclp_vt220_lock, flags); - count = 0; if (sclp_vt220_current_request != NULL) count = sclp_vt220_chars_stored(sclp_vt220_current_request); list_for_each(l, &sclp_vt220_outqueue) { diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index a151cd76d24e..d2b286ea27c5 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c @@ -1127,16 +1127,16 @@ static unsigned int fwtty_write_room(struct tty_struct *tty) return n; } -static int fwtty_chars_in_buffer(struct tty_struct *tty) +static unsigned int fwtty_chars_in_buffer(struct tty_struct *tty) { struct fwtty_port *port = tty->driver_data; - int n; + unsigned int n; spin_lock_bh(&port->lock); n = dma_fifo_level(&port->tx_fifo); spin_unlock_bh(&port->lock); - fwtty_dbg(port, "%d\n", n); + fwtty_dbg(port, "%u\n", n); return n; } diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c index 529eccb99b6c..ccfaa0f21b9c 100644 --- a/drivers/staging/greybus/uart.c +++ b/drivers/staging/greybus/uart.c @@ -457,11 +457,11 @@ static unsigned int gb_tty_write_room(struct tty_struct *tty) return room; } -static int gb_tty_chars_in_buffer(struct tty_struct *tty) +static unsigned int gb_tty_chars_in_buffer(struct tty_struct *tty) { struct gb_tty *gb_tty = tty->driver_data; unsigned long flags; - int chars; + unsigned int chars; spin_lock_irqsave(&gb_tty->write_lock, flags); chars = kfifo_len(&gb_tty->write_fifo); diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index ee1f4d72cd5e..5ec19c48fb7a 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -834,7 +834,7 @@ static unsigned int rs_write_room(struct tty_struct *tty) return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); } -static int rs_chars_in_buffer(struct tty_struct *tty) +static unsigned int rs_chars_in_buffer(struct tty_struct *tty) { struct serial_state *info = tty->driver_data; diff --git a/drivers/tty/goldfish.c b/drivers/tty/goldfish.c index e4f9a60dcc18..ccb683a6e6f5 100644 --- a/drivers/tty/goldfish.c +++ b/drivers/tty/goldfish.c @@ -198,7 +198,7 @@ static unsigned int goldfish_tty_write_room(struct tty_struct *tty) return 0x10000; } -static int goldfish_tty_chars_in_buffer(struct tty_struct *tty) +static unsigned int goldfish_tty_chars_in_buffer(struct tty_struct *tty) { struct goldfish_tty *qtty = &goldfish_ttys[tty->index]; void __iomem *base = qtty->base; diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index a3725eb69cd3..d0f0253fb93e 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c @@ -596,7 +596,7 @@ static unsigned int hvc_write_room(struct tty_struct *tty) return hp->outbuf_size - hp->n_outbuf; } -static int hvc_chars_in_buffer(struct tty_struct *tty) +static unsigned int hvc_chars_in_buffer(struct tty_struct *tty) { struct hvc_struct *hp = tty->driver_data; diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index f43f2f94d8bd..fe5e6b4f43de 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c @@ -1386,7 +1386,7 @@ static unsigned int hvcs_write_room(struct tty_struct *tty) return HVCS_BUFF_LEN - hvcsd->chars_in_buffer; } -static int hvcs_chars_in_buffer(struct tty_struct *tty) +static unsigned int hvcs_chars_in_buffer(struct tty_struct *tty) { struct hvcs_struct *hvcsd = tty->driver_data; diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index 0a56f44e6b12..bfc15279d5bc 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c @@ -897,7 +897,7 @@ static unsigned int hvsi_write_room(struct tty_struct *tty) return N_OUTBUF - hp->n_outbuf; } -static int hvsi_chars_in_buffer(struct tty_struct *tty) +static unsigned int hvsi_chars_in_buffer(struct tty_struct *tty) { struct hvsi_struct *hp = tty->driver_data; diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c index ab562838313b..e01ca68f24f4 100644 --- a/drivers/tty/ipwireless/tty.c +++ b/drivers/tty/ipwireless/tty.c @@ -270,7 +270,7 @@ static int ipwireless_set_serial_info(struct tty_struct *linux_tty, return 0; /* Keeps the PCMCIA scripts happy. */ } -static int ipw_chars_in_buffer(struct tty_struct *linux_tty) +static unsigned int ipw_chars_in_buffer(struct tty_struct *linux_tty) { struct ipw_tty *tty = linux_tty->driver_data; diff --git a/drivers/tty/mips_ejtag_fdc.c b/drivers/tty/mips_ejtag_fdc.c index f427e8e154d7..3b5915b94fac 100644 --- a/drivers/tty/mips_ejtag_fdc.c +++ b/drivers/tty/mips_ejtag_fdc.c @@ -854,10 +854,10 @@ static unsigned int mips_ejtag_fdc_tty_write_room(struct tty_struct *tty) return room; } -static int mips_ejtag_fdc_tty_chars_in_buffer(struct tty_struct *tty) +static unsigned int mips_ejtag_fdc_tty_chars_in_buffer(struct tty_struct *tty) { struct mips_ejtag_fdc_tty_port *dport = tty->driver_data; - int chars; + unsigned int chars; /* Report the number of bytes in the xmit buffer */ spin_lock(&dport->xmit_lock); diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index e4fe9315de29..64b18177c790 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c @@ -190,7 +190,7 @@ static void moxa_close(struct tty_struct *, struct file *); static int moxa_write(struct tty_struct *, const unsigned char *, int); static unsigned int moxa_write_room(struct tty_struct *); static void moxa_flush_buffer(struct tty_struct *); -static int moxa_chars_in_buffer(struct tty_struct *); +static unsigned int moxa_chars_in_buffer(struct tty_struct *); static void moxa_set_termios(struct tty_struct *, struct ktermios *); static void moxa_stop(struct tty_struct *); static void moxa_start(struct tty_struct *); @@ -216,7 +216,7 @@ static int MoxaPortLineStatus(struct moxa_port *); static void MoxaPortFlushData(struct moxa_port *, int); static int MoxaPortWriteData(struct tty_struct *, const unsigned char *, int); static int MoxaPortReadData(struct moxa_port *); -static int MoxaPortTxQueue(struct moxa_port *); +static unsigned int MoxaPortTxQueue(struct moxa_port *); static int MoxaPortRxQueue(struct moxa_port *); static unsigned int MoxaPortTxFree(struct moxa_port *); static void MoxaPortTxDisable(struct moxa_port *); @@ -1239,10 +1239,10 @@ static void moxa_flush_buffer(struct tty_struct *tty) tty_wakeup(tty); } -static int moxa_chars_in_buffer(struct tty_struct *tty) +static unsigned int moxa_chars_in_buffer(struct tty_struct *tty) { struct moxa_port *ch = tty->driver_data; - int chars; + unsigned int chars; chars = MoxaPortTxQueue(ch); if (chars) @@ -1981,7 +1981,7 @@ static int MoxaPortReadData(struct moxa_port *port) } -static int MoxaPortTxQueue(struct moxa_port *port) +static unsigned int MoxaPortTxQueue(struct moxa_port *port) { void __iomem *ofsAddr = port->tableAddr; u16 rptr, wptr, mask; diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 5851a45d828c..a74e6146a748 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -1192,7 +1192,7 @@ static unsigned int mxser_write_room(struct tty_struct *tty) return ret < 0 ? 0 : ret; } -static int mxser_chars_in_buffer(struct tty_struct *tty) +static unsigned int mxser_chars_in_buffer(struct tty_struct *tty) { struct mxser_port *info = tty->driver_data; return info->xmit_cnt; diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 06f0c6d39620..bd24dc0d7e96 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -3064,7 +3064,7 @@ static unsigned int gsmtty_write_room(struct tty_struct *tty) return TX_SIZE - kfifo_len(&dlci->fifo); } -static int gsmtty_chars_in_buffer(struct tty_struct *tty) +static unsigned int gsmtty_chars_in_buffer(struct tty_struct *tty) { struct gsm_dlci *dlci = tty->driver_data; if (dlci->state == DLCI_CLOSED) diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index c55475a9a184..62c16731ccd8 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c @@ -1776,7 +1776,7 @@ static void ntty_throttle(struct tty_struct *tty) } /* Returns number of chars in buffer, called by tty layer */ -static s32 ntty_chars_in_buffer(struct tty_struct *tty) +static unsigned int ntty_chars_in_buffer(struct tty_struct *tty) { struct port *port = tty->driver_data; struct nozomi *dc = get_dc_by_tty(tty); diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index cb46a65a5dd8..d29329eb52f4 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -629,12 +629,12 @@ static unsigned int uart_write_room(struct tty_struct *tty) return ret; } -static int uart_chars_in_buffer(struct tty_struct *tty) +static unsigned int uart_chars_in_buffer(struct tty_struct *tty) { struct uart_state *state = tty->driver_data; struct uart_port *port; unsigned long flags; - int ret; + unsigned int ret; port = uart_port_lock(state, flags); ret = uart_circ_chars_pending(&state->xmit); diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index 583aa8342112..cf87dc66087b 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -1254,14 +1254,14 @@ static int synclink_gt_proc_show(struct seq_file *m, void *v) /* * return count of bytes in transmit buffer */ -static int chars_in_buffer(struct tty_struct *tty) +static unsigned int chars_in_buffer(struct tty_struct *tty) { struct slgt_info *info = tty->driver_data; - int count; + unsigned int count; if (sanity_check(info, tty->name, "chars_in_buffer")) return 0; count = tbuf_bytes(info); - DBGINFO(("%s chars_in_buffer()=%d\n", info->device_name, count)); + DBGINFO(("%s chars_in_buffer()=%u\n", info->device_name, count)); return count; } diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index d8834784b586..aa9ecc8be990 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -54,7 +54,7 @@ * to be no queue on the device. */ -int tty_chars_in_buffer(struct tty_struct *tty) +unsigned int tty_chars_in_buffer(struct tty_struct *tty) { if (tty->ops->chars_in_buffer) return tty->ops->chars_in_buffer(tty); diff --git a/drivers/tty/vcc.c b/drivers/tty/vcc.c index d82ce3bb82c3..e883b8f12099 100644 --- a/drivers/tty/vcc.c +++ b/drivers/tty/vcc.c @@ -888,10 +888,10 @@ static unsigned int vcc_write_room(struct tty_struct *tty) return num; } -static int vcc_chars_in_buffer(struct tty_struct *tty) +static unsigned int vcc_chars_in_buffer(struct tty_struct *tty) { struct vcc_port *port; - u64 num; + unsigned int num; port = vcc_get_ne(tty->index); if (unlikely(!port)) { diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 76b7fd234238..81199efe0312 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -848,7 +848,7 @@ static unsigned int acm_tty_write_room(struct tty_struct *tty) return acm_wb_is_avail(acm) ? acm->writesize : 0; } -static int acm_tty_chars_in_buffer(struct tty_struct *tty) +static unsigned int acm_tty_chars_in_buffer(struct tty_struct *tty) { struct acm *acm = tty->driver_data; /* diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index 676a920d9d6b..bffef8e47dac 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -791,17 +791,17 @@ static unsigned int gs_write_room(struct tty_struct *tty) return room; } -static int gs_chars_in_buffer(struct tty_struct *tty) +static unsigned int gs_chars_in_buffer(struct tty_struct *tty) { struct gs_port *port = tty->driver_data; unsigned long flags; - int chars = 0; + unsigned int chars; spin_lock_irqsave(&port->port_lock, flags); chars = kfifo_len(&port->port_write_buf); spin_unlock_irqrestore(&port->port_lock, flags); - pr_vdebug("gs_chars_in_buffer: (%d,%p) chars=%d\n", + pr_vdebug("gs_chars_in_buffer: (%d,%p) chars=%u\n", port->port_num, tty, chars); return chars; diff --git a/drivers/usb/host/xhci-dbgtty.c b/drivers/usb/host/xhci-dbgtty.c index cd3ab35dd689..bef104511352 100644 --- a/drivers/usb/host/xhci-dbgtty.c +++ b/drivers/usb/host/xhci-dbgtty.c @@ -253,11 +253,11 @@ static unsigned int dbc_tty_write_room(struct tty_struct *tty) return room; } -static int dbc_tty_chars_in_buffer(struct tty_struct *tty) +static unsigned int dbc_tty_chars_in_buffer(struct tty_struct *tty) { struct dbc_port *port = tty->driver_data; unsigned long flags; - int chars = 0; + unsigned int chars; spin_lock_irqsave(&port->port_lock, flags); chars = kfifo_len(&port->write_fifo); diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 055096831daf..eeb441c77207 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -385,7 +385,7 @@ static unsigned int serial_write_room(struct tty_struct *tty) return port->serial->type->write_room(tty); } -static int serial_chars_in_buffer(struct tty_struct *tty) +static unsigned int serial_chars_in_buffer(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct usb_serial *serial = port->serial; diff --git a/include/linux/tty.h b/include/linux/tty.h index d18fc34d3054..5cf6b2e7331b 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -458,7 +458,7 @@ extern void tty_unregister_device(struct tty_driver *driver, unsigned index); extern void tty_write_message(struct tty_struct *tty, char *msg); extern int tty_send_xchar(struct tty_struct *tty, char ch); extern int tty_put_char(struct tty_struct *tty, unsigned char c); -extern int tty_chars_in_buffer(struct tty_struct *tty); +extern unsigned int tty_chars_in_buffer(struct tty_struct *tty); extern unsigned int tty_write_room(struct tty_struct *tty); extern void tty_driver_flush_buffer(struct tty_struct *tty); extern void tty_throttle(struct tty_struct *tty); diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index ea5b15c72764..a4694bb125cc 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -257,7 +257,7 @@ struct tty_operations { int (*put_char)(struct tty_struct *tty, unsigned char ch); void (*flush_chars)(struct tty_struct *tty); unsigned int (*write_room)(struct tty_struct *tty); - int (*chars_in_buffer)(struct tty_struct *tty); + unsigned int (*chars_in_buffer)(struct tty_struct *tty); int (*ioctl)(struct tty_struct *tty, unsigned int cmd, unsigned long arg); long (*compat_ioctl)(struct tty_struct *tty, diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index a5e3d957f20f..c76dcc0f679b 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -1010,7 +1010,7 @@ static void rfcomm_tty_unthrottle(struct tty_struct *tty) rfcomm_dlc_unthrottle(dev->dlc); } -static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty) +static unsigned int rfcomm_tty_chars_in_buffer(struct tty_struct *tty) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; From 3d18354248b14a5ffefaa31a43fd0d45a283e97d Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:19:21 +0200 Subject: [PATCH 049/227] nozomi: simplify ntty_chars_in_buffer ntty_chars_in_buffer is overly complicated. Simplify it by inverting the condition. Side FIXME: how can dc or port be NULL here? Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210505091928.22010-29-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/nozomi.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index 62c16731ccd8..5e0ddf22931e 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c @@ -1780,16 +1780,11 @@ static unsigned int ntty_chars_in_buffer(struct tty_struct *tty) { struct port *port = tty->driver_data; struct nozomi *dc = get_dc_by_tty(tty); - s32 rval = 0; - if (unlikely(!dc || !port)) { - goto exit_in_buffer; - } + if (unlikely(!dc || !port)) + return 0; - rval = kfifo_len(&port->fifo_ul); - -exit_in_buffer: - return rval; + return kfifo_len(&port->fifo_ul); } static const struct tty_port_operations noz_tty_port_ops = { From 4fb266e1976ed664252d172c4889c639abd53930 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:19:23 +0200 Subject: [PATCH 050/227] tty: remove empty tty_operations::flush_buffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tty_operations::flush_buffer is optional. If it doesn't exist, nothing is called. So remove almost¹ empty flush_buffer implementations. ¹ capi had an useless pr_debug in it. Signed-off-by: Jiri Slaby Cc: Karsten Keil Cc: Heiko Carstens Cc: Vasily Gorbik Cc: Christian Borntraeger Link: https://lore.kernel.org/r/20210505091928.22010-31-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/isdn/capi/capi.c | 6 ------ drivers/s390/char/tty3270.c | 6 ------ 2 files changed, 12 deletions(-) diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index dae80197ad9c..6d99b93bb09e 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -1249,11 +1249,6 @@ static int capinc_tty_break_ctl(struct tty_struct *tty, int state) return 0; } -static void capinc_tty_flush_buffer(struct tty_struct *tty) -{ - pr_debug("capinc_tty_flush_buffer\n"); -} - static void capinc_tty_set_ldisc(struct tty_struct *tty) { pr_debug("capinc_tty_set_ldisc\n"); @@ -1279,7 +1274,6 @@ static const struct tty_operations capinc_ops = { .start = capinc_tty_start, .hangup = capinc_tty_hangup, .break_ctl = capinc_tty_break_ctl, - .flush_buffer = capinc_tty_flush_buffer, .set_ldisc = capinc_tty_set_ldisc, .send_xchar = capinc_tty_send_xchar, .install = capinc_tty_install, diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index ba1fbce63fee..adc33846bf8e 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -1756,11 +1756,6 @@ tty3270_flush_chars(struct tty_struct *tty) } } -static void -tty3270_flush_buffer(struct tty_struct *tty) -{ -} - /* * Check for visible/invisible input switches */ @@ -1881,7 +1876,6 @@ static const struct tty_operations tty3270_ops = { .put_char = tty3270_put_char, .flush_chars = tty3270_flush_chars, .write_room = tty3270_write_room, - .flush_buffer = tty3270_flush_buffer, .throttle = tty3270_throttle, .unthrottle = tty3270_unthrottle, .hangup = tty3270_hangup, From 4da872befc83e65b106211272f18ff78a308ec97 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:19:24 +0200 Subject: [PATCH 051/227] tty: remove empty tty_operations::set_termios MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tty_operations::set_termios is optional. If it doesn't exist, nothing is called. So remove almost¹ empty set_termios implementations. ¹ capi had an useless pr_debug in it. Signed-off-by: Jiri Slaby Cc: Jeff Dike Cc: Richard Weinberger Cc: Karsten Keil Acked-By: Anton Ivanov Link: https://lore.kernel.org/r/20210505091928.22010-32-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- arch/um/drivers/line.c | 5 ----- arch/um/drivers/line.h | 1 - arch/um/drivers/ssl.c | 1 - arch/um/drivers/stdio_console.c | 1 - drivers/isdn/capi/capi.c | 6 ------ 5 files changed, 14 deletions(-) diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 159434851417..fbc623d2cc07 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -211,11 +211,6 @@ out_up: return ret; } -void line_set_termios(struct tty_struct *tty, struct ktermios * old) -{ - /* nothing */ -} - void line_throttle(struct tty_struct *tty) { struct line *line = tty->driver_data; diff --git a/arch/um/drivers/line.h b/arch/um/drivers/line.h index 3325e2bc64e4..bdb16b96e76f 100644 --- a/arch/um/drivers/line.h +++ b/arch/um/drivers/line.h @@ -66,7 +66,6 @@ extern int line_setup(char **conf, unsigned nlines, char **def, char *init, char *name); extern int line_write(struct tty_struct *tty, const unsigned char *buf, int len); -extern void line_set_termios(struct tty_struct *tty, struct ktermios * old); extern unsigned int line_chars_in_buffer(struct tty_struct *tty); extern void line_flush_buffer(struct tty_struct *tty); extern void line_flush_chars(struct tty_struct *tty); diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index 6476b28d7c5e..41eae2e8fb65 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c @@ -99,7 +99,6 @@ static const struct tty_operations ssl_ops = { .chars_in_buffer = line_chars_in_buffer, .flush_buffer = line_flush_buffer, .flush_chars = line_flush_chars, - .set_termios = line_set_termios, .throttle = line_throttle, .unthrottle = line_unthrottle, .install = ssl_install, diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c index 37b127941e6f..e8b762f4d8c2 100644 --- a/arch/um/drivers/stdio_console.c +++ b/arch/um/drivers/stdio_console.c @@ -106,7 +106,6 @@ static const struct tty_operations console_ops = { .chars_in_buffer = line_chars_in_buffer, .flush_buffer = line_flush_buffer, .flush_chars = line_flush_chars, - .set_termios = line_set_termios, .throttle = line_throttle, .unthrottle = line_unthrottle, .hangup = line_hangup, diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 6d99b93bb09e..693b0bc31395 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -1197,11 +1197,6 @@ static unsigned int capinc_tty_chars_in_buffer(struct tty_struct *tty) return mp->outbytes; } -static void capinc_tty_set_termios(struct tty_struct *tty, struct ktermios *old) -{ - pr_debug("capinc_tty_set_termios\n"); -} - static void capinc_tty_throttle(struct tty_struct *tty) { struct capiminor *mp = tty->driver_data; @@ -1267,7 +1262,6 @@ static const struct tty_operations capinc_ops = { .flush_chars = capinc_tty_flush_chars, .write_room = capinc_tty_write_room, .chars_in_buffer = capinc_tty_chars_in_buffer, - .set_termios = capinc_tty_set_termios, .throttle = capinc_tty_throttle, .unthrottle = capinc_tty_unthrottle, .stop = capinc_tty_stop, From 3e679e1da5ef01825df87d0ed96bef8cb2e39635 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:19:25 +0200 Subject: [PATCH 052/227] isdn: capi, remove optional tty ops break_ctl and set_ldisc are optional tty_operations hooks. Given capi does nothing useful in them, just remove these. Signed-off-by: Jiri Slaby Cc: Karsten Keil Cc: netdev@vger.kernel.org Link: https://lore.kernel.org/r/20210505091928.22010-33-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/isdn/capi/capi.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 693b0bc31395..bf8a8809eff1 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -1238,17 +1238,6 @@ static void capinc_tty_hangup(struct tty_struct *tty) tty_port_hangup(&mp->port); } -static int capinc_tty_break_ctl(struct tty_struct *tty, int state) -{ - pr_debug("capinc_tty_break_ctl(%d)\n", state); - return 0; -} - -static void capinc_tty_set_ldisc(struct tty_struct *tty) -{ - pr_debug("capinc_tty_set_ldisc\n"); -} - static void capinc_tty_send_xchar(struct tty_struct *tty, char ch) { pr_debug("capinc_tty_send_xchar(%d)\n", ch); @@ -1267,8 +1256,6 @@ static const struct tty_operations capinc_ops = { .stop = capinc_tty_stop, .start = capinc_tty_start, .hangup = capinc_tty_hangup, - .break_ctl = capinc_tty_break_ctl, - .set_ldisc = capinc_tty_set_ldisc, .send_xchar = capinc_tty_send_xchar, .install = capinc_tty_install, .cleanup = capinc_tty_cleanup, From 1bf42296634178b2435e2b313443864467bbb848 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 5 May 2021 11:19:26 +0200 Subject: [PATCH 053/227] isdn: capi, drop useless pr_debugs capi have many pr_debugs in tty_operations hooks to print only a functions name. We have better debugging aids in the kernel many years now. So remove these useless pr_debugs. Signed-off-by: Jiri Slaby Cc: Karsten Keil Cc: netdev@vger.kernel.org Link: https://lore.kernel.org/r/20210505091928.22010-34-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/isdn/capi/capi.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index bf8a8809eff1..d5f9261fa879 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -1158,8 +1158,6 @@ static void capinc_tty_flush_chars(struct tty_struct *tty) struct capiminor *mp = tty->driver_data; struct sk_buff *skb; - pr_debug("capinc_tty_flush_chars\n"); - spin_lock_bh(&mp->outlock); skb = mp->outskb; if (skb) { @@ -1200,7 +1198,6 @@ static unsigned int capinc_tty_chars_in_buffer(struct tty_struct *tty) static void capinc_tty_throttle(struct tty_struct *tty) { struct capiminor *mp = tty->driver_data; - pr_debug("capinc_tty_throttle\n"); mp->ttyinstop = 1; } @@ -1208,7 +1205,6 @@ static void capinc_tty_unthrottle(struct tty_struct *tty) { struct capiminor *mp = tty->driver_data; - pr_debug("capinc_tty_unthrottle\n"); mp->ttyinstop = 0; handle_minor_recv(mp); } @@ -1217,7 +1213,6 @@ static void capinc_tty_stop(struct tty_struct *tty) { struct capiminor *mp = tty->driver_data; - pr_debug("capinc_tty_stop\n"); mp->ttyoutstop = 1; } @@ -1225,7 +1220,6 @@ static void capinc_tty_start(struct tty_struct *tty) { struct capiminor *mp = tty->driver_data; - pr_debug("capinc_tty_start\n"); mp->ttyoutstop = 0; handle_minor_send(mp); } @@ -1234,7 +1228,6 @@ static void capinc_tty_hangup(struct tty_struct *tty) { struct capiminor *mp = tty->driver_data; - pr_debug("capinc_tty_hangup\n"); tty_port_hangup(&mp->port); } From 76af233d9b0c0b749e97b8f90fd0ff0e417ce3e3 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 10 May 2021 08:59:22 +0200 Subject: [PATCH 054/227] tty: remove unused tty_throttle The last user was removed in commit e91e52e42814 (n_tty: Fix stuck throttled driver) in 2013. So remove exported tty_throttle completely. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210510065923.5112-1-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ioctl.c | 31 +++++-------------------------- include/linux/tty.h | 1 - include/linux/tty_driver.h | 2 +- 3 files changed, 6 insertions(+), 28 deletions(-) diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index aa9ecc8be990..75885d502749 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -96,28 +96,6 @@ void tty_driver_flush_buffer(struct tty_struct *tty) } EXPORT_SYMBOL(tty_driver_flush_buffer); -/** - * tty_throttle - flow control - * @tty: terminal - * - * Indicate that a tty should stop transmitting data down the stack. - * Takes the termios rwsem to protect against parallel throttle/unthrottle - * and also to ensure the driver can consistently reference its own - * termios data at this point when implementing software flow control. - */ - -void tty_throttle(struct tty_struct *tty) -{ - down_write(&tty->termios_rwsem); - /* check TTY_THROTTLED first so it indicates our state */ - if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) && - tty->ops->throttle) - tty->ops->throttle(tty); - tty->flow_change = 0; - up_write(&tty->termios_rwsem); -} -EXPORT_SYMBOL(tty_throttle); - /** * tty_unthrottle - flow control * @tty: terminal @@ -146,10 +124,11 @@ EXPORT_SYMBOL(tty_unthrottle); * tty_throttle_safe - flow control * @tty: terminal * - * Similar to tty_throttle() but will only attempt throttle - * if tty->flow_change is TTY_THROTTLE_SAFE. Prevents an accidental - * throttle due to race conditions when throttling is conditional - * on factors evaluated prior to throttling. + * Indicate that a tty should stop transmitting data down the stack. + * tty_throttle_safe will only attempt throttle if tty->flow_change is + * TTY_THROTTLE_SAFE. Prevents an accidental throttle due to race + * conditions when throttling is conditional on factors evaluated prior to + * throttling. * * Returns 0 if tty is throttled (or was already throttled) */ diff --git a/include/linux/tty.h b/include/linux/tty.h index 5cf6b2e7331b..4c0c7ca1d9a4 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -461,7 +461,6 @@ extern int tty_put_char(struct tty_struct *tty, unsigned char c); extern unsigned int tty_chars_in_buffer(struct tty_struct *tty); extern unsigned int tty_write_room(struct tty_struct *tty); extern void tty_driver_flush_buffer(struct tty_struct *tty); -extern void tty_throttle(struct tty_struct *tty); extern void tty_unthrottle(struct tty_struct *tty); extern int tty_throttle_safe(struct tty_struct *tty); extern int tty_unthrottle_safe(struct tty_struct *tty); diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index a4694bb125cc..448f8ee6db6e 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -136,7 +136,7 @@ * the line discipline are close to full, and it should somehow * signal that no more characters should be sent to the tty. * - * Optional: Always invoke via tty_throttle(), called under the + * Optional: Always invoke via tty_throttle_safe(), called under the * termios lock. * * void (*unthrottle)(struct tty_struct * tty); From 635b258962da2f0ab6d94f2bf9c31bcedc071adc Mon Sep 17 00:00:00 2001 From: Zihao Tang Date: Thu, 13 May 2021 11:01:33 +0800 Subject: [PATCH 055/227] tty: serial: atmel: include instead of Include the more general linux/io.h instead of asm/io.h as checkpatch suggests. Signed-off-by: Zihao Tang Signed-off-by: Jay Fang Link: https://lore.kernel.org/r/1620874904-39285-2-git-send-email-f.fangjian@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 058886d9045b..249ea35088d2 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -30,9 +30,9 @@ #include #include #include +#include #include -#include #include #define PDC_BUFFER_SIZE 512 From 27bcf79b8adbdcda0abfa6bcbac59fdaf7ae7568 Mon Sep 17 00:00:00 2001 From: Zihao Tang Date: Thu, 13 May 2021 11:01:34 +0800 Subject: [PATCH 056/227] tty: serial: dz: include instead of Include the more general linux/io.h instead of asm/io.h as checkpatch suggests. Signed-off-by: Zihao Tang Signed-off-by: Jay Fang Link: https://lore.kernel.org/r/1620874904-39285-3-git-send-email-f.fangjian@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/dz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/dz.c b/drivers/tty/serial/dz.c index 6d91e9b6284d..e9edabc5a211 100644 --- a/drivers/tty/serial/dz.c +++ b/drivers/tty/serial/dz.c @@ -47,8 +47,8 @@ #include #include +#include #include -#include #include #include From 0ebee1ebbc72c9706e5dc1df4f503e8876fd4ebe Mon Sep 17 00:00:00 2001 From: Zihao Tang Date: Thu, 13 May 2021 11:01:35 +0800 Subject: [PATCH 057/227] tty: serial: icom: include instead of Include the more general linux/io.h instead of asm/io.h as checkpatch suggests. Signed-off-by: Zihao Tang Signed-off-by: Jay Fang Link: https://lore.kernel.org/r/1620874904-39285-4-git-send-email-f.fangjian@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/icom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/icom.c b/drivers/tty/serial/icom.c index 9e9abfc4824a..03a2fe9f4c9a 100644 --- a/drivers/tty/serial/icom.c +++ b/drivers/tty/serial/icom.c @@ -37,7 +37,7 @@ #include #include -#include +#include #include #include From 3dccc357b7da16e5ce1e428bd5ebfa4d00e5a5d4 Mon Sep 17 00:00:00 2001 From: Zihao Tang Date: Thu, 13 May 2021 11:01:36 +0800 Subject: [PATCH 058/227] tty: serial: ip22zilog: include instead of Include the more general linux/io.h instead of asm/io.h as checkpatch suggests. Signed-off-by: Zihao Tang Signed-off-by: Jay Fang Link: https://lore.kernel.org/r/1620874904-39285-5-git-send-email-f.fangjian@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ip22zilog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/ip22zilog.c b/drivers/tty/serial/ip22zilog.c index 86fff69d7e7c..f4dc5fe4ba92 100644 --- a/drivers/tty/serial/ip22zilog.c +++ b/drivers/tty/serial/ip22zilog.c @@ -31,7 +31,7 @@ #include #include -#include +#include #include #include #include From b1c92c121b77fc8e05a19f058a0b5ebfd95fee94 Mon Sep 17 00:00:00 2001 From: Zihao Tang Date: Thu, 13 May 2021 11:01:37 +0800 Subject: [PATCH 059/227] tty: serial: mux: include instead of Include the more general linux/io.h instead of asm/io.h as checkpatch suggests. Signed-off-by: Zihao Tang Signed-off-by: Jay Fang Link: https://lore.kernel.org/r/1620874904-39285-6-git-send-email-f.fangjian@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/mux.c b/drivers/tty/serial/mux.c index 47ab280f553b..be640d9863cd 100644 --- a/drivers/tty/serial/mux.c +++ b/drivers/tty/serial/mux.c @@ -21,7 +21,7 @@ #include #include /* for udelay */ #include -#include +#include #include #include From ce6ff28069d8bf4141c9763d4edd64f5439f0982 Mon Sep 17 00:00:00 2001 From: Zihao Tang Date: Thu, 13 May 2021 11:01:38 +0800 Subject: [PATCH 060/227] tty: serial: pmac_zilog: include insteiad of Include the more general linux/io.h instead of asm/io.h as checkpatch suggests. Signed-off-by: Zihao Tang Signed-off-by: Jay Fang Link: https://lore.kernel.org/r/1620874904-39285-7-git-send-email-f.fangjian@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pmac_zilog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index d6aef8a1f0a4..12ce150b0ad4 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c @@ -47,7 +47,7 @@ #include #include #include -#include +#include #include #ifdef CONFIG_PPC_PMAC From 10dab44f78dfa45bcd7862a887362355e522639d Mon Sep 17 00:00:00 2001 From: Zihao Tang Date: Thu, 13 May 2021 11:01:39 +0800 Subject: [PATCH 061/227] tty: serial: txx9: include instead of Include the more general linux/io.h instead of asm/io.h as checkpatch suggests. Signed-off-by: Zihao Tang Signed-off-by: Jay Fang Link: https://lore.kernel.org/r/1620874904-39285-8-git-send-email-f.fangjian@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_txx9.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/serial_txx9.c b/drivers/tty/serial/serial_txx9.c index 0a7e5b74bc1d..aaca4fe38486 100644 --- a/drivers/tty/serial/serial_txx9.c +++ b/drivers/tty/serial/serial_txx9.c @@ -24,7 +24,7 @@ #include #include -#include +#include static char *serial_version = "1.11"; static char *serial_name = "TX39/49 Serial driver"; From d890c508769b05a589a4f197c45f74011679d580 Mon Sep 17 00:00:00 2001 From: Zihao Tang Date: Thu, 13 May 2021 11:01:40 +0800 Subject: [PATCH 062/227] tty: serial: sunsab: include instead of Include the more general linux/io.h instead of asm/io.h as checkpatch suggests. Signed-off-by: Zihao Tang Signed-off-by: Jay Fang Link: https://lore.kernel.org/r/1620874904-39285-9-git-send-email-f.fangjian@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sunsab.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index bab551f46963..92e572634009 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c @@ -35,7 +35,7 @@ #include #include -#include +#include #include #include #include From 4f1c658130728a6089c88d10626805535fdc063b Mon Sep 17 00:00:00 2001 From: Zihao Tang Date: Thu, 13 May 2021 11:01:41 +0800 Subject: [PATCH 063/227] tty: serial: sunsu: include instead of Include the more general linux/io.h instead of asm/io.h as checkpatch suggests. Signed-off-by: Zihao Tang Signed-off-by: Jay Fang Link: https://lore.kernel.org/r/1620874904-39285-10-git-send-email-f.fangjian@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sunsu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index 12c2468f2b0e..425a016f9db7 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c @@ -39,7 +39,7 @@ #include #include -#include +#include #include #include #include From 933100787d6463e0d4ff634cbcd59b417d9c7e39 Mon Sep 17 00:00:00 2001 From: Zihao Tang Date: Thu, 13 May 2021 11:01:42 +0800 Subject: [PATCH 064/227] tty: serial: sunzilog: include instead of Include the more general linux/io.h instead of asm/io.h as checkpatch suggests. Signed-off-by: Zihao Tang Signed-off-by: Jay Fang Link: https://lore.kernel.org/r/1620874904-39285-11-git-send-email-f.fangjian@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sunzilog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c index 001e19d7c17d..1a54e3e52ed6 100644 --- a/drivers/tty/serial/sunzilog.c +++ b/drivers/tty/serial/sunzilog.c @@ -35,7 +35,7 @@ #include #include -#include +#include #include #include #include From 7d5a3ec537d9063bf4f1685a667d13a9e9196b85 Mon Sep 17 00:00:00 2001 From: Zihao Tang Date: Thu, 13 May 2021 11:01:43 +0800 Subject: [PATCH 065/227] tty: serial: vr41xx_siu: include instead of Include the more general linux/io.h instead of asm/io.h as checkpatch suggests. Signed-off-by: Zihao Tang Signed-off-by: Jay Fang Link: https://lore.kernel.org/r/1620874904-39285-12-git-send-email-f.fangjian@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/vr41xx_siu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/vr41xx_siu.c b/drivers/tty/serial/vr41xx_siu.c index eeb4b6568776..647198b1e2b9 100644 --- a/drivers/tty/serial/vr41xx_siu.c +++ b/drivers/tty/serial/vr41xx_siu.c @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include From 27dede097d2062252916c1c55ec0e04b027162b8 Mon Sep 17 00:00:00 2001 From: Zihao Tang Date: Thu, 13 May 2021 11:01:44 +0800 Subject: [PATCH 066/227] tty: serial: sb1250-duart: include instead of Include the more general linux/io.h instead of asm/io.h as checkpatch suggests. Signed-off-by: Zihao Tang Signed-off-by: Jay Fang Link: https://lore.kernel.org/r/1620874904-39285-13-git-send-email-f.fangjian@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sb1250-duart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/sb1250-duart.c b/drivers/tty/serial/sb1250-duart.c index 22c7bc90b104..738df6d9c0d9 100644 --- a/drivers/tty/serial/sb1250-duart.c +++ b/drivers/tty/serial/sb1250-duart.c @@ -34,7 +34,7 @@ #include #include -#include +#include #include #include From bf3d6ab9bc1295fdf37cbc363ba9f7dfa14a84b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samo=20Poga=C4=8Dnik?= Date: Tue, 27 Apr 2021 13:40:51 +0200 Subject: [PATCH 067/227] ttyprintk: Add TTY port shutdown callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By adding the TTY port shutdown callback, the final buffer flush has been moved from tpk_close() to tpk_port_shutdown(). This enables buffer flush upon close and hangup as well. The change also removes the specific 'buf == NULL' handling in tpk_printk(), which became useless. Signed-off-by: Samo Pogačnik Link: https://lore.kernel.org/r/f236ea26520fbef176fefec2e06a43548f63fa9c.camel@t-2.net Signed-off-by: Greg Kroah-Hartman --- drivers/char/ttyprintk.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c index e93b0af92339..620065b6cef9 100644 --- a/drivers/char/ttyprintk.c +++ b/drivers/char/ttyprintk.c @@ -54,11 +54,6 @@ static int tpk_printk(const unsigned char *buf, int count) { int i = tpk_curr; - if (buf == NULL) { - tpk_flush(); - return i; - } - for (i = 0; i < count; i++) { if (tpk_curr >= TPK_STR_SIZE) { /* end of tmp buffer reached: cut the message in two */ @@ -100,12 +95,6 @@ static int tpk_open(struct tty_struct *tty, struct file *filp) static void tpk_close(struct tty_struct *tty, struct file *filp) { struct ttyprintk_port *tpkp = tty->driver_data; - unsigned long flags; - - spin_lock_irqsave(&tpkp->spinlock, flags); - /* flush tpk_printk buffer */ - tpk_printk(NULL, 0); - spin_unlock_irqrestore(&tpkp->spinlock, flags); tty_port_close(&tpkp->port, tty, filp); } @@ -168,6 +157,20 @@ static void tpk_hangup(struct tty_struct *tty) tty_port_hangup(&tpkp->port); } +/* + * TTY port operations shutdown function. + */ +static void tpk_port_shutdown(struct tty_port *tport) +{ + struct ttyprintk_port *tpkp = + container_of(tport, struct ttyprintk_port, port); + unsigned long flags; + + spin_lock_irqsave(&tpkp->spinlock, flags); + tpk_flush(); + spin_unlock_irqrestore(&tpkp->spinlock, flags); +} + static const struct tty_operations ttyprintk_ops = { .open = tpk_open, .close = tpk_close, @@ -177,7 +180,9 @@ static const struct tty_operations ttyprintk_ops = { .hangup = tpk_hangup, }; -static const struct tty_port_operations null_ops = { }; +static const struct tty_port_operations tpk_port_ops = { + .shutdown = tpk_port_shutdown, +}; static struct tty_driver *ttyprintk_driver; @@ -195,7 +200,7 @@ static int __init ttyprintk_init(void) return PTR_ERR(ttyprintk_driver); tty_port_init(&tpk_port.port); - tpk_port.port.ops = &null_ops; + tpk_port.port.ops = &tpk_port_ops; ttyprintk_driver->driver_name = "ttyprintk"; ttyprintk_driver->name = "ttyprintk"; From 2fee8811219793cb16ed3f09b5629bb5c78e7dbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samo=20Poga=C4=8Dnik?= Date: Tue, 27 Apr 2021 13:43:26 +0200 Subject: [PATCH 068/227] ttyprintk: Removed unnecessary TTY ioctl callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It turns-out, that TIOCCONS is completely handled in tty_io.c, so the current local ioctl callback is of no real use. Signed-off-by: Samo Pogačnik Link: https://lore.kernel.org/r/1502946c760b1aae3ad9cffcf4ea3b9f37206585.camel@t-2.net Signed-off-by: Greg Kroah-Hartman --- drivers/char/ttyprintk.c | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c index 620065b6cef9..219fa1382396 100644 --- a/drivers/char/ttyprintk.c +++ b/drivers/char/ttyprintk.c @@ -109,7 +109,6 @@ static int tpk_write(struct tty_struct *tty, unsigned long flags; int ret; - /* exclusive use of tpk_printk within this tty */ spin_lock_irqsave(&tpkp->spinlock, flags); ret = tpk_printk(buf, count); @@ -126,27 +125,6 @@ static unsigned int tpk_write_room(struct tty_struct *tty) return TPK_MAX_ROOM; } -/* - * TTY operations ioctl function. - */ -static int tpk_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct ttyprintk_port *tpkp = tty->driver_data; - - if (!tpkp) - return -EINVAL; - - switch (cmd) { - /* Stop TIOCCONS */ - case TIOCCONS: - return -EOPNOTSUPP; - default: - return -ENOIOCTLCMD; - } - return 0; -} - /* * TTY operations hangup function. */ @@ -176,7 +154,6 @@ static const struct tty_operations ttyprintk_ops = { .close = tpk_close, .write = tpk_write, .write_room = tpk_write_room, - .ioctl = tpk_ioctl, .hangup = tpk_hangup, }; From 31a9a318255960d32ae183e95d0999daf2418608 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 9 May 2021 19:22:33 +0200 Subject: [PATCH 069/227] tty: nozomi: Fix a resource leak in an error handling function A 'request_irq()' call is not balanced by a corresponding 'free_irq()' in the error handling path, as already done in the remove function. Add it. Fixes: 9842c38e9176 ("kfifo: fix warn_unused_result") Reviewed-by: Jiri Slaby Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/4f0d2b3038e82f081d370ccb0cade3ad88463fe7.1620580838.git.christophe.jaillet@wanadoo.fr Signed-off-by: Greg Kroah-Hartman --- drivers/tty/nozomi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index 5e0ddf22931e..b85d4beabc1f 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c @@ -1420,6 +1420,7 @@ err_free_tty: tty_unregister_device(ntty_driver, dc->index_start + i); tty_port_destroy(&dc->port[i].port); } + free_irq(pdev->irq, dc); err_free_kfifo: for (i = 0; i < MAX_PORT; i++) kfifo_free(&dc->port[i].fifo_ul); From eb460edb5f831c976144bc298564c14072860134 Mon Sep 17 00:00:00 2001 From: Xiaofei Tan Date: Wed, 12 May 2021 17:26:09 +0800 Subject: [PATCH 070/227] tty: tty_baudrate: Remove unnecessary tab and spaces in comment sentence Remove unnecessary tab and spaces in comment sentence, reported by checkpatch.pl. Signed-off-by: Xiaofei Tan Link: https://lore.kernel.org/r/1620811585-18582-2-git-send-email-tanxiaofei@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_baudrate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/tty_baudrate.c b/drivers/tty/tty_baudrate.c index 48b5de659c77..b3f5ba95e03c 100644 --- a/drivers/tty/tty_baudrate.c +++ b/drivers/tty/tty_baudrate.c @@ -147,7 +147,7 @@ void tty_termios_encode_baud_rate(struct ktermios *termios, int iclose = ibaud/50, oclose = obaud/50; int ibinput = 0; - if (obaud == 0) /* CD dropped */ + if (obaud == 0) /* CD dropped */ ibaud = 0; /* Clear ibaud to be sure */ termios->c_ispeed = ibaud; From ad48749b98c7e2eeb75a2d55041ad7a59ac063e3 Mon Sep 17 00:00:00 2001 From: Xiaofei Tan Date: Wed, 12 May 2021 17:26:10 +0800 Subject: [PATCH 071/227] tty: tty_baudrate: Fix coding style issues of block comments Fix coding style issues of block comments, reported by checkpatch.pl. Besides, add a period at the end of comment sentenses. Signed-off-by: Xiaofei Tan Link: https://lore.kernel.org/r/1620811585-18582-3-git-send-email-tanxiaofei@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_baudrate.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/tty/tty_baudrate.c b/drivers/tty/tty_baudrate.c index b3f5ba95e03c..426b1252781a 100644 --- a/drivers/tty/tty_baudrate.c +++ b/drivers/tty/tty_baudrate.c @@ -159,8 +159,9 @@ void tty_termios_encode_baud_rate(struct ktermios *termios, #endif #ifdef BOTHER /* If the user asked for a precise weird speed give a precise weird - answer. If they asked for a Bfoo speed they may have problems - digesting non-exact replies so fuzz a bit */ + * answer. If they asked for a Bfoo speed they may have problems + * digesting non-exact replies so fuzz a bit. + */ if ((termios->c_cflag & CBAUD) == BOTHER) { oclose = 0; @@ -191,7 +192,8 @@ void tty_termios_encode_baud_rate(struct ktermios *termios, if (ibaud - iclose <= baud_table[i] && ibaud + iclose >= baud_table[i]) { /* For the case input == output don't set IBAUD bits - if the user didn't do so */ + * if the user didn't do so. + */ if (ofound == i && !ibinput) ifound = i; #ifdef IBSHIFT @@ -211,7 +213,8 @@ void tty_termios_encode_baud_rate(struct ktermios *termios, if (ofound == -1) termios->c_cflag |= BOTHER; /* Set exact input bits only if the input and output differ or the - user already did */ + * user already did. + */ if (ifound == -1 && (ibaud != obaud || ibinput)) termios->c_cflag |= (BOTHER << IBSHIFT); #else From 993c67b1fe44f340bb2aac970adca48a8c20daa9 Mon Sep 17 00:00:00 2001 From: Xiaofei Tan Date: Wed, 12 May 2021 17:26:11 +0800 Subject: [PATCH 072/227] tty: tty_buffer: Add a blank line after declarations Add a blank line after declarations, reported by checkpatch.pl. Signed-off-by: Xiaofei Tan Link: https://lore.kernel.org/r/1620811585-18582-4-git-send-email-tanxiaofei@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_buffer.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 585a19f65284..1b52432282c2 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -91,6 +91,7 @@ EXPORT_SYMBOL_GPL(tty_buffer_unlock_exclusive); unsigned int tty_buffer_space_avail(struct tty_port *port) { int space = port->buf.mem_limit - atomic_read(&port->buf.mem_used); + return max(space, 0); } EXPORT_SYMBOL_GPL(tty_buffer_space_avail); @@ -312,11 +313,13 @@ int tty_insert_flip_string_fixed_flag(struct tty_port *port, const unsigned char *chars, char flag, size_t size) { int copied = 0; + do { int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); int flags = (flag == TTY_NORMAL) ? TTYB_NORMAL : 0; int space = __tty_buffer_request_room(port, goal, flags); struct tty_buffer *tb = port->buf.tail; + if (unlikely(space == 0)) break; memcpy(char_buf_ptr(tb, tb->used), chars, space); @@ -348,10 +351,12 @@ int tty_insert_flip_string_flags(struct tty_port *port, const unsigned char *chars, const char *flags, size_t size) { int copied = 0; + do { int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); int space = tty_buffer_request_room(port, goal); struct tty_buffer *tb = port->buf.tail; + if (unlikely(space == 0)) break; memcpy(char_buf_ptr(tb, tb->used), chars, space); @@ -431,8 +436,10 @@ int tty_prepare_flip_string(struct tty_port *port, unsigned char **chars, size_t size) { int space = __tty_buffer_request_room(port, size, TTYB_NORMAL); + if (likely(space)) { struct tty_buffer *tb = port->buf.tail; + *chars = char_buf_ptr(tb, tb->used); if (~tb->flags & TTYB_NORMAL) memset(flag_buf_ptr(tb, tb->used), TTY_NORMAL, space); From dadc104948689a39304cc3cc3782fca1e4f38475 Mon Sep 17 00:00:00 2001 From: Xiaofei Tan Date: Wed, 12 May 2021 17:26:12 +0800 Subject: [PATCH 073/227] tty: tty_buffer: Remove the repeated word 'the' Remove the repeated word 'the' following advice of checkpatch.pl Besides, add a period at the end of comment sentence. Signed-off-by: Xiaofei Tan Link: https://lore.kernel.org/r/1620811585-18582-5-git-send-email-tanxiaofei@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_buffer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 1b52432282c2..0df8a7250344 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -32,8 +32,8 @@ * We default to dicing tty buffer allocations to this many characters * in order to avoid multiple page allocations. We know the size of * tty_buffer itself but it must also be taken into account that the - * the buffer is 256 byte aligned. See tty_buffer_find for the allocation - * logic this must match + * buffer is 256 byte aligned. See tty_buffer_find for the allocation + * logic this must match. */ #define TTY_BUFFER_PAGE (((PAGE_SIZE - sizeof(struct tty_buffer)) / 2) & ~0xFF) From 80e3fce1034a8b94ad375545b127dcec6d0e4151 Mon Sep 17 00:00:00 2001 From: Xiaofei Tan Date: Wed, 12 May 2021 17:26:13 +0800 Subject: [PATCH 074/227] tty: tty_buffer: Fix coding style issues of block comments Fix coding style issues of block comments, reported by checkpatch.pl. Besides, add a period at the end of the sentenses. Signed-off-by: Xiaofei Tan Link: https://lore.kernel.org/r/1620811585-18582-6-git-send-email-tanxiaofei@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_buffer.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 0df8a7250344..ace778ed23b9 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -170,7 +170,8 @@ static struct tty_buffer *tty_buffer_alloc(struct tty_port *port, size_t size) } /* Should possibly check if this fails for the largest buffer we - have queued and recycle that ? */ + * have queued and recycle that ? + */ if (atomic_read(&port->buf.mem_used) > port->buf.mem_limit) return NULL; p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC); @@ -329,7 +330,8 @@ int tty_insert_flip_string_fixed_flag(struct tty_port *port, copied += space; chars += space; /* There is a small chance that we need to split the data over - several buffers. If this is the case we must loop */ + * several buffers. If this is the case we must loop. + */ } while (unlikely(size > copied)); return copied; } @@ -366,7 +368,8 @@ int tty_insert_flip_string_flags(struct tty_port *port, chars += space; flags += space; /* There is a small chance that we need to split the data over - several buffers. If this is the case we must loop */ + * several buffers. If this is the case we must loop. + */ } while (unlikely(size > copied)); return copied; } From 395e783371de05aad0f1acfe802ba618aa8267e8 Mon Sep 17 00:00:00 2001 From: Xiaofei Tan Date: Wed, 12 May 2021 17:26:14 +0800 Subject: [PATCH 075/227] tty: tty_io: Remove spaces before tabs Remove spaces before tabs following the advice of checkpatch.pl. Signed-off-by: Xiaofei Tan Link: https://lore.kernel.org/r/1620811585-18582-7-git-send-email-tanxiaofei@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 362845dc1c19..b0ccb152bf40 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -33,7 +33,7 @@ * -- Nick Holloway , 27th May 1993. * * Rewrote canonical mode and added more termios flags. - * -- julian@uhunix.uhcc.hawaii.edu (J. Cowley), 13Jan94 + * -- julian@uhunix.uhcc.hawaii.edu (J. Cowley), 13Jan94 * * Reorganized FASYNC support so mouse code can share it. * -- ctm@ardi.com, 9Sep95 @@ -1114,7 +1114,7 @@ void tty_write_message(struct tty_struct *tty, char *msg) static ssize_t file_tty_write(struct file *file, struct kiocb *iocb, struct iov_iter *from) { struct tty_struct *tty = file_tty(file); - struct tty_ldisc *ld; + struct tty_ldisc *ld; ssize_t ret; if (tty_paranoia_check(tty, file_inode(file), "tty_write")) @@ -1928,8 +1928,8 @@ static struct tty_struct *tty_open_current_tty(dev_t device, struct file *filp) * @index: index for the device in the @return driver * @return: driver for this inode (with increased refcount) * - * If @return is not erroneous, the caller is responsible to decrement the - * refcount by tty_driver_kref_put. + * If @return is not erroneous, the caller is responsible to decrement the + * refcount by tty_driver_kref_put. * * Locking: tty_mutex protects get_tty_driver */ @@ -3317,11 +3317,11 @@ err_put: EXPORT_SYMBOL_GPL(tty_register_device_attr); /** - * tty_unregister_device - unregister a tty device - * @driver: the tty driver that describes the tty device - * @index: the index in the tty driver for this tty device + * tty_unregister_device - unregister a tty device + * @driver: the tty driver that describes the tty device + * @index: the index in the tty driver for this tty device * - * If a tty device is registered with a call to tty_register_device() then + * If a tty device is registered with a call to tty_register_device() then * this function must be called when the tty device is gone. * * Locking: ?? From e73b240785f284582f95dd778437da7eaa5cddc2 Mon Sep 17 00:00:00 2001 From: Xiaofei Tan Date: Wed, 12 May 2021 17:26:15 +0800 Subject: [PATCH 076/227] tty: tty_io: Add a blank line after declarations Add a blank line after declarations, reported by checkpatch.pl. Signed-off-by: Xiaofei Tan Link: https://lore.kernel.org/r/1620811585-18582-8-git-send-email-tanxiaofei@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index b0ccb152bf40..1266d45730fe 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -320,6 +320,7 @@ static struct tty_driver *get_tty_driver(dev_t device, int *index) list_for_each_entry(p, &tty_drivers, tty_drivers) { dev_t base = MKDEV(p->major, p->minor_start); + if (device < base || device >= base + p->num) continue; *index = device - base; @@ -1033,6 +1034,7 @@ static inline ssize_t do_tty_write( /* Do the write .. */ for (;;) { size_t size = count; + if (size > chunk) size = chunk; @@ -1155,6 +1157,7 @@ ssize_t redirected_tty_write(struct kiocb *iocb, struct iov_iter *iter) */ if (p) { ssize_t res; + res = file_tty_write(p, iocb, iter); fput(p); return res; @@ -1942,6 +1945,7 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, #ifdef CONFIG_VT case MKDEV(TTY_MAJOR, 0): { extern struct tty_driver *console_driver; + driver = tty_driver_kref_get(console_driver); *index = fg_console; break; @@ -1949,6 +1953,7 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, #endif case MKDEV(TTYAUX_MAJOR, 1): { struct tty_driver *console_driver = console_device(index); + if (console_driver) { driver = tty_driver_kref_get(console_driver); if (driver && filp) { @@ -2388,6 +2393,7 @@ EXPORT_SYMBOL(tty_do_resize); static int tiocswinsz(struct tty_struct *tty, struct winsize __user *arg) { struct winsize tmp_ws; + if (copy_from_user(&tmp_ws, arg, sizeof(*arg))) return -EFAULT; @@ -2412,6 +2418,7 @@ static int tioccons(struct file *file) return -EPERM; if (file->f_op->write_iter == redirected_tty_write) { struct file *f; + spin_lock(&redirect_lock); f = redirect; redirect = NULL; @@ -2734,6 +2741,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case TIOCGEXCL: { int excl = test_bit(TTY_EXCLUSIVE, &tty->flags); + return put_user(excl, (int __user *)p); } case TIOCGETD: @@ -2748,6 +2756,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case TIOCGDEV: { unsigned int ret = new_encode_dev(tty_devnum(real_tty)); + return put_user(ret, (unsigned int __user *)p); } /* @@ -3103,6 +3112,7 @@ EXPORT_SYMBOL(do_SAK); static struct device *tty_get_device(struct tty_struct *tty) { dev_t devt = tty_devnum(tty); + return class_find_device_by_devt(tty_class, devt); } From 94bc2eb5fb4337db9ae654e5865f6b368dc1e11e Mon Sep 17 00:00:00 2001 From: Xiaofei Tan Date: Wed, 12 May 2021 17:26:16 +0800 Subject: [PATCH 077/227] tty: tty_io: Fix spaces required around that ':' Fix spaces required around that ':', reported by checkpatch.pl. Signed-off-by: Xiaofei Tan Link: https://lore.kernel.org/r/1620811585-18582-9-git-send-email-tanxiaofei@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 1266d45730fe..ff0809d462eb 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2341,7 +2341,7 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg) err = copy_to_user(arg, &tty->winsize, sizeof(*arg)); mutex_unlock(&tty->winsize_mutex); - return err ? -EFAULT: 0; + return err ? -EFAULT : 0; } /** From d91c1a3eed06694514a522525510a2aeba351efa Mon Sep 17 00:00:00 2001 From: Xiaofei Tan Date: Wed, 12 May 2021 17:26:17 +0800 Subject: [PATCH 078/227] tty: tty_io: Fix trailing whitespace issues Fix trailing whitespace issues, reported by checkpatch.pl. Signed-off-by: Xiaofei Tan Link: https://lore.kernel.org/r/1620811585-18582-10-git-send-email-tanxiaofei@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index ff0809d462eb..1fe40153d7d9 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -3015,7 +3015,7 @@ static int this_tty(const void *t, struct file *file, unsigned fd) return 0; return file_tty(file) != t ? 0 : fd + 1; } - + /* * This implements the "Secure Attention Key" --- the idea is to * prevent trojan horses by killing all processes associated with this From b426a5b8154c3f3858e8e431ef2e69b73c3ee4a2 Mon Sep 17 00:00:00 2001 From: Xiaofei Tan Date: Wed, 12 May 2021 17:26:18 +0800 Subject: [PATCH 079/227] tty: tty_io: Fix coding style issues of block comments Fix coding style issues of block comments, reported by checkpatch.pl. Besides, add a period at the end of the sentenses. Signed-off-by: Xiaofei Tan Link: https://lore.kernel.org/r/1620811585-18582-11-git-send-email-tanxiaofei@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 1fe40153d7d9..6da0b07269b2 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -135,8 +135,9 @@ struct ktermios tty_std_termios = { /* for the benefit of tty drivers */ EXPORT_SYMBOL(tty_std_termios); /* This list gets poked at by procfs and various bits of boot up code. This - could do with some rationalisation such as pulling the tty proc function - into this file */ + * could do with some rationalisation such as pulling the tty proc function + * into this file. + */ LIST_HEAD(tty_drivers); /* linked list of tty drivers */ @@ -614,8 +615,9 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session) set_bit(TTY_HUPPING, &tty->flags); /* inuse_filps is protected by the single tty lock, - this really needs to change if we want to flush the - workqueue with the lock held */ + * this really needs to change if we want to flush the + * workqueue with the lock held. + */ check_tty_count(tty, "tty_hangup"); spin_lock(&tty->files_lock); @@ -942,7 +944,8 @@ static ssize_t tty_read(struct kiocb *iocb, struct iov_iter *to) return -EIO; /* We want to wait for the line discipline to sort out in this - situation */ + * situation. + */ ld = tty_ldisc_ref_wait(tty); if (!ld) return hung_up_tty_read(iocb, to); @@ -1572,7 +1575,8 @@ static void queue_release_one_tty(struct kref *kref) struct tty_struct *tty = container_of(kref, struct tty_struct, kref); /* The hangup queue is now free so we can reuse it rather than - waste a chunk of memory for each port */ + * waste a chunk of memory for each port. + */ INIT_WORK(&tty->hangup_work, release_one_tty); schedule_work(&tty->hangup_work); } @@ -1877,7 +1881,8 @@ int tty_release(struct inode *inode, struct file *filp) tty_unlock(tty); /* At this point, the tty->count == 0 should ensure a dead tty - cannot be re-opened by a racing opener */ + * cannot be re-opened by a racing opener. + */ if (!final) return 0; From 44969f85402e2f8a9fcfa33520e5ba7f81556f0a Mon Sep 17 00:00:00 2001 From: Xiaofei Tan Date: Wed, 12 May 2021 17:26:19 +0800 Subject: [PATCH 080/227] tty: tty_io: Remove the repeated word 'can' Remove the repeated word 'can' following advice of checkpatch.pl Signed-off-by: Xiaofei Tan Link: https://lore.kernel.org/r/1620811585-18582-12-git-send-email-tanxiaofei@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 6da0b07269b2..7a1bd4e222ed 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1155,7 +1155,7 @@ ssize_t redirected_tty_write(struct kiocb *iocb, struct iov_iter *iter) spin_unlock(&redirect_lock); /* - * We know the redirected tty is just another tty, we can can + * We know the redirected tty is just another tty, we can * call file_tty_write() directly with that file pointer. */ if (p) { From 5e4d5ac32ba538f29ff64104e7211486cc805904 Mon Sep 17 00:00:00 2001 From: Xiaofei Tan Date: Wed, 12 May 2021 17:26:20 +0800 Subject: [PATCH 081/227] tty: tty_io: Fix an issue of code indent for conditional statements Fix an issue of code indent for conditional statements,reported by checkpatch.pl. Signed-off-by: Xiaofei Tan Link: https://lore.kernel.org/r/1620811585-18582-13-git-send-email-tanxiaofei@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 7a1bd4e222ed..88739b1fab45 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1125,7 +1125,7 @@ static ssize_t file_tty_write(struct file *file, struct kiocb *iocb, struct iov_ if (tty_paranoia_check(tty, file_inode(file), "tty_write")) return -EIO; if (!tty || !tty->ops->write || tty_io_error(tty)) - return -EIO; + return -EIO; /* Short term debug to catch buggy drivers */ if (tty->ops->write_room == NULL) tty_err(tty, "missing write_room method\n"); From 27eab129323bac984a3de4d9585351dc525793bd Mon Sep 17 00:00:00 2001 From: Xiaofei Tan Date: Wed, 12 May 2021 17:26:21 +0800 Subject: [PATCH 082/227] tty: tty_io: Delete a blank line before EXPORT_SYMBOL(foo) Delete a blank line before EXPORT_SYMBOL(foo) so that EXPORT_SYMBOL(foo) immediately follow its function/variable, reported by checkpatch.pl. Signed-off-by: Xiaofei Tan Link: https://lore.kernel.org/r/1620811585-18582-14-git-send-email-tanxiaofei@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 88739b1fab45..4a1c1a1928a3 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -131,7 +131,6 @@ struct ktermios tty_std_termios = { /* for the benefit of tty drivers */ .c_ospeed = 38400, /* .c_line = N_TTY, */ }; - EXPORT_SYMBOL(tty_std_termios); /* This list gets poked at by procfs and various bits of boot up code. This @@ -249,7 +248,6 @@ const char *tty_name(const struct tty_struct *tty) return "NULL tty"; return tty->name; } - EXPORT_SYMBOL(tty_name); const char *tty_driver_name(const struct tty_struct *tty) @@ -539,7 +537,6 @@ void tty_wakeup(struct tty_struct *tty) } wake_up_interruptible_poll(&tty->write_wait, EPOLLOUT); } - EXPORT_SYMBOL_GPL(tty_wakeup); /** @@ -697,7 +694,6 @@ void tty_hangup(struct tty_struct *tty) tty_debug_hangup(tty, "hangup\n"); schedule_work(&tty->hangup_work); } - EXPORT_SYMBOL(tty_hangup); /** @@ -714,7 +710,6 @@ void tty_vhangup(struct tty_struct *tty) tty_debug_hangup(tty, "vhangup\n"); __tty_hangup(tty, 0); } - EXPORT_SYMBOL(tty_vhangup); @@ -764,7 +759,6 @@ int tty_hung_up_p(struct file *filp) { return (filp && filp->f_op == &hung_up_tty_fops); } - EXPORT_SYMBOL(tty_hung_up_p); /** @@ -3110,7 +3104,6 @@ void do_SAK(struct tty_struct *tty) return; schedule_work(&tty->SAK_work); } - EXPORT_SYMBOL(do_SAK); /* Must put_device() after it's unused! */ From fab491030cea293692f3a48a2c77a754f79c9ccc Mon Sep 17 00:00:00 2001 From: Xiaofei Tan Date: Wed, 12 May 2021 17:26:22 +0800 Subject: [PATCH 083/227] tty: tty_io: Remove return in void function Remove return in void function, reported by checkpatch.pl. Signed-off-by: Xiaofei Tan Link: https://lore.kernel.org/r/1620811585-18582-15-git-send-email-tanxiaofei@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 4a1c1a1928a3..8f9e89715a68 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1090,7 +1090,6 @@ void tty_write_message(struct tty_struct *tty, char *msg) tty_unlock(tty); tty_write_unlock(tty); } - return; } From 16d15f747a099f107f4522547a75a3b9b658131b Mon Sep 17 00:00:00 2001 From: Xiaofei Tan Date: Wed, 12 May 2021 17:26:23 +0800 Subject: [PATCH 084/227] tty: tty_port: Delete a blank line before EXPORT_SYMBOL(foo) Delete a blank line before EXPORT_SYMBOL(foo) so that EXPORT_SYMBOL(foo) immediately follow its function/variable, reported by checkpatch.pl. Signed-off-by: Xiaofei Tan Link: https://lore.kernel.org/r/1620811585-18582-16-git-send-email-tanxiaofei@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_port.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 0eb523207828..7557bcd84b27 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -698,5 +698,4 @@ int tty_port_open(struct tty_port *port, struct tty_struct *tty, mutex_unlock(&port->mutex); return tty_port_block_til_ready(port, tty, filp); } - EXPORT_SYMBOL(tty_port_open); From 54ad59a25ad1e2ec2eb24156a899aaa8e3411376 Mon Sep 17 00:00:00 2001 From: Xiaofei Tan Date: Wed, 12 May 2021 17:26:24 +0800 Subject: [PATCH 085/227] tty: tty_port: Add a blank line after declarations Add a blank line after declarations, reported by checkpatch.pl. Signed-off-by: Xiaofei Tan Link: https://lore.kernel.org/r/1620811585-18582-17-git-send-email-tanxiaofei@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_port.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 7557bcd84b27..189c2fa09c6d 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -688,6 +688,7 @@ int tty_port_open(struct tty_port *port, struct tty_struct *tty, clear_bit(TTY_IO_ERROR, &tty->flags); if (port->ops->activate) { int retval = port->ops->activate(port, tty); + if (retval) { mutex_unlock(&port->mutex); return retval; From 1df92640ba7db67c359dc2d53ef43861281f5af6 Mon Sep 17 00:00:00 2001 From: Xiaofei Tan Date: Wed, 12 May 2021 17:26:25 +0800 Subject: [PATCH 086/227] tty: tty_port: Fix coding style issues of block comments Fix coding style issues of block comments, reported by checkpatch.pl. Besides, add a period at the end of the sentenses. Signed-off-by: Xiaofei Tan Link: https://lore.kernel.org/r/1620811585-18582-18-git-send-email-tanxiaofei@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_port.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 189c2fa09c6d..2f1061a9d926 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -468,7 +468,8 @@ int tty_port_block_til_ready(struct tty_port *port, DEFINE_WAIT(wait); /* if non-blocking mode is set we can pass directly to open unless - the port has just hung up or is in another error state */ + * the port has just hung up or is in another error state. + */ if (tty_io_error(tty)) { tty_port_set_active(port, 1); return 0; @@ -485,8 +486,9 @@ int tty_port_block_til_ready(struct tty_port *port, do_clocal = 1; /* Block waiting until we can proceed. We may need to wait for the - carrier, but we must also wait for any close that is in progress - before the next open may complete */ + * carrier, but we must also wait for any close that is in progress + * before the next open may complete. + */ retval = 0; @@ -503,7 +505,8 @@ int tty_port_block_til_ready(struct tty_port *port, prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE); /* Check for a hangup or uninitialised port. - Return accordingly */ + * Return accordingly. + */ if (tty_hung_up_p(filp) || !tty_port_initialized(port)) { if (port->flags & ASYNC_HUP_NOTIFY) retval = -EAGAIN; @@ -530,7 +533,8 @@ int tty_port_block_til_ready(struct tty_port *port, finish_wait(&port->open_wait, &wait); /* Update counts. A parallel hangup will have set count to zero and - we must not mess that up further */ + * we must not mess that up further. + */ spin_lock_irqsave(&port->lock, flags); if (!tty_hung_up_p(filp)) port->count++; From 7985723d21a15d4a237efa89e85c938875a3f9c3 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 10 May 2021 17:49:47 +0300 Subject: [PATCH 087/227] vt: Move custom isspace() to its own namespace If by some reason any of the headers will include ctype.h we will have a name collision. Avoid this by moving isspace() to the dedicate namespace. First appearance of the code is in the commit 24a1c2a769cf ("Import 1.1.92"). Reported-by: kernel test robot Reviewed-by: Jiri Slaby Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210510144947.58270-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/selection.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c index f245a5acf7e9..bcb6bc5731cc 100644 --- a/drivers/tty/vt/selection.c +++ b/drivers/tty/vt/selection.c @@ -33,7 +33,7 @@ #include /* Don't take this from : 011-015 on the screen aren't spaces */ -#define isspace(c) ((c) == ' ') +#define is_space_on_vt(c) ((c) == ' ') /* FIXME: all this needs locking */ static struct vc_selection { @@ -209,7 +209,7 @@ static int vc_selection_store_chars(struct vc_data *vc, bool unicode) bp += store_utf8(c, bp); else *bp++ = c; - if (!isspace(c)) + if (!is_space_on_vt(c)) obp = bp; if (!((i + 2) % vc->vc_size_row)) { /* strip trailing blanks from line and add newline, @@ -238,9 +238,9 @@ static int vc_do_selection(struct vc_data *vc, unsigned short mode, int ps, new_sel_end = pe; break; case TIOCL_SELWORD: /* word-by-word selection */ - spc = isspace(sel_pos(ps, unicode)); + spc = is_space_on_vt(sel_pos(ps, unicode)); for (new_sel_start = ps; ; ps -= 2) { - if ((spc && !isspace(sel_pos(ps, unicode))) || + if ((spc && !is_space_on_vt(sel_pos(ps, unicode))) || (!spc && !inword(sel_pos(ps, unicode)))) break; new_sel_start = ps; @@ -248,9 +248,9 @@ static int vc_do_selection(struct vc_data *vc, unsigned short mode, int ps, break; } - spc = isspace(sel_pos(pe, unicode)); + spc = is_space_on_vt(sel_pos(pe, unicode)); for (new_sel_end = pe; ; pe += 2) { - if ((spc && !isspace(sel_pos(pe, unicode))) || + if ((spc && !is_space_on_vt(sel_pos(pe, unicode))) || (!spc && !inword(sel_pos(pe, unicode)))) break; new_sel_end = pe; @@ -276,12 +276,12 @@ static int vc_do_selection(struct vc_data *vc, unsigned short mode, int ps, /* select to end of line if on trailing space */ if (new_sel_end > new_sel_start && !atedge(new_sel_end, vc->vc_size_row) && - isspace(sel_pos(new_sel_end, unicode))) { + is_space_on_vt(sel_pos(new_sel_end, unicode))) { for (pe = new_sel_end + 2; ; pe += 2) - if (!isspace(sel_pos(pe, unicode)) || + if (!is_space_on_vt(sel_pos(pe, unicode)) || atedge(pe, vc->vc_size_row)) break; - if (isspace(sel_pos(pe, unicode))) + if (is_space_on_vt(sel_pos(pe, unicode))) new_sel_end = pe; } if (vc_sel.start == -1) /* no current selection */ From 7912146abf6705c771b28ea5b6d608ee2ea39dcd Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Mon, 10 May 2021 18:25:19 -0700 Subject: [PATCH 088/227] tty: hvc_iucv: Drop unnecessary NULL check after container_of The result of container_of() operations is never NULL unless the extracted element is the first element of the embedded structure. This is not the case here. The NULL check is therefore unnecessary and misleading. Remove it. This change was made automatically with the following Coccinelle script. @@ type t; identifier v; statement s; @@ <+... ( t v = container_of(...); | v = container_of(...); ) ... when != v - if (\( !v \| v == NULL \) ) s ...+> Signed-off-by: Guenter Roeck Link: https://lore.kernel.org/r/20210511012519.2359074-1-linux@roeck-us.net Signed-off-by: Greg Kroah-Hartman --- drivers/tty/hvc/hvc_iucv.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/tty/hvc/hvc_iucv.c b/drivers/tty/hvc/hvc_iucv.c index 2af1e5751bd6..3bd03ae01bf5 100644 --- a/drivers/tty/hvc/hvc_iucv.c +++ b/drivers/tty/hvc/hvc_iucv.c @@ -438,8 +438,6 @@ static void hvc_iucv_sndbuf_work(struct work_struct *work) struct hvc_iucv_private *priv; priv = container_of(work, struct hvc_iucv_private, sndbuf_work.work); - if (!priv) - return; spin_lock_bh(&priv->lock); hvc_iucv_send(priv); From f985b0b6e1db4d5301379c5207606de915f9c4d0 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 18 May 2021 09:58:31 +0200 Subject: [PATCH 089/227] dt-bindings: serial: amlogic, meson-uart: add fifo-size property On most of the Amlogic SoCs, the first UART controller in the "Everything-Else" power domain has 128bytes of RX & TX FIFO, so add an optional property to describe a different FIFO size from the other ports (64bytes). Reviewed-by: Martin Blumenstingl Reviewed-by: Rob Herring Signed-off-by: Neil Armstrong Link: https://lore.kernel.org/r/20210518075833.3736038-2-narmstrong@baylibre.com Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/serial/amlogic,meson-uart.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml index 75ebc9952a99..7487aa6ef849 100644 --- a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml +++ b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml @@ -55,6 +55,11 @@ properties: - const: pclk - const: baud + fifo-size: + description: The fifo size supported by the UART channel. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [64, 128] + required: - compatible - reg From 27d44e05d7b85d9d4cfe0a3c0663ea49752ece93 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 18 May 2021 09:58:32 +0200 Subject: [PATCH 090/227] tty: serial: meson: retrieve port FIFO size from DT Now the DT bindings has a property to get the FIFO size for a particular port, retrieve it and use to setup the FIFO interrupts threshold. Reviewed-by: Kevin Hilman Signed-off-by: Neil Armstrong Link: https://lore.kernel.org/r/20210518075833.3736038-3-narmstrong@baylibre.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/meson_uart.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index d7f55031b2cf..efee3935917f 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -715,6 +715,7 @@ static int meson_uart_probe(struct platform_device *pdev) { struct resource *res_mem, *res_irq; struct uart_port *port; + u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */ int ret = 0; if (pdev->dev.of_node) @@ -742,6 +743,8 @@ static int meson_uart_probe(struct platform_device *pdev) if (!res_irq) return -ENODEV; + of_property_read_u32(pdev->dev.of_node, "fifo-size", &fifosize); + if (meson_ports[pdev->id]) { dev_err(&pdev->dev, "port %d already allocated\n", pdev->id); return -EBUSY; @@ -771,7 +774,7 @@ static int meson_uart_probe(struct platform_device *pdev) port->type = PORT_MESON; port->x_char = 0; port->ops = &meson_uart_ops; - port->fifosize = 64; + port->fifosize = fifosize; meson_ports[pdev->id] = port; platform_set_drvdata(pdev, port); From 92e06e12212abe4b27ff18445a0f88e6b5236331 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Fri, 14 May 2021 20:22:11 +0100 Subject: [PATCH 091/227] dt-bindings: serial: renesas,scif: Document r9a07g044 bindings Document R9A07G044 SoC variants, common compatiable string "renesas,scif-r9a07g044" is added for RZ/G2L and RZ/G2LC SoC. Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das Acked-by: Rob Herring Link: https://lore.kernel.org/r/20210514192218.13022-10-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/renesas,scif.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/serial/renesas,scif.yaml b/Documentation/devicetree/bindings/serial/renesas,scif.yaml index 22d76829f7ae..6b8731f7f2fb 100644 --- a/Documentation/devicetree/bindings/serial/renesas,scif.yaml +++ b/Documentation/devicetree/bindings/serial/renesas,scif.yaml @@ -64,6 +64,10 @@ properties: - const: renesas,rcar-gen3-scif # R-Car Gen3 and RZ/G2 - const: renesas,scif # generic SCIF compatible UART + - items: + - enum: + - renesas,scif-r9a07g044 # RZ/G2{L,LC} + reg: maxItems: 1 From 064b6e47b2b2d4a20566ba6f8dc90e46b599b35f Mon Sep 17 00:00:00 2001 From: Biju Das Date: Fri, 14 May 2021 20:22:12 +0100 Subject: [PATCH 092/227] serial: sh-sci: Add support for RZ/G2L SoC Add serial support for RZ/G2L SoC with earlycon and extended mode register support. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Link: https://lore.kernel.org/r/20210514192218.13022-11-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 11 +++++++++++ drivers/tty/serial/sh-sci.h | 1 + 2 files changed, 12 insertions(+) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index ef37fdf37612..872a2c3b11c4 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -306,6 +306,7 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = { [SCFDR] = { 0x0E, 16 }, [SCSPTR] = { 0x10, 16 }, [SCLSR] = { 0x12, 16 }, + [SEMR] = { 0x14, 8 }, }, .fifosize = 16, .overrun_reg = SCLSR, @@ -2527,6 +2528,8 @@ done: case 27: smr_val |= SCSMR_SRC_27; break; } smr_val |= cks; + if (sci_getreg(port, SEMR)->size) + serial_port_out(port, SEMR, 0); serial_port_out(port, SCSCR, scr_val | s->hscif_tot); serial_port_out(port, SCSMR, smr_val); serial_port_out(port, SCBRR, brr); @@ -2561,6 +2564,8 @@ done: scr_val = s->cfg->scscr & (SCSCR_CKE1 | SCSCR_CKE0); smr_val |= serial_port_in(port, SCSMR) & (SCSMR_CKEDG | SCSMR_SRC_MASK | SCSMR_CKS); + if (sci_getreg(port, SEMR)->size) + serial_port_out(port, SEMR, 0); serial_port_out(port, SCSCR, scr_val | s->hscif_tot); serial_port_out(port, SCSMR, smr_val); } @@ -3170,6 +3175,10 @@ static const struct of_device_id of_sci_match[] = { .compatible = "renesas,scif-r7s9210", .data = SCI_OF_DATA(PORT_SCIF, SCIx_RZ_SCIFA_REGTYPE), }, + { + .compatible = "renesas,scif-r9a07g044", + .data = SCI_OF_DATA(PORT_SCIF, SCIx_RZ_SCIFA_REGTYPE), + }, /* Family-specific types */ { .compatible = "renesas,rcar-gen1-scif", @@ -3452,6 +3461,7 @@ static int __init rzscifa_early_console_setup(struct earlycon_device *device, port_cfg.regtype = SCIx_RZ_SCIFA_REGTYPE; return early_console_setup(device, PORT_SCIF); } + static int __init scifa_early_console_setup(struct earlycon_device *device, const char *opt) { @@ -3471,6 +3481,7 @@ static int __init hscif_early_console_setup(struct earlycon_device *device, OF_EARLYCON_DECLARE(sci, "renesas,sci", sci_early_console_setup); OF_EARLYCON_DECLARE(scif, "renesas,scif", scif_early_console_setup); OF_EARLYCON_DECLARE(scif, "renesas,scif-r7s9210", rzscifa_early_console_setup); +OF_EARLYCON_DECLARE(scif, "renesas,scif-r9a07g044", rzscifa_early_console_setup); OF_EARLYCON_DECLARE(scifa, "renesas,scifa", scifa_early_console_setup); OF_EARLYCON_DECLARE(scifb, "renesas,scifb", scifb_early_console_setup); OF_EARLYCON_DECLARE(hscif, "renesas,hscif", hscif_early_console_setup); diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h index c0dfe4382898..c0ae78632dda 100644 --- a/drivers/tty/serial/sh-sci.h +++ b/drivers/tty/serial/sh-sci.h @@ -31,6 +31,7 @@ enum { SCCKS, /* BRG Clock Select Register */ HSRTRGR, /* Rx FIFO Data Count Trigger Register */ HSTTRGR, /* Tx FIFO Data Count Trigger Register */ + SEMR, /* Serial extended mode register */ SCIx_NR_REGS, }; From 1e49b0954c91019f51ce22cd0bce2297dd928f8c Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 14 May 2021 00:02:24 +0100 Subject: [PATCH 093/227] serial: kgdb_nmi: remove redundant initialization of variable c The variable c is being initialized with a value that is never read, it is being updated later on. The assignment is redundant and can be removed. Reviewed-by: Jiri Slaby Signed-off-by: Colin Ian King Addresses-Coverity: ("Unused value") Link: https://lore.kernel.org/r/20210513230224.138859-1-colin.king@canonical.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/kgdb_nmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/kgdb_nmi.c b/drivers/tty/serial/kgdb_nmi.c index b193bbc666d4..3e7c6ee8e4b3 100644 --- a/drivers/tty/serial/kgdb_nmi.c +++ b/drivers/tty/serial/kgdb_nmi.c @@ -115,7 +115,7 @@ static void kgdb_tty_recv(int ch) static int kgdb_nmi_poll_one_knock(void) { static int n; - int c = -1; + int c; const char *magic = kgdb_nmi_magic; size_t m = strlen(magic); bool printch = false; From 1d751b04a49dd7c2c7a07388074d262225f4de74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Mon, 17 May 2021 01:05:44 +0200 Subject: [PATCH 094/227] dt-bindings: serial: snps-dw-apb-uart: Add Rockchip RK1808 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a Rockchip RK1808 compatible. Signed-off-by: Andreas Färber Acked-by: Rob Herring Link: https://lore.kernel.org/r/20210516230551.12469-3-afaerber@suse.de Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml index 88bf4adf1067..b49fda5e608f 100644 --- a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml +++ b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml @@ -23,6 +23,7 @@ properties: - items: - enum: - rockchip,px30-uart + - rockchip,rk1808-uart - rockchip,rk3036-uart - rockchip,rk3066-uart - rockchip,rk3188-uart From 18ee37e1382a7c4840e753bc8e9ba5fd5dc663f5 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 19 May 2021 11:25:41 +0200 Subject: [PATCH 095/227] serial: drop irq-flags initialisations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's no need to initialise irq-flags variables before saving the interrupt state. Drop the redundant initialisations from drivers that got this wrong. Acked-by: Uwe Kleine-König Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20210519092541.10137-1-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 2 +- drivers/tty/serial/imx.c | 2 +- drivers/tty/serial/omap-serial.c | 10 +++++----- drivers/tty/serial/serial_core.c | 4 ++-- drivers/tty/serial/st-asc.c | 2 +- drivers/tty/serial/stm32-usart.c | 2 +- drivers/tty/serial/xilinx_uartps.c | 8 ++++---- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 78682c12156a..e14f3378b8a0 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -1062,7 +1062,7 @@ static void pl011_dma_rx_poll(struct timer_list *t) struct tty_port *port = &uap->port.state->port; struct pl011_dmarx_data *dmarx = &uap->dmarx; struct dma_chan *rxchan = uap->dmarx.chan; - unsigned long flags = 0; + unsigned long flags; unsigned int dmataken = 0; unsigned int size = 0; struct pl011_sgbuf *sgbuf; diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 7d5a8dfa3e91..4b838601cdce 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -1975,8 +1975,8 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count) { struct imx_port *sport = imx_uart_ports[co->index]; struct imx_port_ucrs old_ucr; + unsigned long flags; unsigned int ucr1; - unsigned long flags = 0; int locked = 1; if (sport->port.sysrq) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 84e8158088cd..9e81b09ba08e 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -626,7 +626,7 @@ static irqreturn_t serial_omap_irq(int irq, void *dev_id) static unsigned int serial_omap_tx_empty(struct uart_port *port) { struct uart_omap_port *up = to_uart_omap_port(port); - unsigned long flags = 0; + unsigned long flags; unsigned int ret = 0; pm_runtime_get_sync(up->dev); @@ -704,7 +704,7 @@ static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl) static void serial_omap_break_ctl(struct uart_port *port, int break_state) { struct uart_omap_port *up = to_uart_omap_port(port); - unsigned long flags = 0; + unsigned long flags; dev_dbg(up->port.dev, "serial_omap_break_ctl+%d\n", up->port.line); pm_runtime_get_sync(up->dev); @@ -722,7 +722,7 @@ static void serial_omap_break_ctl(struct uart_port *port, int break_state) static int serial_omap_startup(struct uart_port *port) { struct uart_omap_port *up = to_uart_omap_port(port); - unsigned long flags = 0; + unsigned long flags; int retval; /* @@ -797,7 +797,7 @@ static int serial_omap_startup(struct uart_port *port) static void serial_omap_shutdown(struct uart_port *port) { struct uart_omap_port *up = to_uart_omap_port(port); - unsigned long flags = 0; + unsigned long flags; dev_dbg(up->port.dev, "serial_omap_shutdown+%d\n", up->port.line); @@ -845,7 +845,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, { struct uart_omap_port *up = to_uart_omap_port(port); unsigned char cval = 0; - unsigned long flags = 0; + unsigned long flags; unsigned int baud, quot; switch (termios->c_cflag & CSIZE) { diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index d29329eb52f4..2793b1cf2d24 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -184,8 +184,8 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, int init_hw) { struct uart_port *uport = uart_port_check(state); + unsigned long flags; unsigned long page; - unsigned long flags = 0; int retval = 0; if (uport->type == PORT_UNKNOWN) @@ -275,7 +275,7 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state) { struct uart_port *uport = uart_port_check(state); struct tty_port *port = &state->port; - unsigned long flags = 0; + unsigned long flags; char *xmit_buf = NULL; /* diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c index e7048515a79c..f092c11f9d7d 100644 --- a/drivers/tty/serial/st-asc.c +++ b/drivers/tty/serial/st-asc.c @@ -478,7 +478,7 @@ static void asc_pm(struct uart_port *port, unsigned int state, unsigned int oldstate) { struct asc_port *ascport = to_asc_port(port); - unsigned long flags = 0; + unsigned long flags; u32 ctl; switch (state) { diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index c2ae7b392b86..bf188bdf9717 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -980,7 +980,7 @@ static void stm32_usart_pm(struct uart_port *port, unsigned int state, struct stm32_port, port); const struct stm32_usart_offsets *ofs = &stm32port->info->ofs; const struct stm32_usart_config *cfg = &stm32port->info->cfg; - unsigned long flags = 0; + unsigned long flags; switch (state) { case UART_PM_STATE_ON: diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index 67a2db621e2b..9bca52ffd84d 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -497,8 +497,8 @@ static int cdns_uart_clk_notifier_cb(struct notifier_block *nb, struct uart_port *port; int locked = 0; struct clk_notifier_data *ndata = data; - unsigned long flags = 0; struct cdns_uart *cdns_uart = to_cdns_uart(nb); + unsigned long flags; port = cdns_uart->port; if (port->suspended) @@ -1210,7 +1210,7 @@ static void cdns_uart_console_write(struct console *co, const char *s, unsigned int count) { struct uart_port *port = console_port; - unsigned long flags = 0; + unsigned long flags; unsigned int imr, ctrl; int locked = 1; @@ -1308,7 +1308,7 @@ static int cdns_uart_suspend(struct device *device) may_wake = device_may_wakeup(device); if (console_suspend_enabled && uart_console(port) && may_wake) { - unsigned long flags = 0; + unsigned long flags; spin_lock_irqsave(&port->lock, flags); /* Empty the receive FIFO 1st before making changes */ @@ -1339,7 +1339,7 @@ static int cdns_uart_resume(struct device *device) { struct uart_port *port = dev_get_drvdata(device); struct cdns_uart *cdns_uart = port->private_data; - unsigned long flags = 0; + unsigned long flags; u32 ctrl_reg; int may_wake; From d4d6f03c4fb3a91dadfe147b47edd40e4d7e4d36 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 17 May 2021 20:29:30 +0300 Subject: [PATCH 096/227] serial: max310x: Try to get crystal clock rate from property In some configurations, mainly ACPI-based, the clock frequency of the device is supplied by very well established 'clock-frequency' property. Hence, try to get it from the property at last if no other providers are available. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210517172930.83353-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/max310x.c | 40 +++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 8534d6e45a1d..b5d780fc16eb 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -552,7 +552,7 @@ static int max310x_update_best_err(unsigned long f, long *besterr) return 1; } -static int max310x_set_ref_clk(struct device *dev, struct max310x_port *s, +static u32 max310x_set_ref_clk(struct device *dev, struct max310x_port *s, unsigned long freq, bool xtal) { unsigned int div, clksrc, pllcfg = 0; @@ -618,7 +618,7 @@ static int max310x_set_ref_clk(struct device *dev, struct max310x_port *s, } } - return (int)bestfreq; + return bestfreq; } static void max310x_batch_write(struct uart_port *port, u8 *txbuf, unsigned int len) @@ -1253,9 +1253,10 @@ static int max310x_gpio_set_config(struct gpio_chip *chip, unsigned int offset, static int max310x_probe(struct device *dev, const struct max310x_devtype *devtype, struct regmap *regmap, int irq) { - int i, ret, fmin, fmax, freq, uartclk; + int i, ret, fmin, fmax, freq; struct max310x_port *s; - bool xtal = false; + u32 uartclk = 0; + bool xtal; if (IS_ERR(regmap)) return PTR_ERR(regmap); @@ -1267,24 +1268,20 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty return -ENOMEM; } + /* Always ask for fixed clock rate from a property. */ + device_property_read_u32(dev, "clock-frequency", &uartclk); + s->clk = devm_clk_get_optional(dev, "osc"); if (IS_ERR(s->clk)) return PTR_ERR(s->clk); if (s->clk) { - fmin = 500000; - fmax = 35000000; + xtal = false; } else { s->clk = devm_clk_get_optional(dev, "xtal"); if (IS_ERR(s->clk)) return PTR_ERR(s->clk); - if (s->clk) { - fmin = 1000000; - fmax = 4000000; - xtal = true; - } else { - dev_err(dev, "Cannot get clock\n"); - return -EINVAL; - } + + xtal = true; } ret = clk_prepare_enable(s->clk); @@ -1292,6 +1289,21 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty return ret; freq = clk_get_rate(s->clk); + if (freq == 0) + freq = uartclk; + if (freq == 0) { + dev_err(dev, "Cannot get clock rate\n"); + return -EINVAL; + } + + if (xtal) { + fmin = 1000000; + fmax = 4000000; + } else { + fmin = 500000; + fmax = 35000000; + } + /* Check frequency limits */ if (freq < fmin || freq > fmax) { ret = -ERANGE; From cb1b206cff461d02ce373f54f1d215532cc5ac7c Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 17 May 2021 20:34:15 +0300 Subject: [PATCH 097/227] serial: sc16is7xx: Use devm_clk_get_optional() Replace open coded variants of devm_clk_get_optional(). Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210517173415.7483-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sc16is7xx.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index 9adb8362578c..acbb615dd28f 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -1208,8 +1208,16 @@ static int sc16is7xx_probe(struct device *dev, /* Always ask for fixed clock rate from a property. */ device_property_read_u32(dev, "clock-frequency", &uartclk); - s->clk = devm_clk_get(dev, NULL); - if (IS_ERR(s->clk)) { + s->clk = devm_clk_get_optional(dev, NULL); + if (IS_ERR(s->clk)) + return PTR_ERR(s->clk); + + ret = clk_prepare_enable(s->clk); + if (ret) + return ret; + + freq = clk_get_rate(s->clk); + if (freq == 0) { if (uartclk) freq = uartclk; if (pfreq) @@ -1217,13 +1225,7 @@ static int sc16is7xx_probe(struct device *dev, if (freq) dev_dbg(dev, "Clock frequency: %luHz\n", freq); else - return PTR_ERR(s->clk); - } else { - ret = clk_prepare_enable(s->clk); - if (ret) - return ret; - - freq = clk_get_rate(s->clk); + return -EINVAL; } s->regmap = regmap; @@ -1358,8 +1360,7 @@ out_thread: kthread_stop(s->kworker_task); out_clk: - if (!IS_ERR(s->clk)) - clk_disable_unprepare(s->clk); + clk_disable_unprepare(s->clk); return ret; } @@ -1383,8 +1384,7 @@ static int sc16is7xx_remove(struct device *dev) kthread_flush_worker(&s->kworker); kthread_stop(s->kworker_task); - if (!IS_ERR(s->clk)) - clk_disable_unprepare(s->clk); + clk_disable_unprepare(s->clk); return 0; } From 4503b1c29db414de608e62d7c67753be8926b2fa Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 13 May 2021 23:18:33 +0100 Subject: [PATCH 098/227] tty: pty: remove redundant initialization of variable fd The variable fd is being initialized with a value that is never read, it is being updated later on. The assignment is redundant and can be removed. Reviewed-by: Jiri Slaby Signed-off-by: Colin Ian King Addresses-Coverity: ("Unused value") Link: https://lore.kernel.org/r/20210513221833.137672-1-colin.king@canonical.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 5ada7e9381eb..73c43f72b4c9 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -611,7 +611,7 @@ static struct cdev ptmx_cdev; */ int ptm_open_peer(struct file *master, struct tty_struct *tty, int flags) { - int fd = -1; + int fd; struct file *filp; int retval = -EINVAL; struct path path; From f6038cf46e376e21a689605e64ab5152e673ac7e Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Tue, 18 May 2021 12:53:53 +0800 Subject: [PATCH 099/227] tty: pty: correct function name pty_resize() Fix the following make W=1 kernel build warning: drivers/tty/pty.c:307: warning: expecting prototype for pty_do_resize(). Prototype was for pty_resize() instead Reviewed-by: Jiri Slaby Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20210518045353.611017-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 73c43f72b4c9..74bfabe5b453 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -282,7 +282,7 @@ static void pty_set_termios(struct tty_struct *tty, } /** - * pty_do_resize - resize event + * pty_resize - resize event * @tty: tty being resized * @ws: window size being set. * From 758dfe3ddcae59b337d4109331f9be39da53b0ed Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Tue, 18 May 2021 07:21:17 +0200 Subject: [PATCH 100/227] MAINTAINERS: TTY LAYER: add some ./include/linux/ header files An early prototypical automated code analysis of headers and the existing MAINTAINERS sections identified some header files in ./include/linux/ to be probably included into the TTY LAYER section. I further checked those suggestions by this analysis and identified a subset of files that I am rather certain to belong to the TTY LAYER. Add these ./include/linux/ header files to TTY LAYER in MAINTAINERS. The patterns include/linux/tty*.h and include/linux/vt_*.h currently cover: include/linux/tty.h include/linux/tty_driver.h include/linux/tty_flip.h include/linux/tty_ldisc.h include/linux/vt_buffer.h include/linux/vt_kern.h Signed-off-by: Lukas Bulwahn Link: https://lore.kernel.org/r/20210518052117.14819-2-lukas.bulwahn@gmail.com Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index bd7aff0c120f..bf9e97cf71bc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -18546,9 +18546,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git F: Documentation/driver-api/serial/ F: drivers/tty/ F: drivers/tty/serial/serial_core.c +F: include/linux/selection.h F: include/linux/serial.h F: include/linux/serial_core.h -F: include/linux/tty.h +F: include/linux/sysrq.h +F: include/linux/tty*.h +F: include/linux/vt.h +F: include/linux/vt_*.h F: include/uapi/linux/serial.h F: include/uapi/linux/serial_core.h F: include/uapi/linux/tty.h From 4bc2bd5aefd60a2837a20b1e88e89eaaa677d229 Mon Sep 17 00:00:00 2001 From: Stafford Horne Date: Mon, 17 May 2021 20:54:52 +0900 Subject: [PATCH 101/227] serial: liteuart: Add support for earlycon Most litex boards using RISC-V soft cores us the sbi earlycon, however this is not available for non RISC-V litex SoC's. This patch enables earlycon for liteuart which is available on all Litex SoC's making support for earycon debugging more widely available. Cc: Florent Kermarrec Cc: Mateusz Holenko Cc: Joel Stanley Cc: Gabriel L. Somlo Reviewed-and-tested-by: Gabriel Somlo Reviewed-by: Jiri Slaby Reviewed-by: Joel Stanley Signed-off-by: Stafford Horne Link: https://lore.kernel.org/r/20210517115453.24365-1-shorne@gmail.com Signed-off-by: Greg Kroah-Hartman --- .../admin-guide/kernel-parameters.txt | 5 +++++ drivers/tty/serial/Kconfig | 1 + drivers/tty/serial/liteuart.c | 21 +++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index cb89dbdedc46..17bdf5df404c 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -1092,6 +1092,11 @@ the driver will use only 32-bit accessors to read/write the device registers. + liteuart, + Start an early console on a litex serial port at the + specified address. The serial port must already be + setup and configured. Options are not yet supported. + meson, Start an early, polled-mode console on a meson serial port at the specified address. The serial port must diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 682f9171c82c..24282ad99d85 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1553,6 +1553,7 @@ config SERIAL_LITEUART_CONSOLE bool "LiteUART serial port console support" depends on SERIAL_LITEUART=y select SERIAL_CORE_CONSOLE + select SERIAL_EARLYCON help Say 'Y' or 'M' here if you wish to use the FPGA-based LiteUART serial controller from LiteX SoC builder as the system console diff --git a/drivers/tty/serial/liteuart.c b/drivers/tty/serial/liteuart.c index 0b06770642cb..dbc0559a9157 100644 --- a/drivers/tty/serial/liteuart.c +++ b/drivers/tty/serial/liteuart.c @@ -370,6 +370,27 @@ static int __init liteuart_console_init(void) return 0; } console_initcall(liteuart_console_init); + +static void early_liteuart_write(struct console *console, const char *s, + unsigned int count) +{ + struct earlycon_device *device = console->data; + struct uart_port *port = &device->port; + + uart_console_write(port, s, count, liteuart_putchar); +} + +static int __init early_liteuart_setup(struct earlycon_device *device, + const char *options) +{ + if (!device->port.membase) + return -ENODEV; + + device->con->write = early_liteuart_write; + return 0; +} + +OF_EARLYCON_DECLARE(liteuart, "litex,liteuart", early_liteuart_setup); #endif /* CONFIG_SERIAL_LITEUART_CONSOLE */ static int __init liteuart_init(void) From b8be5db573b822920b0f6230498d900752bede17 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 19 May 2021 09:21:50 +0200 Subject: [PATCH 102/227] tty/serial: clean up uart_match_port * make parameters const (as they are only read) * return bool (as comparison results are returned) * add \n before final return Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210519072153.3859-1-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 16 +++++++++------- include/linux/serial_core.h | 3 ++- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 2793b1cf2d24..b5beb215f062 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -3027,26 +3027,28 @@ out: /* * Are the two ports equivalent? */ -int uart_match_port(struct uart_port *port1, struct uart_port *port2) +bool uart_match_port(const struct uart_port *port1, + const struct uart_port *port2) { if (port1->iotype != port2->iotype) - return 0; + return false; switch (port1->iotype) { case UPIO_PORT: - return (port1->iobase == port2->iobase); + return port1->iobase == port2->iobase; case UPIO_HUB6: - return (port1->iobase == port2->iobase) && - (port1->hub6 == port2->hub6); + return port1->iobase == port2->iobase && + port1->hub6 == port2->hub6; case UPIO_MEM: case UPIO_MEM16: case UPIO_MEM32: case UPIO_MEM32BE: case UPIO_AU: case UPIO_TSI: - return (port1->mapbase == port2->mapbase); + return port1->mapbase == port2->mapbase; } - return 0; + + return false; } EXPORT_SYMBOL(uart_match_port); diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 7445c8fd88c0..52d7fb92a69d 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -408,7 +408,8 @@ int uart_register_driver(struct uart_driver *uart); void uart_unregister_driver(struct uart_driver *uart); int uart_add_one_port(struct uart_driver *reg, struct uart_port *port); int uart_remove_one_port(struct uart_driver *reg, struct uart_port *port); -int uart_match_port(struct uart_port *port1, struct uart_port *port2); +bool uart_match_port(const struct uart_port *port1, + const struct uart_port *port2); /* * Power Management From cd256b068f80e8b4a1eccd73527b67b3eb50f7ad Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 19 May 2021 09:21:51 +0200 Subject: [PATCH 103/227] tty/serial: make port of serial8250_register_8250_port const After the previous patch, we can make port passed to serial8250_find_match_or_unused const. And then we can make const also port of serial8250_register_8250_port. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210519072153.3859-2-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_core.c | 4 ++-- include/linux/serial_8250.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 1082e76c4d37..1ce193daea7f 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -906,7 +906,7 @@ static struct platform_device *serial8250_isa_devs; */ static DEFINE_MUTEX(serial_mutex); -static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *port) +static struct uart_8250_port *serial8250_find_match_or_unused(const struct uart_port *port) { int i; @@ -971,7 +971,7 @@ static void serial_8250_overrun_backoff_work(struct work_struct *work) * * On success the port is ready to use and the line number is returned. */ -int serial8250_register_8250_port(struct uart_8250_port *up) +int serial8250_register_8250_port(const struct uart_8250_port *up) { struct uart_8250_port *uart; int ret = -ENOSPC; diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index 9e655055112d..5db211f43b29 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h @@ -146,7 +146,7 @@ static inline struct uart_8250_port *up_to_u8250p(struct uart_port *up) return container_of(up, struct uart_8250_port, port); } -int serial8250_register_8250_port(struct uart_8250_port *); +int serial8250_register_8250_port(const struct uart_8250_port *); void serial8250_unregister_port(int line); void serial8250_suspend_port(int line); void serial8250_resume_port(int line); From 756a4e4a7a4b866f1d834e206cb370988cf394d1 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 19 May 2021 09:21:52 +0200 Subject: [PATCH 104/227] tty: fix kernel-doc for tty_{read,write} After commits a9cbbb80e3e7 (tty: avoid using vfs_iocb_iter_write() for redirected console writes) and dd78b0c483e3 (tty: implement read_iter), the tty_read and tty_write kernel-doc comments don't match the code: tty_io.c:931: warning: Function parameter or member 'iocb' not described in 'tty_read' tty_io.c:931: warning: Function parameter or member 'to' not described in 'tty_read' tty_io.c:931: warning: Excess function parameter 'file' description in 'tty_read' tty_io.c:931: warning: Excess function parameter 'buf' description in 'tty_read' tty_io.c:931: warning: Excess function parameter 'count' description in 'tty_read' tty_io.c:931: warning: Excess function parameter 'ppos' description in 'tty_read' tty_io.c:1115: warning: Function parameter or member 'iocb' not described in 'file_tty_write' tty_io.c:1115: warning: Function parameter or member 'from' not described in 'file_tty_write' tty_io.c:1115: warning: expecting prototype for tty_write(). Prototype was for file_tty_write() instead Fix them to correspond the reality, i.e. the switch from read/write to read_iter/write_iter. Cc: Linus Torvalds Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210519072153.3859-3-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 8f9e89715a68..ad64232cecae 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -911,10 +911,8 @@ static int iterate_tty_read(struct tty_ldisc *ld, struct tty_struct *tty, /** * tty_read - read method for tty device files - * @file: pointer to tty file - * @buf: user buffer - * @count: size of user buffer - * @ppos: unused + * @iocb: kernel I/O control block + * @to: destination for the data read * * Perform the read system call function on this terminal device. Checks * for hung up devices before calling the line discipline method. @@ -1092,23 +1090,6 @@ void tty_write_message(struct tty_struct *tty, char *msg) } } - -/** - * tty_write - write method for tty device file - * @file: tty file pointer - * @buf: user data to write - * @count: bytes to write - * @ppos: unused - * - * Write data to a tty device via the line discipline. - * - * Locking: - * Locks the line discipline as required - * Writes to the tty driver are serialized by the atomic_write_lock - * and are then processed in chunks to the device. The line discipline - * write method will not be invoked in parallel for each device. - */ - static ssize_t file_tty_write(struct file *file, struct kiocb *iocb, struct iov_iter *from) { struct tty_struct *tty = file_tty(file); @@ -1133,6 +1114,20 @@ static ssize_t file_tty_write(struct file *file, struct kiocb *iocb, struct iov_ return ret; } +/** + * tty_write - write method for tty device file + * @iocb: kernel I/O control block + * @from: iov_iter with data to write + * + * Write data to a tty device via the line discipline. + * + * Locking: + * Locks the line discipline as required + * Writes to the tty driver are serialized by the atomic_write_lock + * and are then processed in chunks to the device. The line + * discipline write method will not be invoked in parallel for + * each device. + */ static ssize_t tty_write(struct kiocb *iocb, struct iov_iter *from) { return file_tty_write(iocb->ki_filp, iocb, from); From d06e256f7a4bee97324a0fa316f0326ab7468347 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 19 May 2021 09:21:53 +0200 Subject: [PATCH 105/227] tty: fix kernel-doc for {start,stop}_tty Commit f9e053dcfc02 (tty: Serialize tty flow control changes with flow_lock) renamed start_tty to __start_tty and stop_tty to __stop_tty and introduced new start_tty and stop_tty. But it left kernel-doc comments on the old locations: tty_io.c:785: warning: expecting prototype for stop_tty(). Prototype was for __stop_tty() instead tty_io.c:816: warning: expecting prototype for start_tty(). Prototype was for __start_tty() instead Fix that by moving the comments to appropriate locations. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210519072153.3859-4-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index ad64232cecae..26debec26b4e 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -761,6 +761,15 @@ int tty_hung_up_p(struct file *filp) } EXPORT_SYMBOL(tty_hung_up_p); +void __stop_tty(struct tty_struct *tty) +{ + if (tty->flow.stopped) + return; + tty->flow.stopped = true; + if (tty->ops->stop) + tty->ops->stop(tty); +} + /** * stop_tty - propagate flow control * @tty: tty to stop @@ -777,16 +786,6 @@ EXPORT_SYMBOL(tty_hung_up_p); * Locking: * flow.lock */ - -void __stop_tty(struct tty_struct *tty) -{ - if (tty->flow.stopped) - return; - tty->flow.stopped = true; - if (tty->ops->stop) - tty->ops->stop(tty); -} - void stop_tty(struct tty_struct *tty) { unsigned long flags; @@ -797,6 +796,16 @@ void stop_tty(struct tty_struct *tty) } EXPORT_SYMBOL(stop_tty); +void __start_tty(struct tty_struct *tty) +{ + if (!tty->flow.stopped || tty->flow.tco_stopped) + return; + tty->flow.stopped = false; + if (tty->ops->start) + tty->ops->start(tty); + tty_wakeup(tty); +} + /** * start_tty - propagate flow control * @tty: tty to start @@ -808,17 +817,6 @@ EXPORT_SYMBOL(stop_tty); * Locking: * flow.lock */ - -void __start_tty(struct tty_struct *tty) -{ - if (!tty->flow.stopped || tty->flow.tco_stopped) - return; - tty->flow.stopped = false; - if (tty->ops->start) - tty->ops->start(tty); - tty_wakeup(tty); -} - void start_tty(struct tty_struct *tty) { unsigned long flags; From 816cea10285d148a0d8bcaeeca6ba84c947f945f Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 20 May 2021 13:18:56 +0100 Subject: [PATCH 106/227] tty: vt: selection: Correct misspelled function sel_loadlut() Fixes the following W=1 kernel build warning(s): drivers/tty/vt/selection.c:119: warning: expecting prototype for set loadlut(). Prototype was for sel_loadlut() instead Cc: Greg Kroah-Hartman Cc: Jiri Slaby Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20210520121906.3468725-2-lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/selection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c index bcb6bc5731cc..f7755e73696e 100644 --- a/drivers/tty/vt/selection.c +++ b/drivers/tty/vt/selection.c @@ -109,7 +109,7 @@ static inline int inword(const u32 c) } /** - * set loadlut - load the LUT table + * sel_loadlut() - load the LUT table * @p: user table * * Load the LUT table from user space. The caller must hold the console From 1d31d0caa33fdc3d65fdee804771c5ed307eb12c Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 20 May 2021 13:18:57 +0100 Subject: [PATCH 107/227] tty: serdev: core: Fix misspelled function name __serdev_device_driver_register() Fixes the following W=1 kernel build warning(s): drivers/tty/serdev/core.c:809: warning: expecting prototype for serdev_driver_register(). Prototype was for __serdev_device_driver_register() instead Cc: Rob Herring Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: linux-serial@vger.kernel.org Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20210520121906.3468725-3-lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serdev/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c index aead0c0c9796..9cdfcfe07e87 100644 --- a/drivers/tty/serdev/core.c +++ b/drivers/tty/serdev/core.c @@ -798,7 +798,7 @@ void serdev_controller_remove(struct serdev_controller *ctrl) EXPORT_SYMBOL_GPL(serdev_controller_remove); /** - * serdev_driver_register() - Register client driver with serdev core + * __serdev_device_driver_register() - Register client driver with serdev core * @sdrv: client driver to be associated with client-device. * @owner: client driver owner to set. * From a1c0da88f1ca3966ec73e0cc579153a784f20ce0 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 20 May 2021 13:19:00 +0100 Subject: [PATCH 108/227] tty: tty_buffer: Fix incorrectly documented function __tty_buffer_request_room() Fixes the following W=1 kernel build warning(s): drivers/tty/tty_buffer.c:259: warning: expecting prototype for tty_buffer_request_room(). Prototype was for __tty_buffer_request_room() instead Cc: Greg Kroah-Hartman Cc: Jiri Slaby Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20210520121906.3468725-6-lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index ace778ed23b9..635d0af229b7 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -244,7 +244,7 @@ void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld) } /** - * tty_buffer_request_room - grow tty buffer if needed + * __tty_buffer_request_room - grow tty buffer if needed * @port: tty port * @size: size desired * @flags: buffer flags if new buffer allocated (default = 0) From 6ef6785d781e9cea207cdd9e530878fa7cda8e2a Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 20 May 2021 13:19:01 +0100 Subject: [PATCH 109/227] tty: tty_jobctrl: Fix 2 incorrectly documented functions Fixes the following W=1 kernel build warning(s): drivers/tty/tty_jobctrl.c:33: warning: expecting prototype for tty_check_change(). Prototype was for __tty_check_change() instead drivers/tty/tty_jobctrl.c:97: warning: expecting prototype for proc_set_tty(). Prototype was for __proc_set_tty() instead Cc: Greg Kroah-Hartman Cc: Jiri Slaby Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20210520121906.3468725-7-lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_jobctrl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/tty_jobctrl.c b/drivers/tty/tty_jobctrl.c index 6119b5e48610..80b86a7992b5 100644 --- a/drivers/tty/tty_jobctrl.c +++ b/drivers/tty/tty_jobctrl.c @@ -20,7 +20,7 @@ static int is_ignored(int sig) } /** - * tty_check_change - check for POSIX terminal changes + * __tty_check_change - check for POSIX terminal changes * @tty: tty to check * @sig: signal to send * @@ -85,7 +85,7 @@ void proc_clear_tty(struct task_struct *p) } /** - * proc_set_tty - set the controlling terminal + * __proc_set_tty - set the controlling terminal * @tty: tty structure * * Only callable by the session leader and only if it does not already have From ef80f77ba29ec824e249d15b63d6a1cddd7eebd2 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 20 May 2021 13:19:03 +0100 Subject: [PATCH 110/227] tty: n_hdlc: Fix a little doc-rot in n_hdlc_tty_read() Fixes the following W=1 kernel build warning(s): drivers/tty/n_hdlc.c:421: warning: Function parameter or member 'kbuf' not described in 'n_hdlc_tty_read' drivers/tty/n_hdlc.c:421: warning: Function parameter or member 'cookie' not described in 'n_hdlc_tty_read' drivers/tty/n_hdlc.c:421: warning: Function parameter or member 'offset' not described in 'n_hdlc_tty_read' drivers/tty/n_hdlc.c:421: warning: Excess function parameter 'buf' description in 'n_hdlc_tty_read' Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: Paul Fulghum Cc: Michael Callahan Cc: Al Longyear Cc: Paul Mackerras Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20210520121906.3468725-9-lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_hdlc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index d899ee4e0116..580a37b3fe1b 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c @@ -411,8 +411,10 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data, * n_hdlc_tty_read - Called to retrieve one frame of data (if available) * @tty: pointer to tty instance data * @file: pointer to open file object - * @buf: pointer to returned data buffer + * @kbuf: pointer to returned data buffer * @nr: size of returned data buffer + * @cookie: stored rbuf from previous run + * @offset: offset into the data buffer * * Returns the number of bytes returned or error code. */ From 0e4b5597350e4c0fe943a666819aacd31b06d6e8 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 20 May 2021 13:19:04 +0100 Subject: [PATCH 111/227] tty: serial: st-asc: Demote a kernel-doc formatting abuse Fixes the following W=1 kernel build warning(s): drivers/tty/serial/st-asc.c:73: warning: expecting prototype for Some of status comes from higher bits of the character and some come from(). Prototype was for ASC_RXBUF_DUMMY_RX() instead Cc: Patrice Chotard Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: linux-arm-kernel@lists.infradead.org Cc: linux-serial@vger.kernel.org Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20210520121906.3468725-10-lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/st-asc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c index f092c11f9d7d..87e480cc8206 100644 --- a/drivers/tty/serial/st-asc.c +++ b/drivers/tty/serial/st-asc.c @@ -65,7 +65,7 @@ static struct uart_driver asc_uart_driver; /* ASC_RXBUF */ #define ASC_RXBUF_PE 0x100 #define ASC_RXBUF_FE 0x200 -/** +/* * Some of status comes from higher bits of the character and some come from * the status register. Combining both of them in to single status using dummy * bits. From 542a121aea6d72114f9050707f69b9265ef1d9c8 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 20 May 2021 13:19:05 +0100 Subject: [PATCH 112/227] tty: n_gsm: Fix function naming and provide missing param descriptions Fixes the following W=1 kernel build warning(s): drivers/tty/n_gsm.c:525: warning: expecting prototype for gsm_stuff_packet(). Prototype was for gsm_stuff_frame() instead drivers/tty/n_gsm.c:1608: warning: expecting prototype for gsm_dlci_control(). Prototype was for gsm_dlci_command() instead drivers/tty/n_gsm.c:2561: warning: Function parameter or member 'cookie' not described in 'gsmld_read' drivers/tty/n_gsm.c:2561: warning: Function parameter or member 'offset' not described in 'gsmld_read' Cc: Greg Kroah-Hartman Cc: Jiri Slaby Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20210520121906.3468725-11-lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_gsm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index bd24dc0d7e96..e907b7a5cab5 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -512,7 +512,7 @@ static void gsm_print_packet(const char *hdr, int addr, int cr, */ /** - * gsm_stuff_packet - bytestuff a packet + * gsm_stuff_frame - bytestuff a packet * @input: input buffer * @output: output buffer * @len: length of input @@ -1594,7 +1594,7 @@ static void gsm_dlci_data(struct gsm_dlci *dlci, const u8 *data, int clen) } /** - * gsm_dlci_control - data arrived on control channel + * gsm_dlci_command - data arrived on control channel * @dlci: channel * @data: block of bytes received * @len: length of received block @@ -2557,6 +2557,8 @@ static void gsmld_write_wakeup(struct tty_struct *tty) * @file: file object * @buf: userspace buffer pointer * @nr: size of I/O + * @cookie: unused + * @offset: unused * * Perform reads for the line discipline. We are guaranteed that the * line discipline will not be closed under us but we may get multiple From b50155c65c579c3ad6e73010e400e9ea7b15860a Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 20 May 2021 13:19:06 +0100 Subject: [PATCH 113/227] tty: serial: xilinx_uartps: Fix documentation for cdns_uart_clk_notifier_cb() Fixes the following W=1 kernel build warning(s): drivers/tty/serial/xilinx_uartps.c:496: warning: expecting prototype for cdns_uart_clk_notitifer_cb(). Prototype was for cdns_uart_clk_notifier_cb() instead Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: Michal Simek Cc: linux-serial@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Reviewed-by: Michal Simek Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20210520121906.3468725-12-lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/xilinx_uartps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index 9bca52ffd84d..bafdf75c1fa8 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -484,7 +484,7 @@ static unsigned int cdns_uart_set_baud_rate(struct uart_port *port, #ifdef CONFIG_COMMON_CLK /** - * cdns_uart_clk_notitifer_cb - Clock notifier callback + * cdns_uart_clk_notifier_cb - Clock notifier callback * @nb: Notifier block * @event: Notify event * @data: Notifier data From f421ed33ee2bddac5857862da3a37f0ea3f197d8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 21 May 2021 20:29:38 +0200 Subject: [PATCH 114/227] Revert "serial: sh-sci: Add support for RZ/G2L SoC" This reverts commit 064b6e47b2b2d4a20566ba6f8dc90e46b599b35f as it wasn't quite ready yet :( Cc: Biju Das CC: Geert Uytterhoeven Reported-by: Lad Prabhakar Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 11 ----------- drivers/tty/serial/sh-sci.h | 1 - 2 files changed, 12 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 872a2c3b11c4..ef37fdf37612 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -306,7 +306,6 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = { [SCFDR] = { 0x0E, 16 }, [SCSPTR] = { 0x10, 16 }, [SCLSR] = { 0x12, 16 }, - [SEMR] = { 0x14, 8 }, }, .fifosize = 16, .overrun_reg = SCLSR, @@ -2528,8 +2527,6 @@ done: case 27: smr_val |= SCSMR_SRC_27; break; } smr_val |= cks; - if (sci_getreg(port, SEMR)->size) - serial_port_out(port, SEMR, 0); serial_port_out(port, SCSCR, scr_val | s->hscif_tot); serial_port_out(port, SCSMR, smr_val); serial_port_out(port, SCBRR, brr); @@ -2564,8 +2561,6 @@ done: scr_val = s->cfg->scscr & (SCSCR_CKE1 | SCSCR_CKE0); smr_val |= serial_port_in(port, SCSMR) & (SCSMR_CKEDG | SCSMR_SRC_MASK | SCSMR_CKS); - if (sci_getreg(port, SEMR)->size) - serial_port_out(port, SEMR, 0); serial_port_out(port, SCSCR, scr_val | s->hscif_tot); serial_port_out(port, SCSMR, smr_val); } @@ -3175,10 +3170,6 @@ static const struct of_device_id of_sci_match[] = { .compatible = "renesas,scif-r7s9210", .data = SCI_OF_DATA(PORT_SCIF, SCIx_RZ_SCIFA_REGTYPE), }, - { - .compatible = "renesas,scif-r9a07g044", - .data = SCI_OF_DATA(PORT_SCIF, SCIx_RZ_SCIFA_REGTYPE), - }, /* Family-specific types */ { .compatible = "renesas,rcar-gen1-scif", @@ -3461,7 +3452,6 @@ static int __init rzscifa_early_console_setup(struct earlycon_device *device, port_cfg.regtype = SCIx_RZ_SCIFA_REGTYPE; return early_console_setup(device, PORT_SCIF); } - static int __init scifa_early_console_setup(struct earlycon_device *device, const char *opt) { @@ -3481,7 +3471,6 @@ static int __init hscif_early_console_setup(struct earlycon_device *device, OF_EARLYCON_DECLARE(sci, "renesas,sci", sci_early_console_setup); OF_EARLYCON_DECLARE(scif, "renesas,scif", scif_early_console_setup); OF_EARLYCON_DECLARE(scif, "renesas,scif-r7s9210", rzscifa_early_console_setup); -OF_EARLYCON_DECLARE(scif, "renesas,scif-r9a07g044", rzscifa_early_console_setup); OF_EARLYCON_DECLARE(scifa, "renesas,scifa", scifa_early_console_setup); OF_EARLYCON_DECLARE(scifb, "renesas,scifb", scifb_early_console_setup); OF_EARLYCON_DECLARE(hscif, "renesas,hscif", hscif_early_console_setup); diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h index c0ae78632dda..c0dfe4382898 100644 --- a/drivers/tty/serial/sh-sci.h +++ b/drivers/tty/serial/sh-sci.h @@ -31,7 +31,6 @@ enum { SCCKS, /* BRG Clock Select Register */ HSRTRGR, /* Rx FIFO Data Count Trigger Register */ HSTTRGR, /* Tx FIFO Data Count Trigger Register */ - SEMR, /* Serial extended mode register */ SCIx_NR_REGS, }; From 2ac62268a2c0f2ffafc19a7ced6972a9b1330389 Mon Sep 17 00:00:00 2001 From: Xiaofei Tan Date: Fri, 21 May 2021 10:52:38 +0800 Subject: [PATCH 115/227] tty: hvc_console: Remove the repeated words 'no' and 'from' Remove the repeated words 'no' and 'from', reported by checkpatch.pl. Signed-off-by: Xiaofei Tan Link: https://lore.kernel.org/r/1621565558-26118-1-git-send-email-tanxiaofei@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/hvc/hvc_console.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index d0f0253fb93e..5bb8c4e44961 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c @@ -292,7 +292,7 @@ int hvc_instantiate(uint32_t vtermno, int index, const struct hv_ops *ops) if (vtermnos[index] != -1) return -1; - /* make sure no no tty has been registered in this index */ + /* make sure no tty has been registered in this index */ hp = hvc_get_by_index(index); if (hp) { tty_port_put(&hp->port); @@ -620,7 +620,7 @@ static u32 timeout = MIN_TIMEOUT; /* * Maximum number of bytes to get from the console driver if hvc_poll is * called from driver (and can't sleep). Any more than this and we break - * and start polling with khvcd. This value was derived from from an OpenBMC + * and start polling with khvcd. This value was derived from an OpenBMC * console with the OPAL driver that results in about 0.25ms interrupts off * latency. */ From 18c092e5c35ece7fa1fe0b2c6f8c4a13da3fc641 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 18 May 2021 19:21:26 +0100 Subject: [PATCH 116/227] ttyprintk: remove redundant initialization of variable i The variable i is being initialized with a value that is never read, it is being updated later on. The assignment is redundant and can be removed. Signed-off-by: Colin Ian King Addresses-Coverity: ("Unused value") Link: https://lore.kernel.org/r/20210518182126.140978-1-colin.king@canonical.com Signed-off-by: Greg Kroah-Hartman --- drivers/char/ttyprintk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c index 219fa1382396..230b2c9b3e3c 100644 --- a/drivers/char/ttyprintk.c +++ b/drivers/char/ttyprintk.c @@ -52,7 +52,7 @@ static void tpk_flush(void) static int tpk_printk(const unsigned char *buf, int count) { - int i = tpk_curr; + int i; for (i = 0; i < count; i++) { if (tpk_curr >= TPK_STR_SIZE) { From f2b0fe4b121e25bacdcfebd8a9dfd307b87142e7 Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Thu, 20 May 2021 19:54:39 +0800 Subject: [PATCH 117/227] dt-bindings: serial: pl011: Delete an incorrect compatible string The compatible strings "zte,zx296702-uart" and "arm,primecell" are a combination, but commit 89d4f98ae90d ("ARM: remove zte zx platform") removes only the former. It is incorrect to match driver pl011 based only on the remaining "arm,primecell". Delete it. Signed-off-by: Zhen Lei Reviewed-by: Rob Herring Documentation/devicetree/bindings/serial/pl011.yaml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) Link: https://lore.kernel.org/r/20210520115440.8259-2-thunder.leizhen@huawei.com Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/pl011.yaml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/serial/pl011.yaml b/Documentation/devicetree/bindings/serial/pl011.yaml index 142187337c76..5ea00f8a283d 100644 --- a/Documentation/devicetree/bindings/serial/pl011.yaml +++ b/Documentation/devicetree/bindings/serial/pl011.yaml @@ -24,12 +24,9 @@ select: properties: compatible: - oneOf: - - items: - - const: arm,pl011 - - const: arm,primecell - - items: - - const: arm,primecell + items: + - const: arm,pl011 + - const: arm,primecell reg: maxItems: 1 From 6ae7d0f5a92b9619f6e3c307ce56b2cefff3f0e9 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Tue, 25 May 2021 20:51:57 +0200 Subject: [PATCH 118/227] tty: nozomi: Fix the error handling path of 'nozomi_card_init()' The error handling path is broken and we may un-register things that have never been registered. Update the loops index accordingly. Fixes: 9842c38e9176 ("kfifo: fix warn_unused_result") Suggested-by: Dan Carpenter Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/e28c2e92c7475da25b03d022ea2d6dcf1ba807a2.1621968629.git.christophe.jaillet@wanadoo.fr Signed-off-by: Greg Kroah-Hartman --- drivers/tty/nozomi.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index b85d4beabc1f..0c80f25c8c3d 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c @@ -1378,7 +1378,7 @@ static int nozomi_card_init(struct pci_dev *pdev, NOZOMI_NAME, dc); if (unlikely(ret)) { dev_err(&pdev->dev, "can't request irq %d\n", pdev->irq); - goto err_free_kfifo; + goto err_free_all_kfifo; } DBG1("base_addr: %p", dc->base_addr); @@ -1416,13 +1416,15 @@ static int nozomi_card_init(struct pci_dev *pdev, return 0; err_free_tty: - for (i = 0; i < MAX_PORT; ++i) { + for (i--; i >= 0; i--) { tty_unregister_device(ntty_driver, dc->index_start + i); tty_port_destroy(&dc->port[i].port); } free_irq(pdev->irq, dc); +err_free_all_kfifo: + i = MAX_PORT; err_free_kfifo: - for (i = 0; i < MAX_PORT; i++) + for (i--; i >= PORT_MDM; i--) kfifo_free(&dc->port[i].fifo_ul); err_free_sbuf: kfree(dc->send_buf); From fad92b11047a748c996ebd6cfb164a63814eeb2e Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Tue, 25 May 2021 21:44:04 +0200 Subject: [PATCH 119/227] tty: serial: 8250: serial_cs: Fix a memory leak in error handling path In the probe function, if the final 'serial_config()' fails, 'info' is leaking. Add a resource handling path to free this memory. Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/dc25f96b7faebf42e60fe8d02963c941cf4d8124.1621971720.git.christophe.jaillet@wanadoo.fr Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/serial_cs.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/serial_cs.c b/drivers/tty/serial/8250/serial_cs.c index 63ea9c4da3d5..3708114343b0 100644 --- a/drivers/tty/serial/8250/serial_cs.c +++ b/drivers/tty/serial/8250/serial_cs.c @@ -306,6 +306,7 @@ static int serial_resume(struct pcmcia_device *link) static int serial_probe(struct pcmcia_device *link) { struct serial_info *info; + int ret; dev_dbg(&link->dev, "serial_attach()\n"); @@ -320,7 +321,15 @@ static int serial_probe(struct pcmcia_device *link) if (do_sound) link->config_flags |= CONF_ENABLE_SPKR; - return serial_config(link); + ret = serial_config(link); + if (ret) + goto free_info; + + return 0; + +free_info: + kfree(info); + return ret; } static void serial_detach(struct pcmcia_device *link) From db0a196bd8ad1d6bb4b1a9e54f54c09f8dc2cc25 Mon Sep 17 00:00:00 2001 From: Fabien Lahoudere Date: Fri, 30 Apr 2021 19:50:37 +0200 Subject: [PATCH 120/227] serial: imx: Add DMA buffer configuration via DT In order to optimize serial communication (performance/throughput VS latency), we may need to tweak DMA period number and size. This adds DT properties to configure those values before initialising DMA. The defaults will stay the same as before. [update documentation and commit message, rebase to current master, switch back to DT instead of sysfs] Signed-off-by: Fabien Lahoudere Signed-off-by: Sebastian Reichel Link: https://lore.kernel.org/r/20210430175038.103226-2-sebastian.reichel@collabora.com Signed-off-by: Greg Kroah-Hartman --- .../bindings/serial/fsl-imx-uart.yaml | 12 +++++++++ drivers/tty/serial/imx.c | 25 +++++++++++++------ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/Documentation/devicetree/bindings/serial/fsl-imx-uart.yaml b/Documentation/devicetree/bindings/serial/fsl-imx-uart.yaml index 2b06c6ce4a75..9d949296a142 100644 --- a/Documentation/devicetree/bindings/serial/fsl-imx-uart.yaml +++ b/Documentation/devicetree/bindings/serial/fsl-imx-uart.yaml @@ -71,6 +71,18 @@ properties: received, and that the peripheral should invert its input using the INVR registers. + fsl,dma-info: + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 2 + maxItems: 2 + description: | + First cell contains the size of DMA buffer chunks, second cell contains + the amount of chunks used for the device. Multiplying both numbers is + the total size of memory used for receiving data. + When not being configured the system will use default settings, which + are sensible for most use cases. If you need low latency processing on + slow connections this needs to be configured appropriately. + uart-has-rtscts: true rs485-rts-delay: true diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 4b838601cdce..8b121cd869e9 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -225,6 +225,8 @@ struct imx_port { struct scatterlist rx_sgl, tx_sgl[2]; void *rx_buf; struct circ_buf rx_ring; + unsigned int rx_buf_size; + unsigned int rx_period_length; unsigned int rx_periods; dma_cookie_t rx_cookie; unsigned int tx_bytes; @@ -1183,10 +1185,6 @@ static void imx_uart_dma_rx_callback(void *data) } } -/* RX DMA buffer periods */ -#define RX_DMA_PERIODS 16 -#define RX_BUF_SIZE (RX_DMA_PERIODS * PAGE_SIZE / 4) - static int imx_uart_start_rx_dma(struct imx_port *sport) { struct scatterlist *sgl = &sport->rx_sgl; @@ -1197,9 +1195,8 @@ static int imx_uart_start_rx_dma(struct imx_port *sport) sport->rx_ring.head = 0; sport->rx_ring.tail = 0; - sport->rx_periods = RX_DMA_PERIODS; - sg_init_one(sgl, sport->rx_buf, RX_BUF_SIZE); + sg_init_one(sgl, sport->rx_buf, sport->rx_buf_size); ret = dma_map_sg(dev, sgl, 1, DMA_FROM_DEVICE); if (ret == 0) { dev_err(dev, "DMA mapping error for RX.\n"); @@ -1316,7 +1313,8 @@ static int imx_uart_dma_init(struct imx_port *sport) goto err; } - sport->rx_buf = kzalloc(RX_BUF_SIZE, GFP_KERNEL); + sport->rx_buf_size = sport->rx_period_length * sport->rx_periods; + sport->rx_buf = kzalloc(sport->rx_buf_size, GFP_KERNEL); if (!sport->rx_buf) { ret = -ENOMEM; goto err; @@ -2179,11 +2177,16 @@ static enum hrtimer_restart imx_trigger_stop_tx(struct hrtimer *t) return HRTIMER_NORESTART; } +/* Default RX DMA buffer configuration */ +#define RX_DMA_PERIODS 16 +#define RX_DMA_PERIOD_LEN (PAGE_SIZE / 4) + static int imx_uart_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct imx_port *sport; void __iomem *base; + u32 dma_buf_conf[2]; int ret = 0; u32 ucr1; struct resource *res; @@ -2218,6 +2221,14 @@ static int imx_uart_probe(struct platform_device *pdev) if (of_get_property(np, "fsl,inverted-rx", NULL)) sport->inverted_rx = 1; + if (!of_property_read_u32_array(np, "fsl,dma-info", dma_buf_conf, 2)) { + sport->rx_period_length = dma_buf_conf[0]; + sport->rx_periods = dma_buf_conf[1]; + } else { + sport->rx_period_length = RX_DMA_PERIOD_LEN; + sport->rx_periods = RX_DMA_PERIODS; + } + if (sport->port.line >= ARRAY_SIZE(imx_uart_ports)) { dev_err(&pdev->dev, "serial%d out of range\n", sport->port.line); From 236b26f18814669c6311c067ff4ed0491992e6f2 Mon Sep 17 00:00:00 2001 From: Fabien Lahoudere Date: Fri, 30 Apr 2021 19:50:38 +0200 Subject: [PATCH 121/227] ARM: dts: imx53-ppd: add dma-info nodes GEHC CS ONE (codename is PPD), has multiple microcontrollers connected via UART controlling. UART2 is connected to an on-board microcontroller at 19200 baud, which constantly pushes critical data (so aging character detect interrupt will never trigger). This data must be processed at 50-200 Hz, so UART should return data in less than 5-20ms. With 1024 byte DMA buffer (and a constant data stream) the read operation instead needs 1024 byte / 19200 baud = 53.333ms, which is way too long (note: Worst case would be remote processor sending data with short pauses <= 7 characters, which would further increase this number). The current downstream kernel instead configures 24 bytes resulting in 1.25ms, but that is obviously not sensible for normal UART use cases and cannot be used as new default. The same device also has another microcontroller with a 4M baud connected to UART5 exchanging lots of data. For this the same mechanism can be used to increase the buffer size (downstream uses 4K instead of the default 1K) with potentially slightly reduced buffer count. At this baud rate latency is not an issue (4096 byte / 4M baud = 0.977 ms). Before increasing the default buffer count from 4 to 16 in 76c38d30fee7, this was required to avoid data loss. With the changed default it's a performance optimization. Signed-off-by: Fabien Lahoudere [replace commit message] Signed-off-by: Sebastian Reichel Link: https://lore.kernel.org/r/20210430175038.103226-3-sebastian.reichel@collabora.com Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/imx53-ppd.dts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/imx53-ppd.dts b/arch/arm/boot/dts/imx53-ppd.dts index be040b6a02fa..5a5fa6190a52 100644 --- a/arch/arm/boot/dts/imx53-ppd.dts +++ b/arch/arm/boot/dts/imx53-ppd.dts @@ -651,6 +651,7 @@ &uart2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart2>; + fsl,dma-info = <24 20>; status = "okay"; }; @@ -670,6 +671,7 @@ &uart5 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart5>; + fsl,dma-info = <4096 4>; status = "okay"; }; From d157fca711ad42e75efef3444c83d2e1a17be27a Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Fri, 28 May 2021 15:33:20 +0200 Subject: [PATCH 122/227] serial: tty: uartlite: fix console setup Remove the hack to assign the global console_port variable at probe time. This assumption that cons->index is -1 is wrong for systems that specify 'console=' in the cmdline (or 'stdout-path' in dts). Hence, on such system the actual console assignment is ignored, and the first UART that happens to be probed is used as console instead. Move the logic to console_setup() and map the console to the correct port through the array of available ports instead. Signed-off-by: Daniel Mack Link: https://lore.kernel.org/r/20210528133321.1859346-1-daniel@zonque.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/uartlite.c | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index f42ccc40ffa6..a5f15f22d9ef 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c @@ -505,21 +505,23 @@ static void ulite_console_write(struct console *co, const char *s, static int ulite_console_setup(struct console *co, char *options) { - struct uart_port *port; + struct uart_port *port = NULL; int baud = 9600; int bits = 8; int parity = 'n'; int flow = 'n'; - - port = console_port; + if (co->index >= 0 && co->index < ULITE_NR_UARTS) + port = ulite_ports + co->index; /* Has the device been initialized yet? */ - if (!port->mapbase) { + if (!port || !port->mapbase) { pr_debug("console on ttyUL%i not present\n", co->index); return -ENODEV; } + console_port = port; + /* not initialized yet? */ if (!port->membase) { if (ulite_request_port(port)) @@ -655,17 +657,6 @@ static int ulite_assign(struct device *dev, int id, u32 base, int irq, dev_set_drvdata(dev, port); -#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE - /* - * If console hasn't been found yet try to assign this port - * because it is required to be assigned for console setup function. - * If register_console() don't assign value, then console_port pointer - * is cleanup. - */ - if (ulite_uart_driver.cons->index == -1) - console_port = port; -#endif - /* Register the port */ rc = uart_add_one_port(&ulite_uart_driver, port); if (rc) { @@ -675,12 +666,6 @@ static int ulite_assign(struct device *dev, int id, u32 base, int irq, return rc; } -#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE - /* This is not port which is used for console that's why clean it up */ - if (ulite_uart_driver.cons->index == -1) - console_port = NULL; -#endif - return 0; } From 3b2cd60689fa439481f535ee4463fb223a276f43 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Thu, 3 Jun 2021 23:17:56 +0100 Subject: [PATCH 123/227] serial: sh-sci: Add support for RZ/G2L SoC Add serial support for RZ/G2L SoC with earlycon and extended mode register support. Signed-off-by: Biju Das Signed-off-by: Lad Prabhakar Link: https://lore.kernel.org/r/20210603221758.10305-11-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 12 +++++++++++- drivers/tty/serial/sh-sci.h | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 4baf1316ea72..afdd39da82f7 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -289,7 +289,7 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = { }, /* - * The "SCIFA" that is in RZ/T and RZ/A2. + * The "SCIFA" that is in RZ/A2, RZ/G2L and RZ/T. * It looks like a normal SCIF with FIFO data, but with a * compressed address space. Also, the break out of interrupts * are different: ERI/BRI, RXI, TXI, TEI, DRI. @@ -306,6 +306,7 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = { [SCFDR] = { 0x0E, 16 }, [SCSPTR] = { 0x10, 16 }, [SCLSR] = { 0x12, 16 }, + [SEMR] = { 0x14, 8 }, }, .fifosize = 16, .overrun_reg = SCLSR, @@ -2514,6 +2515,9 @@ done: if (termios->c_cflag & PARENB) bits++; + if (sci_getreg(port, SEMR)->size) + serial_port_out(port, SEMR, 0); + if (best_clk >= 0) { if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) switch (srr + 1) { @@ -3170,6 +3174,10 @@ static const struct of_device_id of_sci_match[] = { .compatible = "renesas,scif-r7s9210", .data = SCI_OF_DATA(PORT_SCIF, SCIx_RZ_SCIFA_REGTYPE), }, + { + .compatible = "renesas,scif-r9a07g044", + .data = SCI_OF_DATA(PORT_SCIF, SCIx_RZ_SCIFA_REGTYPE), + }, /* Family-specific types */ { .compatible = "renesas,rcar-gen1-scif", @@ -3452,6 +3460,7 @@ static int __init rzscifa_early_console_setup(struct earlycon_device *device, port_cfg.regtype = SCIx_RZ_SCIFA_REGTYPE; return early_console_setup(device, PORT_SCIF); } + static int __init scifa_early_console_setup(struct earlycon_device *device, const char *opt) { @@ -3471,6 +3480,7 @@ static int __init hscif_early_console_setup(struct earlycon_device *device, OF_EARLYCON_DECLARE(sci, "renesas,sci", sci_early_console_setup); OF_EARLYCON_DECLARE(scif, "renesas,scif", scif_early_console_setup); OF_EARLYCON_DECLARE(scif, "renesas,scif-r7s9210", rzscifa_early_console_setup); +OF_EARLYCON_DECLARE(scif, "renesas,scif-r9a07g044", rzscifa_early_console_setup); OF_EARLYCON_DECLARE(scifa, "renesas,scifa", scifa_early_console_setup); OF_EARLYCON_DECLARE(scifb, "renesas,scifb", scifb_early_console_setup); OF_EARLYCON_DECLARE(hscif, "renesas,hscif", hscif_early_console_setup); diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h index c0dfe4382898..c0ae78632dda 100644 --- a/drivers/tty/serial/sh-sci.h +++ b/drivers/tty/serial/sh-sci.h @@ -31,6 +31,7 @@ enum { SCCKS, /* BRG Clock Select Register */ HSRTRGR, /* Rx FIFO Data Count Trigger Register */ HSTTRGR, /* Tx FIFO Data Count Trigger Register */ + SEMR, /* Serial extended mode register */ SCIx_NR_REGS, }; From 2877389f59dc455e4283ae23ad494b410c15b3a3 Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Wed, 2 Jun 2021 09:48:39 +0800 Subject: [PATCH 124/227] tty: vcc: use DEVICE_ATTR_*() macro Use DEVICE_ATTR_*() macro helper instead of plain DEVICE_ATTR, which makes the code a bit shorter and easier to read. Acked-by: David S. Miller Signed-off-by: Zhen Lei Link: https://lore.kernel.org/r/20210602014839.10587-1-thunder.leizhen@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vcc.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/tty/vcc.c b/drivers/tty/vcc.c index e883b8f12099..ba79da20bf73 100644 --- a/drivers/tty/vcc.c +++ b/drivers/tty/vcc.c @@ -473,9 +473,9 @@ static struct vio_version vcc_versions[] = { static struct tty_port_operations vcc_port_ops = { 0 }; -static ssize_t vcc_sysfs_domain_show(struct device *dev, - struct device_attribute *attr, - char *buf) +static ssize_t domain_show(struct device *dev, + struct device_attribute *attr, + char *buf) { struct vcc_port *port; int rv; @@ -505,9 +505,9 @@ static int vcc_send_ctl(struct vcc_port *port, int ctl) return rv; } -static ssize_t vcc_sysfs_break_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t break_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { struct vcc_port *port; unsigned long flags; @@ -530,8 +530,8 @@ static ssize_t vcc_sysfs_break_store(struct device *dev, return rv; } -static DEVICE_ATTR(domain, 0400, vcc_sysfs_domain_show, NULL); -static DEVICE_ATTR(break, 0200, NULL, vcc_sysfs_break_store); +static DEVICE_ATTR_ADMIN_RO(domain); +static DEVICE_ATTR_WO(break); static struct attribute *vcc_sysfs_entries[] = { &dev_attr_domain.attr, From e901000aa6d0b0d428839aa142c698825d76da7f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 7 Jun 2021 16:43:45 +0200 Subject: [PATCH 125/227] serial: sh-sci: Remove unused STEPFN() macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The last user of the STEPFN() macro was removed in commit d5cb1319a91d4f13 ("serial: sh-sci: Remove manual break debouncing"). Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/970387d104dea5bb7ea674bb89229641467e629b.1623076891.git.geert+renesas@glider.be Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index afdd39da82f7..df4f70716ba2 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -841,9 +841,6 @@ static void sci_transmit_chars(struct uart_port *port) } -/* On SH3, SCIF may read end-of-break as a space->mark char */ -#define STEPFN(c) ({int __c = (c); (((__c-1)|(__c)) == -1); }) - static void sci_receive_chars(struct uart_port *port) { struct tty_port *tport = &port->state->port; From 7d356a438b2466a3a9ca1b916aaf198d05f2b3e4 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 8 Jun 2021 17:42:38 +0300 Subject: [PATCH 126/227] serial: 8250_exar: Extract exar_get_platform() helper We would like to use DMI matching in other functions as well. Hence, extract it as exar_get_platform() helper function. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210608144239.12697-2-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_exar.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c index 2f49c580139b..9b197dacaefb 100644 --- a/drivers/tty/serial/8250/8250_exar.c +++ b/drivers/tty/serial/8250/8250_exar.c @@ -501,23 +501,27 @@ static const struct dmi_system_id exar_platforms[] = { {} }; +static const struct exar8250_platform *exar_get_platform(void) +{ + const struct dmi_system_id *dmi_match; + + dmi_match = dmi_first_match(exar_platforms); + if (dmi_match) + return dmi_match->driver_data; + + return &exar8250_default_platform; +} + static int pci_xr17v35x_setup(struct exar8250 *priv, struct pci_dev *pcidev, struct uart_8250_port *port, int idx) { - const struct exar8250_platform *platform; - const struct dmi_system_id *dmi_match; + const struct exar8250_platform *platform = exar_get_platform(); unsigned int offset = idx * 0x400; unsigned int baud = 7812500; u8 __iomem *p; int ret; - dmi_match = dmi_first_match(exar_platforms); - if (dmi_match) - platform = dmi_match->driver_data; - else - platform = &exar8250_default_platform; - port->port.uartclk = baud * 16; port->port.rs485_config = platform->rs485_config; From e2129550de99a7654f323eb332c337314bd6b592 Mon Sep 17 00:00:00 2001 From: Baokun Li Date: Tue, 8 Jun 2021 10:48:43 +0800 Subject: [PATCH 127/227] tty: tty_ldisc: fix doc warnings in tty_ldisc.c Fixes the following W=1 kernel build warning(s): drivers/tty/tty_ldisc.c:63: warning: Excess function parameter 'disc' description in 'tty_register_ldisc' drivers/tty/tty_ldisc.c:90: warning: Function parameter or member 'ldisc' not described in 'tty_unregister_ldisc' drivers/tty/tty_ldisc.c:90: warning: Excess function parameter 'disc' description in 'tty_unregister_ldisc' Signed-off-by: Baokun Li Link: https://lore.kernel.org/r/20210608024843.2756746-1-libaokun1@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 8edd73ab9148..756a4bfa6a69 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -48,7 +48,6 @@ static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS]; /** * tty_register_ldisc - install a line discipline - * @disc: ldisc number * @new_ldisc: pointer to the ldisc object * * Installs a new line discipline into the kernel. The discipline @@ -77,7 +76,7 @@ EXPORT_SYMBOL(tty_register_ldisc); /** * tty_unregister_ldisc - unload a line discipline - * @disc: ldisc number + * @ldisc: ldisc number * * Remove a line discipline from the kernel providing it is not * currently in use. From a69008475fc565cec5a760f1997f326773c84aac Mon Sep 17 00:00:00 2001 From: Shaokun Zhang Date: Mon, 7 Jun 2021 18:48:53 +0800 Subject: [PATCH 128/227] vt: vt_kern.h, remove the repeated declaration Function 'vt_set_led_state' is declared twice, so remove the repeated declaration. Cc: Jiri Slaby Signed-off-by: Shaokun Zhang Link: https://lore.kernel.org/r/1623062933-52943-1-git-send-email-zhangshaokun@hisilicon.com Signed-off-by: Greg Kroah-Hartman --- include/linux/vt_kern.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h index 94e7a315479c..0da94a6dee15 100644 --- a/include/linux/vt_kern.h +++ b/include/linux/vt_kern.h @@ -166,7 +166,6 @@ int vt_get_kbd_mode_bit(int console, int bit); void vt_set_kbd_mode_bit(int console, int bit); void vt_clr_kbd_mode_bit(int console, int bit); void vt_set_led_state(int console, int leds); -void vt_set_led_state(int console, int leds); void vt_kbd_con_start(int console); void vt_kbd_con_stop(int console); From 08a84410a04f05c7c1b8e833f552416d8eb9f6fe Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Thu, 10 Jun 2021 20:08:06 +0900 Subject: [PATCH 129/227] serial: sh-sci: Stop dmaengine transfer in sci_stop_tx() Stop dmaengine transfer in sci_stop_tx(). Otherwise, the following message is possible output when system enters suspend and while transferring data, because clearing TIE bit in SCSCR is not able to stop any dmaengine transfer. sh-sci e6550000.serial: ttySC1: Unable to drain transmitter Note that this driver has already used some #ifdef in the .c file so that this patch also uses #ifdef to fix the issue. Otherwise, build errors happens if the CONFIG_SERIAL_SH_SCI_DMA is disabled. Fixes: 73a19e4c0301 ("serial: sh-sci: Add DMA support.") Cc: # v4.9+ Signed-off-by: Yoshihiro Shimoda Link: https://lore.kernel.org/r/20210610110806.277932-1-yoshihiro.shimoda.uh@renesas.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index df4f70716ba2..aabe66c99c1a 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -611,6 +611,14 @@ static void sci_stop_tx(struct uart_port *port) ctrl &= ~SCSCR_TIE; serial_port_out(port, SCSCR, ctrl); + +#ifdef CONFIG_SERIAL_SH_SCI_DMA + if (to_sci_port(port)->chan_tx && + !dma_submit_error(to_sci_port(port)->cookie_tx)) { + dmaengine_terminate_async(to_sci_port(port)->chan_tx); + to_sci_port(port)->cookie_tx = -EINVAL; + } +#endif } static void sci_start_rx(struct uart_port *port) From af9a1f61ac331c2f910d9186767d02f8e982c38e Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Wed, 9 Jun 2021 18:56:55 +0300 Subject: [PATCH 130/227] serial: tegra-tcu: Reorder channel initialization Request the RX mailbox only after initializing the UART data structures. Otherwise it can rarely happen that the receive callback is called before the UART is ready. Fixes: 2d908b38d409 ("serial: Add Tegra Combined UART driver") Signed-off-by: Mikko Perttunen Link: https://lore.kernel.org/r/20210609155655.3567545-1-mperttunen@nvidia.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/tegra-tcu.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/drivers/tty/serial/tegra-tcu.c b/drivers/tty/serial/tegra-tcu.c index 52687c65ad74..4877c54c613d 100644 --- a/drivers/tty/serial/tegra-tcu.c +++ b/drivers/tty/serial/tegra-tcu.c @@ -195,13 +195,6 @@ static int tegra_tcu_probe(struct platform_device *pdev) return err; } - tcu->rx = mbox_request_channel_byname(&tcu->rx_client, "rx"); - if (IS_ERR(tcu->rx)) { - err = PTR_ERR(tcu->rx); - dev_err(&pdev->dev, "failed to get rx mailbox: %d\n", err); - goto free_tx; - } - #if IS_ENABLED(CONFIG_SERIAL_TEGRA_TCU_CONSOLE) /* setup the console */ strcpy(tcu->console.name, "ttyTCU"); @@ -226,7 +219,7 @@ static int tegra_tcu_probe(struct platform_device *pdev) if (err) { dev_err(&pdev->dev, "failed to register UART driver: %d\n", err); - goto free_rx; + goto free_tx; } /* setup the port */ @@ -246,6 +239,17 @@ static int tegra_tcu_probe(struct platform_device *pdev) goto unregister_uart; } + /* + * Request RX channel after creating port to ensure tcu->port + * is ready for any immediate incoming bytes. + */ + tcu->rx = mbox_request_channel_byname(&tcu->rx_client, "rx"); + if (IS_ERR(tcu->rx)) { + err = PTR_ERR(tcu->rx); + dev_err(&pdev->dev, "failed to get rx mailbox: %d\n", err); + goto remove_uart_port; + } + platform_set_drvdata(pdev, tcu); #if IS_ENABLED(CONFIG_SERIAL_TEGRA_TCU_CONSOLE) register_console(&tcu->console); @@ -253,10 +257,10 @@ static int tegra_tcu_probe(struct platform_device *pdev) return 0; +remove_uart_port: + uart_remove_one_port(&tcu->driver, &tcu->port); unregister_uart: uart_unregister_driver(&tcu->driver); -free_rx: - mbox_free_channel(tcu->rx); free_tx: mbox_free_channel(tcu->tx); @@ -270,9 +274,9 @@ static int tegra_tcu_remove(struct platform_device *pdev) #if IS_ENABLED(CONFIG_SERIAL_TEGRA_TCU_CONSOLE) unregister_console(&tcu->console); #endif + mbox_free_channel(tcu->rx); uart_remove_one_port(&tcu->driver, &tcu->port); uart_unregister_driver(&tcu->driver); - mbox_free_channel(tcu->rx); mbox_free_channel(tcu->tx); return 0; From a7770a4bfcf4e6dea406304c2386c6a9505e9999 Mon Sep 17 00:00:00 2001 From: Erwan Le Ray Date: Thu, 10 Jun 2021 12:00:20 +0200 Subject: [PATCH 131/227] serial: stm32: defer probe for dma devices Defer device probe operation when a DMA channel request probe deferral. With this change both DMA channels are acquired before DMA channels are configured. Once no probe deferral is expected, DMAs are configured and any failure in their configuration will make the driver to fallback to interrupt mode as prior this change. Signed-off-by: Erwan Le Ray Signed-off-by: Etienne Carriere Link: https://lore.kernel.org/r/20210610100020.2318-1-erwan.leray@foss.st.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/stm32-usart.c | 165 +++++++++++++++---------------- 1 file changed, 78 insertions(+), 87 deletions(-) diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index bf188bdf9717..cd6adb979df9 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -1182,6 +1182,14 @@ static const struct of_device_id stm32_match[] = { MODULE_DEVICE_TABLE(of, stm32_match); #endif +static void stm32_usart_of_dma_rx_remove(struct stm32_port *stm32port, + struct platform_device *pdev) +{ + if (stm32port->rx_buf) + dma_free_coherent(&pdev->dev, RX_BUF_L, stm32port->rx_buf, + stm32port->rx_dma_buf); +} + static int stm32_usart_of_dma_rx_probe(struct stm32_port *stm32port, struct platform_device *pdev) { @@ -1199,19 +1207,11 @@ static int stm32_usart_of_dma_rx_probe(struct stm32_port *stm32port, if (uart_console(port)) return -ENODEV; - /* Request DMA RX channel */ - stm32port->rx_ch = dma_request_slave_channel(dev, "rx"); - if (!stm32port->rx_ch) { - dev_info(dev, "rx dma alloc failed\n"); - return -ENODEV; - } stm32port->rx_buf = dma_alloc_coherent(&pdev->dev, RX_BUF_L, &stm32port->rx_dma_buf, GFP_KERNEL); - if (!stm32port->rx_buf) { - ret = -ENOMEM; - goto alloc_err; - } + if (!stm32port->rx_buf) + return -ENOMEM; /* Configure DMA channel */ memset(&config, 0, sizeof(config)); @@ -1221,8 +1221,8 @@ static int stm32_usart_of_dma_rx_probe(struct stm32_port *stm32port, ret = dmaengine_slave_config(stm32port->rx_ch, &config); if (ret < 0) { dev_err(dev, "rx dma channel config failed\n"); - ret = -ENODEV; - goto config_err; + stm32_usart_of_dma_rx_remove(stm32port, pdev); + return ret; } /* Prepare a DMA cyclic transaction */ @@ -1232,8 +1232,8 @@ static int stm32_usart_of_dma_rx_probe(struct stm32_port *stm32port, DMA_PREP_INTERRUPT); if (!desc) { dev_err(dev, "rx dma prep cyclic failed\n"); - ret = -ENODEV; - goto config_err; + stm32_usart_of_dma_rx_remove(stm32port, pdev); + return -ENODEV; } /* No callback as dma buffer is drained on usart interrupt */ @@ -1244,24 +1244,22 @@ static int stm32_usart_of_dma_rx_probe(struct stm32_port *stm32port, ret = dma_submit_error(dmaengine_submit(desc)); if (ret) { dmaengine_terminate_sync(stm32port->rx_ch); - goto config_err; + stm32_usart_of_dma_rx_remove(stm32port, pdev); + return ret; } /* Issue pending DMA requests */ dma_async_issue_pending(stm32port->rx_ch); return 0; +} -config_err: - dma_free_coherent(&pdev->dev, - RX_BUF_L, stm32port->rx_buf, - stm32port->rx_dma_buf); - -alloc_err: - dma_release_channel(stm32port->rx_ch); - stm32port->rx_ch = NULL; - - return ret; +static void stm32_usart_of_dma_tx_remove(struct stm32_port *stm32port, + struct platform_device *pdev) +{ + if (stm32port->tx_buf) + dma_free_coherent(&pdev->dev, TX_BUF_L, stm32port->tx_buf, + stm32port->tx_dma_buf); } static int stm32_usart_of_dma_tx_probe(struct stm32_port *stm32port, @@ -1275,19 +1273,11 @@ static int stm32_usart_of_dma_tx_probe(struct stm32_port *stm32port, stm32port->tx_dma_busy = false; - /* Request DMA TX channel */ - stm32port->tx_ch = dma_request_slave_channel(dev, "tx"); - if (!stm32port->tx_ch) { - dev_info(dev, "tx dma alloc failed\n"); - return -ENODEV; - } stm32port->tx_buf = dma_alloc_coherent(&pdev->dev, TX_BUF_L, &stm32port->tx_dma_buf, GFP_KERNEL); - if (!stm32port->tx_buf) { - ret = -ENOMEM; - goto alloc_err; - } + if (!stm32port->tx_buf) + return -ENOMEM; /* Configure DMA channel */ memset(&config, 0, sizeof(config)); @@ -1297,22 +1287,11 @@ static int stm32_usart_of_dma_tx_probe(struct stm32_port *stm32port, ret = dmaengine_slave_config(stm32port->tx_ch, &config); if (ret < 0) { dev_err(dev, "tx dma channel config failed\n"); - ret = -ENODEV; - goto config_err; + stm32_usart_of_dma_tx_remove(stm32port, pdev); + return ret; } return 0; - -config_err: - dma_free_coherent(&pdev->dev, - TX_BUF_L, stm32port->tx_buf, - stm32port->tx_dma_buf); - -alloc_err: - dma_release_channel(stm32port->tx_ch); - stm32port->tx_ch = NULL; - - return ret; } static int stm32_usart_serial_probe(struct platform_device *pdev) @@ -1336,16 +1315,43 @@ static int stm32_usart_serial_probe(struct platform_device *pdev) device_set_wakeup_capable(&pdev->dev, true); ret = dev_pm_set_wake_irq(&pdev->dev, stm32port->port.irq); if (ret) - goto err_nowup; + goto err_deinit_port; } - ret = stm32_usart_of_dma_rx_probe(stm32port, pdev); - if (ret) - dev_info(&pdev->dev, "interrupt mode used for rx (no dma)\n"); + stm32port->rx_ch = dma_request_chan(&pdev->dev, "rx"); + if (PTR_ERR(stm32port->rx_ch) == -EPROBE_DEFER) { + ret = -EPROBE_DEFER; + goto err_wakeirq; + } + /* Fall back in interrupt mode for any non-deferral error */ + if (IS_ERR(stm32port->rx_ch)) + stm32port->rx_ch = NULL; - ret = stm32_usart_of_dma_tx_probe(stm32port, pdev); - if (ret) - dev_info(&pdev->dev, "interrupt mode used for tx (no dma)\n"); + stm32port->tx_ch = dma_request_chan(&pdev->dev, "tx"); + if (PTR_ERR(stm32port->tx_ch) == -EPROBE_DEFER) { + ret = -EPROBE_DEFER; + goto err_dma_rx; + } + /* Fall back in interrupt mode for any non-deferral error */ + if (IS_ERR(stm32port->tx_ch)) + stm32port->tx_ch = NULL; + + if (stm32port->rx_ch && stm32_usart_of_dma_rx_probe(stm32port, pdev)) { + /* Fall back in interrupt mode */ + dma_release_channel(stm32port->rx_ch); + stm32port->rx_ch = NULL; + } + + if (stm32port->tx_ch && stm32_usart_of_dma_tx_probe(stm32port, pdev)) { + /* Fall back in interrupt mode */ + dma_release_channel(stm32port->tx_ch); + stm32port->tx_ch = NULL; + } + + if (!stm32port->rx_ch) + dev_info(&pdev->dev, "interrupt mode for rx (no dma)\n"); + if (!stm32port->tx_ch) + dev_info(&pdev->dev, "interrupt mode for tx (no dma)\n"); platform_set_drvdata(pdev, &stm32port->port); @@ -1366,30 +1372,23 @@ err_port: pm_runtime_set_suspended(&pdev->dev); pm_runtime_put_noidle(&pdev->dev); - if (stm32port->rx_ch) { - dmaengine_terminate_async(stm32port->rx_ch); - dma_release_channel(stm32port->rx_ch); - } - - if (stm32port->rx_dma_buf) - dma_free_coherent(&pdev->dev, - RX_BUF_L, stm32port->rx_buf, - stm32port->rx_dma_buf); - if (stm32port->tx_ch) { - dmaengine_terminate_async(stm32port->tx_ch); + stm32_usart_of_dma_tx_remove(stm32port, pdev); dma_release_channel(stm32port->tx_ch); } - if (stm32port->tx_dma_buf) - dma_free_coherent(&pdev->dev, - TX_BUF_L, stm32port->tx_buf, - stm32port->tx_dma_buf); + if (stm32port->rx_ch) + stm32_usart_of_dma_rx_remove(stm32port, pdev); +err_dma_rx: + if (stm32port->rx_ch) + dma_release_channel(stm32port->rx_ch); + +err_wakeirq: if (stm32port->wakeup_src) dev_pm_clear_wake_irq(&pdev->dev); -err_nowup: +err_deinit_port: if (stm32port->wakeup_src) device_set_wakeup_capable(&pdev->dev, false); @@ -1416,27 +1415,19 @@ static int stm32_usart_serial_remove(struct platform_device *pdev) stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAR); - if (stm32_port->rx_ch) { - dmaengine_terminate_async(stm32_port->rx_ch); - dma_release_channel(stm32_port->rx_ch); - } - - if (stm32_port->rx_dma_buf) - dma_free_coherent(&pdev->dev, - RX_BUF_L, stm32_port->rx_buf, - stm32_port->rx_dma_buf); - - stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT); - if (stm32_port->tx_ch) { dmaengine_terminate_async(stm32_port->tx_ch); + stm32_usart_of_dma_tx_remove(stm32_port, pdev); dma_release_channel(stm32_port->tx_ch); } - if (stm32_port->tx_dma_buf) - dma_free_coherent(&pdev->dev, - TX_BUF_L, stm32_port->tx_buf, - stm32_port->tx_dma_buf); + if (stm32_port->rx_ch) { + dmaengine_terminate_async(stm32_port->rx_ch); + stm32_usart_of_dma_rx_remove(stm32_port, pdev); + dma_release_channel(stm32_port->rx_ch); + } + + stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT); if (stm32_port->wakeup_src) { dev_pm_clear_wake_irq(&pdev->dev); From fb524360f52228201b56149a138369da505141a2 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 10 Jun 2021 11:03:07 +0200 Subject: [PATCH 132/227] ipwireless: remove unused ipw_tty::closing It's only set, but never read because commit 01261cb94318 ("tty: ipwireless: Remove tty->closing abort from ipw_open()") removed last use of tty::closing. Cc: Jiri Kosina Cc: David Sterba Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210610090307.2689-1-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/ipwireless/tty.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c index e01ca68f24f4..e3a5a5ba752c 100644 --- a/drivers/tty/ipwireless/tty.c +++ b/drivers/tty/ipwireless/tty.c @@ -54,7 +54,6 @@ struct ipw_tty { unsigned int control_lines; struct mutex ipw_tty_mutex; int tx_bytes_queued; - int closing; }; static struct ipw_tty *ttys[IPWIRELESS_PCMCIA_MINORS]; @@ -525,7 +524,6 @@ void ipwireless_tty_free(struct ipw_tty *tty) printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": deregistering %s device ttyIPWp%d\n", tty_type_name(ttyj->tty_type), j); - ttyj->closing = 1; if (ttyj->port.tty != NULL) { mutex_unlock(&ttyj->ipw_tty_mutex); tty_vhangup(ttyj->port.tty); From 654ee49b7e0883e660be6e6e20876fc4cbdaadd1 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 10 Jun 2021 11:02:44 +0200 Subject: [PATCH 133/227] tty: make tty_get_{char,frame}_size available Many tty drivers contain code to compute bits count depending on termios cflags. So extract this code from serial core to two separate tty helper functions: * tty_get_char_size -- only size of a character, without flags, * tty_get_frame_size -- complete size of a frame including flags. In the next patch, calls to these new functions replace many copies of this code. Note that we accept only cflag as a parameter. That's because some callers like pch_uart_startup or sunsab_console_setup don't have at hand termios which we could pass around. Cc: Joe Perches Cc: Johan Hovold Reviewed-by: Andy Shevchenko Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210610090247.2593-1-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 30 +++------------------ drivers/tty/tty_ioctl.c | 45 ++++++++++++++++++++++++++++++++ include/linux/tty.h | 3 +++ 3 files changed, 51 insertions(+), 27 deletions(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 642e24d6c475..69092deba11f 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -334,39 +334,15 @@ void uart_update_timeout(struct uart_port *port, unsigned int cflag, unsigned int baud) { - unsigned int bits; + unsigned int size; - /* byte size and parity */ - switch (cflag & CSIZE) { - case CS5: - bits = 7; - break; - case CS6: - bits = 8; - break; - case CS7: - bits = 9; - break; - default: - bits = 10; - break; /* CS8 */ - } - - if (cflag & CSTOPB) - bits++; - if (cflag & PARENB) - bits++; - - /* - * The total number of bits to be transmitted in the fifo. - */ - bits = bits * port->fifosize; + size = tty_get_frame_size(cflag) * port->fifosize; /* * Figure the timeout to send the above number of bits. * Add .02 seconds of slop */ - port->timeout = (HZ * bits) / baud + HZ/50; + port->timeout = (HZ * size) / baud + HZ/50; } EXPORT_SYMBOL(uart_update_timeout); diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 75885d502749..507a25d692bb 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -279,6 +279,51 @@ int tty_termios_hw_change(const struct ktermios *a, const struct ktermios *b) } EXPORT_SYMBOL(tty_termios_hw_change); +/** + * tty_get_char_size - get size of a character + * @cflag: termios cflag value + * + * Get the size (in bits) of a character depending on @cflag's %CSIZE + * setting. + */ +unsigned char tty_get_char_size(unsigned int cflag) +{ + switch (cflag & CSIZE) { + case CS5: + return 5; + case CS6: + return 6; + case CS7: + return 7; + case CS8: + default: + return 8; + } +} +EXPORT_SYMBOL_GPL(tty_get_char_size); + +/** + * tty_get_frame_size - get size of a frame + * @cflag: termios cflag value + * + * Get the size (in bits) of a frame depending on @cflag's %CSIZE, %CSTOPB, + * and %PARENB setting. The result is a sum of character size, start and + * stop bits -- one bit each -- second stop bit (if set), and parity bit + * (if set). + */ +unsigned char tty_get_frame_size(unsigned int cflag) +{ + unsigned char bits = 2 + tty_get_char_size(cflag); + + if (cflag & CSTOPB) + bits++; + if (cflag & PARENB) + bits++; + + return bits; +} +EXPORT_SYMBOL_GPL(tty_get_frame_size); + /** * tty_set_termios - update termios values * @tty: tty to update diff --git a/include/linux/tty.h b/include/linux/tty.h index 4c0c7ca1d9a4..19dc1097e09c 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -495,6 +495,9 @@ static inline speed_t tty_get_baud_rate(struct tty_struct *tty) return tty_termios_baud_rate(&tty->termios); } +unsigned char tty_get_char_size(unsigned int cflag); +unsigned char tty_get_frame_size(unsigned int cflag); + extern void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old); extern int tty_termios_hw_change(const struct ktermios *a, const struct ktermios *b); extern int tty_set_termios(struct tty_struct *tty, struct ktermios *kt); From 8ea43acc690ca2fe88500356f25c431d25f8a0bb Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 10 Jun 2021 11:02:45 +0200 Subject: [PATCH 134/227] mxs-auart: redefine AUART_LINECTRL_WLEN to accept bits count It's a bit illogical to take magic constants in AUART_LINECTRL_WLEN. Like in auart_console_get_options(), 2 means 7 bits. Switch AUART_LINECTRL_WLEN to accept bit length, i.e. let it subtract 5 from the parameter before doing the logic. This will ease conversion from CSIZE to bits in mxs_auart_settermios() in the next patch. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210610090247.2593-2-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mxs-auart.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index f414d6acad69..7b4b6bb75424 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -87,7 +87,7 @@ #define AUART_LINECTRL_BAUD_DIVFRAC(v) (((v) & 0x3f) << 8) #define AUART_LINECTRL_SPS (1 << 7) #define AUART_LINECTRL_WLEN_MASK 0x00000060 -#define AUART_LINECTRL_WLEN(v) (((v) & 0x3) << 5) +#define AUART_LINECTRL_WLEN(v) ((((v) - 5) & 0x3) << 5) #define AUART_LINECTRL_FEN (1 << 4) #define AUART_LINECTRL_STP2 (1 << 3) #define AUART_LINECTRL_EPS (1 << 2) @@ -973,16 +973,16 @@ static void mxs_auart_settermios(struct uart_port *u, /* byte size */ switch (cflag & CSIZE) { case CS5: - bm = 0; + bm = 5; break; case CS6: - bm = 1; + bm = 6; break; case CS7: - bm = 2; + bm = 7; break; case CS8: - bm = 3; + bm = 8; break; default: return; @@ -1403,7 +1403,7 @@ auart_console_get_options(struct mxs_auart_port *s, int *baud, *parity = 'o'; } - if ((lcr_h & AUART_LINECTRL_WLEN_MASK) == AUART_LINECTRL_WLEN(2)) + if ((lcr_h & AUART_LINECTRL_WLEN_MASK) == AUART_LINECTRL_WLEN(7)) *bits = 7; else *bits = 8; From d8f0209bfedb801d06a81a74b003a882dee3ea3f Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 10 Jun 2021 11:02:46 +0200 Subject: [PATCH 135/227] cypress_m8: switch data_bits to real character bits Make data_bits what it really is. Assign proper bit counts to data_bits instead of magic 0..3. There are two reasons: 1) it's clear what we store there, and 2) it will make the transition to tty_tty_get_char_size() in the next patch easier. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210610090247.2593-3-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cypress_m8.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 166ee2286fda..4dea3ec2d8b5 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -326,7 +326,7 @@ static int cypress_serial_control(struct tty_struct *tty, /* fill the feature_buffer with new configuration */ put_unaligned_le32(new_baudrate, feature_buffer); - feature_buffer[4] |= data_bits; /* assign data bits in 2 bit space ( max 3 ) */ + feature_buffer[4] |= data_bits - 5; /* assign data bits in 2 bit space ( max 3 ) */ /* 1 bit gap */ feature_buffer[4] |= (stop_bits << 3); /* assign stop bits in 1 bit space */ feature_buffer[4] |= (parity_enable << 4); /* assign parity flag in 1 bit space */ @@ -889,20 +889,20 @@ static void cypress_set_termios(struct tty_struct *tty, switch (cflag & CSIZE) { case CS5: - data_bits = 0; + data_bits = 5; break; case CS6: - data_bits = 1; + data_bits = 6; break; case CS7: - data_bits = 2; + data_bits = 7; break; case CS8: - data_bits = 3; + data_bits = 8; break; default: dev_err(dev, "%s - CSIZE was set, but not CS5-CS8\n", __func__); - data_bits = 3; + data_bits = 8; } spin_lock_irqsave(&priv->lock, flags); oldlines = priv->line_control; From 3ec2ff37230e1c961d4b0d0118dd23c46b5bcdbb Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 10 Jun 2021 11:02:47 +0200 Subject: [PATCH 136/227] tty: make use of tty_get_{char,frame}_size In the previous patch, we introduced tty_get_char_size() and tty_get_frame_size() for computing character and frame sizes, respectively. Here, we make use of them in various tty drivers where applicable. The stats look nice: 12 insertions, 169 deletions. Cc: Arnd Bergmann Cc: David Lin Cc: Johan Hovold Cc: Alex Elder Cc: Shawn Guo Cc: Sascha Hauer Cc: Andy Gross Cc: Bjorn Andersson Cc: Maxime Coquelin Cc: Alexandre Torgue Cc: Oliver Neukum Acked-by: Alex Elder Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210610090247.2593-4-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/char/pcmcia/synclink_cs.c | 8 +----- drivers/staging/greybus/uart.c | 16 +---------- drivers/tty/serial/cpm_uart/cpm_uart_core.c | 19 +----------- drivers/tty/serial/mxs-auart.c | 22 ++------------ drivers/tty/serial/qcom_geni_serial.c | 16 +---------- drivers/tty/serial/sh-sci.c | 20 +------------ drivers/tty/serial/stm32-usart.c | 32 +-------------------- drivers/tty/synclink_gt.c | 9 +----- drivers/usb/class/cdc-acm.c | 17 ++--------- drivers/usb/serial/belkin_sa.c | 20 +------------ drivers/usb/serial/cypress_m8.c | 19 ++---------- drivers/usb/serial/pl2303.c | 15 +--------- drivers/usb/serial/whiteheat.c | 9 +----- 13 files changed, 16 insertions(+), 206 deletions(-) diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 9f7420bc5026..6eaefea0520e 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -1419,13 +1419,7 @@ static void mgslpc_change_params(MGSLPC_INFO *info, struct tty_struct *tty) /* byte size and parity */ - switch (cflag & CSIZE) { - case CS5: info->params.data_bits = 5; break; - case CS6: info->params.data_bits = 6; break; - case CS7: info->params.data_bits = 7; break; - case CS8: info->params.data_bits = 8; break; - default: info->params.data_bits = 7; break; - } + info->params.data_bits = tty_get_char_size(cflag); if (cflag & CSTOPB) info->params.stop_bits = 2; diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c index ccfaa0f21b9c..73f01ed1e5b7 100644 --- a/drivers/staging/greybus/uart.c +++ b/drivers/staging/greybus/uart.c @@ -494,21 +494,7 @@ static void gb_tty_set_termios(struct tty_struct *tty, (termios->c_cflag & PARODD ? 1 : 2) + (termios->c_cflag & CMSPAR ? 2 : 0) : 0; - switch (termios->c_cflag & CSIZE) { - case CS5: - newline.data_bits = 5; - break; - case CS6: - newline.data_bits = 6; - break; - case CS7: - newline.data_bits = 7; - break; - case CS8: - default: - newline.data_bits = 8; - break; - } + newline.data_bits = tty_get_char_size(termios->c_cflag); /* FIXME: needs to clear unsupported bits in the termios */ gb_tty->clocal = ((termios->c_cflag & CLOCAL) != 0); diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index 58aaa533203b..c719aa2b1832 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c @@ -524,24 +524,7 @@ static void cpm_uart_set_termios(struct uart_port *port, scval = 0; /* byte size */ - switch (termios->c_cflag & CSIZE) { - case CS5: - bits = 5; - break; - case CS6: - bits = 6; - break; - case CS7: - bits = 7; - break; - case CS8: - bits = 8; - break; - /* Never happens, but GCC is too dumb to figure it out */ - default: - bits = 8; - break; - } + bits = tty_get_char_size(termios->c_cflag); sbits = bits - 5; if (termios->c_cflag & CSTOPB) { diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 7b4b6bb75424..ac45f3386e97 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -962,7 +962,7 @@ static void mxs_auart_settermios(struct uart_port *u, struct ktermios *old) { struct mxs_auart_port *s = to_auart_port(u); - u32 bm, ctrl, ctrl2, div; + u32 ctrl, ctrl2, div; unsigned int cflag, baud, baud_min, baud_max; cflag = termios->c_cflag; @@ -970,25 +970,7 @@ static void mxs_auart_settermios(struct uart_port *u, ctrl = AUART_LINECTRL_FEN; ctrl2 = mxs_read(s, REG_CTRL2); - /* byte size */ - switch (cflag & CSIZE) { - case CS5: - bm = 5; - break; - case CS6: - bm = 6; - break; - case CS7: - bm = 7; - break; - case CS8: - bm = 8; - break; - default: - return; - } - - ctrl |= AUART_LINECTRL_WLEN(bm); + ctrl |= AUART_LINECTRL_WLEN(tty_get_char_size(cflag)); /* parity */ if (cflag & PARENB) { diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 463f84a66f6e..379ab15daa85 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -1050,21 +1050,7 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport, } /* bits per char */ - switch (termios->c_cflag & CSIZE) { - case CS5: - bits_per_char = 5; - break; - case CS6: - bits_per_char = 6; - break; - case CS7: - bits_per_char = 7; - break; - case CS8: - default: - bits_per_char = 8; - break; - } + bits_per_char = tty_get_char_size(termios->c_cflag); /* stop bits */ if (termios->c_cflag & CSTOPB) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index aabe66c99c1a..07eb56294371 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -2500,25 +2500,7 @@ done: uart_update_timeout(port, termios->c_cflag, baud); /* byte size and parity */ - switch (termios->c_cflag & CSIZE) { - case CS5: - bits = 7; - break; - case CS6: - bits = 8; - break; - case CS7: - bits = 9; - break; - default: - bits = 10; - break; - } - - if (termios->c_cflag & CSTOPB) - bits++; - if (termios->c_cflag & PARENB) - bits++; + bits = tty_get_frame_size(termios->c_cflag); if (sci_getreg(port, SEMR)->size) serial_port_out(port, SEMR, 0); diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index cd6adb979df9..ef793b3b4591 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -718,36 +718,6 @@ static void stm32_usart_shutdown(struct uart_port *port) free_irq(port->irq, port); } -static unsigned int stm32_usart_get_databits(struct ktermios *termios) -{ - unsigned int bits; - - tcflag_t cflag = termios->c_cflag; - - switch (cflag & CSIZE) { - /* - * CSIZE settings are not necessarily supported in hardware. - * CSIZE unsupported configurations are handled here to set word length - * to 8 bits word as default configuration and to print debug message. - */ - case CS5: - bits = 5; - break; - case CS6: - bits = 6; - break; - case CS7: - bits = 7; - break; - /* default including CS8 */ - default: - bits = 8; - break; - } - - return bits; -} - static void stm32_usart_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) @@ -805,7 +775,7 @@ static void stm32_usart_set_termios(struct uart_port *port, if (cflag & CSTOPB) cr2 |= USART_CR2_STOP_2B; - bits = stm32_usart_get_databits(termios); + bits = tty_get_char_size(cflag); stm32_port->rdr_mask = (BIT(bits) - 1); if (cflag & PARENB) { diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index cf87dc66087b..5bb928b7873e 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -2465,14 +2465,7 @@ static void change_params(struct slgt_info *info) /* byte size and parity */ - switch (cflag & CSIZE) { - case CS5: info->params.data_bits = 5; break; - case CS6: info->params.data_bits = 6; break; - case CS7: info->params.data_bits = 7; break; - case CS8: info->params.data_bits = 8; break; - default: info->params.data_bits = 7; break; - } - + info->params.data_bits = tty_get_char_size(cflag); info->params.stop_bits = (cflag & CSTOPB) ? 2 : 1; if (cflag & PARENB) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 81199efe0312..c9954eb56e00 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1056,21 +1056,8 @@ static void acm_tty_set_termios(struct tty_struct *tty, newline.bParityType = termios->c_cflag & PARENB ? (termios->c_cflag & PARODD ? 1 : 2) + (termios->c_cflag & CMSPAR ? 2 : 0) : 0; - switch (termios->c_cflag & CSIZE) { - case CS5: - newline.bDataBits = 5; - break; - case CS6: - newline.bDataBits = 6; - break; - case CS7: - newline.bDataBits = 7; - break; - case CS8: - default: - newline.bDataBits = 8; - break; - } + newline.bDataBits = tty_get_char_size(termios->c_cflag); + /* FIXME: Needs to clear unsupported bits in the termios */ acm->clocal = ((termios->c_cflag & CLOCAL) != 0); diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index ed9193f3bb1a..8107e4b5b03b 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -356,25 +356,7 @@ static void belkin_sa_set_termios(struct tty_struct *tty, /* set the number of data bits */ if ((cflag & CSIZE) != (old_cflag & CSIZE)) { - switch (cflag & CSIZE) { - case CS5: - urb_value = BELKIN_SA_DATA_BITS(5); - break; - case CS6: - urb_value = BELKIN_SA_DATA_BITS(6); - break; - case CS7: - urb_value = BELKIN_SA_DATA_BITS(7); - break; - case CS8: - urb_value = BELKIN_SA_DATA_BITS(8); - break; - default: - dev_dbg(&port->dev, - "CSIZE was not CS5-CS8, using default of 8\n"); - urb_value = BELKIN_SA_DATA_BITS(8); - break; - } + urb_value = BELKIN_SA_DATA_BITS(tty_get_char_size(cflag)); if (BSA_USB_CMD(BELKIN_SA_SET_DATA_BITS_REQUEST, urb_value) < 0) dev_err(&port->dev, "Set data bits error\n"); } diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 4dea3ec2d8b5..55f23df03e0b 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -887,23 +887,8 @@ static void cypress_set_termios(struct tty_struct *tty, } else parity_enable = parity_type = 0; - switch (cflag & CSIZE) { - case CS5: - data_bits = 5; - break; - case CS6: - data_bits = 6; - break; - case CS7: - data_bits = 7; - break; - case CS8: - data_bits = 8; - break; - default: - dev_err(dev, "%s - CSIZE was set, but not CS5-CS8\n", __func__); - data_bits = 8; - } + data_bits = tty_get_char_size(cflag); + spin_lock_irqsave(&priv->lock, flags); oldlines = priv->line_control; if ((cflag & CBAUD) == B0) { diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 940050c31482..2f2f5047452b 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -789,20 +789,7 @@ static void pl2303_set_termios(struct tty_struct *tty, pl2303_get_line_request(port, buf); - switch (C_CSIZE(tty)) { - case CS5: - buf[6] = 5; - break; - case CS6: - buf[6] = 6; - break; - case CS7: - buf[6] = 7; - break; - default: - case CS8: - buf[6] = 8; - } + buf[6] = tty_get_char_size(tty->termios.c_cflag); dev_dbg(&port->dev, "data bits = %d\n", buf[6]); /* For reference buf[0]:buf[3] baud rate value */ diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 5116ed9db3eb..da65d14c9ed5 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -625,14 +625,7 @@ static void firm_setup_port(struct tty_struct *tty) port_settings.port = port->port_number + 1; - /* get the byte size */ - switch (cflag & CSIZE) { - case CS5: port_settings.bits = 5; break; - case CS6: port_settings.bits = 6; break; - case CS7: port_settings.bits = 7; break; - default: - case CS8: port_settings.bits = 8; break; - } + port_settings.bits = tty_get_char_size(cflag); dev_dbg(dev, "%s - data bits = %d\n", __func__, port_settings.bits); /* determine the parity */ From f771a34b141124a68265f91acae34cdb08aeb9e0 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Thu, 10 Jun 2021 20:38:59 +0200 Subject: [PATCH 137/227] serial: 8250: Dissociate 4MHz Titan ports from Oxford ports Oxford Semiconductor PCIe (Tornado) serial port devices have their baud base set incorrectly, however their `pciserial_board' entries have been reused for Titan serial port devices. Define own entries for the latter devices then, carrying over the settings, so that Oxford entries can be fixed. Signed-off-by: Maciej W. Rozycki Link: https://lore.kernel.org/r/alpine.DEB.2.21.2106100142310.5469@angie.orcam.me.uk Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 44 ++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 780cc99732b6..f4134e72ee71 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -2972,6 +2972,10 @@ enum pci_board_num_t { pbn_sunix_pci_4s, pbn_sunix_pci_8s, pbn_sunix_pci_16s, + pbn_titan_1_4000000, + pbn_titan_2_4000000, + pbn_titan_4_4000000, + pbn_titan_8_4000000, pbn_moxa8250_2p, pbn_moxa8250_4p, pbn_moxa8250_8p, @@ -3759,6 +3763,34 @@ static struct pciserial_board pci_boards[] = { .base_baud = 921600, .uart_offset = 0x8, }, + [pbn_titan_1_4000000] = { + .flags = FL_BASE0, + .num_ports = 1, + .base_baud = 4000000, + .uart_offset = 0x200, + .first_offset = 0x1000, + }, + [pbn_titan_2_4000000] = { + .flags = FL_BASE0, + .num_ports = 2, + .base_baud = 4000000, + .uart_offset = 0x200, + .first_offset = 0x1000, + }, + [pbn_titan_4_4000000] = { + .flags = FL_BASE0, + .num_ports = 4, + .base_baud = 4000000, + .uart_offset = 0x200, + .first_offset = 0x1000, + }, + [pbn_titan_8_4000000] = { + .flags = FL_BASE0, + .num_ports = 8, + .base_baud = 4000000, + .uart_offset = 0x200, + .first_offset = 0x1000, + }, [pbn_moxa8250_2p] = { .flags = FL_BASE1, .num_ports = 2, @@ -4703,22 +4735,22 @@ static const struct pci_device_id serial_pci_tbl[] = { pbn_b0_4_921600 }, { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_titan_1_4000000 }, { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_2_4000000 }, + pbn_titan_2_4000000 }, { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_4_4000000 }, + pbn_titan_4_4000000 }, { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_8_4000000 }, + pbn_titan_8_4000000 }, { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EI, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_2_4000000 }, + pbn_titan_2_4000000 }, { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EISI, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_2_4000000 }, + pbn_titan_2_4000000 }, { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200V3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b0_bt_2_921600 }, From 6cbe45d8ac9316ceedd0749759bd54caf03f7012 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Thu, 10 Jun 2021 20:39:03 +0200 Subject: [PATCH 138/227] serial: 8250: Correct the clock for OxSemi PCIe devices Oxford Semiconductor PCIe (Tornado) serial port devices are driven by a fixed 62.5MHz clock input derived from the 100MHz PCI Express clock. In the enhanced (650) mode, which we select in `autoconfig_has_efr' by setting the ECB bit in the EFR register, and in the absence of clock reconfiguration, which we currently don't do, the clock rate is divided only by the oversampling rate of 16 as it is supplied to the baud rate generator, yielding the baud base of 3906250. This comes from the reset values of the TCR and MCR[7] registers which are both zero[1][2][3][4], choosing the oversampling rate of 16 and the normal (divide by 1) baud rate generator prescaler respectively. This is the rate that is divided by the value held in the divisor latch to determine the baud rate used. Replace the incorrect baud base of 4000000 with the right value of 3906250 then. References: [1] "OXPCIe200 PCI Express Multi-Port Bridge", Oxford Semiconductor, Inc., DS-0045, 10 Nov 2008, Section "Reset Configuration", p. 72 [2] "OXPCIe952 PCI Express Bridge to Dual Serial & Parallel Port", Oxford Semiconductor, Inc., DS-0046, Mar 06 08, Section "Reset Configuration", p. 27 [3] "OXPCIe954 PCI Express Bridge to Quad Serial Port", Oxford Semiconductor, Inc., DS-0047, Feb 08, Section "Reset Configuration", p. 28 [4] "OXPCIe958 PCI Express Bridge to Octal Serial Port", Oxford Semiconductor, Inc., DS-0048, Feb 08, Section "Reset Configuration", p. 28 Fixes: 7106b4e333bae ("8250: Oxford Semiconductor Devices") Signed-off-by: Maciej W. Rozycki Link: https://lore.kernel.org/r/alpine.DEB.2.21.2106100203510.5469@angie.orcam.me.uk Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 128 ++++++++++++++--------------- 1 file changed, 64 insertions(+), 64 deletions(-) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index f4134e72ee71..75827b608fdb 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -2851,7 +2851,7 @@ enum pci_board_num_t { pbn_b0_2_1843200, pbn_b0_4_1843200, - pbn_b0_1_4000000, + pbn_b0_1_3906250, pbn_b0_bt_1_115200, pbn_b0_bt_2_115200, @@ -2931,10 +2931,10 @@ enum pci_board_num_t { pbn_plx_romulus, pbn_endrun_2_4000000, pbn_oxsemi, - pbn_oxsemi_1_4000000, - pbn_oxsemi_2_4000000, - pbn_oxsemi_4_4000000, - pbn_oxsemi_8_4000000, + pbn_oxsemi_1_3906250, + pbn_oxsemi_2_3906250, + pbn_oxsemi_4_3906250, + pbn_oxsemi_8_3906250, pbn_intel_i960, pbn_sgi_ioc3, pbn_computone_4, @@ -3081,10 +3081,10 @@ static struct pciserial_board pci_boards[] = { .uart_offset = 8, }, - [pbn_b0_1_4000000] = { + [pbn_b0_1_3906250] = { .flags = FL_BASE0, .num_ports = 1, - .base_baud = 4000000, + .base_baud = 3906250, .uart_offset = 8, }, @@ -3479,31 +3479,31 @@ static struct pciserial_board pci_boards[] = { .base_baud = 115200, .uart_offset = 8, }, - [pbn_oxsemi_1_4000000] = { + [pbn_oxsemi_1_3906250] = { .flags = FL_BASE0, .num_ports = 1, - .base_baud = 4000000, + .base_baud = 3906250, .uart_offset = 0x200, .first_offset = 0x1000, }, - [pbn_oxsemi_2_4000000] = { + [pbn_oxsemi_2_3906250] = { .flags = FL_BASE0, .num_ports = 2, - .base_baud = 4000000, + .base_baud = 3906250, .uart_offset = 0x200, .first_offset = 0x1000, }, - [pbn_oxsemi_4_4000000] = { + [pbn_oxsemi_4_3906250] = { .flags = FL_BASE0, .num_ports = 4, - .base_baud = 4000000, + .base_baud = 3906250, .uart_offset = 0x200, .first_offset = 0x1000, }, - [pbn_oxsemi_8_4000000] = { + [pbn_oxsemi_8_3906250] = { .flags = FL_BASE0, .num_ports = 8, - .base_baud = 4000000, + .base_baud = 3906250, .uart_offset = 0x200, .first_offset = 0x1000, }, @@ -4510,158 +4510,158 @@ static const struct pci_device_id serial_pci_tbl[] = { */ { PCI_VENDOR_ID_OXSEMI, 0xc101, /* OXPCIe952 1 Legacy UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_b0_1_4000000 }, + pbn_b0_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc105, /* OXPCIe952 1 Legacy UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_b0_1_4000000 }, + pbn_b0_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc11b, /* OXPCIe952 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc11f, /* OXPCIe952 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc120, /* OXPCIe952 1 Legacy UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_b0_1_4000000 }, + pbn_b0_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc124, /* OXPCIe952 1 Legacy UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_b0_1_4000000 }, + pbn_b0_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc138, /* OXPCIe952 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc13d, /* OXPCIe952 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc140, /* OXPCIe952 1 Legacy UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_b0_1_4000000 }, + pbn_b0_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc141, /* OXPCIe952 1 Legacy UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_b0_1_4000000 }, + pbn_b0_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc144, /* OXPCIe952 1 Legacy UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_b0_1_4000000 }, + pbn_b0_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc145, /* OXPCIe952 1 Legacy UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_b0_1_4000000 }, + pbn_b0_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc158, /* OXPCIe952 2 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_2_4000000 }, + pbn_oxsemi_2_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc15d, /* OXPCIe952 2 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_2_4000000 }, + pbn_oxsemi_2_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc208, /* OXPCIe954 4 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_4_4000000 }, + pbn_oxsemi_4_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc20d, /* OXPCIe954 4 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_4_4000000 }, + pbn_oxsemi_4_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc308, /* OXPCIe958 8 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_8_4000000 }, + pbn_oxsemi_8_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc30d, /* OXPCIe958 8 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_8_4000000 }, + pbn_oxsemi_8_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc40b, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc40f, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc41b, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc41f, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc42b, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc42f, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc43b, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc43f, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc44b, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc44f, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc45b, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc45f, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc46b, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc46f, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc47b, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc47f, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc48b, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc48f, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc49b, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc49f, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc4ab, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc4af, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc4bb, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc4bf, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc4cb, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_OXSEMI, 0xc4cf, /* OXPCIe200 1 Native UART */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, /* * Mainpine Inc. IQ Express "Rev3" utilizing OxSemi Tornado */ { PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 1 Port V.34 Super-G3 Fax */ PCI_VENDOR_ID_MAINPINE, 0x4001, 0, 0, - pbn_oxsemi_1_4000000 }, + pbn_oxsemi_1_3906250 }, { PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 2 Port V.34 Super-G3 Fax */ PCI_VENDOR_ID_MAINPINE, 0x4002, 0, 0, - pbn_oxsemi_2_4000000 }, + pbn_oxsemi_2_3906250 }, { PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 4 Port V.34 Super-G3 Fax */ PCI_VENDOR_ID_MAINPINE, 0x4004, 0, 0, - pbn_oxsemi_4_4000000 }, + pbn_oxsemi_4_3906250 }, { PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 8 Port V.34 Super-G3 Fax */ PCI_VENDOR_ID_MAINPINE, 0x4008, 0, 0, - pbn_oxsemi_8_4000000 }, + pbn_oxsemi_8_3906250 }, /* * Digi/IBM PCIe 2-port Async EIA-232 Adapter utilizing OxSemi Tornado */ { PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_2_OX_IBM, PCI_SUBVENDOR_ID_IBM, PCI_ANY_ID, 0, 0, - pbn_oxsemi_2_4000000 }, + pbn_oxsemi_2_3906250 }, /* * SBS Technologies, Inc. P-Octal and PMC-OCTPRO cards, From 1882441cd788a496b378f4d2684fa66cec195051 Mon Sep 17 00:00:00 2001 From: Vignesh Raghavendra Date: Thu, 10 Jun 2021 23:52:27 +0530 Subject: [PATCH 139/227] dt-bindings: serial: Move omap-serial.txt to YAML schema Convert serial-omap.txt to YAML schema for better checks and documentation. Acked-by: Tony Lindgren Signed-off-by: Vignesh Raghavendra Link: https://lore.kernel.org/r/20210610182227.2480-1-vigneshr@ti.com Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/serial/8250_omap.yaml | 118 ++++++++++++++++++ .../bindings/serial/omap_serial.txt | 40 ------ 2 files changed, 118 insertions(+), 40 deletions(-) create mode 100644 Documentation/devicetree/bindings/serial/8250_omap.yaml delete mode 100644 Documentation/devicetree/bindings/serial/omap_serial.txt diff --git a/Documentation/devicetree/bindings/serial/8250_omap.yaml b/Documentation/devicetree/bindings/serial/8250_omap.yaml new file mode 100644 index 000000000000..1c826fcf5828 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/8250_omap.yaml @@ -0,0 +1,118 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/serial/8250_omap.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Bindings for 8250 compliant UARTs on TI's OMAP2+ and K3 SoCs + +maintainers: + - Vignesh Raghavendra + +allOf: + - $ref: /schemas/serial/serial.yaml# + - $ref: /schemas/serial/rs485.yaml# + +properties: + compatible: + oneOf: + - enum: + - ti,am3352-uart + - ti,am4372-uart + - ti,am654-uart + - ti,dra742-uart + - ti,omap2-uart + - ti,omap3-uart + - ti,omap4-uart + - items: + - enum: + - ti,am64-uart + - ti,j721e-uart + - const: ti,am654-uart + + ti,hwmods: + description: + Must be "uart", n being the instance number (1-based) + This property is applicable only on legacy platforms mainly omap2/3 + and ti81xx and should not be used on other platforms. + $ref: /schemas/types.yaml#/definitions/string + deprecated: true + + dmas: + minItems: 1 + maxItems: 2 + + dma-names: + items: + - const: tx + - const: rx + + reg: + maxItems: 1 + + interrupts: + minItems: 1 + maxItems: 2 + description: + First entry is module IRQ required for normal IO operation. + Second entry is optional and corresponds to system wakeup IRQ + where supported. + + clocks: + maxItems: 1 + + clock-names: + const: fclk + + rts-gpios: true + cts-gpios: true + dtr-gpios: true + dsr-gpios: true + rng-gpios: true + dcd-gpios: true + rs485-rts-delay: true + rs485-rts-active-low: true + rs485-rx-during-tx: true + rs485-rts-active-high: true + linux,rs485-enabled-at-boot-time: true + rts-gpio: true + power-domains: true + clock-frequency: true + current-speed: true + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +if: + properties: + compatible: + oneOf: + - const: ti,omap2-uart + - const: ti,omap3-uart + - const: ti,omap4-uart + +then: + properties: + ti,hwmods: + items: + - pattern: "^uart([1-9])$" + +else: + properties: + ti,hwmods: false + +examples: + - | + serial@49042000 { + compatible = "ti,omap3-uart"; + reg = <0x49042000 0x400>; + interrupts = <80>; + dmas = <&sdma 81 &sdma 82>; + dma-names = "tx", "rx"; + ti,hwmods = "uart4"; + clock-frequency = <48000000>; + }; diff --git a/Documentation/devicetree/bindings/serial/omap_serial.txt b/Documentation/devicetree/bindings/serial/omap_serial.txt deleted file mode 100644 index c2db8cabf2ab..000000000000 --- a/Documentation/devicetree/bindings/serial/omap_serial.txt +++ /dev/null @@ -1,40 +0,0 @@ -OMAP UART controller - -Required properties: -- compatible : should be "ti,am64-uart", "ti,am654-uart" for AM64 controllers -- compatible : should be "ti,j721e-uart", "ti,am654-uart" for J721E controllers -- compatible : should be "ti,am654-uart" for AM654 controllers -- compatible : should be "ti,omap2-uart" for OMAP2 controllers -- compatible : should be "ti,omap3-uart" for OMAP3 controllers -- compatible : should be "ti,omap4-uart" for OMAP4 controllers -- compatible : should be "ti,am4372-uart" for AM437x controllers -- compatible : should be "ti,am3352-uart" for AM335x controllers -- compatible : should be "ti,dra742-uart" for DRA7x controllers -- reg : address and length of the register space -- interrupts or interrupts-extended : Should contain the uart interrupt - specifier or both the interrupt - controller phandle and interrupt - specifier. -- ti,hwmods : Must be "uart", n being the instance number (1-based) - -Optional properties: -- clock-frequency : frequency of the clock input to the UART -- dmas : DMA specifier, consisting of a phandle to the DMA controller - node and a DMA channel number. -- dma-names : "rx" for receive channel, "tx" for transmit channel. -- rs485-rts-delay, rs485-rx-during-tx, linux,rs485-enabled-at-boot-time: see rs485.txt -- rs485-rts-active-high: drive RTS high when sending (default is low). -- clocks: phandle to the functional clock as per - Documentation/devicetree/bindings/clock/clock-bindings.txt - -Example: - - uart4: serial@49042000 { - compatible = "ti,omap3-uart"; - reg = <0x49042000 0x400>; - interrupts = <80>; - dmas = <&sdma 81 &sdma 82>; - dma-names = "tx", "rx"; - ti,hwmods = "uart4"; - clock-frequency = <48000000>; - }; From b1691bd04952bc6cbb7d75b1758c73942133c8ba Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Thu, 10 Jun 2021 20:38:28 +0200 Subject: [PATCH 140/227] serial: 8250: Document SMSC Super I/O UART peculiarities Contrary to what SMSC documentation says and unlike NS16C550A UARTs the SMSC Super I/O IC claims compatibility with the SMSC UART implementation does not support dividing the internal PLL clock by any divisor from 1 to 65535[1], with the exception of two magic divisors of 32769 and 32770 used respectively to select the high-speed data rates of 460800bps and 230400bps[2] if enabled on a port-by-port basis in with the Serial Port Mode Register in the Device Configuration Space[3][4]. Instead empirical evidence indicates that the divisor, as stored in the DLL and DLM register pair, has the range of 1 to 32767 only, and bit 7 of the DLM register (bit 15 of the divisor) effectively serves as a selection bit for the prescaler from the base frequency of 7.3728MHz, either 4 if the bit is 0, or 1 if the bit is 1 and high-speed operation has been enabled with the Serial Port Mode Register. So if high-speed operation has not been enabled, then say the values of 1 and 32769 (0x8001) written into the combined DLL and DLM register pair both select the divisor of 1 and the baud rate of 115200bps. [1] "FDC37M81x, PC98/99 Compliant Enhanced Super I/O Controller with Keyboard/Mouse Wake-Up", Standard Microsystems Corporation, Rev. 03/27/2000, Section "Programmable Baud Rate Generator (and Divisor Latches DLH, DLL)", p. 75 [2] same, Table 31 - "Baud Rates", p. 77 [3] same, Table 60 - "Serial Port 1, Logical Device 4 [Logical Device Number = 0x04]", p. 153 [4] same, Table 61 - "Serial Port 2, Logical Device 5 [Logical Device Number = 0x05]", p. 153 Signed-off-by: Maciej W. Rozycki Link: https://lore.kernel.org/r/alpine.DEB.2.21.2106092330530.5469@angie.orcam.me.uk Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_port.c | 31 +++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index fc5ab2032282..b96562102b43 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -2516,9 +2516,36 @@ static unsigned int serial8250_do_get_divisor(struct uart_port *port, unsigned int quot; /* - * Handle magic divisors for baud rates above baud_base on - * SMSC SuperIO chips. + * Handle magic divisors for baud rates above baud_base on SMSC + * Super I/O chips. We clamp custom rates from clk/6 and clk/12 + * up to clk/4 (0x8001) and clk/8 (0x8002) respectively. These + * magic divisors actually reprogram the baud rate generator's + * reference clock derived from chips's 14.318MHz clock input. * + * Documentation claims that with these magic divisors the base + * frequencies of 7.3728MHz and 3.6864MHz are used respectively + * for the extra baud rates of 460800bps and 230400bps rather + * than the usual base frequency of 1.8462MHz. However empirical + * evidence contradicts that. + * + * Instead bit 7 of the DLM register (bit 15 of the divisor) is + * effectively used as a clock prescaler selection bit for the + * base frequency of 7.3728MHz, always used. If set to 0, then + * the base frequency is divided by 4 for use by the Baud Rate + * Generator, for the usual arrangement where the value of 1 of + * the divisor produces the baud rate of 115200bps. Conversely, + * if set to 1 and high-speed operation has been enabled with the + * Serial Port Mode Register in the Device Configuration Space, + * then the base frequency is supplied directly to the Baud Rate + * Generator, so for the divisor values of 0x8001, 0x8002, 0x8003, + * 0x8004, etc. the respective baud rates produced are 460800bps, + * 230400bps, 153600bps, 115200bps, etc. + * + * In all cases only low 15 bits of the divisor are used to divide + * the baud base and therefore 32767 is the maximum divisor value + * possible, even though documentation says that the programmable + * Baud Rate Generator is capable of dividing the internal PLL + * clock by any divisor from 1 to 65535. */ if ((port->flags & UPF_MAGIC_MULTIPLIER) && baud == (port->uartclk/4)) From 78bcae8616ac277d6cb7f38e211493948ed73e30 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Thu, 10 Jun 2021 20:38:34 +0200 Subject: [PATCH 141/227] serial: 8250: Actually allow UPF_MAGIC_MULTIPLIER baud rates Support for magic baud rate divisors of 32770 and 32769 used with SMSC Super I/O chips for extra baud rates of 230400 and 460800 respectively where base rate is 115200[1] has been added around Linux 2.5.64, which predates our repo history, but the origin could be identified as commit 2a717aad772f ("Merge with Linux 2.5.64.") with the old MIPS/Linux repo also at: . Code that is now in `serial8250_do_get_divisor' was added back then to `serial8250_get_divisor', but that code would only ever trigger if one of the higher baud rates was actually requested, and that cannot ever happen, because the earlier call to `serial8250_get_baud_rate' never returns them. This is because it calls `uart_get_baud_rate' with the maximum requested being the base rate, that is clk/16 or 115200 for SMSC chips at their nominal clock rate. Fix it then and allow UPF_MAGIC_MULTIPLIER baud rates to be selected, by requesting the maximum baud rate of clk/4 rather than clk/16 if the flag has been set. Also correct the minimum baud rate, observing that these ports only support actual (non-magic) divisors of up to 32767 only. References: [1] "FDC37M81x, PC98/99 Compliant Enhanced Super I/O Controller with Keyboard/Mouse Wake-Up", Standard Microsystems Corporation, Rev. 03/27/2000, Table 31 - "Baud Rates", p. 77 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Maciej W. Rozycki Link: https://lore.kernel.org/r/alpine.DEB.2.21.2105190412280.29169@angie.orcam.me.uk Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_port.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index b96562102b43..2cec419cd3cd 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -2656,6 +2656,21 @@ static unsigned int serial8250_get_baud_rate(struct uart_port *port, struct ktermios *old) { unsigned int tolerance = port->uartclk / 100; + unsigned int min; + unsigned int max; + + /* + * Handle magic divisors for baud rates above baud_base on SMSC + * Super I/O chips. Enable custom rates of clk/4 and clk/8, but + * disable divisor values beyond 32767, which are unavailable. + */ + if (port->flags & UPF_MAGIC_MULTIPLIER) { + min = port->uartclk / 16 / UART_DIV_MAX >> 1; + max = (port->uartclk + tolerance) / 4; + } else { + min = port->uartclk / 16 / UART_DIV_MAX; + max = (port->uartclk + tolerance) / 16; + } /* * Ask the core to calculate the divisor for us. @@ -2663,9 +2678,7 @@ static unsigned int serial8250_get_baud_rate(struct uart_port *port, * slower than nominal still match standard baud rates without * causing transmission errors. */ - return uart_get_baud_rate(port, termios, old, - port->uartclk / 16 / UART_DIV_MAX, - (port->uartclk + tolerance) / 16); + return uart_get_baud_rate(port, termios, old, min, max); } /* From f7adc73878187be895e8790033cea1fb59ffbc16 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Thu, 10 Jun 2021 20:38:39 +0200 Subject: [PATCH 142/227] serial: 8250: Handle custom baud rates in UPF_MAGIC_MULTIPLIER range Handle custom baud rates requested in the UPF_MAGIC_MULTIPLIER range with BOTHER. Currently matching is exact, that is if a baud rate that is not either of clk/4 or clk/8 is requested, then we fall through to the default case, which will just divide the clock rate by 16 times the rate requested, round it to closest integer, and possibly yield even worse results then if clamping to the extra baud rates was chosen. So for example if we have the usual base rate of 115200 and request a rate of 230399, then the fall-through divisor calculation will yield 1, and consequently the baud rate of 115200 will be programmed even though obviously the magic rate of 230400 would be more appropriate. Make the selection of the magic rates range-qualified then and use clk/4 for rates from clk/6 up (assuming `serial8250_get_baud_rate' has already rejected any rates too far beyond clk/4), and otherwise use clk/8 for rates from clk/12 up, and finally fall through to the standard divisor calculation. Explicitly void using the undocumented rate of 153600bps and stick to documented divisor values only. Signed-off-by: Maciej W. Rozycki Link: https://lore.kernel.org/r/alpine.DEB.2.21.2105200232090.29169@angie.orcam.me.uk Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_port.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 2cec419cd3cd..2164290cbd31 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -2512,6 +2512,7 @@ static unsigned int serial8250_do_get_divisor(struct uart_port *port, unsigned int baud, unsigned int *frac) { + upf_t magic_multiplier = port->flags & UPF_MAGIC_MULTIPLIER; struct uart_8250_port *up = up_to_u8250p(port); unsigned int quot; @@ -2547,11 +2548,9 @@ static unsigned int serial8250_do_get_divisor(struct uart_port *port, * Baud Rate Generator is capable of dividing the internal PLL * clock by any divisor from 1 to 65535. */ - if ((port->flags & UPF_MAGIC_MULTIPLIER) && - baud == (port->uartclk/4)) + if (magic_multiplier && baud >= port->uartclk / 6) quot = 0x8001; - else if ((port->flags & UPF_MAGIC_MULTIPLIER) && - baud == (port->uartclk/8)) + else if (magic_multiplier && baud >= port->uartclk / 12) quot = 0x8002; else if (up->port.type == PORT_NPCM) quot = npcm_get_divisor(up, baud); From 788847839873ebe9fdf107f86e7e9928515ffbee Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Thu, 10 Jun 2021 20:38:48 +0200 Subject: [PATCH 143/227] MIPS: Malta: Enable magic multipliers for Super I/O UARTs The SMSC FDC37M817 Super I/O chip has a configuration feature that lets it support special UART divisor values of 32770 and 32769 for bit rates of 230400 and 460800 bits per second respectively. Our 8250 driver core provides support for these special divisors via the UPF_MAGIC_MULTIPLIER flag, and YAMON firmware unconditionally configures the Super I/O chip with these divisors enabled as well, so all we need to do in platform setup for these bit rates to work is to set the flag. Signed-off-by: Maciej W. Rozycki Link: https://lore.kernel.org/r/alpine.DEB.2.21.2105182249380.3032@angie.orcam.me.uk Signed-off-by: Greg Kroah-Hartman --- arch/mips/mti-malta/malta-platform.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/mips/mti-malta/malta-platform.c b/arch/mips/mti-malta/malta-platform.c index 11e9527c6e44..ee7471984fe7 100644 --- a/arch/mips/mti-malta/malta-platform.c +++ b/arch/mips/mti-malta/malta-platform.c @@ -33,7 +33,8 @@ .irq = int, \ .uartclk = 1843200, \ .iotype = UPIO_PORT, \ - .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \ + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | \ + UPF_MAGIC_MULTIPLIER, \ .regshift = 0, \ } From 11b1d881a90fc184cc7d06e9804eb288c24a2a0d Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Fri, 11 Jun 2021 22:19:39 +0200 Subject: [PATCH 144/227] serial_cs: remove wrong GLOBETROTTER.cis entry The GLOBETROTTER.cis entry in serial_cs matches more devices than intended and breaks them. Remove it. Example: # pccardctl info PRODID_1="Option International " PRODID_2="GSM-Ready 56K/ISDN " PRODID_3="021 " PRODID_4="A " MANFID=0013,0000 FUNCID=0 result: pcmcia 0.0: Direct firmware load for cis/GLOBETROTTER.cis failed with error -2 The GLOBETROTTER.cis is nowhere to be found. There's GLOBETROTTER.cis.ihex at https://netdev.vger.kernel.narkive.com/h4inqdxM/patch-axnet-cs-fix-phy-id-detection-for-bogus-asix-chip#post41 It's from completely diffetent card: vers_1 4.1, "Option International", "GSM/GPRS GlobeTrotter", "001", "A" Signed-off-by: Ondrej Zary Cc: stable Link: https://lore.kernel.org/r/20210611201940.23898-1-linux@zary.sk Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/serial_cs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/tty/serial/8250/serial_cs.c b/drivers/tty/serial/8250/serial_cs.c index 3708114343b0..2f1d33ea26e1 100644 --- a/drivers/tty/serial/8250/serial_cs.c +++ b/drivers/tty/serial/8250/serial_cs.c @@ -813,7 +813,6 @@ static const struct pcmcia_device_id serial_ids[] = { PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "cis/COMpad4.cis"), PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "cis/COMpad2.cis"), PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"), - PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "cis/GLOBETROTTER.cis"), PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.", "SERIAL CARD: SL100 1.00.", 0x19ca78af, 0xf964f42b), PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.", "SERIAL CARD: SL100", 0x19ca78af, 0x71d98e83), PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.", "SERIAL CARD: SL232 1.00.", 0x19ca78af, 0x69fb7490), From d495dd743d5ecd47288156e25c4d9163294a0992 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Fri, 11 Jun 2021 22:19:40 +0200 Subject: [PATCH 145/227] serial_cs: Add Option International GSM-Ready 56K/ISDN modem Add support for Option International GSM-Ready 56K/ISDN PCMCIA modem card. Signed-off-by: Ondrej Zary Cc: stable Link: https://lore.kernel.org/r/20210611201940.23898-2-linux@zary.sk Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/serial_cs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/8250/serial_cs.c b/drivers/tty/serial/8250/serial_cs.c index 2f1d33ea26e1..dc2ef05a10eb 100644 --- a/drivers/tty/serial/8250/serial_cs.c +++ b/drivers/tty/serial/8250/serial_cs.c @@ -786,6 +786,7 @@ static const struct pcmcia_device_id serial_ids[] = { PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT2834LT", 0x5f73be51, 0x4cd7c09e), PCMCIA_DEVICE_PROD_ID12("OEM ", "C288MX ", 0xb572d360, 0xd2385b7a), PCMCIA_DEVICE_PROD_ID12("Option International", "V34bis GSM/PSTN Data/Fax Modem", 0x9d7cd6f5, 0x5cb8bf41), + PCMCIA_DEVICE_PROD_ID12("Option International", "GSM-Ready 56K/ISDN", 0x9d7cd6f5, 0xb23844aa), PCMCIA_DEVICE_PROD_ID12("PCMCIA ", "C336MX ", 0x99bcafe9, 0xaa25bcab), PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f), PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "Dual RS-232 Serial Port PC Card", 0xc4420b35, 0x031a380d), From 291343676e328e1493204faa149746829c488b06 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:07 +0200 Subject: [PATCH 146/227] mxser: drop ISA support While mxser PCI cards are still around and produced (Moxa provided me with two recently), ISA cards are obsolete for a long time. I haven't seen anyone using the cards and the ISA code paths are barely tested. Hence, remove ISA support from mxser driver so that we can clean the driver up. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-2-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- .../driver-api/serial/moxa-smartio.rst | 107 +----- drivers/tty/Kconfig | 2 +- drivers/tty/mxser.c | 348 +----------------- 3 files changed, 17 insertions(+), 440 deletions(-) diff --git a/Documentation/driver-api/serial/moxa-smartio.rst b/Documentation/driver-api/serial/moxa-smartio.rst index 156100f17c3f..aedda2546242 100644 --- a/Documentation/driver-api/serial/moxa-smartio.rst +++ b/Documentation/driver-api/serial/moxa-smartio.rst @@ -37,8 +37,7 @@ Date: 01/21/2008 CP-102U, CP-102UL, CP-102UF CP-132U-I, CP-132UL, CP-132, CP-132I, CP132S, CP-132IS, - CI-132, CI-132I, CI-132IS, - (C102H, C102HI, C102HIS, C102P, CP-102, CP-102S) + (CP-102, CP-102S) - 4 ports multiport board CP-104EL, @@ -46,10 +45,7 @@ Date: 01/21/2008 CP-134U, CP-134U-I, C104H/PCI, C104HS/PCI, CP-114, CP-114I, CP-114S, CP-114IS, CP-114UL, - C104H, C104HS, - CI-104J, CI-104JS, - CI-134, CI-134I, CI-134IS, - (C114HI, CT-114I, C104P), + (C114HI, CT-114I), POS-104UL, CB-114, CB-134I @@ -58,8 +54,6 @@ Date: 01/21/2008 CP-118EL, CP-168EL, CP-118U, CP-168U, C168H/PCI, - C168H, C168HS, - (C168P), CB-108 This driver and installation procedure have been developed upon Linux Kernel @@ -78,9 +72,6 @@ Date: 01/21/2008 Monitor program to observe data count and line status signals. - msterm A simple terminal program which is useful in testing serial ports. - - io-irq.exe - Configuration program to setup ISA boards. Please note that - this program can only be executed under DOS. All the drivers and utilities are published in form of source code under GNU General Public License in this version. Please refer to GNU General @@ -112,17 +103,6 @@ Date: 01/21/2008 3.1 Hardware installation ========================= - There are two types of buses, ISA and PCI, for Smartio/Industio - family multiport board. - -ISA board ---------- - - You'll have to configure CAP address, I/O address, Interrupt Vector - as well as IRQ before installing this driver. Please refer to hardware - installation procedure in User's Manual before proceed any further. - Please make sure the JP1 is open after the ISA board is set properly. - PCI/UPCI board -------------- @@ -194,16 +174,6 @@ Device naming when more than 2 boards installed Under Kernel 2.6 and upper, the cum Device is Obsolete. So use ttyM* device instead. -Board sequence --------------- - - This driver will activate ISA boards according to the parameter set - in the driver. After all specified ISA board activated, PCI board - will be installed in the system automatically driven. - Therefore the board number is sorted by the CAP address of ISA boards. - For PCI boards, their sequence will be after ISA boards and C168H/PCI - has higher priority than C104H/PCI boards. - 3.4 Module driver configuration =============================== @@ -274,12 +244,10 @@ Board sequence :: - # modprobe mxser + # modprobe mxser will activate the module driver. You may run "lsmod" to check - if "mxser" is activated. If the MOXA board is ISA board, the - is needed. Please refer to section "3.4.5" for more - information. + if "mxser" is activated. ------------- Load MOXA driver on boot -------------------- @@ -296,13 +264,6 @@ Board sequence achieved by rc file. We offer one "rc.mxser" file to simplify the procedure under "moxa/mxser/driver". - But if you use ISA board, please modify the "modprobe ..." command - to add the argument (see "3.4.5" section). After modifying the - rc.mxser, please try to execute "/moxa/mxser/driver/rc.mxser" - manually to make sure the modification is ok. If any error - encountered, please try to modify again. If the modification is - completed, follow the below step. - Run following command for setting rc files:: # cd /moxa/mxser/driver @@ -316,21 +277,6 @@ Board sequence Reboot and check if moxa.o activated by "lsmod" command. -3.4.5. specify CAP address --------------------------- - - If you'd like to drive Smartio/Industio ISA boards in the system, - you'll have to add parameter to specify CAP address of given - board while activating "mxser.o". The format for parameters are - as follows.:: - - modprobe mxser ioaddr=0x???,0x???,0x???,0x??? - | | | | - | | | +- 4th ISA board - | | +------ 3rd ISA board - | +------------ 2nd ISA board - +-------------------1st ISA board - 3.5 Static driver configuration for Linux kernel 2.4.x and 2.6.x ================================================================ @@ -357,35 +303,7 @@ Board sequence # cd /usr/src/linux/drivers/char # ln -s /moxa/mxser/driver/mxser.c mxser.c -3.5.3 Add CAP address list for ISA boards. ------------------------------------------- - - For PCI boards user, please skip this step. - - In module mode, the CAP address for ISA board is given by - parameter. In static driver configuration, you'll have to - assign it within driver's source code. If you will not - install any ISA boards, you may skip to next portion. - The instructions to modify driver source code are as - below. - - a. run:: - - # cd /moxa/mxser/driver - # vi mxser.c - - b. Find the array mxserBoardCAP[] as below:: - - static int mxserBoardCAP[] = {0x00, 0x00, 0x00, 0x00}; - - c. Change the address within this array using vi. For - example, to driver 2 ISA boards with CAP address - 0x280 and 0x180 as 1st and 2nd board. Just to change - the source code as follows:: - - static int mxserBoardCAP[] = {0x280, 0x180, 0x00, 0x00}; - -3.5.4 Setup kernel configuration +3.5.3 Setup kernel configuration -------------------------------- Configure the kernel:: @@ -398,7 +316,7 @@ Board sequence SmartIO support] driver with "[*]" for built-in (not "[M]"), then select [Exit] to exit this program. -3.5.5 Rebuild kernel +3.5.4 Rebuild kernel -------------------- The following are for Linux kernel rebuilding, for your @@ -426,14 +344,14 @@ Board sequence directory /usr/src/linux. -3.5.6 Make tty device and special file +3.5.5 Make tty device and special file -------------------------------------- :: # cd /moxa/mxser/driver # ./msmknod -3.5.7 Make utility +3.5.6 Make utility ------------------ :: @@ -441,7 +359,7 @@ Board sequence # cd /moxa/mxser/utility # make clean; make install -3.5.8 Reboot +3.5.7 Reboot ------------ @@ -591,13 +509,6 @@ msterm - Terminal Emulation Each port within the same multiport board shares the same IRQ. Please set one IRQ (IRQ doesn't equal to zero) for one Moxa board. - Error msg: - No interrupt vector be set for Moxa ISA board(CAP=xxx). - - Solution: - Moxa ISA board needs an interrupt vector.Please refer to user's manual - "Hardware Installation" chapter to set interrupt vector. - Error msg: Couldn't install MOXA Smartio/Industio family driver! diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig index f6a7fd6d3bb6..476c11278235 100644 --- a/drivers/tty/Kconfig +++ b/drivers/tty/Kconfig @@ -204,7 +204,7 @@ config MOXA_INTELLIO config MOXA_SMARTIO tristate "Moxa SmartIO support v. 2.0" - depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA) + depends on SERIAL_NONSTANDARD && PCI help Say Y here if you have a Moxa SmartIO multiport serial card and/or want to help develop a new version of this driver. diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index a74e6146a748..3a00f180f54a 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -70,18 +70,8 @@ #define PCI_DEVICE_ID_CB134I 0x1341 #define PCI_DEVICE_ID_CP138U 0x1380 - -#define C168_ASIC_ID 1 -#define C104_ASIC_ID 2 -#define C102_ASIC_ID 0xB -#define CI132_ASIC_ID 4 -#define CI134_ASIC_ID 3 -#define CI104J_ASIC_ID 5 - #define MXSER_HIGHBAUD 1 -#define MXSER_HAS2 2 -/* This is only for PCI */ static const struct { int type; int tx_fifo; @@ -105,14 +95,14 @@ struct mxser_cardinfo { }; static const struct mxser_cardinfo mxser_cards[] = { -/* 0*/ { "C168 series", 8, }, - { "C104 series", 4, }, - { "CI-104J series", 4, }, +/* 0*/ { }, + { }, + { }, { "C168H/PCI series", 8, }, { "C104H/PCI series", 4, }, -/* 5*/ { "C102 series", 4, MXSER_HAS2 }, /* C102-ISA */ - { "CI-132 series", 4, MXSER_HAS2 }, - { "CI-134 series", 4, }, +/* 5*/ { }, + { }, + { }, { "CP-132 series", 2, }, { "CP-114 series", 4, }, /*10*/ { "CT-114 series", 4, }, @@ -172,15 +162,12 @@ static const struct pci_device_id mxser_pcibrds[] = { }; MODULE_DEVICE_TABLE(pci, mxser_pcibrds); -static unsigned long ioaddr[MXSER_BOARDS]; static int ttymajor = MXSERMAJOR; /* Variables for insmod */ MODULE_AUTHOR("Casper Yang"); MODULE_DESCRIPTION("MOXA Smartio/Industio Family Multiport Board Device Driver"); -module_param_hw_array(ioaddr, ulong, ioport, NULL, 0); -MODULE_PARM_DESC(ioaddr, "ISA io addresses to look for a moxa board"); module_param(ttymajor, int, 0); MODULE_LICENSE("GPL"); @@ -300,7 +287,6 @@ static void mxser_enable_must_enchance_mode(unsigned long baseio) outb(oldlcr, baseio + UART_LCR); } -#ifdef CONFIG_PCI static void mxser_disable_must_enchance_mode(unsigned long baseio) { u8 oldlcr; @@ -315,7 +301,6 @@ static void mxser_disable_must_enchance_mode(unsigned long baseio) outb(efr, baseio + MOXA_MUST_EFR_REGISTER); outb(oldlcr, baseio + UART_LCR); } -#endif static void mxser_set_must_xon1_value(unsigned long baseio, u8 value) { @@ -387,7 +372,6 @@ static void mxser_set_must_enum_value(unsigned long baseio, u8 value) outb(oldlcr, baseio + UART_LCR); } -#ifdef CONFIG_PCI static void mxser_get_must_hardware_id(unsigned long baseio, u8 *pId) { u8 oldlcr; @@ -404,7 +388,6 @@ static void mxser_get_must_hardware_id(unsigned long baseio, u8 *pId) *pId = inb(baseio + MOXA_MUST_HWID_REGISTER); outb(oldlcr, baseio + UART_LCR); } -#endif static void SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(unsigned long baseio) { @@ -483,7 +466,6 @@ static void mxser_disable_must_rx_software_flow_control(unsigned long baseio) outb(oldlcr, baseio + UART_LCR); } -#ifdef CONFIG_PCI static int CheckIsMoxaMust(unsigned long io) { u8 oldmcr, hwid; @@ -506,7 +488,6 @@ static int CheckIsMoxaMust(unsigned long io) } return MOXA_OTHER_UART; } -#endif static void process_txrx_fifo(struct mxser_port *info) { @@ -1398,109 +1379,6 @@ static int mxser_tiocmset(struct tty_struct *tty, return 0; } -static int __init mxser_program_mode(int port) -{ - int id, i, j, n; - - outb(0, port); - outb(0, port); - outb(0, port); - (void)inb(port); - (void)inb(port); - outb(0, port); - (void)inb(port); - - id = inb(port + 1) & 0x1F; - if ((id != C168_ASIC_ID) && - (id != C104_ASIC_ID) && - (id != C102_ASIC_ID) && - (id != CI132_ASIC_ID) && - (id != CI134_ASIC_ID) && - (id != CI104J_ASIC_ID)) - return -1; - for (i = 0, j = 0; i < 4; i++) { - n = inb(port + 2); - if (n == 'M') { - j = 1; - } else if ((j == 1) && (n == 1)) { - j = 2; - break; - } else - j = 0; - } - if (j != 2) - id = -2; - return id; -} - -static void __init mxser_normal_mode(int port) -{ - int i, n; - - outb(0xA5, port + 1); - outb(0x80, port + 3); - outb(12, port + 0); /* 9600 bps */ - outb(0, port + 1); - outb(0x03, port + 3); /* 8 data bits */ - outb(0x13, port + 4); /* loop back mode */ - for (i = 0; i < 16; i++) { - n = inb(port + 5); - if ((n & 0x61) == 0x60) - break; - if ((n & 1) == 1) - (void)inb(port); - } - outb(0x00, port + 4); -} - -#define CHIP_SK 0x01 /* Serial Data Clock in Eprom */ -#define CHIP_DO 0x02 /* Serial Data Output in Eprom */ -#define CHIP_CS 0x04 /* Serial Chip Select in Eprom */ -#define CHIP_DI 0x08 /* Serial Data Input in Eprom */ -#define EN_CCMD 0x000 /* Chip's command register */ -#define EN0_RSARLO 0x008 /* Remote start address reg 0 */ -#define EN0_RSARHI 0x009 /* Remote start address reg 1 */ -#define EN0_RCNTLO 0x00A /* Remote byte count reg WR */ -#define EN0_RCNTHI 0x00B /* Remote byte count reg WR */ -#define EN0_DCFG 0x00E /* Data configuration reg WR */ -#define EN0_PORT 0x010 /* Rcv missed frame error counter RD */ -#define ENC_PAGE0 0x000 /* Select page 0 of chip registers */ -#define ENC_PAGE3 0x0C0 /* Select page 3 of chip registers */ -static int __init mxser_read_register(int port, unsigned short *regs) -{ - int i, k, value, id; - unsigned int j; - - id = mxser_program_mode(port); - if (id < 0) - return id; - for (i = 0; i < 14; i++) { - k = (i & 0x3F) | 0x180; - for (j = 0x100; j > 0; j >>= 1) { - outb(CHIP_CS, port); - if (k & j) { - outb(CHIP_CS | CHIP_DO, port); - outb(CHIP_CS | CHIP_DO | CHIP_SK, port); /* A? bit of read */ - } else { - outb(CHIP_CS, port); - outb(CHIP_CS | CHIP_SK, port); /* A? bit of read */ - } - } - (void)inb(port); - value = 0; - for (k = 0, j = 0x8000; k < 16; k++, j >>= 1) { - outb(CHIP_CS, port); - outb(CHIP_CS | CHIP_SK, port); - if (inb(port) & CHIP_DI) - value |= j; - } - regs[i] = value; - outb(0, port); - } - mxser_normal_mode(port); - return id; -} - static int mxser_ioctl_special(unsigned int cmd, void __user *argp) { struct mxser_port *ip; @@ -2346,37 +2224,6 @@ static const struct tty_port_operations mxser_port_ops = { * The MOXA Smartio/Industio serial driver boot-time initialization code! */ -static bool allow_overlapping_vector; -module_param(allow_overlapping_vector, bool, S_IRUGO); -MODULE_PARM_DESC(allow_overlapping_vector, "whether we allow ISA cards to be configured such that vector overlabs IO ports (default=no)"); - -static bool mxser_overlapping_vector(struct mxser_board *brd) -{ - return allow_overlapping_vector && - brd->vector >= brd->ports[0].ioaddr && - brd->vector < brd->ports[0].ioaddr + 8 * brd->info->nports; -} - -static int mxser_request_vector(struct mxser_board *brd) -{ - if (mxser_overlapping_vector(brd)) - return 0; - return request_region(brd->vector, 1, "mxser(vector)") ? 0 : -EIO; -} - -static void mxser_release_vector(struct mxser_board *brd) -{ - if (mxser_overlapping_vector(brd)) - return; - release_region(brd->vector, 1); -} - -static void mxser_release_ISA_res(struct mxser_board *brd) -{ - release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); - mxser_release_vector(brd); -} - static int mxser_initbrd(struct mxser_board *brd) { struct mxser_port *info; @@ -2439,125 +2286,9 @@ static void mxser_board_remove(struct mxser_board *brd) free_irq(brd->irq, brd); } -static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd) -{ - int id, i, bits, ret; - unsigned short regs[16], irq; - unsigned char scratch, scratch2; - - brd->chip_flag = MOXA_OTHER_UART; - - id = mxser_read_register(cap, regs); - switch (id) { - case C168_ASIC_ID: - brd->info = &mxser_cards[0]; - break; - case C104_ASIC_ID: - brd->info = &mxser_cards[1]; - break; - case CI104J_ASIC_ID: - brd->info = &mxser_cards[2]; - break; - case C102_ASIC_ID: - brd->info = &mxser_cards[5]; - break; - case CI132_ASIC_ID: - brd->info = &mxser_cards[6]; - break; - case CI134_ASIC_ID: - brd->info = &mxser_cards[7]; - break; - default: - return 0; - } - - irq = 0; - /* some ISA cards have 2 ports, but we want to see them as 4-port (why?) - Flag-hack checks if configuration should be read as 2-port here. */ - if (brd->info->nports == 2 || (brd->info->flags & MXSER_HAS2)) { - irq = regs[9] & 0xF000; - irq = irq | (irq >> 4); - if (irq != (regs[9] & 0xFF00)) - goto err_irqconflict; - } else if (brd->info->nports == 4) { - irq = regs[9] & 0xF000; - irq = irq | (irq >> 4); - irq = irq | (irq >> 8); - if (irq != regs[9]) - goto err_irqconflict; - } else if (brd->info->nports == 8) { - irq = regs[9] & 0xF000; - irq = irq | (irq >> 4); - irq = irq | (irq >> 8); - if ((irq != regs[9]) || (irq != regs[10])) - goto err_irqconflict; - } - - if (!irq) { - printk(KERN_ERR "mxser: interrupt number unset\n"); - return -EIO; - } - brd->irq = ((int)(irq & 0xF000) >> 12); - for (i = 0; i < 8; i++) - brd->ports[i].ioaddr = (int) regs[i + 1] & 0xFFF8; - if ((regs[12] & 0x80) == 0) { - printk(KERN_ERR "mxser: invalid interrupt vector\n"); - return -EIO; - } - brd->vector = (int)regs[11]; /* interrupt vector */ - if (id == 1) - brd->vector_mask = 0x00FF; - else - brd->vector_mask = 0x000F; - for (i = 7, bits = 0x0100; i >= 0; i--, bits <<= 1) { - if (regs[12] & bits) { - brd->ports[i].baud_base = 921600; - brd->ports[i].max_baud = 921600; - } else { - brd->ports[i].baud_base = 115200; - brd->ports[i].max_baud = 115200; - } - } - scratch2 = inb(cap + UART_LCR) & (~UART_LCR_DLAB); - outb(scratch2 | UART_LCR_DLAB, cap + UART_LCR); - outb(0, cap + UART_EFR); /* EFR is the same as FCR */ - outb(scratch2, cap + UART_LCR); - outb(UART_FCR_ENABLE_FIFO, cap + UART_FCR); - scratch = inb(cap + UART_IIR); - - if (scratch & 0xC0) - brd->uart_type = PORT_16550A; - else - brd->uart_type = PORT_16450; - if (!request_region(brd->ports[0].ioaddr, 8 * brd->info->nports, - "mxser(IO)")) { - printk(KERN_ERR "mxser: can't request ports I/O region: " - "0x%.8lx-0x%.8lx\n", - brd->ports[0].ioaddr, brd->ports[0].ioaddr + - 8 * brd->info->nports - 1); - return -EIO; - } - - ret = mxser_request_vector(brd); - if (ret) { - release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); - printk(KERN_ERR "mxser: can't request interrupt vector region: " - "0x%.8lx-0x%.8lx\n", - brd->ports[0].ioaddr, brd->ports[0].ioaddr + - 8 * brd->info->nports - 1); - return ret; - } - return brd->info->nports; - -err_irqconflict: - printk(KERN_ERR "mxser: invalid interrupt number\n"); - return -EIO; -} - static int mxser_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { -#ifdef CONFIG_PCI struct mxser_board *brd; unsigned int i, j; unsigned long ioaddress; @@ -2673,14 +2404,10 @@ err_dis: pci_disable_device(pdev); err: return retval; -#else - return -ENODEV; -#endif } static void mxser_remove(struct pci_dev *pdev) { -#ifdef CONFIG_PCI struct mxser_board *brd = pci_get_drvdata(pdev); mxser_board_remove(brd); @@ -2689,7 +2416,6 @@ static void mxser_remove(struct pci_dev *pdev) pci_release_region(pdev, 3); pci_disable_device(pdev); brd->info = NULL; -#endif } static struct pci_driver mxser_driver = { @@ -2701,9 +2427,6 @@ static struct pci_driver mxser_driver = { static int __init mxser_module_init(void) { - struct mxser_board *brd; - struct device *tty_dev; - unsigned int b, i, m; int retval; mxvar_sdriver = alloc_tty_driver(MXSER_PORTS + 1); @@ -2731,57 +2454,10 @@ static int __init mxser_module_init(void) goto err_put; } - /* Start finding ISA boards here */ - for (m = 0, b = 0; b < MXSER_BOARDS; b++) { - if (!ioaddr[b]) - continue; - - brd = &mxser_boards[m]; - retval = mxser_get_ISA_conf(ioaddr[b], brd); - if (retval <= 0) { - brd->info = NULL; - continue; - } - - printk(KERN_INFO "mxser: found MOXA %s board (CAP=0x%lx)\n", - brd->info->name, ioaddr[b]); - - /* mxser_initbrd will hook ISR. */ - if (mxser_initbrd(brd) < 0) { - mxser_release_ISA_res(brd); - brd->info = NULL; - continue; - } - - brd->idx = m * MXSER_PORTS_PER_BOARD; - for (i = 0; i < brd->info->nports; i++) { - tty_dev = tty_port_register_device(&brd->ports[i].port, - mxvar_sdriver, brd->idx + i, NULL); - if (IS_ERR(tty_dev)) { - for (; i > 0; i--) - tty_unregister_device(mxvar_sdriver, - brd->idx + i - 1); - for (i = 0; i < brd->info->nports; i++) - tty_port_destroy(&brd->ports[i].port); - free_irq(brd->irq, brd); - mxser_release_ISA_res(brd); - brd->info = NULL; - break; - } - } - if (brd->info == NULL) - continue; - - m++; - } - retval = pci_register_driver(&mxser_driver); if (retval) { printk(KERN_ERR "mxser: can't register pci driver\n"); - if (!m) { - retval = -ENODEV; - goto err_unr; - } /* else: we have some ISA cards under control */ + goto err_unr; } return 0; @@ -2794,19 +2470,9 @@ err_put: static void __exit mxser_module_exit(void) { - unsigned int i; - pci_unregister_driver(&mxser_driver); - - for (i = 0; i < MXSER_BOARDS; i++) /* ISA remains */ - if (mxser_boards[i].info != NULL) - mxser_board_remove(&mxser_boards[i]); tty_unregister_driver(mxvar_sdriver); put_tty_driver(mxvar_sdriver); - - for (i = 0; i < MXSER_BOARDS; i++) - if (mxser_boards[i].info != NULL) - mxser_release_ISA_res(&mxser_boards[i]); } module_init(mxser_module_init); From 152549026901afb1e8143a4e07df6cb8df42f3bf Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:08 +0200 Subject: [PATCH 147/227] mxser: renumber mxser_cards After the ISA cards removal in the previous patch, the mxser_cards array has holes in it. So renumber the array while updating PCI device's driver_data. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-3-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 80 +++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 43 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 3a00f180f54a..ef539f084e55 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -95,69 +95,63 @@ struct mxser_cardinfo { }; static const struct mxser_cardinfo mxser_cards[] = { -/* 0*/ { }, - { }, - { }, - { "C168H/PCI series", 8, }, +/* 0*/ { "C168H/PCI series", 8, }, { "C104H/PCI series", 4, }, -/* 5*/ { }, - { }, - { }, { "CP-132 series", 2, }, { "CP-114 series", 4, }, -/*10*/ { "CT-114 series", 4, }, - { "CP-102 series", 2, MXSER_HIGHBAUD }, + { "CT-114 series", 4, }, +/* 5*/ { "CP-102 series", 2, MXSER_HIGHBAUD }, { "CP-104U series", 4, }, { "CP-168U series", 8, }, { "CP-132U series", 2, }, -/*15*/ { "CP-134U series", 4, }, - { "CP-104JU series", 4, }, + { "CP-134U series", 4, }, +/*10*/ { "CP-104JU series", 4, }, { "Moxa UC7000 Serial", 8, }, /* RC7000 */ { "CP-118U series", 8, }, { "CP-102UL series", 2, }, -/*20*/ { "CP-102U series", 2, }, - { "CP-118EL series", 8, }, + { "CP-102U series", 2, }, +/*15*/ { "CP-118EL series", 8, }, { "CP-168EL series", 8, }, { "CP-104EL series", 4, }, { "CB-108 series", 8, }, -/*25*/ { "CB-114 series", 4, }, - { "CB-134I series", 4, }, + { "CB-114 series", 4, }, +/*20*/ { "CB-134I series", 4, }, { "CP-138U series", 8, }, { "POS-104UL series", 4, }, { "CP-114UL series", 4, }, -/*30*/ { "CP-102UF series", 2, }, - { "CP-112UL series", 2, }, + { "CP-102UF series", 2, }, +/*25*/ { "CP-112UL series", 2, }, }; /* driver_data correspond to the lines in the structure above see also ISA probe function before you change something */ static const struct pci_device_id mxser_pcibrds[] = { - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C168), .driver_data = 3 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C104), .driver_data = 4 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132), .driver_data = 8 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP114), .driver_data = 9 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CT114), .driver_data = 10 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102), .driver_data = 11 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104U), .driver_data = 12 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168U), .driver_data = 13 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132U), .driver_data = 14 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP134U), .driver_data = 15 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104JU),.driver_data = 16 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_RC7000), .driver_data = 17 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118U), .driver_data = 18 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102UL),.driver_data = 19 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102U), .driver_data = 20 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118EL),.driver_data = 21 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168EL),.driver_data = 22 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104EL),.driver_data = 23 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB108), .driver_data = 24 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB114), .driver_data = 25 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB134I), .driver_data = 26 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP138U), .driver_data = 27 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_POS104UL), .driver_data = 28 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP114UL), .driver_data = 29 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP102UF), .driver_data = 30 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP112UL), .driver_data = 31 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C168), .driver_data = 0 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C104), .driver_data = 1 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132), .driver_data = 2 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP114), .driver_data = 3 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CT114), .driver_data = 4 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102), .driver_data = 5 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104U), .driver_data = 6 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168U), .driver_data = 7 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132U), .driver_data = 8 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP134U), .driver_data = 9 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104JU),.driver_data = 10 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_RC7000), .driver_data = 11 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118U), .driver_data = 12 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102UL),.driver_data = 13 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102U), .driver_data = 14 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118EL),.driver_data = 15 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168EL),.driver_data = 16 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104EL),.driver_data = 17 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB108), .driver_data = 18 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB114), .driver_data = 19 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB134I), .driver_data = 20 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP138U), .driver_data = 21 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_POS104UL), .driver_data = 22 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP114UL), .driver_data = 23 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP102UF), .driver_data = 24 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP112UL), .driver_data = 25 }, { } }; MODULE_DEVICE_TABLE(pci, mxser_pcibrds); From cede216a0539db096e7767e7dd77ac4544415e49 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:09 +0200 Subject: [PATCH 148/227] mxser: remove info printout from init There is no reason/desire to print module information upon module load. Drop this printk (and a version define). Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-4-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index ef539f084e55..d91f8e791aab 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -43,7 +43,6 @@ #include "mxser.h" -#define MXSER_VERSION "2.0.5" /* 1.14 */ #define MXSERMAJOR 174 #define MXSER_BOARDS 4 /* Max. boards */ @@ -2427,9 +2426,6 @@ static int __init mxser_module_init(void) if (!mxvar_sdriver) return -ENOMEM; - printk(KERN_INFO "MOXA Smartio/Industio family driver version %s\n", - MXSER_VERSION); - /* Initialize the tty_driver structure */ mxvar_sdriver->name = "ttyMI"; mxvar_sdriver->major = ttymajor; From 4463cc5b8cbeb38cf1bf4b25ac285a9cd10a7f2b Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:10 +0200 Subject: [PATCH 149/227] mxser: integrate mxser.h into .c As mxser.h serves only mxser.c, integrate the definitions into .c and drop .h. There are some "semi-public" ioctl definitions, but they are mostly go away in the next patches. If something, they would need to live in an uapi header anyway. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-5-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 130 +++++++++++++++++++++++++++++++++++++- drivers/tty/mxser.h | 151 -------------------------------------------- 2 files changed, 129 insertions(+), 152 deletions(-) delete mode 100644 drivers/tty/mxser.h diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index d91f8e791aab..0c779559f978 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -41,7 +41,135 @@ #include #include -#include "mxser.h" +/* + * Semi-public control interfaces + */ + +/* + * MOXA ioctls + */ + +#define MOXA 0x400 +#define MOXA_GETDATACOUNT (MOXA + 23) +#define MOXA_DIAGNOSE (MOXA + 50) +#define MOXA_CHKPORTENABLE (MOXA + 60) +#define MOXA_HighSpeedOn (MOXA + 61) +#define MOXA_GET_MAJOR (MOXA + 63) +#define MOXA_GETMSTATUS (MOXA + 65) +#define MOXA_SET_OP_MODE (MOXA + 66) +#define MOXA_GET_OP_MODE (MOXA + 67) + +#define RS232_MODE 0 +#define RS485_2WIRE_MODE 1 +#define RS422_MODE 2 +#define RS485_4WIRE_MODE 3 +#define OP_MODE_MASK 3 + +#define MOXA_SDS_RSTICOUNTER (MOXA + 69) +#define MOXA_ASPP_OQUEUE (MOXA + 70) +#define MOXA_ASPP_MON (MOXA + 73) +#define MOXA_ASPP_LSTATUS (MOXA + 74) +#define MOXA_ASPP_MON_EXT (MOXA + 75) +#define MOXA_SET_BAUD_METHOD (MOXA + 76) + +/* --------------------------------------------------- */ + +#define NPPI_NOTIFY_PARITY 0x01 +#define NPPI_NOTIFY_FRAMING 0x02 +#define NPPI_NOTIFY_HW_OVERRUN 0x04 +#define NPPI_NOTIFY_SW_OVERRUN 0x08 +#define NPPI_NOTIFY_BREAK 0x10 + +#define NPPI_NOTIFY_CTSHOLD 0x01 /* Tx hold by CTS low */ +#define NPPI_NOTIFY_DSRHOLD 0x02 /* Tx hold by DSR low */ +#define NPPI_NOTIFY_XOFFHOLD 0x08 /* Tx hold by Xoff received */ +#define NPPI_NOTIFY_XOFFXENT 0x10 /* Xoff Sent */ + +/* + * Follow just what Moxa Must chip defines. + * + * When LCR register (offset 0x03) writes the following value, the Must chip + * will enter enchance mode. And write value on EFR (offset 0x02) bit 6,7 to + * change bank. + */ +#define MOXA_MUST_ENTER_ENCHANCE 0xBF + +/* when enhance mode enabled, access on general bank register */ +#define MOXA_MUST_GDL_REGISTER 0x07 +#define MOXA_MUST_GDL_MASK 0x7F +#define MOXA_MUST_GDL_HAS_BAD_DATA 0x80 + +#define MOXA_MUST_LSR_RERR 0x80 /* error in receive FIFO */ +/* enchance register bank select and enchance mode setting register */ +/* when LCR register equals to 0xBF */ +#define MOXA_MUST_EFR_REGISTER 0x02 +#define MOXA_MUST_EFR_EFRB_ENABLE 0x10 /* enchance mode enable */ +/* enchance register bank set 0, 1, 2 */ +#define MOXA_MUST_EFR_BANK0 0x00 +#define MOXA_MUST_EFR_BANK1 0x40 +#define MOXA_MUST_EFR_BANK2 0x80 +#define MOXA_MUST_EFR_BANK3 0xC0 +#define MOXA_MUST_EFR_BANK_MASK 0xC0 + +/* set XON1 value register, when LCR=0xBF and change to bank0 */ +#define MOXA_MUST_XON1_REGISTER 0x04 + +/* set XON2 value register, when LCR=0xBF and change to bank0 */ +#define MOXA_MUST_XON2_REGISTER 0x05 + +/* set XOFF1 value register, when LCR=0xBF and change to bank0 */ +#define MOXA_MUST_XOFF1_REGISTER 0x06 + +/* set XOFF2 value register, when LCR=0xBF and change to bank0 */ +#define MOXA_MUST_XOFF2_REGISTER 0x07 + +#define MOXA_MUST_RBRTL_REGISTER 0x04 +#define MOXA_MUST_RBRTH_REGISTER 0x05 +#define MOXA_MUST_RBRTI_REGISTER 0x06 +#define MOXA_MUST_THRTL_REGISTER 0x07 +#define MOXA_MUST_ENUM_REGISTER 0x04 +#define MOXA_MUST_HWID_REGISTER 0x05 +#define MOXA_MUST_ECR_REGISTER 0x06 +#define MOXA_MUST_CSR_REGISTER 0x07 + +#define MOXA_MUST_FCR_GDA_MODE_ENABLE 0x20 /* good data mode enable */ +#define MOXA_MUST_FCR_GDA_ONLY_ENABLE 0x10 /* only good data put into RxFIFO */ + +#define MOXA_MUST_IER_ECTSI 0x80 /* enable CTS interrupt */ +#define MOXA_MUST_IER_ERTSI 0x40 /* enable RTS interrupt */ +#define MOXA_MUST_IER_XINT 0x20 /* enable Xon/Xoff interrupt */ +#define MOXA_MUST_IER_EGDAI 0x10 /* enable GDA interrupt */ + +#define MOXA_MUST_RECV_ISR (UART_IER_RDI | MOXA_MUST_IER_EGDAI) + +/* GDA interrupt pending */ +#define MOXA_MUST_IIR_GDA 0x1C +#define MOXA_MUST_IIR_RDA 0x04 +#define MOXA_MUST_IIR_RTO 0x0C +#define MOXA_MUST_IIR_LSR 0x06 + +/* received Xon/Xoff or specical interrupt pending */ +#define MOXA_MUST_IIR_XSC 0x10 + +/* RTS/CTS change state interrupt pending */ +#define MOXA_MUST_IIR_RTSCTS 0x20 +#define MOXA_MUST_IIR_MASK 0x3E + +#define MOXA_MUST_MCR_XON_FLAG 0x40 +#define MOXA_MUST_MCR_XON_ANY 0x80 +#define MOXA_MUST_MCR_TX_XON 0x08 + +#define MOXA_MUST_EFR_SF_MASK 0x0F /* software flow control on chip mask value */ +#define MOXA_MUST_EFR_SF_TX1 0x08 /* send Xon1/Xoff1 */ +#define MOXA_MUST_EFR_SF_TX2 0x04 /* send Xon2/Xoff2 */ +#define MOXA_MUST_EFR_SF_TX12 0x0C /* send Xon1,Xon2/Xoff1,Xoff2 */ +#define MOXA_MUST_EFR_SF_TX_NO 0x00 /* don't send Xon/Xoff */ +#define MOXA_MUST_EFR_SF_TX_MASK 0x0C /* Tx software flow control mask */ +#define MOXA_MUST_EFR_SF_RX_NO 0x00 /* don't receive Xon/Xoff */ +#define MOXA_MUST_EFR_SF_RX1 0x02 /* receive Xon1/Xoff1 */ +#define MOXA_MUST_EFR_SF_RX2 0x01 /* receive Xon2/Xoff2 */ +#define MOXA_MUST_EFR_SF_RX12 0x03 /* receive Xon1,Xon2/Xoff1,Xoff2 */ +#define MOXA_MUST_EFR_SF_RX_MASK 0x03 /* Rx software flow control mask */ #define MXSERMAJOR 174 diff --git a/drivers/tty/mxser.h b/drivers/tty/mxser.h deleted file mode 100644 index e6cb15626567..000000000000 --- a/drivers/tty/mxser.h +++ /dev/null @@ -1,151 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _MXSER_H -#define _MXSER_H - -/* - * Semi-public control interfaces - */ - -/* - * MOXA ioctls - */ - -#define MOXA 0x400 -#define MOXA_GETDATACOUNT (MOXA + 23) -#define MOXA_DIAGNOSE (MOXA + 50) -#define MOXA_CHKPORTENABLE (MOXA + 60) -#define MOXA_HighSpeedOn (MOXA + 61) -#define MOXA_GET_MAJOR (MOXA + 63) -#define MOXA_GETMSTATUS (MOXA + 65) -#define MOXA_SET_OP_MODE (MOXA + 66) -#define MOXA_GET_OP_MODE (MOXA + 67) - -#define RS232_MODE 0 -#define RS485_2WIRE_MODE 1 -#define RS422_MODE 2 -#define RS485_4WIRE_MODE 3 -#define OP_MODE_MASK 3 - -#define MOXA_SDS_RSTICOUNTER (MOXA + 69) -#define MOXA_ASPP_OQUEUE (MOXA + 70) -#define MOXA_ASPP_MON (MOXA + 73) -#define MOXA_ASPP_LSTATUS (MOXA + 74) -#define MOXA_ASPP_MON_EXT (MOXA + 75) -#define MOXA_SET_BAUD_METHOD (MOXA + 76) - -/* --------------------------------------------------- */ - -#define NPPI_NOTIFY_PARITY 0x01 -#define NPPI_NOTIFY_FRAMING 0x02 -#define NPPI_NOTIFY_HW_OVERRUN 0x04 -#define NPPI_NOTIFY_SW_OVERRUN 0x08 -#define NPPI_NOTIFY_BREAK 0x10 - -#define NPPI_NOTIFY_CTSHOLD 0x01 /* Tx hold by CTS low */ -#define NPPI_NOTIFY_DSRHOLD 0x02 /* Tx hold by DSR low */ -#define NPPI_NOTIFY_XOFFHOLD 0x08 /* Tx hold by Xoff received */ -#define NPPI_NOTIFY_XOFFXENT 0x10 /* Xoff Sent */ - -/* follow just for Moxa Must chip define. */ -/* */ -/* when LCR register (offset 0x03) write following value, */ -/* the Must chip will enter enchance mode. And write value */ -/* on EFR (offset 0x02) bit 6,7 to change bank. */ -#define MOXA_MUST_ENTER_ENCHANCE 0xBF - -/* when enhance mode enable, access on general bank register */ -#define MOXA_MUST_GDL_REGISTER 0x07 -#define MOXA_MUST_GDL_MASK 0x7F -#define MOXA_MUST_GDL_HAS_BAD_DATA 0x80 - -#define MOXA_MUST_LSR_RERR 0x80 /* error in receive FIFO */ -/* enchance register bank select and enchance mode setting register */ -/* when LCR register equal to 0xBF */ -#define MOXA_MUST_EFR_REGISTER 0x02 -/* enchance mode enable */ -#define MOXA_MUST_EFR_EFRB_ENABLE 0x10 -/* enchance reister bank set 0, 1, 2 */ -#define MOXA_MUST_EFR_BANK0 0x00 -#define MOXA_MUST_EFR_BANK1 0x40 -#define MOXA_MUST_EFR_BANK2 0x80 -#define MOXA_MUST_EFR_BANK3 0xC0 -#define MOXA_MUST_EFR_BANK_MASK 0xC0 - -/* set XON1 value register, when LCR=0xBF and change to bank0 */ -#define MOXA_MUST_XON1_REGISTER 0x04 - -/* set XON2 value register, when LCR=0xBF and change to bank0 */ -#define MOXA_MUST_XON2_REGISTER 0x05 - -/* set XOFF1 value register, when LCR=0xBF and change to bank0 */ -#define MOXA_MUST_XOFF1_REGISTER 0x06 - -/* set XOFF2 value register, when LCR=0xBF and change to bank0 */ -#define MOXA_MUST_XOFF2_REGISTER 0x07 - -#define MOXA_MUST_RBRTL_REGISTER 0x04 -#define MOXA_MUST_RBRTH_REGISTER 0x05 -#define MOXA_MUST_RBRTI_REGISTER 0x06 -#define MOXA_MUST_THRTL_REGISTER 0x07 -#define MOXA_MUST_ENUM_REGISTER 0x04 -#define MOXA_MUST_HWID_REGISTER 0x05 -#define MOXA_MUST_ECR_REGISTER 0x06 -#define MOXA_MUST_CSR_REGISTER 0x07 - -/* good data mode enable */ -#define MOXA_MUST_FCR_GDA_MODE_ENABLE 0x20 -/* only good data put into RxFIFO */ -#define MOXA_MUST_FCR_GDA_ONLY_ENABLE 0x10 - -/* enable CTS interrupt */ -#define MOXA_MUST_IER_ECTSI 0x80 -/* enable RTS interrupt */ -#define MOXA_MUST_IER_ERTSI 0x40 -/* enable Xon/Xoff interrupt */ -#define MOXA_MUST_IER_XINT 0x20 -/* enable GDA interrupt */ -#define MOXA_MUST_IER_EGDAI 0x10 - -#define MOXA_MUST_RECV_ISR (UART_IER_RDI | MOXA_MUST_IER_EGDAI) - -/* GDA interrupt pending */ -#define MOXA_MUST_IIR_GDA 0x1C -#define MOXA_MUST_IIR_RDA 0x04 -#define MOXA_MUST_IIR_RTO 0x0C -#define MOXA_MUST_IIR_LSR 0x06 - -/* received Xon/Xoff or specical interrupt pending */ -#define MOXA_MUST_IIR_XSC 0x10 - -/* RTS/CTS change state interrupt pending */ -#define MOXA_MUST_IIR_RTSCTS 0x20 -#define MOXA_MUST_IIR_MASK 0x3E - -#define MOXA_MUST_MCR_XON_FLAG 0x40 -#define MOXA_MUST_MCR_XON_ANY 0x80 -#define MOXA_MUST_MCR_TX_XON 0x08 - -/* software flow control on chip mask value */ -#define MOXA_MUST_EFR_SF_MASK 0x0F -/* send Xon1/Xoff1 */ -#define MOXA_MUST_EFR_SF_TX1 0x08 -/* send Xon2/Xoff2 */ -#define MOXA_MUST_EFR_SF_TX2 0x04 -/* send Xon1,Xon2/Xoff1,Xoff2 */ -#define MOXA_MUST_EFR_SF_TX12 0x0C -/* don't send Xon/Xoff */ -#define MOXA_MUST_EFR_SF_TX_NO 0x00 -/* Tx software flow control mask */ -#define MOXA_MUST_EFR_SF_TX_MASK 0x0C -/* don't receive Xon/Xoff */ -#define MOXA_MUST_EFR_SF_RX_NO 0x00 -/* receive Xon1/Xoff1 */ -#define MOXA_MUST_EFR_SF_RX1 0x02 -/* receive Xon2/Xoff2 */ -#define MOXA_MUST_EFR_SF_RX2 0x01 -/* receive Xon1,Xon2/Xoff1,Xoff2 */ -#define MOXA_MUST_EFR_SF_RX12 0x03 -/* Rx software flow control mask */ -#define MOXA_MUST_EFR_SF_RX_MASK 0x03 - -#endif From dc33f644f1cbcf333eb13e213f2e4af82af1dfcd Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:11 +0200 Subject: [PATCH 150/227] mxser: cleanup Gpci_uart_info struct The Gpci_uart_info structure contains up to tripled information and chose weird types for the members. Deduplicate the members and choose proper types for the data -- everything can be u8 except baud rate. There, we use speed_t, which is used in this context. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-6-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 42 ++++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 0c779559f978..3b3f0da9ea64 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -200,18 +200,15 @@ #define MXSER_HIGHBAUD 1 static const struct { - int type; - int tx_fifo; - int rx_fifo; - int xmit_fifo_size; - int rx_high_water; - int rx_trigger; - int rx_low_water; - long max_baud; + u8 type; + u8 fifo_size; + u8 rx_high_water; + u8 rx_low_water; + speed_t max_baud; } Gpci_uart_info[] = { - {MOXA_OTHER_UART, 16, 16, 16, 14, 14, 1, 921600L}, - {MOXA_MUST_MU150_HWID, 64, 64, 64, 48, 48, 16, 230400L}, - {MOXA_MUST_MU860_HWID, 128, 128, 128, 96, 96, 32, 921600L} + { MOXA_OTHER_UART, 16, 14, 1, 921600 }, + { MOXA_MUST_MU150_HWID, 64, 48, 16, 230400 }, + { MOXA_MUST_MU860_HWID, 128, 96, 32, 921600 } }; #define UART_INFO_NUM ARRAY_SIZE(Gpci_uart_info) @@ -331,11 +328,10 @@ struct mxser_port { unsigned long ioaddr; unsigned long opmode_ioaddr; - int max_baud; + speed_t max_baud; - int rx_high_water; - int rx_trigger; /* Rx fifo trigger level */ - int rx_low_water; + u8 rx_high_water; + u8 rx_low_water; int baud_base; /* max. speed */ int type; /* UART type */ @@ -354,7 +350,7 @@ struct mxser_port { int read_status_mask; int ignore_status_mask; - unsigned int xmit_fifo_size; + u8 xmit_fifo_size; int xmit_head; int xmit_tail; int xmit_cnt; @@ -470,9 +466,9 @@ static void mxser_set_must_fifo_value(struct mxser_port *info) efr |= MOXA_MUST_EFR_BANK1; outb(efr, info->ioaddr + MOXA_MUST_EFR_REGISTER); - outb((u8)info->rx_high_water, info->ioaddr + MOXA_MUST_RBRTH_REGISTER); - outb((u8)info->rx_trigger, info->ioaddr + MOXA_MUST_RBRTI_REGISTER); - outb((u8)info->rx_low_water, info->ioaddr + MOXA_MUST_RBRTL_REGISTER); + outb(info->rx_high_water, info->ioaddr + MOXA_MUST_RBRTH_REGISTER); + outb(info->rx_high_water, info->ioaddr + MOXA_MUST_RBRTI_REGISTER); + outb(info->rx_low_water, info->ioaddr + MOXA_MUST_RBRTL_REGISTER); outb(oldlcr, info->ioaddr + UART_LCR); } @@ -615,17 +611,15 @@ static void process_txrx_fifo(struct mxser_port *info) int i; if ((info->type == PORT_16450) || (info->type == PORT_8250)) { - info->rx_trigger = 1; info->rx_high_water = 1; info->rx_low_water = 1; info->xmit_fifo_size = 1; } else for (i = 0; i < UART_INFO_NUM; i++) if (info->board->chip_flag == Gpci_uart_info[i].type) { - info->rx_trigger = Gpci_uart_info[i].rx_trigger; info->rx_low_water = Gpci_uart_info[i].rx_low_water; info->rx_high_water = Gpci_uart_info[i].rx_high_water; - info->xmit_fifo_size = Gpci_uart_info[i].xmit_fifo_size; + info->xmit_fifo_size = Gpci_uart_info[i].fifo_size; break; } } @@ -667,7 +661,7 @@ static void mxser_dtr_rts(struct tty_port *port, int on) spin_unlock_irqrestore(&mp->slock, flags); } -static int mxser_set_baud(struct tty_struct *tty, long newspd) +static int mxser_set_baud(struct tty_struct *tty, speed_t newspd) { struct mxser_port *info = tty->driver_data; unsigned int quot = 0, baud; @@ -793,7 +787,7 @@ static void mxser_change_speed(struct tty_struct *tty) fcr |= MOXA_MUST_FCR_GDA_MODE_ENABLE; mxser_set_must_fifo_value(info); } else { - switch (info->rx_trigger) { + switch (info->rx_high_water) { case 1: fcr |= UART_FCR_TRIGGER_1; break; From 3b6618299a38c8bc21c6f70109c52a2dc8627350 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:12 +0200 Subject: [PATCH 151/227] mxser: rename CheckIsMoxaMust to mxser_get_must_hwid CheckIsMoxaMust actually finds out what the card is. So rename it to mxser_must_get_hwid, so that the name conforms to the semantics of the function. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-7-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 3b3f0da9ea64..72e1aeabdee7 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -583,7 +583,7 @@ static void mxser_disable_must_rx_software_flow_control(unsigned long baseio) outb(oldlcr, baseio + UART_LCR); } -static int CheckIsMoxaMust(unsigned long io) +static int mxser_must_get_hwid(unsigned long io) { u8 oldmcr, hwid; int i; @@ -2452,7 +2452,7 @@ static int mxser_probe(struct pci_dev *pdev, /* irq */ brd->irq = pdev->irq; - brd->chip_flag = CheckIsMoxaMust(brd->ports[0].ioaddr); + brd->chip_flag = mxser_must_get_hwid(brd->ports[0].ioaddr); brd->uart_type = PORT_16550A; brd->vector_mask = 0; From 292955a7c011e2351a7ed6f8d7e418d4f3fdd585 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:13 +0200 Subject: [PATCH 152/227] mxser: rename mxser_board::chip_flag to must_hwid It is named IsMoxaMustChipFlag in the original Moxa's driver. Over the time, it was reduced to chip_flag which doesn't make much sense. So dub it again by what it is: must_hwid (mxser_must_get_hwid assigns to it). Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-8-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 70 ++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 72e1aeabdee7..1865f965334a 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -370,7 +370,7 @@ struct mxser_board { unsigned long vector; unsigned long vector_mask; - int chip_flag; + int must_hwid; int uart_type; struct mxser_port ports[MXSER_PORTS_PER_BOARD]; @@ -616,7 +616,7 @@ static void process_txrx_fifo(struct mxser_port *info) info->xmit_fifo_size = 1; } else for (i = 0; i < UART_INFO_NUM; i++) - if (info->board->chip_flag == Gpci_uart_info[i].type) { + if (info->board->must_hwid == Gpci_uart_info[i].type) { info->rx_low_water = Gpci_uart_info[i].rx_low_water; info->rx_high_water = Gpci_uart_info[i].rx_high_water; info->xmit_fifo_size = Gpci_uart_info[i].fifo_size; @@ -775,7 +775,7 @@ static void mxser_change_speed(struct tty_struct *tty) cval |= UART_LCR_SPAR; if ((info->type == PORT_8250) || (info->type == PORT_16450)) { - if (info->board->chip_flag) { + if (info->board->must_hwid) { fcr = UART_FCR_ENABLE_FIFO; fcr |= MOXA_MUST_FCR_GDA_MODE_ENABLE; mxser_set_must_fifo_value(info); @@ -783,7 +783,7 @@ static void mxser_change_speed(struct tty_struct *tty) fcr = 0; } else { fcr = UART_FCR_ENABLE_FIFO; - if (info->board->chip_flag) { + if (info->board->must_hwid) { fcr |= MOXA_MUST_FCR_GDA_MODE_ENABLE; mxser_set_must_fifo_value(info); } else { @@ -810,7 +810,7 @@ static void mxser_change_speed(struct tty_struct *tty) tty_port_set_cts_flow(&info->port, cflag & CRTSCTS); if (cflag & CRTSCTS) { info->IER |= UART_IER_MSI; - if ((info->type == PORT_16550A) || (info->board->chip_flag)) { + if ((info->type == PORT_16550A) || (info->board->must_hwid)) { info->MCR |= UART_MCR_AFE; } else { status = inb(info->ioaddr + UART_MSR); @@ -818,7 +818,7 @@ static void mxser_change_speed(struct tty_struct *tty) if (status & UART_MSR_CTS) { tty->hw_stopped = 0; if (info->type != PORT_16550A && - !info->board->chip_flag) { + !info->board->must_hwid) { outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER); @@ -832,7 +832,7 @@ static void mxser_change_speed(struct tty_struct *tty) if (!(status & UART_MSR_CTS)) { tty->hw_stopped = 1; if ((info->type != PORT_16550A) && - (!info->board->chip_flag)) { + (!info->board->must_hwid)) { info->IER &= ~UART_IER_THRI; outb(info->IER, info->ioaddr + UART_IER); @@ -876,7 +876,7 @@ static void mxser_change_speed(struct tty_struct *tty) UART_LSR_FE; } } - if (info->board->chip_flag) { + if (info->board->must_hwid) { mxser_set_must_xon1_value(info->ioaddr, START_CHAR(tty)); mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(tty)); if (I_IXON(tty)) { @@ -926,7 +926,7 @@ static void mxser_check_modem_status(struct tty_struct *tty, tty->hw_stopped = 0; if ((port->type != PORT_16550A) && - (!port->board->chip_flag)) { + (!port->board->must_hwid)) { outb(port->IER & ~UART_IER_THRI, port->ioaddr + UART_IER); port->IER |= UART_IER_THRI; @@ -939,7 +939,7 @@ static void mxser_check_modem_status(struct tty_struct *tty, if (!(status & UART_MSR_CTS)) { tty->hw_stopped = 1; if (port->type != PORT_16550A && - !port->board->chip_flag) { + !port->board->must_hwid) { port->IER &= ~UART_IER_THRI; outb(port->IER, port->ioaddr + UART_IER); @@ -973,7 +973,7 @@ static int mxser_activate(struct tty_port *port, struct tty_struct *tty) * Clear the FIFO buffers and disable them * (they will be reenabled in mxser_change_speed()) */ - if (info->board->chip_flag) + if (info->board->must_hwid) outb((UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT | MOXA_MUST_FCR_GDA_MODE_ENABLE), info->ioaddr + UART_FCR); @@ -1015,7 +1015,7 @@ static int mxser_activate(struct tty_port *port, struct tty_struct *tty) */ info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI; - if (info->board->chip_flag) + if (info->board->must_hwid) info->IER |= MOXA_MUST_IER_EGDAI; outb(info->IER, info->ioaddr + UART_IER); /* enable interrupts */ @@ -1067,7 +1067,7 @@ static void mxser_shutdown_port(struct tty_port *port) outb(0x00, info->ioaddr + UART_IER); /* clear Rx/Tx FIFO's */ - if (info->board->chip_flag) + if (info->board->must_hwid) outb(UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT | MOXA_MUST_FCR_GDA_MODE_ENABLE, info->ioaddr + UART_FCR); @@ -1079,7 +1079,7 @@ static void mxser_shutdown_port(struct tty_port *port) (void) inb(info->ioaddr + UART_RX); - if (info->board->chip_flag) + if (info->board->must_hwid) SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(info->ioaddr); spin_unlock_irqrestore(&info->slock, flags); @@ -1139,7 +1139,7 @@ static void mxser_close_port(struct tty_port *port) * line status register. */ info->IER &= ~UART_IER_RLSI; - if (info->board->chip_flag) + if (info->board->must_hwid) info->IER &= ~MOXA_MUST_RECV_ISR; outb(info->IER, info->ioaddr + UART_IER); @@ -1217,7 +1217,7 @@ static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int cou if (info->xmit_cnt && !tty->flow.stopped) { if (!tty->hw_stopped || (info->type == PORT_16550A) || - (info->board->chip_flag)) { + (info->board->must_hwid)) { spin_lock_irqsave(&info->slock, flags); outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER); @@ -1248,7 +1248,7 @@ static int mxser_put_char(struct tty_struct *tty, unsigned char ch) if (!tty->flow.stopped) { if (!tty->hw_stopped || (info->type == PORT_16550A) || - info->board->chip_flag) { + info->board->must_hwid) { spin_lock_irqsave(&info->slock, flags); outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER); info->IER |= UART_IER_THRI; @@ -1267,7 +1267,7 @@ static void mxser_flush_chars(struct tty_struct *tty) if (info->xmit_cnt <= 0 || tty->flow.stopped || !info->port.xmit_buf || (tty->hw_stopped && info->type != PORT_16550A && - !info->board->chip_flag)) + !info->board->must_hwid)) return; spin_lock_irqsave(&info->slock, flags); @@ -1631,7 +1631,7 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) if (ip->type == PORT_16550A) me->fifo[p] = 1; - if (ip->board->chip_flag == MOXA_MUST_MU860_HWID) { + if (ip->board->must_hwid == MOXA_MUST_MU860_HWID) { opmode = inb(ip->opmode_ioaddr)>>((p % 4) * 2); opmode &= OP_MODE_MASK; } else { @@ -1691,7 +1691,7 @@ static int mxser_ioctl(struct tty_struct *tty, int shiftbit; unsigned char val, mask; - if (info->board->chip_flag != MOXA_MUST_MU860_HWID) + if (info->board->must_hwid != MOXA_MUST_MU860_HWID) return -EFAULT; p = tty->index % 4; @@ -1853,7 +1853,7 @@ static void mxser_stoprx(struct tty_struct *tty) info->ldisc_stop_rx = 1; if (I_IXOFF(tty)) { - if (info->board->chip_flag) { + if (info->board->must_hwid) { info->IER &= ~MOXA_MUST_RECV_ISR; outb(info->IER, info->ioaddr + UART_IER); } else { @@ -1889,7 +1889,7 @@ static void mxser_unthrottle(struct tty_struct *tty) if (info->x_char) info->x_char = 0; else { - if (info->board->chip_flag) { + if (info->board->must_hwid) { info->IER |= MOXA_MUST_RECV_ISR; outb(info->IER, info->ioaddr + UART_IER); } else { @@ -1958,7 +1958,7 @@ static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termi if ((old_termios->c_iflag & IXON) && !I_IXON(tty)) { tty->flow.stopped = 0; - if (info->board->chip_flag) { + if (info->board->must_hwid) { spin_lock_irqsave(&info->slock, flags); mxser_disable_must_rx_software_flow_control( info->ioaddr); @@ -2068,11 +2068,11 @@ static void mxser_receive_chars(struct tty_struct *tty, recv_room = tty->receive_room; if (recv_room == 0 && !port->ldisc_stop_rx) mxser_stoprx(tty); - if (port->board->chip_flag != MOXA_OTHER_UART) { + if (port->board->must_hwid != MOXA_OTHER_UART) { if (*status & UART_LSR_SPECIAL) goto intr_old; - if (port->board->chip_flag == MOXA_MUST_MU860_HWID && + if (port->board->must_hwid == MOXA_MUST_MU860_HWID && (*status & MOXA_MUST_LSR_RERR)) goto intr_old; if (*status & MOXA_MUST_LSR_RERR) @@ -2080,7 +2080,7 @@ static void mxser_receive_chars(struct tty_struct *tty, gdl = inb(port->ioaddr + MOXA_MUST_GDL_REGISTER); - if (port->board->chip_flag == MOXA_MUST_MU150_HWID) + if (port->board->must_hwid == MOXA_MUST_MU150_HWID) gdl &= MOXA_MUST_GDL_MASK; if (gdl >= recv_room) { if (!port->ldisc_stop_rx) @@ -2100,7 +2100,7 @@ intr_old: break; ch = inb(port->ioaddr + UART_RX); - if (port->board->chip_flag && (*status & UART_LSR_OE)) + if (port->board->must_hwid && (*status & UART_LSR_OE)) outb(0x23, port->ioaddr + UART_FCR); *status &= port->read_status_mask; if (*status & port->ignore_status_mask) { @@ -2137,7 +2137,7 @@ intr_old: } - if (port->board->chip_flag) + if (port->board->must_hwid) break; *status = inb(port->ioaddr + UART_LSR); @@ -2171,7 +2171,7 @@ static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port if (port->xmit_cnt <= 0 || tty->flow.stopped || (tty->hw_stopped && (port->type != PORT_16550A) && - (!port->board->chip_flag))) { + (!port->board->must_hwid))) { port->IER &= ~UART_IER_THRI; outb(port->IER, port->ioaddr + UART_IER); return; @@ -2267,7 +2267,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) if (status & UART_LSR_BI) port->err_shadow |= NPPI_NOTIFY_BREAK; - if (port->board->chip_flag) { + if (port->board->must_hwid) { if (iir == MOXA_MUST_IIR_GDA || iir == MOXA_MUST_IIR_RDA || iir == MOXA_MUST_IIR_RTO || @@ -2285,7 +2285,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) if (msr & UART_MSR_ANY_DELTA) mxser_check_modem_status(tty, port, msr); - if (port->board->chip_flag) { + if (port->board->must_hwid) { if (iir == 0x02 && (status & UART_LSR_THRE)) mxser_transmit_chars(tty, port); @@ -2357,7 +2357,7 @@ static int mxser_initbrd(struct mxser_board *brd) info->ldisc_stop_rx = 0; /* Enhance mode enabled here */ - if (brd->chip_flag != MOXA_OTHER_UART) + if (brd->must_hwid != MOXA_OTHER_UART) mxser_enable_must_enchance_mode(info->ioaddr); info->type = brd->uart_type; @@ -2452,13 +2452,13 @@ static int mxser_probe(struct pci_dev *pdev, /* irq */ brd->irq = pdev->irq; - brd->chip_flag = mxser_must_get_hwid(brd->ports[0].ioaddr); + brd->must_hwid = mxser_must_get_hwid(brd->ports[0].ioaddr); brd->uart_type = PORT_16550A; brd->vector_mask = 0; for (i = 0; i < brd->info->nports; i++) { for (j = 0; j < UART_INFO_NUM; j++) { - if (Gpci_uart_info[j].type == brd->chip_flag) { + if (Gpci_uart_info[j].type == brd->must_hwid) { brd->ports[i].max_baud = Gpci_uart_info[j].max_baud; @@ -2470,7 +2470,7 @@ static int mxser_probe(struct pci_dev *pdev, } } - if (brd->chip_flag == MOXA_MUST_MU860_HWID) { + if (brd->must_hwid == MOXA_MUST_MU860_HWID) { for (i = 0; i < brd->info->nports; i++) { if (i < 4) brd->ports[i].opmode_ioaddr = ioaddress + 4; From e45583668e0313c422c650d5da11405624cf547c Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:14 +0200 Subject: [PATCH 153/227] mxser: introduce enum mxser_must_hwid Provided the MUST HW ID is an enumeration, define one (enum mxser_must_hwid) and use it in the code. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-9-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 1865f965334a..558bd4140ee1 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -178,11 +178,6 @@ #define MXSER_PORTS (MXSER_BOARDS * MXSER_PORTS_PER_BOARD) #define MXSER_ISR_PASS_LIMIT 100 -/*CheckIsMoxaMust return value*/ -#define MOXA_OTHER_UART 0x00 -#define MOXA_MUST_MU150_HWID 0x01 -#define MOXA_MUST_MU860_HWID 0x02 - #define WAKEUP_CHARS 256 #define UART_MCR_AFE 0x20 @@ -199,6 +194,12 @@ #define MXSER_HIGHBAUD 1 +enum mxser_must_hwid { + MOXA_OTHER_UART = 0x00, + MOXA_MUST_MU150_HWID = 0x01, + MOXA_MUST_MU860_HWID = 0x02, +}; + static const struct { u8 type; u8 fifo_size; @@ -370,7 +371,7 @@ struct mxser_board { unsigned long vector; unsigned long vector_mask; - int must_hwid; + enum mxser_must_hwid must_hwid; int uart_type; struct mxser_port ports[MXSER_PORTS_PER_BOARD]; @@ -583,7 +584,7 @@ static void mxser_disable_must_rx_software_flow_control(unsigned long baseio) outb(oldlcr, baseio + UART_LCR); } -static int mxser_must_get_hwid(unsigned long io) +static enum mxser_must_hwid mxser_must_get_hwid(unsigned long io) { u8 oldmcr, hwid; int i; @@ -599,10 +600,10 @@ static int mxser_must_get_hwid(unsigned long io) } mxser_get_must_hardware_id(io, &hwid); - for (i = 1; i < UART_INFO_NUM; i++) { /* 0 = OTHER_UART */ + for (i = 1; i < UART_INFO_NUM; i++) /* 0 = OTHER_UART */ if (hwid == Gpci_uart_info[i].type) - return (int)hwid; - } + return hwid; + return MOXA_OTHER_UART; } From 58a2ddb3aa859c7e5a7beee2c43c80ac2229c1ca Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:15 +0200 Subject: [PATCH 154/227] mxser: drop constant board::uart_type board::uart_type is always set to PORT_16550A. So, use this constant in the code instead. And drop the mxser_board member. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-10-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 558bd4140ee1..a6121fea7a55 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -372,7 +372,6 @@ struct mxser_board { unsigned long vector_mask; enum mxser_must_hwid must_hwid; - int uart_type; struct mxser_port ports[MXSER_PORTS_PER_BOARD]; }; @@ -2361,7 +2360,7 @@ static int mxser_initbrd(struct mxser_board *brd) if (brd->must_hwid != MOXA_OTHER_UART) mxser_enable_must_enchance_mode(info->ioaddr); - info->type = brd->uart_type; + info->type = PORT_16550A; process_txrx_fifo(info); @@ -2454,7 +2453,6 @@ static int mxser_probe(struct pci_dev *pdev, brd->irq = pdev->irq; brd->must_hwid = mxser_must_get_hwid(brd->ports[0].ioaddr); - brd->uart_type = PORT_16550A; brd->vector_mask = 0; for (i = 0; i < brd->info->nports; i++) { From 928f946426905dd3ab4e166699baa26358cd8a8b Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:16 +0200 Subject: [PATCH 155/227] mxser: move max_baud from port to board mxser_port::max_baud is actually a board property, not port's. So move it to mxser_board. While at it, drop the printk informing about max baud rate during probe. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-11-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index a6121fea7a55..db594a64ff00 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -329,7 +329,6 @@ struct mxser_port { unsigned long ioaddr; unsigned long opmode_ioaddr; - speed_t max_baud; u8 rx_high_water; u8 rx_low_water; @@ -372,6 +371,7 @@ struct mxser_board { unsigned long vector_mask; enum mxser_must_hwid must_hwid; + speed_t max_baud; struct mxser_port ports[MXSER_PORTS_PER_BOARD]; }; @@ -671,7 +671,7 @@ static int mxser_set_baud(struct tty_struct *tty, speed_t newspd) if (!info->ioaddr) return -1; - if (newspd > info->max_baud) + if (newspd > info->board->max_baud) return -1; if (newspd == 134) { @@ -2345,9 +2345,6 @@ static int mxser_initbrd(struct mxser_board *brd) unsigned int i; int retval; - printk(KERN_INFO "mxser: max. baud rate = %d bps\n", - brd->ports[0].max_baud); - for (i = 0; i < brd->info->nports; i++) { info = &brd->ports[i]; tty_port_init(&info->port); @@ -2455,17 +2452,14 @@ static int mxser_probe(struct pci_dev *pdev, brd->must_hwid = mxser_must_get_hwid(brd->ports[0].ioaddr); brd->vector_mask = 0; - for (i = 0; i < brd->info->nports; i++) { - for (j = 0; j < UART_INFO_NUM; j++) { - if (Gpci_uart_info[j].type == brd->must_hwid) { - brd->ports[i].max_baud = - Gpci_uart_info[j].max_baud; + for (j = 0; j < UART_INFO_NUM; j++) { + if (Gpci_uart_info[j].type == brd->must_hwid) { + brd->max_baud = Gpci_uart_info[j].max_baud; - /* exception....CP-102 */ - if (brd->info->flags & MXSER_HIGHBAUD) - brd->ports[i].max_baud = 921600; - break; - } + /* exception....CP-102 */ + if (brd->info->flags & MXSER_HIGHBAUD) + brd->max_baud = 921600; + break; } } From cef222cbffccab4ac137b2d4d232103ac9ed8a89 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:17 +0200 Subject: [PATCH 156/227] mxser: remove nonsense from ISR request_irq was passed a board. There is no need to check dev_id and/or find the appropriate board in the ISR. Neither check if board is NULL. Remove this nonsense. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-12-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index db594a64ff00..6602b2741271 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -2207,23 +2207,13 @@ static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port static irqreturn_t mxser_interrupt(int irq, void *dev_id) { int status, iir, i; - struct mxser_board *brd = NULL; + struct mxser_board *brd = dev_id; struct mxser_port *port; int max, irqbits, bits, msr; unsigned int int_cnt, pass_counter = 0; int handled = IRQ_NONE; struct tty_struct *tty; - for (i = 0; i < MXSER_BOARDS; i++) - if (dev_id == &mxser_boards[i]) { - brd = dev_id; - break; - } - - if (i == MXSER_BOARDS) - goto irq_stop; - if (brd == NULL) - goto irq_stop; max = brd->info->nports; while (pass_counter++ < MXSER_ISR_PASS_LIMIT) { irqbits = inb(brd->vector) & brd->vector_mask; @@ -2299,7 +2289,6 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) } } -irq_stop: return handled; } From 15517806037c8633ff44e6cd2099d3de22233b4a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:18 +0200 Subject: [PATCH 157/227] mxser: cleanup LSR handling in mxser_receive_chars mxser_interrupt is a bit confusing as it passes a pointer to LSR variable ("status") to mxser_receive_chars. That function can indeed update the LCR variable. Make this clear by not passing a variable by reference, instead, return updated status. And change its type accordingly -- to u8. Note that the next patches will rework ISR so that even the definition of status will be u8 soon too. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-13-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 6602b2741271..9ba3af4626c6 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -2056,8 +2056,8 @@ static int mxser_rs_break(struct tty_struct *tty, int break_state) return 0; } -static void mxser_receive_chars(struct tty_struct *tty, - struct mxser_port *port, int *status) +static u8 mxser_receive_chars(struct tty_struct *tty, + struct mxser_port *port, u8 status) { unsigned char ch, gdl; int ignored = 0; @@ -2070,12 +2070,12 @@ static void mxser_receive_chars(struct tty_struct *tty, mxser_stoprx(tty); if (port->board->must_hwid != MOXA_OTHER_UART) { - if (*status & UART_LSR_SPECIAL) + if (status & UART_LSR_SPECIAL) goto intr_old; if (port->board->must_hwid == MOXA_MUST_MU860_HWID && - (*status & MOXA_MUST_LSR_RERR)) + (status & MOXA_MUST_LSR_RERR)) goto intr_old; - if (*status & MOXA_MUST_LSR_RERR) + if (status & MOXA_MUST_LSR_RERR) goto intr_old; gdl = inb(port->ioaddr + MOXA_MUST_GDL_REGISTER); @@ -2100,28 +2100,28 @@ intr_old: break; ch = inb(port->ioaddr + UART_RX); - if (port->board->must_hwid && (*status & UART_LSR_OE)) + if (port->board->must_hwid && (status & UART_LSR_OE)) outb(0x23, port->ioaddr + UART_FCR); - *status &= port->read_status_mask; - if (*status & port->ignore_status_mask) { + status &= port->read_status_mask; + if (status & port->ignore_status_mask) { if (++ignored > 100) break; } else { char flag = 0; - if (*status & UART_LSR_SPECIAL) { - if (*status & UART_LSR_BI) { + if (status & UART_LSR_SPECIAL) { + if (status & UART_LSR_BI) { flag = TTY_BREAK; port->icount.brk++; if (port->port.flags & ASYNC_SAK) do_SAK(tty); - } else if (*status & UART_LSR_PE) { + } else if (status & UART_LSR_PE) { flag = TTY_PARITY; port->icount.parity++; - } else if (*status & UART_LSR_FE) { + } else if (status & UART_LSR_FE) { flag = TTY_FRAME; port->icount.frame++; - } else if (*status & UART_LSR_OE) { + } else if (status & UART_LSR_OE) { flag = TTY_OVERRUN; port->icount.overrun++; } else @@ -2140,8 +2140,8 @@ intr_old: if (port->board->must_hwid) break; - *status = inb(port->ioaddr + UART_LSR); - } while (*status & UART_LSR_DR); + status = inb(port->ioaddr + UART_LSR); + } while (status & UART_LSR_DR); end_intr: mxvar_log.rxcnt[tty->index] += cnt; @@ -2149,6 +2149,8 @@ end_intr: port->mon_data.up_rxcnt += cnt; tty_flip_buffer_push(&port->port); + + return status; } static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port) @@ -2262,14 +2264,14 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) iir == MOXA_MUST_IIR_RDA || iir == MOXA_MUST_IIR_RTO || iir == MOXA_MUST_IIR_LSR) - mxser_receive_chars(tty, port, - &status); + status = mxser_receive_chars(tty, + port, status); } else { status &= port->read_status_mask; if (status & UART_LSR_DR) - mxser_receive_chars(tty, port, - &status); + status = mxser_receive_chars(tty, + port, status); } msr = inb(port->ioaddr + UART_MSR); if (msr & UART_MSR_ANY_DELTA) From 9e40ea1f785292356cfb39aafff7d346b46d8b4f Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:19 +0200 Subject: [PATCH 158/227] mxser: extract port ISR The ISR is terrible mix of letters. Let's extract the proper per-port handling to a separate function called mxser_port_isr. This way, we can actually see what both mxser_interrupt and mxser_port_isr do now. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-14-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 119 ++++++++++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 55 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 9ba3af4626c6..555b9b37b52f 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -2203,18 +2203,78 @@ static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port } } +static bool mxser_port_isr(struct mxser_port *port) +{ + struct tty_struct *tty; + u8 iir, msr, status; + bool error = false; + + iir = inb(port->ioaddr + UART_IIR); + if (iir & UART_IIR_NO_INT) + return true; + + iir &= MOXA_MUST_IIR_MASK; + tty = tty_port_tty_get(&port->port); + if (!tty || port->closing || !tty_port_initialized(&port->port)) { + status = inb(port->ioaddr + UART_LSR); + outb(0x27, port->ioaddr + UART_FCR); + inb(port->ioaddr + UART_MSR); + + error = true; + goto put_tty; + } + + status = inb(port->ioaddr + UART_LSR); + + if (status & UART_LSR_PE) + port->err_shadow |= NPPI_NOTIFY_PARITY; + if (status & UART_LSR_FE) + port->err_shadow |= NPPI_NOTIFY_FRAMING; + if (status & UART_LSR_OE) + port->err_shadow |= NPPI_NOTIFY_HW_OVERRUN; + if (status & UART_LSR_BI) + port->err_shadow |= NPPI_NOTIFY_BREAK; + + if (port->board->must_hwid) { + if (iir == MOXA_MUST_IIR_GDA || + iir == MOXA_MUST_IIR_RDA || + iir == MOXA_MUST_IIR_RTO || + iir == MOXA_MUST_IIR_LSR) + status = mxser_receive_chars(tty, port, status); + } else { + status &= port->read_status_mask; + if (status & UART_LSR_DR) + status = mxser_receive_chars(tty, port, status); + } + + msr = inb(port->ioaddr + UART_MSR); + if (msr & UART_MSR_ANY_DELTA) + mxser_check_modem_status(tty, port, msr); + + if (port->board->must_hwid) { + if (iir == 0x02 && (status & UART_LSR_THRE)) + mxser_transmit_chars(tty, port); + } else { + if (status & UART_LSR_THRE) + mxser_transmit_chars(tty, port); + } + +put_tty: + tty_kref_put(tty); + + return error; +} + /* * This is the serial driver's generic interrupt routine */ static irqreturn_t mxser_interrupt(int irq, void *dev_id) { - int status, iir, i; struct mxser_board *brd = dev_id; struct mxser_port *port; - int max, irqbits, bits, msr; unsigned int int_cnt, pass_counter = 0; + int max, irqbits, bits, i; int handled = IRQ_NONE; - struct tty_struct *tty; max = brd->info->nports; while (pass_counter++ < MXSER_ISR_PASS_LIMIT) { @@ -2233,59 +2293,8 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) int_cnt = 0; spin_lock(&port->slock); do { - iir = inb(port->ioaddr + UART_IIR); - if (iir & UART_IIR_NO_INT) + if (mxser_port_isr(port)) break; - iir &= MOXA_MUST_IIR_MASK; - tty = tty_port_tty_get(&port->port); - if (!tty || port->closing || - !tty_port_initialized(&port->port)) { - status = inb(port->ioaddr + UART_LSR); - outb(0x27, port->ioaddr + UART_FCR); - inb(port->ioaddr + UART_MSR); - tty_kref_put(tty); - break; - } - - status = inb(port->ioaddr + UART_LSR); - - if (status & UART_LSR_PE) - port->err_shadow |= NPPI_NOTIFY_PARITY; - if (status & UART_LSR_FE) - port->err_shadow |= NPPI_NOTIFY_FRAMING; - if (status & UART_LSR_OE) - port->err_shadow |= - NPPI_NOTIFY_HW_OVERRUN; - if (status & UART_LSR_BI) - port->err_shadow |= NPPI_NOTIFY_BREAK; - - if (port->board->must_hwid) { - if (iir == MOXA_MUST_IIR_GDA || - iir == MOXA_MUST_IIR_RDA || - iir == MOXA_MUST_IIR_RTO || - iir == MOXA_MUST_IIR_LSR) - status = mxser_receive_chars(tty, - port, status); - - } else { - status &= port->read_status_mask; - if (status & UART_LSR_DR) - status = mxser_receive_chars(tty, - port, status); - } - msr = inb(port->ioaddr + UART_MSR); - if (msr & UART_MSR_ANY_DELTA) - mxser_check_modem_status(tty, port, msr); - - if (port->board->must_hwid) { - if (iir == 0x02 && (status & - UART_LSR_THRE)) - mxser_transmit_chars(tty, port); - } else { - if (status & UART_LSR_THRE) - mxser_transmit_chars(tty, port); - } - tty_kref_put(tty); } while (int_cnt++ < MXSER_ISR_PASS_LIMIT); spin_unlock(&port->slock); } From 9cb5c9c3226ba78e33169721f31b459e6791d6ab Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:20 +0200 Subject: [PATCH 159/227] mxser: simplify mxser_interrupt and drop mxser_board::vector_mask mxser_board::vector_mask is just a bitfield with bits set for all available ports. We can obtain this value simply by "BIT(brd->info->nports) - 1" directly in the ISR. So remove vector_mask and simplify the code a bit. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-15-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 555b9b37b52f..df59ca88acab 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -368,7 +368,6 @@ struct mxser_board { int irq; const struct mxser_cardinfo *info; unsigned long vector; - unsigned long vector_mask; enum mxser_must_hwid must_hwid; speed_t max_baud; @@ -2273,18 +2272,18 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) struct mxser_board *brd = dev_id; struct mxser_port *port; unsigned int int_cnt, pass_counter = 0; - int max, irqbits, bits, i; + unsigned int i, max = brd->info->nports; int handled = IRQ_NONE; + u8 irqbits, bits, mask = BIT(max) - 1; - max = brd->info->nports; while (pass_counter++ < MXSER_ISR_PASS_LIMIT) { - irqbits = inb(brd->vector) & brd->vector_mask; - if (irqbits == brd->vector_mask) + irqbits = inb(brd->vector) & mask; + if (irqbits == mask) break; handled = IRQ_HANDLED; for (i = 0, bits = 1; i < max; i++, irqbits |= bits, bits <<= 1) { - if (irqbits == brd->vector_mask) + if (irqbits == mask) break; if (bits & irqbits) continue; @@ -2450,7 +2449,6 @@ static int mxser_probe(struct pci_dev *pdev, brd->irq = pdev->irq; brd->must_hwid = mxser_must_get_hwid(brd->ports[0].ioaddr); - brd->vector_mask = 0; for (j = 0; j < UART_INFO_NUM; j++) { if (Gpci_uart_info[j].type == brd->must_hwid) { @@ -2475,7 +2473,6 @@ static int mxser_probe(struct pci_dev *pdev, } for (i = 0; i < brd->info->nports; i++) { - brd->vector_mask |= (1 << i); brd->ports[i].baud_base = 921600; } From e5ce1bcedac6875ce9d1ff4bafdf150a899a5694 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:21 +0200 Subject: [PATCH 160/227] mxser: extract mxser_receive_chars_new Extract the new handling of receive chars (using the MUST chip enhancements) into a separate function. This eliminates the need for the intr_old label and makes the code of mxser_receive_chars more compact. In the next step, we will extract the old handling too. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-16-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 58 ++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index df59ca88acab..a321aba24d58 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -2055,10 +2055,41 @@ static int mxser_rs_break(struct tty_struct *tty, int break_state) return 0; } +static bool mxser_receive_chars_new(struct tty_struct *tty, + struct mxser_port *port, u8 status, int *cnt) +{ + enum mxser_must_hwid hwid = port->board->must_hwid; + u8 gdl; + + if (hwid == MOXA_OTHER_UART) + return false; + if (status & UART_LSR_SPECIAL) + return false; + if (hwid == MOXA_MUST_MU860_HWID && (status & MOXA_MUST_LSR_RERR)) + return false; + if (status & MOXA_MUST_LSR_RERR) + return false; + + gdl = inb(port->ioaddr + MOXA_MUST_GDL_REGISTER); + if (hwid == MOXA_MUST_MU150_HWID) + gdl &= MOXA_MUST_GDL_MASK; + + if (gdl >= tty->receive_room && !port->ldisc_stop_rx) + mxser_stoprx(tty); + + while (gdl--) { + u8 ch = inb(port->ioaddr + UART_RX); + tty_insert_flip_char(&port->port, ch, 0); + (*cnt)++; + } + + return true; +} + static u8 mxser_receive_chars(struct tty_struct *tty, struct mxser_port *port, u8 status) { - unsigned char ch, gdl; + unsigned char ch; int ignored = 0; int cnt = 0; int recv_room; @@ -2067,32 +2098,9 @@ static u8 mxser_receive_chars(struct tty_struct *tty, recv_room = tty->receive_room; if (recv_room == 0 && !port->ldisc_stop_rx) mxser_stoprx(tty); - if (port->board->must_hwid != MOXA_OTHER_UART) { - if (status & UART_LSR_SPECIAL) - goto intr_old; - if (port->board->must_hwid == MOXA_MUST_MU860_HWID && - (status & MOXA_MUST_LSR_RERR)) - goto intr_old; - if (status & MOXA_MUST_LSR_RERR) - goto intr_old; - - gdl = inb(port->ioaddr + MOXA_MUST_GDL_REGISTER); - - if (port->board->must_hwid == MOXA_MUST_MU150_HWID) - gdl &= MOXA_MUST_GDL_MASK; - if (gdl >= recv_room) { - if (!port->ldisc_stop_rx) - mxser_stoprx(tty); - } - while (gdl--) { - ch = inb(port->ioaddr + UART_RX); - tty_insert_flip_char(&port->port, ch, 0); - cnt++; - } + if (mxser_receive_chars_new(tty, port, status, &cnt)) goto end_intr; - } -intr_old: do { if (max-- < 0) From 0c4194218cf206405c39e9d3380886a627c0602c Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:22 +0200 Subject: [PATCH 161/227] mxser: extract mxser_receive_chars_old Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-17-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index a321aba24d58..6b8f2b0e0726 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -2086,28 +2086,21 @@ static bool mxser_receive_chars_new(struct tty_struct *tty, return true; } -static u8 mxser_receive_chars(struct tty_struct *tty, - struct mxser_port *port, u8 status) +static u8 mxser_receive_chars_old(struct tty_struct *tty, + struct mxser_port *port, u8 status, int *cnt) { - unsigned char ch; + enum mxser_must_hwid hwid = port->board->must_hwid; + int recv_room = tty->receive_room; int ignored = 0; - int cnt = 0; - int recv_room; int max = 256; - - recv_room = tty->receive_room; - if (recv_room == 0 && !port->ldisc_stop_rx) - mxser_stoprx(tty); - - if (mxser_receive_chars_new(tty, port, status, &cnt)) - goto end_intr; + u8 ch; do { if (max-- < 0) break; ch = inb(port->ioaddr + UART_RX); - if (port->board->must_hwid && (status & UART_LSR_OE)) + if (hwid && (status & UART_LSR_OE)) outb(0x23, port->ioaddr + UART_FCR); status &= port->read_status_mask; if (status & port->ignore_status_mask) { @@ -2135,8 +2128,8 @@ static u8 mxser_receive_chars(struct tty_struct *tty, flag = TTY_BREAK; } tty_insert_flip_char(&port->port, ch, flag); - cnt++; - if (cnt >= recv_room) { + (*cnt)++; + if (*cnt >= recv_room) { if (!port->ldisc_stop_rx) mxser_stoprx(tty); break; @@ -2144,13 +2137,26 @@ static u8 mxser_receive_chars(struct tty_struct *tty, } - if (port->board->must_hwid) + if (hwid) break; status = inb(port->ioaddr + UART_LSR); } while (status & UART_LSR_DR); -end_intr: + return status; +} + +static u8 mxser_receive_chars(struct tty_struct *tty, + struct mxser_port *port, u8 status) +{ + int cnt = 0; + + if (tty->receive_room == 0 && !port->ldisc_stop_rx) + mxser_stoprx(tty); + + if (!mxser_receive_chars_new(tty, port, status, &cnt)) + status = mxser_receive_chars_old(tty, port, status, &cnt); + mxvar_log.rxcnt[tty->index] += cnt; port->mon_data.rxcnt += cnt; port->mon_data.up_rxcnt += cnt; From 6de6e5c4becb5494d09d44ce4db1c54dc43afbae Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:23 +0200 Subject: [PATCH 162/227] mxser: remove else from LSR bits checks UART_LSR_SPECIAL is composed of UART_LSR_BI, UART_LSR_PE, UART_LSR_FE, UART_LSR_OE. So status cannot be anything else. Remove the unused else branch. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-18-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 6b8f2b0e0726..1b8032c9351e 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -2124,8 +2124,7 @@ static u8 mxser_receive_chars_old(struct tty_struct *tty, } else if (status & UART_LSR_OE) { flag = TTY_OVERRUN; port->icount.overrun++; - } else - flag = TTY_BREAK; + } } tty_insert_flip_char(&port->port, ch, flag); (*cnt)++; From a93963e41ffeff71a735f4fab95d2cbacd9da7a8 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:24 +0200 Subject: [PATCH 163/227] mxser: correct types for uart variables In struct mxser_port, all the UART registers and masks, and the xon/xoff character are stored into int. Let's re-type all these as UART registers are 8bit (u8) and xon/xoff character is an unsigned char (cc_t in ktermios). This save some bytes in memory, but more importantly the change makes it what it really is. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-19-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 1b8032c9351e..45f36d92c5ea 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -335,9 +335,9 @@ struct mxser_port { int baud_base; /* max. speed */ int type; /* UART type */ - int x_char; /* xon/xoff character */ - int IER; /* Interrupt Enable Register */ - int MCR; /* Modem control register */ + unsigned char x_char; /* xon/xoff character */ + u8 IER; /* Interrupt Enable Register */ + u8 MCR; /* Modem control register */ unsigned char stop_rx; unsigned char ldisc_stop_rx; @@ -348,8 +348,8 @@ struct mxser_port { struct async_icount icount; /* kernel counters for 4 input interrupts */ unsigned int timeout; - int read_status_mask; - int ignore_status_mask; + u8 read_status_mask; + u8 ignore_status_mask; u8 xmit_fifo_size; int xmit_head; int xmit_tail; From 02e431444b52728872570a14ade413a2a26be657 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:25 +0200 Subject: [PATCH 164/227] mxser: make xmit ring buffer variables unsigned Make the xmit ring buffer pointers and counter (xmit_head, xmit_tail, xmit_cnt) unsigned. Now, the assumptions for the compiler are clear -- they cannot be negative. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-20-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 45f36d92c5ea..53136a7d92b1 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -351,9 +351,9 @@ struct mxser_port { u8 read_status_mask; u8 ignore_status_mask; u8 xmit_fifo_size; - int xmit_head; - int xmit_tail; - int xmit_cnt; + unsigned int xmit_head; + unsigned int xmit_tail; + unsigned int xmit_cnt; int closing; struct ktermios normal_termios; From 70640052324b69de70711c2a3e43bb0a8cff5f7a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:26 +0200 Subject: [PATCH 165/227] mxser: drop UART_MCR_AFE and UART_LSR_SPECIAL defines * UART_MCR_AFE is a redefinition of serial_reg.h's one. * UART_LSR_SPECIAL is a redefinition of serial_reg.h's UART_LSR_BRK_ERROR_BITS. So remove both and replace the latter uses by already defined UART_LSR_BRK_ERROR_BITS. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-21-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 53136a7d92b1..79d7cecb7765 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -180,9 +180,6 @@ #define WAKEUP_CHARS 256 -#define UART_MCR_AFE 0x20 -#define UART_LSR_SPECIAL 0x1E - #define PCI_DEVICE_ID_POS104UL 0x1044 #define PCI_DEVICE_ID_CB108 0x1080 #define PCI_DEVICE_ID_CP102UF 0x1023 @@ -2063,7 +2060,7 @@ static bool mxser_receive_chars_new(struct tty_struct *tty, if (hwid == MOXA_OTHER_UART) return false; - if (status & UART_LSR_SPECIAL) + if (status & UART_LSR_BRK_ERROR_BITS) return false; if (hwid == MOXA_MUST_MU860_HWID && (status & MOXA_MUST_LSR_RERR)) return false; @@ -2108,7 +2105,7 @@ static u8 mxser_receive_chars_old(struct tty_struct *tty, break; } else { char flag = 0; - if (status & UART_LSR_SPECIAL) { + if (status & UART_LSR_BRK_ERROR_BITS) { if (status & UART_LSR_BI) { flag = TTY_BREAK; port->icount.brk++; From a7f8f2c9dcb25ae220ce119794fd1eff417f2b03 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:27 +0200 Subject: [PATCH 166/227] mxser: drop unused MOXA_DIAGNOSE macro It's unused. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-22-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 79d7cecb7765..a830a4359ea1 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -51,7 +51,6 @@ #define MOXA 0x400 #define MOXA_GETDATACOUNT (MOXA + 23) -#define MOXA_DIAGNOSE (MOXA + 50) #define MOXA_CHKPORTENABLE (MOXA + 60) #define MOXA_HighSpeedOn (MOXA + 61) #define MOXA_GET_MAJOR (MOXA + 63) From 413d555e1296e667d574404f00b2e582bb733040 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:28 +0200 Subject: [PATCH 167/227] mxser: remove MOXA_GET_MAJOR deprecated ioctl MOXA_GET_MAJOR was deprecated in commit 41aee9a121fd (Char: mxser, ioctl cleanup) in 2008. Remove this ioctl finally. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-23-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index a830a4359ea1..a55b20f98cb3 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -53,7 +53,6 @@ #define MOXA_GETDATACOUNT (MOXA + 23) #define MOXA_CHKPORTENABLE (MOXA + 60) #define MOXA_HighSpeedOn (MOXA + 61) -#define MOXA_GET_MAJOR (MOXA + 63) #define MOXA_GETMSTATUS (MOXA + 65) #define MOXA_SET_OP_MODE (MOXA + 66) #define MOXA_GET_OP_MODE (MOXA + 67) @@ -1499,12 +1498,6 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) int ret = 0; switch (cmd) { - case MOXA_GET_MAJOR: - printk_ratelimited(KERN_WARNING "mxser: '%s' uses deprecated ioctl " - "%x (GET_MAJOR), fix your userspace\n", - current->comm, cmd); - return put_user(ttymajor, (int __user *)argp); - case MOXA_CHKPORTENABLE: result = 0; for (i = 0; i < MXSER_BOARDS; i++) From ef3dff8a0af9387b881e278676a460ab9c132d12 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:29 +0200 Subject: [PATCH 168/227] mxser: remove MOXA_SET_BAUD_METHOD ioctl 1) The semantics are defined exactly nowhere. 2) The ioctl definition was never exposed to userspace, so noone should actually be reliably using this. 3) It's not even mentioned in any of the mxser utilities. Provided the above, remove this mxser-special ioctl. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-24-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index a55b20f98cb3..cf3b8f9f7e1e 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -68,7 +68,6 @@ #define MOXA_ASPP_MON (MOXA + 73) #define MOXA_ASPP_LSTATUS (MOXA + 74) #define MOXA_ASPP_MON_EXT (MOXA + 75) -#define MOXA_SET_BAUD_METHOD (MOXA + 76) /* --------------------------------------------------- */ @@ -381,7 +380,6 @@ struct mxser_mstatus { static struct mxser_board mxser_boards[MXSER_BOARDS]; static struct tty_driver *mxvar_sdriver; static struct mxser_log mxvar_log; -static int mxser_set_baud_method[MXSER_PORTS + 1]; static void mxser_enable_must_enchance_mode(unsigned long baseio) { @@ -738,8 +736,7 @@ static void mxser_change_speed(struct tty_struct *tty) if (!info->ioaddr) return; - if (mxser_set_baud_method[tty->index] == 0) - mxser_set_baud(tty, tty_get_baud_rate(tty)); + mxser_set_baud(tty, tty_get_baud_rate(tty)); /* byte size and parity */ switch (cflag & CSIZE) { @@ -1788,14 +1785,6 @@ static int mxser_ioctl(struct tty_struct *tty, info->err_shadow = 0; return 0; } - case MOXA_SET_BAUD_METHOD: { - int method; - - if (get_user(method, (int __user *)argp)) - return -EFAULT; - mxser_set_baud_method[tty->index] = method; - return put_user(method, (int __user *)argp); - } default: return -ENOIOCTLCMD; } From 644c55d229537d6770615b01f074537776973a5b Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:30 +0200 Subject: [PATCH 169/227] mxser: remove MOXA_ASPP_MON and friends 1) MOXA_ASPP_MON_EXT is broken at least since commit ecbbfd44a08f (TTY: move tty buffers to tty_port) in 2012. 2) The ioctl definitions were never exposed to userspace, so noone should actually be reliably using them. 3) They're not even mentioned in any of the mxser utilities. So remove all these mxser-special ioctls: MOXA_ASPP_MON, MOXA_ASPP_MON_EXT, and MOXA_SDS_RSTICOUNTER. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-25-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 184 -------------------------------------------- 1 file changed, 184 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index cf3b8f9f7e1e..68c2f2346dcf 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -63,11 +63,8 @@ #define RS485_4WIRE_MODE 3 #define OP_MODE_MASK 3 -#define MOXA_SDS_RSTICOUNTER (MOXA + 69) #define MOXA_ASPP_OQUEUE (MOXA + 70) -#define MOXA_ASPP_MON (MOXA + 73) #define MOXA_ASPP_LSTATUS (MOXA + 74) -#define MOXA_ASPP_MON_EXT (MOXA + 75) /* --------------------------------------------------- */ @@ -77,11 +74,6 @@ #define NPPI_NOTIFY_SW_OVERRUN 0x08 #define NPPI_NOTIFY_BREAK 0x10 -#define NPPI_NOTIFY_CTSHOLD 0x01 /* Tx hold by CTS low */ -#define NPPI_NOTIFY_DSRHOLD 0x02 /* Tx hold by DSR low */ -#define NPPI_NOTIFY_XOFFHOLD 0x08 /* Tx hold by Xoff received */ -#define NPPI_NOTIFY_XOFFXENT 0x10 /* Xoff Sent */ - /* * Follow just what Moxa Must chip defines. * @@ -290,31 +282,6 @@ struct mxser_log { unsigned long txcnt[MXSER_PORTS]; }; -struct mxser_mon { - unsigned long rxcnt; - unsigned long txcnt; - unsigned long up_rxcnt; - unsigned long up_txcnt; - int modem_status; - unsigned char hold_reason; -}; - -struct mxser_mon_ext { - unsigned long rx_cnt[32]; - unsigned long tx_cnt[32]; - unsigned long up_rxcnt[32]; - unsigned long up_txcnt[32]; - int modem_status[32]; - - long baudrate[32]; - int databits[32]; - int stopbits[32]; - int parity[32]; - int flowctrl[32]; - int fifo[32]; - int iftype[32]; -}; - struct mxser_board; struct mxser_port { @@ -352,8 +319,6 @@ struct mxser_port { struct ktermios normal_termios; - struct mxser_mon mon_data; - spinlock_t slock; }; @@ -616,22 +581,6 @@ static void process_txrx_fifo(struct mxser_port *info) } } -static unsigned char mxser_get_msr(int baseaddr, int mode, int port) -{ - static unsigned char mxser_msr[MXSER_PORTS + 1]; - unsigned char status = 0; - - status = inb(baseaddr + UART_MSR); - - mxser_msr[port] &= 0x0F; - mxser_msr[port] |= status; - status = mxser_msr[port]; - if (mode) - mxser_msr[port] = 0; - - return status; -} - static int mxser_carrier_raised(struct tty_port *port) { struct mxser_port *mp = container_of(port, struct mxser_port, port); @@ -903,7 +852,6 @@ static void mxser_check_modem_status(struct tty_struct *tty, port->icount.dcd++; if (status & UART_MSR_DCTS) port->icount.cts++; - port->mon_data.modem_status = status; wake_up_interruptible(&port->port.delta_msr_wait); if (tty_port_check_carrier(&port->port) && (status & UART_MSR_DDCD)) { @@ -1544,93 +1492,6 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) } return 0; } - case MOXA_ASPP_MON_EXT: { - struct mxser_mon_ext *me; /* it's 2k, stack unfriendly */ - unsigned int cflag, iflag, p; - u8 opmode; - - me = kzalloc(sizeof(*me), GFP_KERNEL); - if (!me) - return -ENOMEM; - - for (i = 0, p = 0; i < MXSER_BOARDS; i++) { - for (j = 0; j < MXSER_PORTS_PER_BOARD; j++, p++) { - if (p >= ARRAY_SIZE(me->rx_cnt)) { - i = MXSER_BOARDS; - break; - } - ip = &mxser_boards[i].ports[j]; - port = &ip->port; - - mutex_lock(&port->mutex); - if (!ip->ioaddr) { - mutex_unlock(&port->mutex); - continue; - } - - spin_lock_irq(&ip->slock); - status = mxser_get_msr(ip->ioaddr, 0, p); - - if (status & UART_MSR_TERI) - ip->icount.rng++; - if (status & UART_MSR_DDSR) - ip->icount.dsr++; - if (status & UART_MSR_DDCD) - ip->icount.dcd++; - if (status & UART_MSR_DCTS) - ip->icount.cts++; - - ip->mon_data.modem_status = status; - me->rx_cnt[p] = ip->mon_data.rxcnt; - me->tx_cnt[p] = ip->mon_data.txcnt; - me->up_rxcnt[p] = ip->mon_data.up_rxcnt; - me->up_txcnt[p] = ip->mon_data.up_txcnt; - me->modem_status[p] = - ip->mon_data.modem_status; - spin_unlock_irq(&ip->slock); - - tty = tty_port_tty_get(&ip->port); - - if (!tty) { - cflag = ip->normal_termios.c_cflag; - iflag = ip->normal_termios.c_iflag; - me->baudrate[p] = tty_termios_baud_rate(&ip->normal_termios); - } else { - cflag = tty->termios.c_cflag; - iflag = tty->termios.c_iflag; - me->baudrate[p] = tty_get_baud_rate(tty); - } - tty_kref_put(tty); - - me->databits[p] = cflag & CSIZE; - me->stopbits[p] = cflag & CSTOPB; - me->parity[p] = cflag & (PARENB | PARODD | - CMSPAR); - - if (cflag & CRTSCTS) - me->flowctrl[p] |= 0x03; - - if (iflag & (IXON | IXOFF)) - me->flowctrl[p] |= 0x0C; - - if (ip->type == PORT_16550A) - me->fifo[p] = 1; - - if (ip->board->must_hwid == MOXA_MUST_MU860_HWID) { - opmode = inb(ip->opmode_ioaddr)>>((p % 4) * 2); - opmode &= OP_MODE_MASK; - } else { - opmode = RS232_MODE; - } - me->iftype[p] = opmode; - mutex_unlock(&port->mutex); - } - } - if (copy_to_user(argp, me, sizeof(*me))) - ret = -EFAULT; - kfree(me); - return ret; - } default: return -ENOIOCTLCMD; } @@ -1729,13 +1590,6 @@ static int mxser_ioctl(struct tty_struct *tty, mxser_cflags_changed(info, arg, &cnow)); case MOXA_HighSpeedOn: return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp); - case MOXA_SDS_RSTICOUNTER: - spin_lock_irq(&info->slock); - info->mon_data.rxcnt = 0; - info->mon_data.txcnt = 0; - spin_unlock_irq(&info->slock); - return 0; - case MOXA_ASPP_OQUEUE:{ int len, lsr; @@ -1747,37 +1601,6 @@ static int mxser_ioctl(struct tty_struct *tty, return put_user(len, (int __user *)argp); } - case MOXA_ASPP_MON: { - int mcr, status; - - spin_lock_irq(&info->slock); - status = mxser_get_msr(info->ioaddr, 1, tty->index); - mxser_check_modem_status(tty, info, status); - - mcr = inb(info->ioaddr + UART_MCR); - spin_unlock_irq(&info->slock); - - if (mcr & MOXA_MUST_MCR_XON_FLAG) - info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFHOLD; - else - info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFHOLD; - - if (mcr & MOXA_MUST_MCR_TX_XON) - info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFXENT; - else - info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT; - - if (tty->hw_stopped) - info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; - else - info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; - - if (copy_to_user(argp, &info->mon_data, - sizeof(struct mxser_mon))) - return -EFAULT; - - return 0; - } case MOXA_ASPP_LSTATUS: { if (put_user(info->err_shadow, (unsigned char __user *)argp)) return -EFAULT; @@ -2135,8 +1958,6 @@ static u8 mxser_receive_chars(struct tty_struct *tty, status = mxser_receive_chars_old(tty, port, status, &cnt); mxvar_log.rxcnt[tty->index] += cnt; - port->mon_data.rxcnt += cnt; - port->mon_data.up_rxcnt += cnt; tty_flip_buffer_push(&port->port); @@ -2151,8 +1972,6 @@ static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port outb(port->x_char, port->ioaddr + UART_TX); port->x_char = 0; mxvar_log.txcnt[tty->index]++; - port->mon_data.txcnt++; - port->mon_data.up_txcnt++; port->icount.tx++; return; } @@ -2180,8 +1999,6 @@ static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port } while (--count > 0); mxvar_log.txcnt[tty->index] += (cnt - port->xmit_cnt); - port->mon_data.txcnt += (cnt - port->xmit_cnt); - port->mon_data.up_txcnt += (cnt - port->xmit_cnt); port->icount.tx += (cnt - port->xmit_cnt); if (port->xmit_cnt < WAKEUP_CHARS) @@ -2355,7 +2172,6 @@ static int mxser_initbrd(struct mxser_board *brd) info->port.close_delay = 5 * HZ / 10; info->port.closing_wait = 30 * HZ; info->normal_termios = mxvar_sdriver->init_termios; - memset(&info->mon_data, 0, sizeof(struct mxser_mon)); info->err_shadow = 0; spin_lock_init(&info->slock); From 489435e4abc01682d4da31c9666e2e251e697182 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:31 +0200 Subject: [PATCH 170/227] mxser: remove MOXA_ASPP_LSTATUS ioctl 1) The semantics are defined exactly nowhere. 2) The ioctl definition was never exposed to userspace, so noone should actually be reliably using this. 3) It's not even mentioned in any of the mxser utilities. Provided the above, remove this mxser-special ioctl. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-26-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 68c2f2346dcf..38e12ff17529 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -64,16 +64,9 @@ #define OP_MODE_MASK 3 #define MOXA_ASPP_OQUEUE (MOXA + 70) -#define MOXA_ASPP_LSTATUS (MOXA + 74) /* --------------------------------------------------- */ -#define NPPI_NOTIFY_PARITY 0x01 -#define NPPI_NOTIFY_FRAMING 0x02 -#define NPPI_NOTIFY_HW_OVERRUN 0x04 -#define NPPI_NOTIFY_SW_OVERRUN 0x08 -#define NPPI_NOTIFY_BREAK 0x10 - /* * Follow just what Moxa Must chip defines. * @@ -304,7 +297,6 @@ struct mxser_port { unsigned char ldisc_stop_rx; int custom_divisor; - unsigned char err_shadow; struct async_icount icount; /* kernel counters for 4 input interrupts */ unsigned int timeout; @@ -1601,13 +1593,6 @@ static int mxser_ioctl(struct tty_struct *tty, return put_user(len, (int __user *)argp); } - case MOXA_ASPP_LSTATUS: { - if (put_user(info->err_shadow, (unsigned char __user *)argp)) - return -EFAULT; - - info->err_shadow = 0; - return 0; - } default: return -ENOIOCTLCMD; } @@ -2033,15 +2018,6 @@ static bool mxser_port_isr(struct mxser_port *port) status = inb(port->ioaddr + UART_LSR); - if (status & UART_LSR_PE) - port->err_shadow |= NPPI_NOTIFY_PARITY; - if (status & UART_LSR_FE) - port->err_shadow |= NPPI_NOTIFY_FRAMING; - if (status & UART_LSR_OE) - port->err_shadow |= NPPI_NOTIFY_HW_OVERRUN; - if (status & UART_LSR_BI) - port->err_shadow |= NPPI_NOTIFY_BREAK; - if (port->board->must_hwid) { if (iir == MOXA_MUST_IIR_GDA || iir == MOXA_MUST_IIR_RDA || @@ -2172,7 +2148,6 @@ static int mxser_initbrd(struct mxser_board *brd) info->port.close_delay = 5 * HZ / 10; info->port.closing_wait = 30 * HZ; info->normal_termios = mxvar_sdriver->init_termios; - info->err_shadow = 0; spin_lock_init(&info->slock); /* before set INT ISR, disable all int */ From a1ebc3794e9c737efdaafaeefc054ce473b0751d Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:32 +0200 Subject: [PATCH 171/227] mxser: remove MOXA_CHKPORTENABLE ioctl 1) MOXA_CHKPORTENABLE is broken at least since commit ecbbfd44a08f (TTY: move tty buffers to tty_port) in 2012. 2) The ioctl definition was never exposed to userspace, so noone should actually be reliably using this. 3) It's not even mentioned in any of the mxser utilities. Provided the above, remove this mxser-special ioctl. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-27-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 38e12ff17529..ebe657426636 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -51,7 +51,6 @@ #define MOXA 0x400 #define MOXA_GETDATACOUNT (MOXA + 23) -#define MOXA_CHKPORTENABLE (MOXA + 60) #define MOXA_HighSpeedOn (MOXA + 61) #define MOXA_GETMSTATUS (MOXA + 65) #define MOXA_SET_OP_MODE (MOXA + 66) @@ -1430,18 +1429,11 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) struct mxser_port *ip; struct tty_port *port; struct tty_struct *tty; - int result, status; + int status; unsigned int i, j; int ret = 0; switch (cmd) { - case MOXA_CHKPORTENABLE: - result = 0; - for (i = 0; i < MXSER_BOARDS; i++) - for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) - if (mxser_boards[i].ports[j].ioaddr) - result |= (1 << i); - return put_user(result, (unsigned long __user *)argp); case MOXA_GETDATACOUNT: /* The receive side is locked by port->slock but it isn't clear that an exact snapshot is worth copying here */ From 476c351db8f0e8a837c144a916b23b3abf5a655b Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:33 +0200 Subject: [PATCH 172/227] mxser: remove MOXA_GETDATACOUNT ioctl 1) MOXA_GETDATACOUNT is broken at least since commit ecbbfd44a08f (TTY: move tty buffers to tty_port) in 2012. Even though it's mentioned in the mon_p moxa utility, obviously noone ever tried that in that timeframe. 2) The ioctl definition was never exposed to userspace, so noone should actually be reliably using this. Provided the above, remove this mxser-special ioctl. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-28-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index ebe657426636..9e241f8bd814 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -50,7 +50,6 @@ */ #define MOXA 0x400 -#define MOXA_GETDATACOUNT (MOXA + 23) #define MOXA_HighSpeedOn (MOXA + 61) #define MOXA_GETMSTATUS (MOXA + 65) #define MOXA_SET_OP_MODE (MOXA + 66) @@ -268,12 +267,6 @@ MODULE_DESCRIPTION("MOXA Smartio/Industio Family Multiport Board Device Driver") module_param(ttymajor, int, 0); MODULE_LICENSE("GPL"); -struct mxser_log { - int tick; - unsigned long rxcnt[MXSER_PORTS]; - unsigned long txcnt[MXSER_PORTS]; -}; - struct mxser_board; struct mxser_port { @@ -335,7 +328,6 @@ struct mxser_mstatus { static struct mxser_board mxser_boards[MXSER_BOARDS]; static struct tty_driver *mxvar_sdriver; -static struct mxser_log mxvar_log; static void mxser_enable_must_enchance_mode(unsigned long baseio) { @@ -1431,15 +1423,8 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) struct tty_struct *tty; int status; unsigned int i, j; - int ret = 0; switch (cmd) { - case MOXA_GETDATACOUNT: - /* The receive side is locked by port->slock but it isn't - clear that an exact snapshot is worth copying here */ - if (copy_to_user(argp, &mxvar_log, sizeof(mxvar_log))) - ret = -EFAULT; - return ret; case MOXA_GETMSTATUS: { struct mxser_mstatus ms, __user *msu = argp; for (i = 0; i < MXSER_BOARDS; i++) @@ -1934,8 +1919,6 @@ static u8 mxser_receive_chars(struct tty_struct *tty, if (!mxser_receive_chars_new(tty, port, status, &cnt)) status = mxser_receive_chars_old(tty, port, status, &cnt); - mxvar_log.rxcnt[tty->index] += cnt; - tty_flip_buffer_push(&port->port); return status; @@ -1948,7 +1931,6 @@ static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port if (port->x_char) { outb(port->x_char, port->ioaddr + UART_TX); port->x_char = 0; - mxvar_log.txcnt[tty->index]++; port->icount.tx++; return; } @@ -1974,7 +1956,6 @@ static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port if (--port->xmit_cnt <= 0) break; } while (--count > 0); - mxvar_log.txcnt[tty->index] += (cnt - port->xmit_cnt); port->icount.tx += (cnt - port->xmit_cnt); From c94deae5b708b21727eae5bc830cb176c05ec2e8 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:34 +0200 Subject: [PATCH 173/227] mxser: remove MOXA_GETMSTATUS ioctl 1) MOXA_GETMSTATUS is broken at least since commit ecbbfd44a08f (TTY: move tty buffers to tty_port) in 2012. Even though it's mentioned in the mon_pa moxa utility, obviously noone ever tried that in that timeframe. 2) The ioctl definition was never exposed to userspace, so noone should actually be reliably using this. Provided the above, remove this mxser-special ioctl. And remove the whole concept of mxser_ioctl_special as this was the last ioctl in there. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-29-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 62 +-------------------------------------------- 1 file changed, 1 insertion(+), 61 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 9e241f8bd814..1eb48141d6ca 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -51,7 +51,6 @@ #define MOXA 0x400 #define MOXA_HighSpeedOn (MOXA + 61) -#define MOXA_GETMSTATUS (MOXA + 65) #define MOXA_SET_OP_MODE (MOXA + 66) #define MOXA_GET_OP_MODE (MOXA + 67) @@ -318,14 +317,6 @@ struct mxser_board { struct mxser_port ports[MXSER_PORTS_PER_BOARD]; }; -struct mxser_mstatus { - tcflag_t cflag; - int cts; - int dsr; - int ri; - int dcd; -}; - static struct mxser_board mxser_boards[MXSER_BOARDS]; static struct tty_driver *mxvar_sdriver; @@ -1416,57 +1407,6 @@ static int mxser_tiocmset(struct tty_struct *tty, return 0; } -static int mxser_ioctl_special(unsigned int cmd, void __user *argp) -{ - struct mxser_port *ip; - struct tty_port *port; - struct tty_struct *tty; - int status; - unsigned int i, j; - - switch (cmd) { - case MOXA_GETMSTATUS: { - struct mxser_mstatus ms, __user *msu = argp; - for (i = 0; i < MXSER_BOARDS; i++) - for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) { - ip = &mxser_boards[i].ports[j]; - port = &ip->port; - memset(&ms, 0, sizeof(ms)); - - mutex_lock(&port->mutex); - if (!ip->ioaddr) - goto copy; - - tty = tty_port_tty_get(port); - - if (!tty) - ms.cflag = ip->normal_termios.c_cflag; - else - ms.cflag = tty->termios.c_cflag; - tty_kref_put(tty); - spin_lock_irq(&ip->slock); - status = inb(ip->ioaddr + UART_MSR); - spin_unlock_irq(&ip->slock); - if (status & UART_MSR_DCD) - ms.dcd = 1; - if (status & UART_MSR_DSR) - ms.dsr = 1; - if (status & UART_MSR_CTS) - ms.cts = 1; - copy: - mutex_unlock(&port->mutex); - if (copy_to_user(msu, &ms, sizeof(ms))) - return -EFAULT; - msu++; - } - return 0; - } - default: - return -ENOIOCTLCMD; - } - return 0; -} - static int mxser_cflags_changed(struct mxser_port *info, unsigned long arg, struct async_icount *cprev) { @@ -1497,7 +1437,7 @@ static int mxser_ioctl(struct tty_struct *tty, void __user *argp = (void __user *)arg; if (tty->index == MXSER_PORTS) - return mxser_ioctl_special(cmd, argp); + return -ENOTTY; if (cmd == MOXA_SET_OP_MODE || cmd == MOXA_GET_OP_MODE) { int p; From a7574ca74a6e9021f6a058aa21dab84e552cab22 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:35 +0200 Subject: [PATCH 174/227] mxser: remove MOXA_ASPP_OQUEUE ioctl 1) The semantics are defined exactly nowhere. 2) The ioctl definition was never exposed to userspace, so noone should actually be reliably using this. 3) It's not even mentioned in any of the mxser utilities. Provided the above, remove this mxser-special ioctl. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-30-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 1eb48141d6ca..ca417d9a03cf 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -60,8 +60,6 @@ #define RS485_4WIRE_MODE 3 #define OP_MODE_MASK 3 -#define MOXA_ASPP_OQUEUE (MOXA + 70) - /* --------------------------------------------------- */ /* @@ -1499,17 +1497,6 @@ static int mxser_ioctl(struct tty_struct *tty, mxser_cflags_changed(info, arg, &cnow)); case MOXA_HighSpeedOn: return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp); - case MOXA_ASPP_OQUEUE:{ - int len, lsr; - - len = mxser_chars_in_buffer(tty); - spin_lock_irq(&info->slock); - lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_THRE; - spin_unlock_irq(&info->slock); - len += (lsr ? 0 : 1); - - return put_user(len, (int __user *)argp); - } default: return -ENOIOCTLCMD; } From 47f82769181fdb755bc86aff881775357383ff68 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:36 +0200 Subject: [PATCH 175/227] mxser: remove MOXA_HighSpeedOn ioctl 1) The semantics are defined exactly nowhere. 2) The ioctl definition was never exposed to userspace, so noone should actually be reliably using this. 3) It's not even mentioned in any of the mxser utilities. Provided the above, remove this mxser-special ioctl. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-31-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index ca417d9a03cf..586fa3575673 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -50,7 +50,6 @@ */ #define MOXA 0x400 -#define MOXA_HighSpeedOn (MOXA + 61) #define MOXA_SET_OP_MODE (MOXA + 66) #define MOXA_GET_OP_MODE (MOXA + 67) @@ -1495,8 +1494,6 @@ static int mxser_ioctl(struct tty_struct *tty, return wait_event_interruptible(info->port.delta_msr_wait, mxser_cflags_changed(info, arg, &cnow)); - case MOXA_HighSpeedOn: - return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp); default: return -ENOIOCTLCMD; } From 95b3ea4c6f45f3172dae29f303579743c2aa303d Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:37 +0200 Subject: [PATCH 176/227] mxser: remove cnt from mxser_receive_chars After the previous ioctls removal, cnt is needed only in mxser_receive_chars_old now. So remove it from mxser_receive_chars and mxser_receive_chars_new and account only in mxser_receive_chars_old. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-32-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 586fa3575673..d354c80083fd 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -1743,7 +1743,7 @@ static int mxser_rs_break(struct tty_struct *tty, int break_state) } static bool mxser_receive_chars_new(struct tty_struct *tty, - struct mxser_port *port, u8 status, int *cnt) + struct mxser_port *port, u8 status) { enum mxser_must_hwid hwid = port->board->must_hwid; u8 gdl; @@ -1767,19 +1767,19 @@ static bool mxser_receive_chars_new(struct tty_struct *tty, while (gdl--) { u8 ch = inb(port->ioaddr + UART_RX); tty_insert_flip_char(&port->port, ch, 0); - (*cnt)++; } return true; } static u8 mxser_receive_chars_old(struct tty_struct *tty, - struct mxser_port *port, u8 status, int *cnt) + struct mxser_port *port, u8 status) { enum mxser_must_hwid hwid = port->board->must_hwid; int recv_room = tty->receive_room; int ignored = 0; int max = 256; + int cnt = 0; u8 ch; do { @@ -1814,8 +1814,8 @@ static u8 mxser_receive_chars_old(struct tty_struct *tty, } } tty_insert_flip_char(&port->port, ch, flag); - (*cnt)++; - if (*cnt >= recv_room) { + cnt++; + if (cnt >= recv_room) { if (!port->ldisc_stop_rx) mxser_stoprx(tty); break; @@ -1835,13 +1835,11 @@ static u8 mxser_receive_chars_old(struct tty_struct *tty, static u8 mxser_receive_chars(struct tty_struct *tty, struct mxser_port *port, u8 status) { - int cnt = 0; - if (tty->receive_room == 0 && !port->ldisc_stop_rx) mxser_stoprx(tty); - if (!mxser_receive_chars_new(tty, port, status, &cnt)) - status = mxser_receive_chars_old(tty, port, status, &cnt); + if (!mxser_receive_chars_new(tty, port, status)) + status = mxser_receive_chars_old(tty, port, status); tty_flip_buffer_push(&port->port); From 389fc82e475be8f6c1745f804470bea5e3bf7dc1 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:38 +0200 Subject: [PATCH 177/227] mxser: don't allocate MXSER_PORTS + 1 The MXSER_PORTS's tty_device is never registered and neither its tty_port instance exists. Hence, it's quite pointless to allocate it. It used to be used for global information fetches via ioctls. We have just removed these as non-existent tty_device+tty_port was exactly the reason to remove the ioctls. It would be peculiar to add this "virtual" port as we require a backing tty_port since commit ecbbfd44a08f (TTY: move tty buffers to tty_port) in 2012. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-33-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index d354c80083fd..007137c3b5c9 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -1004,11 +1004,8 @@ static void mxser_shutdown_port(struct tty_port *port) static int mxser_open(struct tty_struct *tty, struct file *filp) { struct mxser_port *info; - int line; + int line = tty->index; - line = tty->index; - if (line == MXSER_PORTS) - return 0; info = &mxser_boards[line / MXSER_PORTS_PER_BOARD].ports[line % MXSER_PORTS_PER_BOARD]; if (!info->ioaddr) return -ENODEV; @@ -1077,7 +1074,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) struct mxser_port *info = tty->driver_data; struct tty_port *port = &info->port; - if (tty->index == MXSER_PORTS || info == NULL) + if (info == NULL) return; if (tty_port_close_start(port, tty, filp) == 0) return; @@ -1216,9 +1213,6 @@ static int mxser_get_serial_info(struct tty_struct *tty, struct tty_port *port = &info->port; unsigned int closing_wait, close_delay; - if (tty->index == MXSER_PORTS) - return -ENOTTY; - mutex_lock(&port->mutex); close_delay = jiffies_to_msecs(info->port.close_delay) / 10; @@ -1249,8 +1243,6 @@ static int mxser_set_serial_info(struct tty_struct *tty, unsigned int flags, close_delay, closing_wait; int retval = 0; - if (tty->index == MXSER_PORTS) - return -ENOTTY; if (tty_io_error(tty)) return -EIO; @@ -1354,9 +1346,6 @@ static int mxser_tiocmget(struct tty_struct *tty) unsigned char control, status; unsigned long flags; - - if (tty->index == MXSER_PORTS) - return -ENOIOCTLCMD; if (tty_io_error(tty)) return -EIO; @@ -1381,9 +1370,6 @@ static int mxser_tiocmset(struct tty_struct *tty, struct mxser_port *info = tty->driver_data; unsigned long flags; - - if (tty->index == MXSER_PORTS) - return -ENOIOCTLCMD; if (tty_io_error(tty)) return -EIO; @@ -1433,9 +1419,6 @@ static int mxser_ioctl(struct tty_struct *tty, unsigned long flags; void __user *argp = (void __user *)arg; - if (tty->index == MXSER_PORTS) - return -ENOTTY; - if (cmd == MOXA_SET_OP_MODE || cmd == MOXA_GET_OP_MODE) { int p; unsigned long opmode; @@ -2211,7 +2194,7 @@ static int __init mxser_module_init(void) { int retval; - mxvar_sdriver = alloc_tty_driver(MXSER_PORTS + 1); + mxvar_sdriver = alloc_tty_driver(MXSER_PORTS); if (!mxvar_sdriver) return -ENOMEM; From cc673990292c21c4bc02461e362d920fe8a7858b Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:39 +0200 Subject: [PATCH 178/227] mxser: drop unused mxser_port::normal_termios After the previous patches, mxser_port::normal_termios is unused, so time to wave bye-bye. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-34-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 007137c3b5c9..e10fbe7270c9 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -297,8 +297,6 @@ struct mxser_port { unsigned int xmit_cnt; int closing; - struct ktermios normal_termios; - spinlock_t slock; }; @@ -2025,7 +2023,6 @@ static int mxser_initbrd(struct mxser_board *brd) info->custom_divisor = info->baud_base * 16; info->port.close_delay = 5 * HZ / 10; info->port.closing_wait = 30 * HZ; - info->normal_termios = mxvar_sdriver->init_termios; spin_lock_init(&info->slock); /* before set INT ISR, disable all int */ From 01c3de9a10bb917b50d98f5565fb50dcafd1239a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:40 +0200 Subject: [PATCH 179/227] mxser: remove unused mxser_port::stop_rx It's been a long time since mxser_port::stop_rx was abandoned. Remove it. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-35-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index e10fbe7270c9..b47b17ec1f12 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -281,7 +281,6 @@ struct mxser_port { u8 IER; /* Interrupt Enable Register */ u8 MCR; /* Modem control register */ - unsigned char stop_rx; unsigned char ldisc_stop_rx; int custom_divisor; @@ -2009,7 +2008,6 @@ static int mxser_initbrd(struct mxser_board *brd) tty_port_init(&info->port); info->port.ops = &mxser_port_ops; info->board = brd; - info->stop_rx = 0; info->ldisc_stop_rx = 0; /* Enhance mode enabled here */ From a6970c39c311f393c2a2b43733e1b4ce2b241f53 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:41 +0200 Subject: [PATCH 180/227] mxser: drop mxser_port::baud_base It's an once-set constant, so define a macro for the constant (MXSER_BAUD_BASE) and use it in the code instead. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-36-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index b47b17ec1f12..204b71c4d1ae 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -156,6 +156,8 @@ #define WAKEUP_CHARS 256 +#define MXSER_BAUD_BASE 921600 + #define PCI_DEVICE_ID_POS104UL 0x1044 #define PCI_DEVICE_ID_CB108 0x1080 #define PCI_DEVICE_ID_CP102UF 0x1023 @@ -274,7 +276,6 @@ struct mxser_port { u8 rx_high_water; u8 rx_low_water; - int baud_base; /* max. speed */ int type; /* UART type */ unsigned char x_char; /* xon/xoff character */ @@ -584,13 +585,13 @@ static int mxser_set_baud(struct tty_struct *tty, speed_t newspd) return -1; if (newspd == 134) { - quot = 2 * info->baud_base / 269; + quot = 2 * MXSER_BAUD_BASE / 269; tty_encode_baud_rate(tty, 134, 134); } else if (newspd) { - quot = info->baud_base / newspd; + quot = MXSER_BAUD_BASE / newspd; if (quot == 0) quot = 1; - baud = info->baud_base/quot; + baud = MXSER_BAUD_BASE / quot; tty_encode_baud_rate(tty, baud, baud); } else { quot = 0; @@ -601,7 +602,7 @@ static int mxser_set_baud(struct tty_struct *tty, speed_t newspd) * u64 domain */ timeout = (u64)info->xmit_fifo_size * HZ * 10 * quot; - do_div(timeout, info->baud_base); + do_div(timeout, MXSER_BAUD_BASE); info->timeout = timeout + HZ / 50; /* Add .02 seconds of slop */ if (quot) { @@ -623,7 +624,7 @@ static int mxser_set_baud(struct tty_struct *tty, speed_t newspd) #ifdef BOTHER if (C_BAUD(tty) == BOTHER) { - quot = info->baud_base % newspd; + quot = MXSER_BAUD_BASE % newspd; quot *= 8; if (quot % newspd > newspd / 2) { quot /= newspd; @@ -1222,7 +1223,7 @@ static int mxser_get_serial_info(struct tty_struct *tty, ss->port = info->ioaddr, ss->irq = info->board->irq, ss->flags = info->port.flags, - ss->baud_base = info->baud_base, + ss->baud_base = MXSER_BAUD_BASE, ss->close_delay = close_delay; ss->closing_wait = closing_wait; ss->custom_divisor = info->custom_divisor, @@ -1263,7 +1264,7 @@ static int mxser_set_serial_info(struct tty_struct *tty, closing_wait = msecs_to_jiffies(closing_wait * 10); if (!capable(CAP_SYS_ADMIN)) { - if ((ss->baud_base != info->baud_base) || + if ((ss->baud_base != MXSER_BAUD_BASE) || (close_delay != info->port.close_delay) || (closing_wait != info->port.closing_wait) || ((ss->flags & ~ASYNC_USR_MASK) != (info->port.flags & ~ASYNC_USR_MASK))) { @@ -1282,7 +1283,7 @@ static int mxser_set_serial_info(struct tty_struct *tty, port->close_delay = close_delay; port->closing_wait = closing_wait; if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && - (ss->baud_base != info->baud_base || + (ss->baud_base != MXSER_BAUD_BASE || ss->custom_divisor != info->custom_divisor)) { if (ss->custom_divisor == 0) { @@ -2018,7 +2019,7 @@ static int mxser_initbrd(struct mxser_board *brd) process_txrx_fifo(info); - info->custom_divisor = info->baud_base * 16; + info->custom_divisor = MXSER_BAUD_BASE * 16; info->port.close_delay = 5 * HZ / 10; info->port.closing_wait = 30 * HZ; spin_lock_init(&info->slock); @@ -2127,10 +2128,6 @@ static int mxser_probe(struct pci_dev *pdev, outb(0, ioaddress + 0x0c); /* default set to RS232 mode */ } - for (i = 0; i < brd->info->nports; i++) { - brd->ports[i].baud_base = 921600; - } - /* mxser_initbrd will hook ISR. */ retval = mxser_initbrd(brd); if (retval) From d811b26ba3a78d45ccfc8e562323d9104d321c87 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:42 +0200 Subject: [PATCH 181/227] mxser: drop mxser_port::custom_divisor It's an once-set constant, so define a macro for the constant (MXSER_CUSTOM_DIVISOR) and use it in the code instead. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-37-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 204b71c4d1ae..c4ee5cb6952e 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -157,6 +157,7 @@ #define WAKEUP_CHARS 256 #define MXSER_BAUD_BASE 921600 +#define MXSER_CUSTOM_DIVISOR (MXSER_BAUD_BASE * 16) #define PCI_DEVICE_ID_POS104UL 0x1044 #define PCI_DEVICE_ID_CB108 0x1080 @@ -284,8 +285,6 @@ struct mxser_port { unsigned char ldisc_stop_rx; - int custom_divisor; - struct async_icount icount; /* kernel counters for 4 input interrupts */ unsigned int timeout; @@ -1226,7 +1225,7 @@ static int mxser_get_serial_info(struct tty_struct *tty, ss->baud_base = MXSER_BAUD_BASE, ss->close_delay = close_delay; ss->closing_wait = closing_wait; - ss->custom_divisor = info->custom_divisor, + ss->custom_divisor = MXSER_CUSTOM_DIVISOR, mutex_unlock(&port->mutex); return 0; } @@ -1285,7 +1284,7 @@ static int mxser_set_serial_info(struct tty_struct *tty, if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && (ss->baud_base != MXSER_BAUD_BASE || ss->custom_divisor != - info->custom_divisor)) { + MXSER_CUSTOM_DIVISOR)) { if (ss->custom_divisor == 0) { mutex_unlock(&port->mutex); return -EINVAL; @@ -2019,7 +2018,6 @@ static int mxser_initbrd(struct mxser_board *brd) process_txrx_fifo(info); - info->custom_divisor = MXSER_BAUD_BASE * 16; info->port.close_delay = 5 * HZ / 10; info->port.closing_wait = 30 * HZ; spin_lock_init(&info->slock); From 2c21832b55dd6f2c5be48133997b6614c1e6327b Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:43 +0200 Subject: [PATCH 182/227] mxser: cleanup mxser_change_speed * use UART macros instead of magic constants * let the default case reuse already existing code (CS5 case) Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-38-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index c4ee5cb6952e..2a8bbce790f3 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -657,24 +657,23 @@ static void mxser_change_speed(struct tty_struct *tty) /* byte size and parity */ switch (cflag & CSIZE) { + default: case CS5: - cval = 0x00; + cval = UART_LCR_WLEN5; break; case CS6: - cval = 0x01; + cval = UART_LCR_WLEN6; break; case CS7: - cval = 0x02; + cval = UART_LCR_WLEN7; break; case CS8: - cval = 0x03; + cval = UART_LCR_WLEN8; break; - default: - cval = 0x00; - break; /* too keep GCC shut... */ } + if (cflag & CSTOPB) - cval |= 0x04; + cval |= UART_LCR_STOP; if (cflag & PARENB) cval |= UART_LCR_PARITY; if (!(cflag & PARODD)) From 9fae5f857e124e843c7a41a04a49b3f9256a2d77 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:44 +0200 Subject: [PATCH 183/227] mxser: extract mxser_ioctl_op_mode This ioctl code sets RS232, RS422 or RS485 mode. Move the code to a separate function (mxser_ioctl_op_mode) with a note that these mxser-special ioctls should be likely replaced eventually by TIOCGRS485 and TIOCSRS485. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-39-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 83 ++++++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 38 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 2a8bbce790f3..4a584db09494 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -1407,6 +1407,48 @@ static int mxser_cflags_changed(struct mxser_port *info, unsigned long arg, return ret; } +/* We should likely switch to TIOCGRS485/TIOCSRS485. */ +static int mxser_ioctl_op_mode(struct mxser_port *port, int index, bool set, + int __user *u_opmode) +{ + static const unsigned char ModeMask[] = { 0xfc, 0xf3, 0xcf, 0x3f }; + int opmode, p = index % 4; + int shiftbit = p * 2; + unsigned char val, mask; + + if (port->board->must_hwid != MOXA_MUST_MU860_HWID) + return -EFAULT; + + if (set) { + if (get_user(opmode, u_opmode)) + return -EFAULT; + + if (opmode != RS232_MODE && opmode != RS485_2WIRE_MODE && + opmode != RS422_MODE && + opmode != RS485_4WIRE_MODE) + return -EFAULT; + + mask = ModeMask[p]; + + spin_lock_irq(&port->slock); + val = inb(port->opmode_ioaddr); + val &= mask; + val |= (opmode << shiftbit); + outb(val, port->opmode_ioaddr); + spin_unlock_irq(&port->slock); + } else { + spin_lock_irq(&port->slock); + opmode = inb(port->opmode_ioaddr) >> shiftbit; + spin_unlock_irq(&port->slock); + + opmode &= OP_MODE_MASK; + if (put_user(opmode, u_opmode)) + return -EFAULT; + } + + return 0; +} + static int mxser_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { @@ -1415,44 +1457,9 @@ static int mxser_ioctl(struct tty_struct *tty, unsigned long flags; void __user *argp = (void __user *)arg; - if (cmd == MOXA_SET_OP_MODE || cmd == MOXA_GET_OP_MODE) { - int p; - unsigned long opmode; - static unsigned char ModeMask[] = { 0xfc, 0xf3, 0xcf, 0x3f }; - int shiftbit; - unsigned char val, mask; - - if (info->board->must_hwid != MOXA_MUST_MU860_HWID) - return -EFAULT; - - p = tty->index % 4; - if (cmd == MOXA_SET_OP_MODE) { - if (get_user(opmode, (int __user *) argp)) - return -EFAULT; - if (opmode != RS232_MODE && - opmode != RS485_2WIRE_MODE && - opmode != RS422_MODE && - opmode != RS485_4WIRE_MODE) - return -EFAULT; - mask = ModeMask[p]; - shiftbit = p * 2; - spin_lock_irq(&info->slock); - val = inb(info->opmode_ioaddr); - val &= mask; - val |= (opmode << shiftbit); - outb(val, info->opmode_ioaddr); - spin_unlock_irq(&info->slock); - } else { - shiftbit = p * 2; - spin_lock_irq(&info->slock); - opmode = inb(info->opmode_ioaddr) >> shiftbit; - spin_unlock_irq(&info->slock); - opmode &= OP_MODE_MASK; - if (put_user(opmode, (int __user *)argp)) - return -EFAULT; - } - return 0; - } + if (cmd == MOXA_SET_OP_MODE || cmd == MOXA_GET_OP_MODE) + return mxser_ioctl_op_mode(info, tty->index, + cmd == MOXA_SET_OP_MODE, argp); if (cmd != TIOCMIWAIT && tty_io_error(tty)) return -EIO; From 238d117d17516f92f5db958809ddec30731e9342 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:45 +0200 Subject: [PATCH 184/227] mxser: simplify mxser_ioctl_op_mode * ModeMask local array is just inverted OP_MODE_MASK shifted by shiftbit. Drop this array and use the value directly. * return from the if's true branch and drop 'else' branch by moving the code completely outside the if. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-40-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 4a584db09494..e082ae055c39 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -1411,10 +1411,9 @@ static int mxser_cflags_changed(struct mxser_port *info, unsigned long arg, static int mxser_ioctl_op_mode(struct mxser_port *port, int index, bool set, int __user *u_opmode) { - static const unsigned char ModeMask[] = { 0xfc, 0xf3, 0xcf, 0x3f }; int opmode, p = index % 4; int shiftbit = p * 2; - unsigned char val, mask; + u8 val; if (port->board->must_hwid != MOXA_MUST_MU860_HWID) return -EFAULT; @@ -1423,30 +1422,24 @@ static int mxser_ioctl_op_mode(struct mxser_port *port, int index, bool set, if (get_user(opmode, u_opmode)) return -EFAULT; - if (opmode != RS232_MODE && opmode != RS485_2WIRE_MODE && - opmode != RS422_MODE && - opmode != RS485_4WIRE_MODE) - return -EFAULT; - - mask = ModeMask[p]; + if (opmode & ~OP_MODE_MASK) + return -EINVAL; spin_lock_irq(&port->slock); val = inb(port->opmode_ioaddr); - val &= mask; + val &= ~(OP_MODE_MASK << shiftbit); val |= (opmode << shiftbit); outb(val, port->opmode_ioaddr); spin_unlock_irq(&port->slock); - } else { - spin_lock_irq(&port->slock); - opmode = inb(port->opmode_ioaddr) >> shiftbit; - spin_unlock_irq(&port->slock); - opmode &= OP_MODE_MASK; - if (put_user(opmode, u_opmode)) - return -EFAULT; + return 0; } - return 0; + spin_lock_irq(&port->slock); + opmode = inb(port->opmode_ioaddr) >> shiftbit; + spin_unlock_irq(&port->slock); + + return put_user(opmode & OP_MODE_MASK, u_opmode); } static int mxser_ioctl(struct tty_struct *tty, From edb7d27cd10382b6fdb3af50873a04f108c4ee64 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:46 +0200 Subject: [PATCH 185/227] mxser: dedup mxser_must_set_enhance_mode There are multiple copies of setting the EFR register. Separate it to a new universal function called __mxser_must_set_EFR. And use it in the code by introducing mxser_must_set_enhance_mode instead of mxser_disable_must_enchance_mode and mxser_enable_must_enchance_mode. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-41-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index e082ae055c39..7caf369571f1 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -314,34 +314,24 @@ struct mxser_board { static struct mxser_board mxser_boards[MXSER_BOARDS]; static struct tty_driver *mxvar_sdriver; -static void mxser_enable_must_enchance_mode(unsigned long baseio) +static u8 __mxser_must_set_EFR(unsigned long baseio, u8 clear, u8 set, + bool restore_LCR) { - u8 oldlcr; - u8 efr; + u8 oldlcr, efr; oldlcr = inb(baseio + UART_LCR); outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); efr = inb(baseio + MOXA_MUST_EFR_REGISTER); - efr |= MOXA_MUST_EFR_EFRB_ENABLE; + efr &= ~clear; + efr |= set; outb(efr, baseio + MOXA_MUST_EFR_REGISTER); - outb(oldlcr, baseio + UART_LCR); -} -static void mxser_disable_must_enchance_mode(unsigned long baseio) -{ - u8 oldlcr; - u8 efr; + if (restore_LCR) + outb(oldlcr, baseio + UART_LCR); - oldlcr = inb(baseio + UART_LCR); - outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); - - efr = inb(baseio + MOXA_MUST_EFR_REGISTER); - efr &= ~MOXA_MUST_EFR_EFRB_ENABLE; - - outb(efr, baseio + MOXA_MUST_EFR_REGISTER); - outb(oldlcr, baseio + UART_LCR); + return oldlcr; } static void mxser_set_must_xon1_value(unsigned long baseio, u8 value) @@ -431,6 +421,18 @@ static void mxser_get_must_hardware_id(unsigned long baseio, u8 *pId) outb(oldlcr, baseio + UART_LCR); } +static void mxser_must_set_EFR(unsigned long baseio, u8 clear, u8 set) +{ + __mxser_must_set_EFR(baseio, clear, set, true); +} + +static void mxser_must_set_enhance_mode(unsigned long baseio, bool enable) +{ + mxser_must_set_EFR(baseio, + enable ? 0 : MOXA_MUST_EFR_EFRB_ENABLE, + enable ? MOXA_MUST_EFR_EFRB_ENABLE : 0); +} + static void SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(unsigned long baseio) { u8 oldlcr; @@ -514,7 +516,7 @@ static enum mxser_must_hwid mxser_must_get_hwid(unsigned long io) int i; outb(0, io + UART_LCR); - mxser_disable_must_enchance_mode(io); + mxser_must_set_enhance_mode(io, false); oldmcr = inb(io + UART_MCR); outb(0, io + UART_MCR); mxser_set_must_xon1_value(io, 0x11); @@ -2011,7 +2013,7 @@ static int mxser_initbrd(struct mxser_board *brd) /* Enhance mode enabled here */ if (brd->must_hwid != MOXA_OTHER_UART) - mxser_enable_must_enchance_mode(info->ioaddr); + mxser_must_set_enhance_mode(info->ioaddr, true); info->type = PORT_16550A; From b286484b3bb1d01dfd6095f01c8ad04b78f1a625 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:47 +0200 Subject: [PATCH 186/227] mxser: introduce mxser_must_select_bank and use it Again, selecting a bank in the EFR register is duplicated many times. Extract it to a separate function (mxser_must_select_bank) and use it on all the places. This cleans up most of the helpers. And mxser_get_must_hardware_id now returns the HW ID directly, not via a by-reference parameter. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-42-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 74 ++++++++++----------------------------------- 1 file changed, 16 insertions(+), 58 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 7caf369571f1..392aee47c803 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -334,53 +334,29 @@ static u8 __mxser_must_set_EFR(unsigned long baseio, u8 clear, u8 set, return oldlcr; } +static u8 mxser_must_select_bank(unsigned long baseio, u8 bank) +{ + return __mxser_must_set_EFR(baseio, MOXA_MUST_EFR_BANK_MASK, bank, + false); +} + static void mxser_set_must_xon1_value(unsigned long baseio, u8 value) { - u8 oldlcr; - u8 efr; - - oldlcr = inb(baseio + UART_LCR); - outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); - - efr = inb(baseio + MOXA_MUST_EFR_REGISTER); - efr &= ~MOXA_MUST_EFR_BANK_MASK; - efr |= MOXA_MUST_EFR_BANK0; - - outb(efr, baseio + MOXA_MUST_EFR_REGISTER); + u8 oldlcr = mxser_must_select_bank(baseio, MOXA_MUST_EFR_BANK0); outb(value, baseio + MOXA_MUST_XON1_REGISTER); outb(oldlcr, baseio + UART_LCR); } static void mxser_set_must_xoff1_value(unsigned long baseio, u8 value) { - u8 oldlcr; - u8 efr; - - oldlcr = inb(baseio + UART_LCR); - outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); - - efr = inb(baseio + MOXA_MUST_EFR_REGISTER); - efr &= ~MOXA_MUST_EFR_BANK_MASK; - efr |= MOXA_MUST_EFR_BANK0; - - outb(efr, baseio + MOXA_MUST_EFR_REGISTER); + u8 oldlcr = mxser_must_select_bank(baseio, MOXA_MUST_EFR_BANK0); outb(value, baseio + MOXA_MUST_XOFF1_REGISTER); outb(oldlcr, baseio + UART_LCR); } static void mxser_set_must_fifo_value(struct mxser_port *info) { - u8 oldlcr; - u8 efr; - - oldlcr = inb(info->ioaddr + UART_LCR); - outb(MOXA_MUST_ENTER_ENCHANCE, info->ioaddr + UART_LCR); - - efr = inb(info->ioaddr + MOXA_MUST_EFR_REGISTER); - efr &= ~MOXA_MUST_EFR_BANK_MASK; - efr |= MOXA_MUST_EFR_BANK1; - - outb(efr, info->ioaddr + MOXA_MUST_EFR_REGISTER); + u8 oldlcr = mxser_must_select_bank(info->ioaddr, MOXA_MUST_EFR_BANK1); outb(info->rx_high_water, info->ioaddr + MOXA_MUST_RBRTH_REGISTER); outb(info->rx_high_water, info->ioaddr + MOXA_MUST_RBRTI_REGISTER); outb(info->rx_low_water, info->ioaddr + MOXA_MUST_RBRTL_REGISTER); @@ -389,36 +365,18 @@ static void mxser_set_must_fifo_value(struct mxser_port *info) static void mxser_set_must_enum_value(unsigned long baseio, u8 value) { - u8 oldlcr; - u8 efr; - - oldlcr = inb(baseio + UART_LCR); - outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); - - efr = inb(baseio + MOXA_MUST_EFR_REGISTER); - efr &= ~MOXA_MUST_EFR_BANK_MASK; - efr |= MOXA_MUST_EFR_BANK2; - - outb(efr, baseio + MOXA_MUST_EFR_REGISTER); + u8 oldlcr = mxser_must_select_bank(baseio, MOXA_MUST_EFR_BANK2); outb(value, baseio + MOXA_MUST_ENUM_REGISTER); outb(oldlcr, baseio + UART_LCR); } -static void mxser_get_must_hardware_id(unsigned long baseio, u8 *pId) +static u8 mxser_get_must_hardware_id(unsigned long baseio) { - u8 oldlcr; - u8 efr; - - oldlcr = inb(baseio + UART_LCR); - outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); - - efr = inb(baseio + MOXA_MUST_EFR_REGISTER); - efr &= ~MOXA_MUST_EFR_BANK_MASK; - efr |= MOXA_MUST_EFR_BANK2; - - outb(efr, baseio + MOXA_MUST_EFR_REGISTER); - *pId = inb(baseio + MOXA_MUST_HWID_REGISTER); + u8 oldlcr = mxser_must_select_bank(baseio, MOXA_MUST_EFR_BANK2); + u8 id = inb(baseio + MOXA_MUST_HWID_REGISTER); outb(oldlcr, baseio + UART_LCR); + + return id; } static void mxser_must_set_EFR(unsigned long baseio, u8 clear, u8 set) @@ -525,7 +483,7 @@ static enum mxser_must_hwid mxser_must_get_hwid(unsigned long io) return MOXA_OTHER_UART; } - mxser_get_must_hardware_id(io, &hwid); + hwid = mxser_get_must_hardware_id(io); for (i = 1; i < UART_INFO_NUM; i++) /* 0 = OTHER_UART */ if (hwid == Gpci_uart_info[i].type) return hwid; From b441eb0f69d19cddf2018ded38a5f3ea7e392836 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:48 +0200 Subject: [PATCH 187/227] mxser: clean up the rest of MUST helpers Clean up the rest of MUST helpers. They all can use the newly added mxser_must_set_EFR. And passing a bool instead of having two functions (_enable+_disable) simplifies the code a lot too. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-43-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 97 ++++++--------------------------------------- 1 file changed, 12 insertions(+), 85 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 392aee47c803..ff85a6e15d9d 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -391,81 +391,21 @@ static void mxser_must_set_enhance_mode(unsigned long baseio, bool enable) enable ? MOXA_MUST_EFR_EFRB_ENABLE : 0); } -static void SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(unsigned long baseio) +static void mxser_must_no_sw_flow_control(unsigned long baseio) { - u8 oldlcr; - u8 efr; - - oldlcr = inb(baseio + UART_LCR); - outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); - - efr = inb(baseio + MOXA_MUST_EFR_REGISTER); - efr &= ~MOXA_MUST_EFR_SF_MASK; - - outb(efr, baseio + MOXA_MUST_EFR_REGISTER); - outb(oldlcr, baseio + UART_LCR); + mxser_must_set_EFR(baseio, MOXA_MUST_EFR_SF_MASK, 0); } -static void mxser_enable_must_tx_software_flow_control(unsigned long baseio) +static void mxser_must_set_tx_sw_flow_control(unsigned long baseio, bool enable) { - u8 oldlcr; - u8 efr; - - oldlcr = inb(baseio + UART_LCR); - outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); - - efr = inb(baseio + MOXA_MUST_EFR_REGISTER); - efr &= ~MOXA_MUST_EFR_SF_TX_MASK; - efr |= MOXA_MUST_EFR_SF_TX1; - - outb(efr, baseio + MOXA_MUST_EFR_REGISTER); - outb(oldlcr, baseio + UART_LCR); + mxser_must_set_EFR(baseio, MOXA_MUST_EFR_SF_TX_MASK, + enable ? MOXA_MUST_EFR_SF_TX1 : 0); } -static void mxser_disable_must_tx_software_flow_control(unsigned long baseio) +static void mxser_must_set_rx_sw_flow_control(unsigned long baseio, bool enable) { - u8 oldlcr; - u8 efr; - - oldlcr = inb(baseio + UART_LCR); - outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); - - efr = inb(baseio + MOXA_MUST_EFR_REGISTER); - efr &= ~MOXA_MUST_EFR_SF_TX_MASK; - - outb(efr, baseio + MOXA_MUST_EFR_REGISTER); - outb(oldlcr, baseio + UART_LCR); -} - -static void mxser_enable_must_rx_software_flow_control(unsigned long baseio) -{ - u8 oldlcr; - u8 efr; - - oldlcr = inb(baseio + UART_LCR); - outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); - - efr = inb(baseio + MOXA_MUST_EFR_REGISTER); - efr &= ~MOXA_MUST_EFR_SF_RX_MASK; - efr |= MOXA_MUST_EFR_SF_RX1; - - outb(efr, baseio + MOXA_MUST_EFR_REGISTER); - outb(oldlcr, baseio + UART_LCR); -} - -static void mxser_disable_must_rx_software_flow_control(unsigned long baseio) -{ - u8 oldlcr; - u8 efr; - - oldlcr = inb(baseio + UART_LCR); - outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); - - efr = inb(baseio + MOXA_MUST_EFR_REGISTER); - efr &= ~MOXA_MUST_EFR_SF_RX_MASK; - - outb(efr, baseio + MOXA_MUST_EFR_REGISTER); - outb(oldlcr, baseio + UART_LCR); + mxser_must_set_EFR(baseio, MOXA_MUST_EFR_SF_RX_MASK, + enable ? MOXA_MUST_EFR_SF_RX1 : 0); } static enum mxser_must_hwid mxser_must_get_hwid(unsigned long io) @@ -746,20 +686,8 @@ static void mxser_change_speed(struct tty_struct *tty) if (info->board->must_hwid) { mxser_set_must_xon1_value(info->ioaddr, START_CHAR(tty)); mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(tty)); - if (I_IXON(tty)) { - mxser_enable_must_rx_software_flow_control( - info->ioaddr); - } else { - mxser_disable_must_rx_software_flow_control( - info->ioaddr); - } - if (I_IXOFF(tty)) { - mxser_enable_must_tx_software_flow_control( - info->ioaddr); - } else { - mxser_disable_must_tx_software_flow_control( - info->ioaddr); - } + mxser_must_set_rx_sw_flow_control(info->ioaddr, I_IXON(tty)); + mxser_must_set_tx_sw_flow_control(info->ioaddr, I_IXOFF(tty)); } @@ -946,7 +874,7 @@ static void mxser_shutdown_port(struct tty_port *port) if (info->board->must_hwid) - SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(info->ioaddr); + mxser_must_no_sw_flow_control(info->ioaddr); spin_unlock_irqrestore(&info->slock, flags); } @@ -1585,8 +1513,7 @@ static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termi if (info->board->must_hwid) { spin_lock_irqsave(&info->slock, flags); - mxser_disable_must_rx_software_flow_control( - info->ioaddr); + mxser_must_set_rx_sw_flow_control(info->ioaddr, false); spin_unlock_irqrestore(&info->slock, flags); } From 57faa7d6148c2de56f7558eb0d4c837264553ba5 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:49 +0200 Subject: [PATCH 188/227] mxser: move board init into mxser_initbrd What's done in ->probe for board is actually its initialization. So move it to mxser_initbrd where it belongs. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-44-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 53 ++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index ff85a6e15d9d..3b20eb96d788 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -1888,9 +1888,36 @@ static int mxser_initbrd(struct mxser_board *brd) struct mxser_port *info; unsigned int i; int retval; + bool is_mu860; + + brd->must_hwid = mxser_must_get_hwid(brd->ports[0].ioaddr); + is_mu860 = brd->must_hwid == MOXA_MUST_MU860_HWID; + + for (i = 0; i < UART_INFO_NUM; i++) { + if (Gpci_uart_info[i].type == brd->must_hwid) { + brd->max_baud = Gpci_uart_info[i].max_baud; + + /* exception....CP-102 */ + if (brd->info->flags & MXSER_HIGHBAUD) + brd->max_baud = 921600; + break; + } + } + + if (is_mu860) { + /* set to RS232 mode by default */ + outb(0, brd->vector + 4); + outb(0, brd->vector + 0x0c); + } for (i = 0; i < brd->info->nports; i++) { info = &brd->ports[i]; + if (is_mu860) { + if (i < 4) + info->opmode_ioaddr = brd->vector + 4; + else + info->opmode_ioaddr = brd->vector + 0x0c; + } tty_port_init(&info->port); info->port.ops = &mxser_port_ops; info->board = brd; @@ -1941,7 +1968,7 @@ static int mxser_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct mxser_board *brd; - unsigned int i, j; + unsigned int i; unsigned long ioaddress; struct device *tty_dev; int retval = -EINVAL; @@ -1988,30 +2015,6 @@ static int mxser_probe(struct pci_dev *pdev, /* irq */ brd->irq = pdev->irq; - brd->must_hwid = mxser_must_get_hwid(brd->ports[0].ioaddr); - - for (j = 0; j < UART_INFO_NUM; j++) { - if (Gpci_uart_info[j].type == brd->must_hwid) { - brd->max_baud = Gpci_uart_info[j].max_baud; - - /* exception....CP-102 */ - if (brd->info->flags & MXSER_HIGHBAUD) - brd->max_baud = 921600; - break; - } - } - - if (brd->must_hwid == MOXA_MUST_MU860_HWID) { - for (i = 0; i < brd->info->nports; i++) { - if (i < 4) - brd->ports[i].opmode_ioaddr = ioaddress + 4; - else - brd->ports[i].opmode_ioaddr = ioaddress + 0x0c; - } - outb(0, ioaddress + 4); /* default set to RS232 mode */ - outb(0, ioaddress + 0x0c); /* default set to RS232 mode */ - } - /* mxser_initbrd will hook ISR. */ retval = mxser_initbrd(brd); if (retval) From d450f0852fccccc4ae7ec4103e146ae1b61a6fef Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:50 +0200 Subject: [PATCH 189/227] mxser: inline mxser_board_remove into mxser_remove The only user of mxser_board_remove is mxser_remove. Move there those few lines. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-45-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 3b20eb96d788..196750676400 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -1953,17 +1953,6 @@ static int mxser_initbrd(struct mxser_board *brd) return retval; } -static void mxser_board_remove(struct mxser_board *brd) -{ - unsigned int i; - - for (i = 0; i < brd->info->nports; i++) { - tty_unregister_device(mxvar_sdriver, brd->idx + i); - tty_port_destroy(&brd->ports[i].port); - } - free_irq(brd->irq, brd); -} - static int mxser_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -2053,8 +2042,14 @@ err: static void mxser_remove(struct pci_dev *pdev) { struct mxser_board *brd = pci_get_drvdata(pdev); + unsigned int i; - mxser_board_remove(brd); + for (i = 0; i < brd->info->nports; i++) { + tty_unregister_device(mxvar_sdriver, brd->idx + i); + tty_port_destroy(&brd->ports[i].port); + } + + free_irq(brd->irq, brd); pci_release_region(pdev, 2); pci_release_region(pdev, 3); From dcb04e21bba349875c97467062a0d5cb06f7524d Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:51 +0200 Subject: [PATCH 190/227] mxser: pci, switch to managed resources Switch to managed resources for PCI using pcim_enable_device. Regions and device disabling is now taken care of by the core and we need not unwind. Neither in ->probe, nor in ->remove. That simplifies the code. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-46-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 196750676400..be58ee025180 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -1978,7 +1978,7 @@ static int mxser_probe(struct pci_dev *pdev, mxser_cards[ent->driver_data].name, pdev->bus->number, PCI_SLOT(pdev->devfn)); - retval = pci_enable_device(pdev); + retval = pcim_enable_device(pdev); if (retval) { dev_err(&pdev->dev, "PCI enable failed\n"); goto err; @@ -1988,7 +1988,7 @@ static int mxser_probe(struct pci_dev *pdev, ioaddress = pci_resource_start(pdev, 2); retval = pci_request_region(pdev, 2, "mxser(IO)"); if (retval) - goto err_dis; + goto err; brd->info = &mxser_cards[ent->driver_data]; for (i = 0; i < brd->info->nports; i++) @@ -2007,7 +2007,7 @@ static int mxser_probe(struct pci_dev *pdev, /* mxser_initbrd will hook ISR. */ retval = mxser_initbrd(brd); if (retval) - goto err_rel3; + goto err_zero; for (i = 0; i < brd->info->nports; i++) { tty_dev = tty_port_register_device(&brd->ports[i].port, @@ -2028,13 +2028,8 @@ err_relbrd: for (i = 0; i < brd->info->nports; i++) tty_port_destroy(&brd->ports[i].port); free_irq(brd->irq, brd); -err_rel3: - pci_release_region(pdev, 3); err_zero: brd->info = NULL; - pci_release_region(pdev, 2); -err_dis: - pci_disable_device(pdev); err: return retval; } @@ -2051,9 +2046,6 @@ static void mxser_remove(struct pci_dev *pdev) free_irq(brd->irq, brd); - pci_release_region(pdev, 2); - pci_release_region(pdev, 3); - pci_disable_device(pdev); brd->info = NULL; } From 7f0e79dc09692357ecd9bb7b9674352b74e0ffad Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:52 +0200 Subject: [PATCH 191/227] mxser: move request irq to probe and switch to managed Move request_irq from mxser_initbrd to mxser_probe so that we can switch it to managed request. It simplifies the cleanup code. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-47-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index be58ee025180..83c795acdb19 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -1883,11 +1883,10 @@ static const struct tty_port_operations mxser_port_ops = { * The MOXA Smartio/Industio serial driver boot-time initialization code! */ -static int mxser_initbrd(struct mxser_board *brd) +static void mxser_initbrd(struct mxser_board *brd) { struct mxser_port *info; unsigned int i; - int retval; bool is_mu860; brd->must_hwid = mxser_must_get_hwid(brd->ports[0].ioaddr); @@ -1939,18 +1938,6 @@ static int mxser_initbrd(struct mxser_board *brd) outb(inb(info->ioaddr + UART_IER) & 0xf0, info->ioaddr + UART_IER); } - - retval = request_irq(brd->irq, mxser_interrupt, IRQF_SHARED, "mxser", - brd); - if (retval) { - for (i = 0; i < brd->info->nports; i++) - tty_port_destroy(&brd->ports[i].port); - printk(KERN_ERR "Board %s: Request irq failed, IRQ (%d) may " - "conflict with another device.\n", - brd->info->name, brd->irq); - } - - return retval; } static int mxser_probe(struct pci_dev *pdev, @@ -2004,10 +1991,14 @@ static int mxser_probe(struct pci_dev *pdev, /* irq */ brd->irq = pdev->irq; - /* mxser_initbrd will hook ISR. */ - retval = mxser_initbrd(brd); - if (retval) - goto err_zero; + mxser_initbrd(brd); + + retval = devm_request_irq(&pdev->dev, brd->irq, mxser_interrupt, + IRQF_SHARED, "mxser", brd); + if (retval) { + dev_err(&pdev->dev, "request irq failed"); + goto err_relbrd; + } for (i = 0; i < brd->info->nports; i++) { tty_dev = tty_port_register_device(&brd->ports[i].port, @@ -2027,7 +2018,6 @@ static int mxser_probe(struct pci_dev *pdev, err_relbrd: for (i = 0; i < brd->info->nports; i++) tty_port_destroy(&brd->ports[i].port); - free_irq(brd->irq, brd); err_zero: brd->info = NULL; err: @@ -2044,8 +2034,6 @@ static void mxser_remove(struct pci_dev *pdev) tty_port_destroy(&brd->ports[i].port); } - free_irq(brd->irq, brd); - brd->info = NULL; } From 1e37f7333c89a5364511e3a0eaf28ff617ee42ed Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:53 +0200 Subject: [PATCH 192/227] mxser: remove info message from probe There is a dev_info in ->probe which prints device's name, bus and slot numbers. All these can be fetched from the lspci output. So remove this useless print. This eliminates the whole mxser_cardinfo::name field. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-48-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 56 +++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 83c795acdb19..04a39c1f13bb 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -190,38 +190,37 @@ static const struct { #define UART_INFO_NUM ARRAY_SIZE(Gpci_uart_info) struct mxser_cardinfo { - char *name; unsigned int nports; unsigned int flags; }; static const struct mxser_cardinfo mxser_cards[] = { -/* 0*/ { "C168H/PCI series", 8, }, - { "C104H/PCI series", 4, }, - { "CP-132 series", 2, }, - { "CP-114 series", 4, }, - { "CT-114 series", 4, }, -/* 5*/ { "CP-102 series", 2, MXSER_HIGHBAUD }, - { "CP-104U series", 4, }, - { "CP-168U series", 8, }, - { "CP-132U series", 2, }, - { "CP-134U series", 4, }, -/*10*/ { "CP-104JU series", 4, }, - { "Moxa UC7000 Serial", 8, }, /* RC7000 */ - { "CP-118U series", 8, }, - { "CP-102UL series", 2, }, - { "CP-102U series", 2, }, -/*15*/ { "CP-118EL series", 8, }, - { "CP-168EL series", 8, }, - { "CP-104EL series", 4, }, - { "CB-108 series", 8, }, - { "CB-114 series", 4, }, -/*20*/ { "CB-134I series", 4, }, - { "CP-138U series", 8, }, - { "POS-104UL series", 4, }, - { "CP-114UL series", 4, }, - { "CP-102UF series", 2, }, -/*25*/ { "CP-112UL series", 2, }, +/* 0*/ { 8, }, + { 4, }, + { 2, }, + { 4, }, + { 4, }, +/* 5*/ { 2, MXSER_HIGHBAUD }, + { 4, }, + { 8, }, + { 2, }, + { 4, }, +/*10*/ { 4, }, + { 8, }, /* RC7000 */ + { 8, }, + { 2, }, + { 2, }, +/*15*/ { 8, }, + { 8, }, + { 4, }, + { 8, }, + { 4, }, +/*20*/ { 4, }, + { 8, }, + { 4, }, + { 4, }, + { 2, }, +/*25*/ { 2, }, }; /* driver_data correspond to the lines in the structure above @@ -1961,9 +1960,6 @@ static int mxser_probe(struct pci_dev *pdev, brd = &mxser_boards[i]; brd->idx = i * MXSER_PORTS_PER_BOARD; - dev_info(&pdev->dev, "found MOXA %s board (BusNo=%d, DevNo=%d)\n", - mxser_cards[ent->driver_data].name, - pdev->bus->number, PCI_SLOT(pdev->devfn)); retval = pcim_enable_device(pdev); if (retval) { From c24c31ff4a7d392945293fd61e844921b9f26f33 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:54 +0200 Subject: [PATCH 193/227] mxser: remove mxser_cardinfo Now that mxser_cards array (of struct mxser_cardinfo) contains only port count and a quirk, we can encode these two directly into pci_device_id::driver_data. And we can remove this struct completely. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-49-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 113 ++++++++++++++++---------------------------- 1 file changed, 41 insertions(+), 72 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 04a39c1f13bb..bb4110d466cb 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -168,7 +168,8 @@ #define PCI_DEVICE_ID_CB134I 0x1341 #define PCI_DEVICE_ID_CP138U 0x1380 -#define MXSER_HIGHBAUD 1 +#define MXSER_NPORTS(ddata) ((ddata) & 0xffU) +#define MXSER_HIGHBAUD 0x0100 enum mxser_must_hwid { MOXA_OTHER_UART = 0x00, @@ -189,69 +190,36 @@ static const struct { }; #define UART_INFO_NUM ARRAY_SIZE(Gpci_uart_info) -struct mxser_cardinfo { - unsigned int nports; - unsigned int flags; -}; - -static const struct mxser_cardinfo mxser_cards[] = { -/* 0*/ { 8, }, - { 4, }, - { 2, }, - { 4, }, - { 4, }, -/* 5*/ { 2, MXSER_HIGHBAUD }, - { 4, }, - { 8, }, - { 2, }, - { 4, }, -/*10*/ { 4, }, - { 8, }, /* RC7000 */ - { 8, }, - { 2, }, - { 2, }, -/*15*/ { 8, }, - { 8, }, - { 4, }, - { 8, }, - { 4, }, -/*20*/ { 4, }, - { 8, }, - { 4, }, - { 4, }, - { 2, }, -/*25*/ { 2, }, -}; /* driver_data correspond to the lines in the structure above see also ISA probe function before you change something */ static const struct pci_device_id mxser_pcibrds[] = { - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C168), .driver_data = 0 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C104), .driver_data = 1 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C168), .driver_data = 8 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C104), .driver_data = 4 }, { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132), .driver_data = 2 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP114), .driver_data = 3 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP114), .driver_data = 4 }, { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CT114), .driver_data = 4 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102), .driver_data = 5 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104U), .driver_data = 6 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168U), .driver_data = 7 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132U), .driver_data = 8 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP134U), .driver_data = 9 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104JU),.driver_data = 10 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_RC7000), .driver_data = 11 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118U), .driver_data = 12 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102UL),.driver_data = 13 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102U), .driver_data = 14 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118EL),.driver_data = 15 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168EL),.driver_data = 16 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104EL),.driver_data = 17 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB108), .driver_data = 18 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB114), .driver_data = 19 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB134I), .driver_data = 20 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP138U), .driver_data = 21 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_POS104UL), .driver_data = 22 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP114UL), .driver_data = 23 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP102UF), .driver_data = 24 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP112UL), .driver_data = 25 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102), .driver_data = 2 | MXSER_HIGHBAUD }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104U), .driver_data = 4 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168U), .driver_data = 8 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132U), .driver_data = 2 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP134U), .driver_data = 4 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104JU),.driver_data = 4 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_RC7000), .driver_data = 8 }, /* RC7000 */ + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118U), .driver_data = 8 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102UL),.driver_data = 2 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102U), .driver_data = 2 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118EL),.driver_data = 8 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168EL),.driver_data = 8 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104EL),.driver_data = 4 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB108), .driver_data = 8 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB114), .driver_data = 4 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB134I), .driver_data = 4 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP138U), .driver_data = 8 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_POS104UL), .driver_data = 4 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP114UL), .driver_data = 4 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP102UF), .driver_data = 2 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP112UL), .driver_data = 2 }, { } }; MODULE_DEVICE_TABLE(pci, mxser_pcibrds); @@ -300,8 +268,8 @@ struct mxser_port { struct mxser_board { unsigned int idx; + unsigned short nports; int irq; - const struct mxser_cardinfo *info; unsigned long vector; enum mxser_must_hwid must_hwid; @@ -1816,7 +1784,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) struct mxser_board *brd = dev_id; struct mxser_port *port; unsigned int int_cnt, pass_counter = 0; - unsigned int i, max = brd->info->nports; + unsigned int i, max = brd->nports; int handled = IRQ_NONE; u8 irqbits, bits, mask = BIT(max) - 1; @@ -1882,7 +1850,7 @@ static const struct tty_port_operations mxser_port_ops = { * The MOXA Smartio/Industio serial driver boot-time initialization code! */ -static void mxser_initbrd(struct mxser_board *brd) +static void mxser_initbrd(struct mxser_board *brd, bool high_baud) { struct mxser_port *info; unsigned int i; @@ -1896,7 +1864,7 @@ static void mxser_initbrd(struct mxser_board *brd) brd->max_baud = Gpci_uart_info[i].max_baud; /* exception....CP-102 */ - if (brd->info->flags & MXSER_HIGHBAUD) + if (high_baud) brd->max_baud = 921600; break; } @@ -1908,7 +1876,7 @@ static void mxser_initbrd(struct mxser_board *brd) outb(0, brd->vector + 0x0c); } - for (i = 0; i < brd->info->nports; i++) { + for (i = 0; i < brd->nports; i++) { info = &brd->ports[i]; if (is_mu860) { if (i < 4) @@ -1945,11 +1913,12 @@ static int mxser_probe(struct pci_dev *pdev, struct mxser_board *brd; unsigned int i; unsigned long ioaddress; + unsigned short nports = MXSER_NPORTS(ent->driver_data); struct device *tty_dev; int retval = -EINVAL; for (i = 0; i < MXSER_BOARDS; i++) - if (mxser_boards[i].info == NULL) + if (mxser_boards[i].nports == 0) break; if (i >= MXSER_BOARDS) { @@ -1973,8 +1942,8 @@ static int mxser_probe(struct pci_dev *pdev, if (retval) goto err; - brd->info = &mxser_cards[ent->driver_data]; - for (i = 0; i < brd->info->nports; i++) + brd->nports = nports; + for (i = 0; i < nports; i++) brd->ports[i].ioaddr = ioaddress + 8 * i; /* vector */ @@ -1987,7 +1956,7 @@ static int mxser_probe(struct pci_dev *pdev, /* irq */ brd->irq = pdev->irq; - mxser_initbrd(brd); + mxser_initbrd(brd, ent->driver_data & MXSER_HIGHBAUD); retval = devm_request_irq(&pdev->dev, brd->irq, mxser_interrupt, IRQF_SHARED, "mxser", brd); @@ -1996,7 +1965,7 @@ static int mxser_probe(struct pci_dev *pdev, goto err_relbrd; } - for (i = 0; i < brd->info->nports; i++) { + for (i = 0; i < nports; i++) { tty_dev = tty_port_register_device(&brd->ports[i].port, mxvar_sdriver, brd->idx + i, &pdev->dev); if (IS_ERR(tty_dev)) { @@ -2012,10 +1981,10 @@ static int mxser_probe(struct pci_dev *pdev, return 0; err_relbrd: - for (i = 0; i < brd->info->nports; i++) + for (i = 0; i < nports; i++) tty_port_destroy(&brd->ports[i].port); err_zero: - brd->info = NULL; + brd->nports = 0; err: return retval; } @@ -2025,12 +1994,12 @@ static void mxser_remove(struct pci_dev *pdev) struct mxser_board *brd = pci_get_drvdata(pdev); unsigned int i; - for (i = 0; i < brd->info->nports; i++) { + for (i = 0; i < brd->nports; i++) { tty_unregister_device(mxvar_sdriver, brd->idx + i); tty_port_destroy(&brd->ports[i].port); } - brd->info = NULL; + brd->nports = 0; } static struct pci_driver mxser_driver = { From c3db20c3b71bf14d49e4a6582325e22db4e74a75 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:55 +0200 Subject: [PATCH 194/227] mxser: cleanup mxser_process_txrx_fifo Rename process_txrx_fifo to mxser_process_txrx_fifo and: * remove useless parentheses * return from the 'if's true branch and process the rest in normal code flow (shift the code one level left) All this to make the code more readable. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-50-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index bb4110d466cb..1e54e94a7ca6 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -398,22 +398,24 @@ static enum mxser_must_hwid mxser_must_get_hwid(unsigned long io) return MOXA_OTHER_UART; } -static void process_txrx_fifo(struct mxser_port *info) +static void mxser_process_txrx_fifo(struct mxser_port *info) { - int i; + unsigned int i; - if ((info->type == PORT_16450) || (info->type == PORT_8250)) { + if (info->type == PORT_16450 || info->type == PORT_8250) { info->rx_high_water = 1; info->rx_low_water = 1; info->xmit_fifo_size = 1; - } else - for (i = 0; i < UART_INFO_NUM; i++) - if (info->board->must_hwid == Gpci_uart_info[i].type) { - info->rx_low_water = Gpci_uart_info[i].rx_low_water; - info->rx_high_water = Gpci_uart_info[i].rx_high_water; - info->xmit_fifo_size = Gpci_uart_info[i].fifo_size; - break; - } + return; + } + + for (i = 0; i < UART_INFO_NUM; i++) + if (info->board->must_hwid == Gpci_uart_info[i].type) { + info->rx_low_water = Gpci_uart_info[i].rx_low_water; + info->rx_high_water = Gpci_uart_info[i].rx_high_water; + info->xmit_fifo_size = Gpci_uart_info[i].fifo_size; + break; + } } static int mxser_carrier_raised(struct tty_port *port) @@ -1149,7 +1151,7 @@ static int mxser_set_serial_info(struct tty_struct *tty, info->type = ss->type; - process_txrx_fifo(info); + mxser_process_txrx_fifo(info); } if (tty_port_initialized(port)) { @@ -1895,7 +1897,7 @@ static void mxser_initbrd(struct mxser_board *brd, bool high_baud) info->type = PORT_16550A; - process_txrx_fifo(info); + mxser_process_txrx_fifo(info); info->port.close_delay = 5 * HZ / 10; info->port.closing_wait = 30 * HZ; From 42ad25fc46d3f6b6fe5b4b933dd328677e328ec7 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:56 +0200 Subject: [PATCH 195/227] mxser: rework and simplify mxser_open In mxser_open, tty->port is already set thanks to tty_port_register_device in ->probe. So we can simply use container_of to deduce the struct mxser_port's pointer. Thus avoiding divisions and complex computations. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-51-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 1e54e94a7ca6..ea5e61a5a173 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -856,15 +856,12 @@ static void mxser_shutdown_port(struct tty_port *port) */ static int mxser_open(struct tty_struct *tty, struct file *filp) { - struct mxser_port *info; - int line = tty->index; + struct tty_port *tport = tty->port; + struct mxser_port *port = container_of(tport, struct mxser_port, port); - info = &mxser_boards[line / MXSER_PORTS_PER_BOARD].ports[line % MXSER_PORTS_PER_BOARD]; - if (!info->ioaddr) - return -ENODEV; + tty->driver_data = port; - tty->driver_data = info; - return tty_port_open(&info->port, tty, filp); + return tty_port_open(tport, tty, filp); } static void mxser_flush_buffer(struct tty_struct *tty) From 13d4aba8a9747c5f88e537cc065a511fe64f92eb Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:57 +0200 Subject: [PATCH 196/227] mxser: make mxser_board::idx really an index mxser_board::idx is named as index, but actually contain a base. So assign index there. And for base, introduce a local variable. This is needed for the next patch (use index as a bit index). Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-52-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index ea5e61a5a173..30b3a5ab6bea 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -1910,7 +1910,7 @@ static int mxser_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct mxser_board *brd; - unsigned int i; + unsigned int i, base; unsigned long ioaddress; unsigned short nports = MXSER_NPORTS(ent->driver_data); struct device *tty_dev; @@ -1927,7 +1927,8 @@ static int mxser_probe(struct pci_dev *pdev, } brd = &mxser_boards[i]; - brd->idx = i * MXSER_PORTS_PER_BOARD; + brd->idx = i; + base = i * MXSER_PORTS_PER_BOARD; retval = pcim_enable_device(pdev); if (retval) { @@ -1966,12 +1967,12 @@ static int mxser_probe(struct pci_dev *pdev, for (i = 0; i < nports; i++) { tty_dev = tty_port_register_device(&brd->ports[i].port, - mxvar_sdriver, brd->idx + i, &pdev->dev); + mxvar_sdriver, base + i, &pdev->dev); if (IS_ERR(tty_dev)) { retval = PTR_ERR(tty_dev); for (; i > 0; i--) tty_unregister_device(mxvar_sdriver, - brd->idx + i - 1); + base + i - 1); goto err_relbrd; } } @@ -1991,10 +1992,10 @@ err: static void mxser_remove(struct pci_dev *pdev) { struct mxser_board *brd = pci_get_drvdata(pdev); - unsigned int i; + unsigned int i, base = brd->idx * MXSER_PORTS_PER_BOARD; for (i = 0; i < brd->nports; i++) { - tty_unregister_device(mxvar_sdriver, brd->idx + i); + tty_unregister_device(mxvar_sdriver, base + i); tty_port_destroy(&brd->ports[i].port); } From f8b6b327aa73dd69577abd4e164447a9cc124315 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:58 +0200 Subject: [PATCH 197/227] mxser: alloc struct mxser_board dynamically There is no need to preallocate an array of four struct mxser_board's. In most cases a single board or two will be present in a machine. So allocate struct mxser_board as needed in ->probe. This makes mxser_boards a bit array. There we store which indexes are free (unallocated). Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-53-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 30b3a5ab6bea..0e99225e260f 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -278,7 +278,7 @@ struct mxser_board { struct mxser_port ports[MXSER_PORTS_PER_BOARD]; }; -static struct mxser_board mxser_boards[MXSER_BOARDS]; +static DECLARE_BITMAP(mxser_boards, MXSER_BOARDS); static struct tty_driver *mxvar_sdriver; static u8 __mxser_must_set_EFR(unsigned long baseio, u8 clear, u8 set, @@ -1916,31 +1916,32 @@ static int mxser_probe(struct pci_dev *pdev, struct device *tty_dev; int retval = -EINVAL; - for (i = 0; i < MXSER_BOARDS; i++) - if (mxser_boards[i].nports == 0) - break; - + i = find_first_zero_bit(mxser_boards, MXSER_BOARDS); if (i >= MXSER_BOARDS) { dev_err(&pdev->dev, "too many boards found (maximum %d), board " "not configured\n", MXSER_BOARDS); goto err; } - brd = &mxser_boards[i]; + brd = devm_kzalloc(&pdev->dev, sizeof(*brd), GFP_KERNEL); + if (!brd) + goto err; + brd->idx = i; + __set_bit(brd->idx, mxser_boards); base = i * MXSER_PORTS_PER_BOARD; retval = pcim_enable_device(pdev); if (retval) { dev_err(&pdev->dev, "PCI enable failed\n"); - goto err; + goto err_zero; } /* io address */ ioaddress = pci_resource_start(pdev, 2); retval = pci_request_region(pdev, 2, "mxser(IO)"); if (retval) - goto err; + goto err_zero; brd->nports = nports; for (i = 0; i < nports; i++) @@ -1984,7 +1985,7 @@ err_relbrd: for (i = 0; i < nports; i++) tty_port_destroy(&brd->ports[i].port); err_zero: - brd->nports = 0; + __clear_bit(brd->idx, mxser_boards); err: return retval; } @@ -1999,7 +2000,7 @@ static void mxser_remove(struct pci_dev *pdev) tty_port_destroy(&brd->ports[i].port); } - brd->nports = 0; + __clear_bit(brd->idx, mxser_boards); } static struct pci_driver mxser_driver = { From ad1c92ff6ee948584603ef2e004704cfceb899a4 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:14:59 +0200 Subject: [PATCH 198/227] mxser: alloc only needed # of ports Many boards have only 2 ports. But we always allocate 8 ports (struct mxser_port) in each struct mxser_board. Switch this to an empty/variable sized array ([]) and allocate the needed number of ports using struct_size helper in ->probe. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-54-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 0e99225e260f..81e2b72fca3f 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -275,7 +275,7 @@ struct mxser_board { enum mxser_must_hwid must_hwid; speed_t max_baud; - struct mxser_port ports[MXSER_PORTS_PER_BOARD]; + struct mxser_port ports[]; }; static DECLARE_BITMAP(mxser_boards, MXSER_BOARDS); @@ -1923,7 +1923,8 @@ static int mxser_probe(struct pci_dev *pdev, goto err; } - brd = devm_kzalloc(&pdev->dev, sizeof(*brd), GFP_KERNEL); + brd = devm_kzalloc(&pdev->dev, struct_size(brd, ports, nports), + GFP_KERNEL); if (!brd) goto err; From 987a4cfee5765c9d7242a81d2f90e1429c83201b Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:15:00 +0200 Subject: [PATCH 199/227] mxser: remove pointless ioaddr checks struct mxser_port::ioaddr can never be NULL once set in ->probe. Hence the checks for it are pointless. Remove them. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-55-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 81e2b72fca3f..e5f8d08de8fd 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -446,9 +446,6 @@ static int mxser_set_baud(struct tty_struct *tty, speed_t newspd) unsigned char cval; u64 timeout; - if (!info->ioaddr) - return -1; - if (newspd > info->board->max_baud) return -1; @@ -519,8 +516,6 @@ static void mxser_change_speed(struct tty_struct *tty) unsigned char status; cflag = tty->termios.c_cflag; - if (!info->ioaddr) - return; mxser_set_baud(tty, tty_get_baud_rate(tty)); @@ -724,7 +719,7 @@ static int mxser_activate(struct tty_port *port, struct tty_struct *tty) spin_lock_irqsave(&info->slock, flags); - if (!info->ioaddr || !info->type) { + if (!info->type) { set_bit(TTY_IO_ERROR, &tty->flags); free_page(page); spin_unlock_irqrestore(&info->slock, flags); @@ -1097,10 +1092,6 @@ static int mxser_set_serial_info(struct tty_struct *tty, return -EIO; mutex_lock(&port->mutex); - if (!info->ioaddr) { - mutex_unlock(&port->mutex); - return -ENODEV; - } if (ss->irq != info->board->irq || ss->port != info->ioaddr) { From 5990843328360dcded98104f75045a92d241c043 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:15:01 +0200 Subject: [PATCH 200/227] mxser: cleanup mxser_rs_break mxser_rs_break now does all inb, outb, & or | in a single statement. The code is hard to follow, so make it more readable by doing one-line = one-statement. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-56-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index e5f8d08de8fd..5789c4343f10 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -1553,15 +1553,17 @@ static int mxser_rs_break(struct tty_struct *tty, int break_state) { struct mxser_port *info = tty->driver_data; unsigned long flags; + u8 lcr; spin_lock_irqsave(&info->slock, flags); + lcr = inb(info->ioaddr + UART_LCR); if (break_state == -1) - outb(inb(info->ioaddr + UART_LCR) | UART_LCR_SBC, - info->ioaddr + UART_LCR); + lcr |= UART_LCR_SBC; else - outb(inb(info->ioaddr + UART_LCR) & ~UART_LCR_SBC, - info->ioaddr + UART_LCR); + lcr &= ~UART_LCR_SBC; + outb(lcr, info->ioaddr + UART_LCR); spin_unlock_irqrestore(&info->slock, flags); + return 0; } From 007bbdc87522d17d711ca6bef0d4fe85f62f8c84 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:15:02 +0200 Subject: [PATCH 201/227] mxser: cleanup mxser_dtr_rts mxser_dtr_rts now does all inb, outb, & or | in a single statement. The code is hard to follow, so make it more readable by doing one-line = one-statement. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-57-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 5789c4343f10..daf820c086f4 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -428,14 +428,15 @@ static void mxser_dtr_rts(struct tty_port *port, int on) { struct mxser_port *mp = container_of(port, struct mxser_port, port); unsigned long flags; + u8 mcr; spin_lock_irqsave(&mp->slock, flags); + mcr = inb(mp->ioaddr + UART_MCR); if (on) - outb(inb(mp->ioaddr + UART_MCR) | - UART_MCR_DTR | UART_MCR_RTS, mp->ioaddr + UART_MCR); + mcr |= UART_MCR_DTR | UART_MCR_RTS; else - outb(inb(mp->ioaddr + UART_MCR)&~(UART_MCR_DTR | UART_MCR_RTS), - mp->ioaddr + UART_MCR); + mcr &= ~(UART_MCR_DTR | UART_MCR_RTS); + outb(mcr, mp->ioaddr + UART_MCR); spin_unlock_irqrestore(&mp->slock, flags); } From 8aff64e00f1eced4e73ca81c7599c06851da4475 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:15:03 +0200 Subject: [PATCH 202/227] mxser: don't start TX from tty_operations::put_char TX is not supposed to be started from tty_operations::put_char. Line disciplines ought to call tty_operations::put_char several times and then do a single tty_operations::flush_chars to start TX. Fix this in mxser by removing TX startup from mxser_put_char. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-58-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index daf820c086f4..52dbdd4282b2 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -998,17 +998,7 @@ static int mxser_put_char(struct tty_struct *tty, unsigned char ch) info->xmit_head &= SERIAL_XMIT_SIZE - 1; info->xmit_cnt++; spin_unlock_irqrestore(&info->slock, flags); - if (!tty->flow.stopped) { - if (!tty->hw_stopped || - (info->type == PORT_16550A) || - info->board->must_hwid) { - spin_lock_irqsave(&info->slock, flags); - outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER); - info->IER |= UART_IER_THRI; - outb(info->IER, info->ioaddr + UART_IER); - spin_unlock_irqrestore(&info->slock, flags); - } - } + return 1; } From be4866671f8302f04e0485573e97d3a5dfe93fca Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:15:04 +0200 Subject: [PATCH 203/227] mxser: extract and dedup CTS handling CTS is handled on two locations in mxser. Extract the code into separation function mxser_handle_cts. And call it from the two locations. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-59-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 87 +++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 54 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 52dbdd4282b2..00363d98277e 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -506,6 +506,35 @@ static int mxser_set_baud(struct tty_struct *tty, speed_t newspd) return 0; } +static void mxser_handle_cts(struct tty_struct *tty, struct mxser_port *info, + u8 msr) +{ + bool cts = msr & UART_MSR_CTS; + + if (tty->hw_stopped) { + if (cts) { + tty->hw_stopped = 0; + + if (info->type != PORT_16550A && + !info->board->must_hwid) { + outb(info->IER & ~UART_IER_THRI, + info->ioaddr + UART_IER); + info->IER |= UART_IER_THRI; + outb(info->IER, info->ioaddr + UART_IER); + } + tty_wakeup(tty); + } + return; + } else if (cts) + return; + + tty->hw_stopped = 1; + if (info->type != PORT_16550A && !info->board->must_hwid) { + info->IER &= ~UART_IER_THRI; + outb(info->IER, info->ioaddr + UART_IER); + } +} + /* * This routine is called to set the UART divisor registers to match * the specified baud rate for a serial port. @@ -514,7 +543,6 @@ static void mxser_change_speed(struct tty_struct *tty) { struct mxser_port *info = tty->driver_data; unsigned cflag, cval, fcr; - unsigned char status; cflag = tty->termios.c_cflag; @@ -585,32 +613,8 @@ static void mxser_change_speed(struct tty_struct *tty) if ((info->type == PORT_16550A) || (info->board->must_hwid)) { info->MCR |= UART_MCR_AFE; } else { - status = inb(info->ioaddr + UART_MSR); - if (tty->hw_stopped) { - if (status & UART_MSR_CTS) { - tty->hw_stopped = 0; - if (info->type != PORT_16550A && - !info->board->must_hwid) { - outb(info->IER & ~UART_IER_THRI, - info->ioaddr + - UART_IER); - info->IER |= UART_IER_THRI; - outb(info->IER, info->ioaddr + - UART_IER); - } - tty_wakeup(tty); - } - } else { - if (!(status & UART_MSR_CTS)) { - tty->hw_stopped = 1; - if ((info->type != PORT_16550A) && - (!info->board->must_hwid)) { - info->IER &= ~UART_IER_THRI; - outb(info->IER, info->ioaddr + - UART_IER); - } - } - } + mxser_handle_cts(tty, info, + inb(info->ioaddr + UART_MSR)); } } outb(info->MCR, info->ioaddr + UART_MCR); @@ -679,33 +683,8 @@ static void mxser_check_modem_status(struct tty_struct *tty, wake_up_interruptible(&port->port.open_wait); } - if (tty_port_cts_enabled(&port->port)) { - if (tty->hw_stopped) { - if (status & UART_MSR_CTS) { - tty->hw_stopped = 0; - - if ((port->type != PORT_16550A) && - (!port->board->must_hwid)) { - outb(port->IER & ~UART_IER_THRI, - port->ioaddr + UART_IER); - port->IER |= UART_IER_THRI; - outb(port->IER, port->ioaddr + - UART_IER); - } - tty_wakeup(tty); - } - } else { - if (!(status & UART_MSR_CTS)) { - tty->hw_stopped = 1; - if (port->type != PORT_16550A && - !port->board->must_hwid) { - port->IER &= ~UART_IER_THRI; - outb(port->IER, port->ioaddr + - UART_IER); - } - } - } - } + if (tty_port_cts_enabled(&port->port)) + mxser_handle_cts(tty, port, status); } static int mxser_activate(struct tty_port *port, struct tty_struct *tty) From 740165f7acbf1e73e6a7bfa2e8642b2e86cdee94 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:15:05 +0200 Subject: [PATCH 204/227] mxser: introduce and use start/stop_tx helpers Starting and stopping TX is performed on many places in the driver. It is repeated outb and info->IER modification. Create few helpers (__mxser_start_tx, mxser_start_tx, __mxser_stop_tx) and use them in the code instead of open coding. This should be a base for an uart driver for this device in the future. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-60-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 80 +++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 43 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 00363d98277e..e46974e9421a 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -418,6 +418,28 @@ static void mxser_process_txrx_fifo(struct mxser_port *info) } } +static void __mxser_start_tx(struct mxser_port *info) +{ + outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER); + info->IER |= UART_IER_THRI; + outb(info->IER, info->ioaddr + UART_IER); +} + +static void mxser_start_tx(struct mxser_port *info) +{ + unsigned long flags; + + spin_lock_irqsave(&info->slock, flags); + __mxser_start_tx(info); + spin_unlock_irqrestore(&info->slock, flags); +} + +static void __mxser_stop_tx(struct mxser_port *info) +{ + info->IER &= ~UART_IER_THRI; + outb(info->IER, info->ioaddr + UART_IER); +} + static int mxser_carrier_raised(struct tty_port *port) { struct mxser_port *mp = container_of(port, struct mxser_port, port); @@ -516,12 +538,8 @@ static void mxser_handle_cts(struct tty_struct *tty, struct mxser_port *info, tty->hw_stopped = 0; if (info->type != PORT_16550A && - !info->board->must_hwid) { - outb(info->IER & ~UART_IER_THRI, - info->ioaddr + UART_IER); - info->IER |= UART_IER_THRI; - outb(info->IER, info->ioaddr + UART_IER); - } + !info->board->must_hwid) + __mxser_start_tx(info); tty_wakeup(tty); } return; @@ -529,10 +547,8 @@ static void mxser_handle_cts(struct tty_struct *tty, struct mxser_port *info, return; tty->hw_stopped = 1; - if (info->type != PORT_16550A && !info->board->must_hwid) { - info->IER &= ~UART_IER_THRI; - outb(info->IER, info->ioaddr + UART_IER); - } + if (info->type != PORT_16550A && !info->board->must_hwid) + __mxser_stop_tx(info); } /* @@ -947,16 +963,9 @@ static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int cou } if (info->xmit_cnt && !tty->flow.stopped) { - if (!tty->hw_stopped || - (info->type == PORT_16550A) || - (info->board->must_hwid)) { - spin_lock_irqsave(&info->slock, flags); - outb(info->IER & ~UART_IER_THRI, info->ioaddr + - UART_IER); - info->IER |= UART_IER_THRI; - outb(info->IER, info->ioaddr + UART_IER); - spin_unlock_irqrestore(&info->slock, flags); - } + if (!tty->hw_stopped || info->type == PORT_16550A || + info->board->must_hwid) + mxser_start_tx(info); } return total; } @@ -985,20 +994,13 @@ static int mxser_put_char(struct tty_struct *tty, unsigned char ch) static void mxser_flush_chars(struct tty_struct *tty) { struct mxser_port *info = tty->driver_data; - unsigned long flags; if (info->xmit_cnt <= 0 || tty->flow.stopped || !info->port.xmit_buf || (tty->hw_stopped && info->type != PORT_16550A && !info->board->must_hwid)) return; - spin_lock_irqsave(&info->slock, flags); - - outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER); - info->IER |= UART_IER_THRI; - outb(info->IER, info->ioaddr + UART_IER); - - spin_unlock_irqrestore(&info->slock, flags); + mxser_start_tx(info); } static unsigned int mxser_write_room(struct tty_struct *tty) @@ -1399,10 +1401,8 @@ static void mxser_stop(struct tty_struct *tty) unsigned long flags; spin_lock_irqsave(&info->slock, flags); - if (info->IER & UART_IER_THRI) { - info->IER &= ~UART_IER_THRI; - outb(info->IER, info->ioaddr + UART_IER); - } + if (info->IER & UART_IER_THRI) + __mxser_stop_tx(info); spin_unlock_irqrestore(&info->slock, flags); } @@ -1412,11 +1412,8 @@ static void mxser_start(struct tty_struct *tty) unsigned long flags; spin_lock_irqsave(&info->slock, flags); - if (info->xmit_cnt && info->port.xmit_buf) { - outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER); - info->IER |= UART_IER_THRI; - outb(info->IER, info->ioaddr + UART_IER); - } + if (info->xmit_cnt && info->port.xmit_buf) + __mxser_start_tx(info); spin_unlock_irqrestore(&info->slock, flags); } @@ -1659,8 +1656,7 @@ static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port (tty->hw_stopped && (port->type != PORT_16550A) && (!port->board->must_hwid))) { - port->IER &= ~UART_IER_THRI; - outb(port->IER, port->ioaddr + UART_IER); + __mxser_stop_tx(port); return; } @@ -1679,10 +1675,8 @@ static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port if (port->xmit_cnt < WAKEUP_CHARS) tty_wakeup(tty); - if (port->xmit_cnt <= 0) { - port->IER &= ~UART_IER_THRI; - outb(port->IER, port->ioaddr + UART_IER); - } + if (port->xmit_cnt <= 0) + __mxser_stop_tx(port); } static bool mxser_port_isr(struct mxser_port *port) From 265ceff7aeaa1001b4bea810e1b832d138352b3f Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:15:06 +0200 Subject: [PATCH 205/227] mxser: remove xmit_cnt < 0 tests mxser_port::xmit_cnt is unsigned, it cannot be negative. Therefore remove all the xmit_cnt < 0 tests. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-61-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index e46974e9421a..1a8698e58b1c 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -995,7 +995,7 @@ static void mxser_flush_chars(struct tty_struct *tty) { struct mxser_port *info = tty->driver_data; - if (info->xmit_cnt <= 0 || tty->flow.stopped || !info->port.xmit_buf || + if (!info->xmit_cnt || tty->flow.stopped || !info->port.xmit_buf || (tty->hw_stopped && info->type != PORT_16550A && !info->board->must_hwid)) return; @@ -1652,7 +1652,7 @@ static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port if (port->port.xmit_buf == NULL) return; - if (port->xmit_cnt <= 0 || tty->flow.stopped || + if (!port->xmit_cnt || tty->flow.stopped || (tty->hw_stopped && (port->type != PORT_16550A) && (!port->board->must_hwid))) { @@ -1666,7 +1666,7 @@ static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port outb(port->port.xmit_buf[port->xmit_tail++], port->ioaddr + UART_TX); port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE - 1); - if (--port->xmit_cnt <= 0) + if (!--port->xmit_cnt) break; } while (--count > 0); @@ -1675,7 +1675,7 @@ static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port if (port->xmit_cnt < WAKEUP_CHARS) tty_wakeup(tty); - if (port->xmit_cnt <= 0) + if (!port->xmit_cnt) __mxser_stop_tx(port); } From aaa28e9f250ca0a63b69b7125a10d49e1c264f85 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:15:07 +0200 Subject: [PATCH 206/227] mxser: decrypt FCR values Currently, some of the values written to FCR are magic constants. But they are composed of well-defined bits. Use these named macros in place of the constants. No changes in objdump -d. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-62-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 1a8698e58b1c..c8ba062d8824 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -1580,7 +1580,9 @@ static u8 mxser_receive_chars_old(struct tty_struct *tty, ch = inb(port->ioaddr + UART_RX); if (hwid && (status & UART_LSR_OE)) - outb(0x23, port->ioaddr + UART_FCR); + outb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | + MOXA_MUST_FCR_GDA_MODE_ENABLE, + port->ioaddr + UART_FCR); status &= port->read_status_mask; if (status & port->ignore_status_mask) { if (++ignored > 100) @@ -1693,7 +1695,9 @@ static bool mxser_port_isr(struct mxser_port *port) tty = tty_port_tty_get(&port->port); if (!tty || port->closing || !tty_port_initialized(&port->port)) { status = inb(port->ioaddr + UART_LSR); - outb(0x27, port->ioaddr + UART_FCR); + outb(MOXA_MUST_FCR_GDA_MODE_ENABLE | UART_FCR_ENABLE_FIFO | + UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, + port->ioaddr + UART_FCR); inb(port->ioaddr + UART_MSR); error = true; From 464fbf6c4fc22f13df641bacd85840cfb826ba40 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:15:08 +0200 Subject: [PATCH 207/227] mxser: fix typos around enhanced mode Fix spelling of "enhanced" in macros and comments around them. While "enchance" comes from the original Moxa's driver, I don't think it was meant to be that. From the context, they obviously mean "enhanced". Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-63-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index c8ba062d8824..54b9a9c7c9e9 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -64,23 +64,23 @@ /* * Follow just what Moxa Must chip defines. * - * When LCR register (offset 0x03) writes the following value, the Must chip - * will enter enchance mode. And write value on EFR (offset 0x02) bit 6,7 to + * When LCR register (offset 0x03) is written the following value, the Must chip + * will enter enhanced mode. And a write to EFR (offset 0x02) bit 6,7 will * change bank. */ -#define MOXA_MUST_ENTER_ENCHANCE 0xBF +#define MOXA_MUST_ENTER_ENHANCED 0xBF -/* when enhance mode enabled, access on general bank register */ +/* when enhanced mode is enabled, access to general bank register */ #define MOXA_MUST_GDL_REGISTER 0x07 #define MOXA_MUST_GDL_MASK 0x7F #define MOXA_MUST_GDL_HAS_BAD_DATA 0x80 #define MOXA_MUST_LSR_RERR 0x80 /* error in receive FIFO */ -/* enchance register bank select and enchance mode setting register */ -/* when LCR register equals to 0xBF */ +/* enhanced register bank select and enhanced mode setting register */ +/* This works only when LCR register equals to 0xBF */ #define MOXA_MUST_EFR_REGISTER 0x02 -#define MOXA_MUST_EFR_EFRB_ENABLE 0x10 /* enchance mode enable */ -/* enchance register bank set 0, 1, 2 */ +#define MOXA_MUST_EFR_EFRB_ENABLE 0x10 /* enhanced mode enable */ +/* enhanced register bank set 0, 1, 2 */ #define MOXA_MUST_EFR_BANK0 0x00 #define MOXA_MUST_EFR_BANK1 0x40 #define MOXA_MUST_EFR_BANK2 0x80 @@ -287,7 +287,7 @@ static u8 __mxser_must_set_EFR(unsigned long baseio, u8 clear, u8 set, u8 oldlcr, efr; oldlcr = inb(baseio + UART_LCR); - outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); + outb(MOXA_MUST_ENTER_ENHANCED, baseio + UART_LCR); efr = inb(baseio + MOXA_MUST_EFR_REGISTER); efr &= ~clear; From 202acdaa143a75d54dd9eec905c7faca7071c1a8 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:15:09 +0200 Subject: [PATCH 208/227] mxser: access info->MCR under info->slock info->MCR is protected by info->slock all over the code. Extend the lock in mxser_tiocmget around the info->MCR fetch too. It likely doesn't change anything, but it's always good to be consistent. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-64-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 54b9a9c7c9e9..5dd121450813 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -1162,13 +1162,13 @@ static int mxser_tiocmget(struct tty_struct *tty) if (tty_io_error(tty)) return -EIO; - control = info->MCR; - spin_lock_irqsave(&info->slock, flags); + control = info->MCR; status = inb(info->ioaddr + UART_MSR); if (status & UART_MSR_ANY_DELTA) mxser_check_modem_status(tty, info, status); spin_unlock_irqrestore(&info->slock, flags); + return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) | From 1b3086b6e602f47d73be282d734dbebbce80d39a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:15:10 +0200 Subject: [PATCH 209/227] mxser: use port variable in mxser_set_serial_info mxser_set_serial_info already defined a local 'port' of type struct tty_port. So use it in the code everywhere. This eliminates some text from the code there. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-65-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 5dd121450813..2f724b4d3f43 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -1080,14 +1080,14 @@ static int mxser_set_serial_info(struct tty_struct *tty, if (!capable(CAP_SYS_ADMIN)) { if ((ss->baud_base != MXSER_BAUD_BASE) || - (close_delay != info->port.close_delay) || - (closing_wait != info->port.closing_wait) || - ((ss->flags & ~ASYNC_USR_MASK) != (info->port.flags & ~ASYNC_USR_MASK))) { + (close_delay != port->close_delay) || + (closing_wait != port->closing_wait) || + ((ss->flags & ~ASYNC_USR_MASK) != (port->flags & ~ASYNC_USR_MASK))) { mutex_unlock(&port->mutex); return -EPERM; } - info->port.flags = ((info->port.flags & ~ASYNC_USR_MASK) | - (ss->flags & ASYNC_USR_MASK)); + port->flags = (port->flags & ~ASYNC_USR_MASK) | + (ss->flags & ASYNC_USR_MASK); } else { /* * OK, past this point, all the error checking has been done. From 06cc52ef8284fa8c95552e6ad0da93d89774eb7f Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:15:11 +0200 Subject: [PATCH 210/227] mxser: rename flags to old_speed in mxser_set_serial_info Local 'flags' are used to store speed in mxser_set_serial_info, not actual flags (by doing & ASYNC_SPD_MASK). So rename 'flags' to 'old_speed' (after what it is). Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-66-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 2f724b4d3f43..f238d17d6fdf 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -1057,7 +1057,7 @@ static int mxser_set_serial_info(struct tty_struct *tty, struct tty_port *port = &info->port; speed_t baud; unsigned long sl_flags; - unsigned int flags, close_delay, closing_wait; + unsigned int old_speed, close_delay, closing_wait; int retval = 0; if (tty_io_error(tty)) @@ -1071,7 +1071,7 @@ static int mxser_set_serial_info(struct tty_struct *tty, return -EINVAL; } - flags = port->flags & ASYNC_SPD_MASK; + old_speed = port->flags & ASYNC_SPD_MASK; close_delay = msecs_to_jiffies(ss->close_delay * 10); closing_wait = ss->closing_wait; @@ -1115,7 +1115,7 @@ static int mxser_set_serial_info(struct tty_struct *tty, } if (tty_port_initialized(port)) { - if (flags != (port->flags & ASYNC_SPD_MASK)) { + if (old_speed != (port->flags & ASYNC_SPD_MASK)) { spin_lock_irqsave(&info->slock, sl_flags); mxser_change_speed(tty); spin_unlock_irqrestore(&info->slock, sl_flags); From 5d1ea1ad288fc9e76acb5ec8af1bc16bb799c14f Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:15:12 +0200 Subject: [PATCH 211/227] mxser: introduce mxser_16550A_or_MUST helper This check is used in the code on many places. Either in positive or negative form. So introduce a helper called mxser_16550A_or_MUST for this purpose. And replace all the occurrences. This simplifies many ifs in there. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-67-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index f238d17d6fdf..900ccb2ca166 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -398,6 +398,11 @@ static enum mxser_must_hwid mxser_must_get_hwid(unsigned long io) return MOXA_OTHER_UART; } +static bool mxser_16550A_or_MUST(struct mxser_port *info) +{ + return info->type == PORT_16550A || info->board->must_hwid; +} + static void mxser_process_txrx_fifo(struct mxser_port *info) { unsigned int i; @@ -537,8 +542,7 @@ static void mxser_handle_cts(struct tty_struct *tty, struct mxser_port *info, if (cts) { tty->hw_stopped = 0; - if (info->type != PORT_16550A && - !info->board->must_hwid) + if (!mxser_16550A_or_MUST(info)) __mxser_start_tx(info); tty_wakeup(tty); } @@ -547,7 +551,7 @@ static void mxser_handle_cts(struct tty_struct *tty, struct mxser_port *info, return; tty->hw_stopped = 1; - if (info->type != PORT_16550A && !info->board->must_hwid) + if (!mxser_16550A_or_MUST(info)) __mxser_stop_tx(info); } @@ -626,7 +630,7 @@ static void mxser_change_speed(struct tty_struct *tty) tty_port_set_cts_flow(&info->port, cflag & CRTSCTS); if (cflag & CRTSCTS) { info->IER |= UART_IER_MSI; - if ((info->type == PORT_16550A) || (info->board->must_hwid)) { + if (mxser_16550A_or_MUST(info)) { info->MCR |= UART_MCR_AFE; } else { mxser_handle_cts(tty, info, @@ -962,11 +966,10 @@ static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int cou total += c; } - if (info->xmit_cnt && !tty->flow.stopped) { - if (!tty->hw_stopped || info->type == PORT_16550A || - info->board->must_hwid) + if (info->xmit_cnt && !tty->flow.stopped) + if (!tty->hw_stopped || mxser_16550A_or_MUST(info)) mxser_start_tx(info); - } + return total; } @@ -996,8 +999,7 @@ static void mxser_flush_chars(struct tty_struct *tty) struct mxser_port *info = tty->driver_data; if (!info->xmit_cnt || tty->flow.stopped || !info->port.xmit_buf || - (tty->hw_stopped && info->type != PORT_16550A && - !info->board->must_hwid)) + (tty->hw_stopped && !mxser_16550A_or_MUST(info))) return; mxser_start_tx(info); @@ -1655,9 +1657,7 @@ static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port return; if (!port->xmit_cnt || tty->flow.stopped || - (tty->hw_stopped && - (port->type != PORT_16550A) && - (!port->board->must_hwid))) { + (tty->hw_stopped && !mxser_16550A_or_MUST(port))) { __mxser_stop_tx(port); return; } From a7f6afcd4ec61136fda54abd3555125a32a9d34e Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:15:13 +0200 Subject: [PATCH 212/227] mxser: Documentation, remove traces of callout device Callout devices are ancient history, so remove its traces from mxser's documentation. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-68-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- .../driver-api/serial/moxa-smartio.rst | 46 +++++-------------- 1 file changed, 12 insertions(+), 34 deletions(-) diff --git a/Documentation/driver-api/serial/moxa-smartio.rst b/Documentation/driver-api/serial/moxa-smartio.rst index aedda2546242..3a0a8b502898 100644 --- a/Documentation/driver-api/serial/moxa-smartio.rst +++ b/Documentation/driver-api/serial/moxa-smartio.rst @@ -147,13 +147,7 @@ or:: run the driver. If you prefer module driver, please refer to 3.4. If static driver is required, please refer to 3.5. -Dialin and callout port ------------------------ - - This driver remains traditional serial device properties. There are - two special file name for each serial port. One is dial-in port - which is named "ttyMxx". For callout port, the naming convention - is "cumxx". + The device node is named "ttyMxx". Device naming when more than 2 boards installed ----------------------------------------------- @@ -161,18 +155,13 @@ Device naming when more than 2 boards installed Naming convention for each Smartio/Industio multiport board is pre-defined as below. - ============ =============== ============== - Board Num. Dial-in Port Callout port - 1st board ttyM0 - ttyM7 cum0 - cum7 - 2nd board ttyM8 - ttyM15 cum8 - cum15 - 3rd board ttyM16 - ttyM23 cum16 - cum23 - 4th board ttyM24 - ttym31 cum24 - cum31 - ============ =============== ============== - -.. note:: - - Under Kernel 2.6 and upper, the cum Device is Obsolete. So use ttyM* - device instead. + ============ =============== + Board Num. Device node + 1st board ttyM0 - ttyM7 + 2nd board ttyM8 - ttyM15 + 3rd board ttyM16 - ttyM23 + 4th board ttyM24 - ttyM31 + ============ =============== 3.4 Module driver configuration =============================== @@ -204,13 +193,10 @@ Device naming when more than 2 boards installed # cd /moxa/mxser/driver # ./msmknod - This shell script will require the major number for dial-in - device and callout device to create tty device. You also need - to specify the total installed MOXA board number. Default major - numbers for dial-in device and callout device are 30, 35. If - you need to change to other number, please refer section "3.7" - for more detailed procedure. - Msmknod will delete any special files occupying the same device + This shell script will require the major number for the device. You also + need to specify the total installed MOXA board number. If you need to + change to other number, please refer section "3.7" for more detailed + procedure. Msmknod will delete any special files occupying the same device naming. 3.4.2 Build the MOXA driver and utilities @@ -516,11 +502,3 @@ msterm - Terminal Emulation Load Moxa driver fail, the major number may conflict with other devices. Please refer to previous section 3.7 to change a free major number for Moxa driver. - - Error msg: - Couldn't install MOXA Smartio/Industio family callout driver! - - Solution: - Load Moxa callout driver fail, the callout device major number may - conflict with other devices. Please refer to previous section 3.7 to - change a free callout device major number for Moxa driver. From b34440ffada76527dd39a7a6e753ac31ede3ae88 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:15:14 +0200 Subject: [PATCH 213/227] mxser: Documentation, make the docs up-to-date Remove all the obsolete information from the documentation of mxser driver. Either it was about the out-of-tree driver, or it was superseded by udev et al. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-69-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- .../driver-api/serial/moxa-smartio.rst | 325 +----------------- 1 file changed, 9 insertions(+), 316 deletions(-) diff --git a/Documentation/driver-api/serial/moxa-smartio.rst b/Documentation/driver-api/serial/moxa-smartio.rst index 3a0a8b502898..838888f81b6d 100644 --- a/Documentation/driver-api/serial/moxa-smartio.rst +++ b/Documentation/driver-api/serial/moxa-smartio.rst @@ -2,14 +2,8 @@ MOXA Smartio/Industio Family Device Driver Installation Guide ============================================================= -.. note:: - - This file is outdated. It needs some care in order to make it - updated to Kernel 5.0 and upper - Copyright (C) 2008, Moxa Inc. - -Date: 01/21/2008 +Copyright (C) 2021, Jiri Slaby .. Content @@ -17,12 +11,7 @@ Date: 01/21/2008 2. System Requirement 3. Installation 3.1 Hardware installation - 3.2 Driver files - 3.3 Device naming convention - 3.4 Module driver configuration - 3.5 Static driver configuration for Linux kernel 2.4.x and 2.6.x. - 3.6 Custom configuration - 3.7 Verify driver installation + 3.2 Device naming convention 4. Utilities 5. Setserial 6. Troubleshooting @@ -56,11 +45,8 @@ Date: 01/21/2008 C168H/PCI, CB-108 - This driver and installation procedure have been developed upon Linux Kernel - 2.4.x and 2.6.x. This driver supports Intel x86 hardware platform. In order - to maintain compatibility, this version has also been properly tested with - RedHat, Mandrake, Fedora and S.u.S.E Linux. However, if compatibility problem - occurs, please contact Moxa at support@moxa.com.tw. + If a compatibility problem occurs, please contact Moxa at + support@moxa.com.tw. In addition to device driver, useful utilities are also provided in this version. They are: @@ -77,14 +63,14 @@ Date: 01/21/2008 GNU General Public License in this version. Please refer to GNU General Public License announcement in each source code file for more detail. - In Moxa's Web sites, you may always find latest driver at http://www.moxa.com/. + In Moxa's Web sites, you may always find latest driver at + https://www.moxa.com/. This version of driver can be installed as Loadable Module (Module driver) - or built-in into kernel (Static driver). You may refer to following - installation procedure for suitable one. Before you install the driver, + or built-in into kernel (Static driver). Before you install the driver, please refer to hardware installation procedure in the User's Manual. - We assume the user should be familiar with following documents. + We assume the user should be familiar with following documents: - Serial-HOWTO - Kernel-HOWTO @@ -92,9 +78,6 @@ Date: 01/21/2008 2. System Requirement ^^^^^^^^^^^^^^^^^^^^^ - - Hardware platform: Intel x86 machine - - Kernel version: 2.4.x or 2.6.x - - gcc version 2.72 or later - Maximum 4 boards can be installed in combination 3. Installation @@ -118,35 +101,10 @@ PCI IRQ Sharing together on one system and they can share the same IRQ. -3.2 Driver files -================ - The driver file may be obtained from ftp, CD-ROM or floppy disk. The - first step, anyway, is to copy driver file "mxser.tgz" into specified - directory. e.g. /moxa. The execute commands as below:: - - # cd / - # mkdir moxa - # cd /moxa - # tar xvf /dev/fd0 - -or:: - - # cd / - # mkdir moxa - # cd /moxa - # cp /mnt/cdrom//mxser.tgz . - # tar xvfz mxser.tgz - - -3.3 Device naming convention +3.2 Device naming convention ============================ - You may find all the driver and utilities files in /moxa/mxser. - Following installation procedure depends on the model you'd like to - run the driver. If you prefer module driver, please refer to 3.4. - If static driver is required, please refer to 3.5. - The device node is named "ttyMxx". Device naming when more than 2 boards installed @@ -163,245 +121,6 @@ Device naming when more than 2 boards installed 4th board ttyM24 - ttyM31 ============ =============== -3.4 Module driver configuration -=============================== - - Module driver is easiest way to install. If you prefer static driver - installation, please skip this paragraph. - - - ------------- Prepare to use the MOXA driver -------------------- - -3.4.1 Create tty device with correct major number -------------------------------------------------- - - Before using MOXA driver, your system must have the tty devices - which are created with driver's major number. We offer one shell - script "msmknod" to simplify the procedure. - This step is only needed to be executed once. But you still - need to do this procedure when: - - a. You change the driver's major number. Please refer the "3.7" - section. - b. Your total installed MOXA boards number is changed. Maybe you - add/delete one MOXA board. - c. You want to change the tty name. This needs to modify the - shell script "msmknod" - - The procedure is:: - - # cd /moxa/mxser/driver - # ./msmknod - - This shell script will require the major number for the device. You also - need to specify the total installed MOXA board number. If you need to - change to other number, please refer section "3.7" for more detailed - procedure. Msmknod will delete any special files occupying the same device - naming. - -3.4.2 Build the MOXA driver and utilities ------------------------------------------ - - Before using the MOXA driver and utilities, you need compile the - all the source code. This step is only need to be executed once. - But you still re-compile the source code if you modify the source - code. For example, if you change the driver's major number (see - "3.7" section), then you need to do this step again. - - Find "Makefile" in /moxa/mxser, then run - - # make clean; make install - - ..note:: - - For Red Hat 9, Red Hat Enterprise Linux AS3/ES3/WS3 & Fedora Core1: - # make clean; make installsp1 - - For Red Hat Enterprise Linux AS4/ES4/WS4: - # make clean; make installsp2 - - The driver files "mxser.o" and utilities will be properly compiled - and copied to system directories respectively. - -------------- Load MOXA driver-------------------- - -3.4.3 Load the MOXA driver --------------------------- - - :: - - # modprobe mxser - - will activate the module driver. You may run "lsmod" to check - if "mxser" is activated. - -------------- Load MOXA driver on boot -------------------- - -3.4.4 Load the mxser driver ---------------------------- - - - For the above description, you may manually execute - "modprobe mxser" to activate this driver and run - "rmmod mxser" to remove it. - - However, it's better to have a boot time configuration to - eliminate manual operation. Boot time configuration can be - achieved by rc file. We offer one "rc.mxser" file to simplify - the procedure under "moxa/mxser/driver". - - Run following command for setting rc files:: - - # cd /moxa/mxser/driver - # cp ./rc.mxser /etc/rc.d - # cd /etc/rc.d - - Check "rc.serial" is existed or not. If "rc.serial" doesn't exist, - create it by vi, run "chmod 755 rc.serial" to change the permission. - - Add "/etc/rc.d/rc.mxser" in last line. - - Reboot and check if moxa.o activated by "lsmod" command. - -3.5 Static driver configuration for Linux kernel 2.4.x and 2.6.x -================================================================ - - Note: - To use static driver, you must install the linux kernel - source package. - -3.5.1 Backup the built-in driver in the kernel ----------------------------------------------- - - :: - - # cd /usr/src/linux/drivers/char - # mv mxser.c mxser.c.old - - For Red Hat 7.x user, you need to create link: - # cd /usr/src - # ln -s linux-2.4 linux - -3.5.2 Create link ------------------ - :: - - # cd /usr/src/linux/drivers/char - # ln -s /moxa/mxser/driver/mxser.c mxser.c - -3.5.3 Setup kernel configuration --------------------------------- - - Configure the kernel:: - - # cd /usr/src/linux - # make menuconfig - - You will go into a menu-driven system. Please select [Character - devices][Non-standard serial port support], enable the [Moxa - SmartIO support] driver with "[*]" for built-in (not "[M]"), then - select [Exit] to exit this program. - -3.5.4 Rebuild kernel --------------------- - - The following are for Linux kernel rebuilding, for your - reference only. - - For appropriate details, please refer to the Linux document: - - a. Run the following commands:: - - cd /usr/src/linux - make clean # take a few minutes - make dep # take a few minutes - make bzImage # take probably 10-20 minutes - make install # copy boot image to correct position - - f. Please make sure the boot kernel (vmlinuz) is in the - correct position. - g. If you use 'lilo' utility, you should check /etc/lilo.conf - 'image' item specified the path which is the 'vmlinuz' path, - or you will load wrong (or old) boot kernel image (vmlinuz). - After checking /etc/lilo.conf, please run "lilo". - - Note that if the result of "make bzImage" is ERROR, then you have to - go back to Linux configuration Setup. Type "make menuconfig" in - directory /usr/src/linux. - - -3.5.5 Make tty device and special file --------------------------------------- - - :: - # cd /moxa/mxser/driver - # ./msmknod - -3.5.6 Make utility ------------------- - - :: - - # cd /moxa/mxser/utility - # make clean; make install - -3.5.7 Reboot ------------- - - - -3.6 Custom configuration -======================== - - Although this driver already provides you default configuration, you - still can change the device name and major number. The instruction to - change these parameters are shown as below. - -a. Change Device name - - If you'd like to use other device names instead of default naming - convention, all you have to do is to modify the internal code - within the shell script "msmknod". First, you have to open "msmknod" - by vi. Locate each line contains "ttyM" and "cum" and change them - to the device name you desired. "msmknod" creates the device names - you need next time executed. - -b. Change Major number - - If major number 30 and 35 had been occupied, you may have to select - 2 free major numbers for this driver. There are 3 steps to change - major numbers. - -3.6.1 Find free major numbers ------------------------------ - - In /proc/devices, you may find all the major numbers occupied - in the system. Please select 2 major numbers that are available. - e.g. 40, 45. - -3.6.2 Create special files --------------------------- - - Run /moxa/mxser/driver/msmknod to create special files with - specified major numbers. - -3.6.3 Modify driver with new major number ------------------------------------------ - - Run vi to open /moxa/mxser/driver/mxser.c. Locate the line - contains "MXSERMAJOR". Change the content as below:: - - #define MXSERMAJOR 40 - #define MXSERCUMAJOR 45 - - 3.6.4 Run "make clean; make install" in /moxa/mxser/driver. - -3.7 Verify driver installation -============================== - - You may refer to /var/log/messages to check the latest status - log reported by this driver whenever it's activated. - 4. Utilities ^^^^^^^^^^^^ @@ -409,9 +128,6 @@ b. Change Major number msterm. These 3 utilities are released in form of source code. They should be compiled into executable file and copied into /usr/bin. - Before using these utilities, please load driver (refer 3.4 & 3.5) and - make sure you had run the "msmknod" utility. - msdiag - Diagnostic =================== @@ -479,26 +195,3 @@ msterm - Terminal Emulation Solution: To avoid this problem, please unplug fifth and after board, because Moxa driver supports up to 4 boards. - - Error msg: - Request_irq fail, IRQ(?) may be conflict with another device. - - Solution: - Other PCI or ISA devices occupy the assigned IRQ. If you are not sure - which device causes the situation, please check /proc/interrupts to find - free IRQ and simply change another free IRQ for Moxa board. - - Error msg: - Board #: C1xx Series(CAP=xxx) interrupt number invalid. - - Solution: - Each port within the same multiport board shares the same IRQ. Please set - one IRQ (IRQ doesn't equal to zero) for one Moxa board. - - Error msg: - Couldn't install MOXA Smartio/Industio family driver! - - Solution: - Load Moxa driver fail, the major number may conflict with other devices. - Please refer to previous section 3.7 to change a free major number for - Moxa driver. From 0dd77d02c3333c14f8892b379fae3f731af23897 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:15:15 +0200 Subject: [PATCH 214/227] mxser: Documentation, fix typos Fix some typos in the mxser's documentation. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-70-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- .../driver-api/serial/moxa-smartio.rst | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/Documentation/driver-api/serial/moxa-smartio.rst b/Documentation/driver-api/serial/moxa-smartio.rst index 838888f81b6d..af25bc5cc3e6 100644 --- a/Documentation/driver-api/serial/moxa-smartio.rst +++ b/Documentation/driver-api/serial/moxa-smartio.rst @@ -20,7 +20,7 @@ Copyright (C) 2021, Jiri Slaby ^^^^^^^^^^^^^^^ The Smartio/Industio/UPCI family Linux driver supports following multiport - boards. + boards: - 2 ports multiport board CP-102U, CP-102UL, CP-102UF @@ -63,10 +63,10 @@ Copyright (C) 2021, Jiri Slaby GNU General Public License in this version. Please refer to GNU General Public License announcement in each source code file for more detail. - In Moxa's Web sites, you may always find latest driver at + In Moxa's Web sites, you may always find the latest driver at https://www.moxa.com/. - This version of driver can be installed as Loadable Module (Module driver) + This version of driver can be installed as a Loadable Module (Module driver) or built-in into kernel (Static driver). Before you install the driver, please refer to hardware installation procedure in the User's Manual. @@ -89,9 +89,9 @@ Copyright (C) 2021, Jiri Slaby PCI/UPCI board -------------- - You may need to adjust IRQ usage in BIOS to avoid from IRQ conflict - with other ISA devices. Please refer to hardware installation - procedure in User's Manual in advance. + You may need to adjust IRQ usage in BIOS to avoid IRQ conflict with other + ISA devices. Please refer to hardware installation procedure in User's + Manual in advance. PCI IRQ Sharing --------------- @@ -132,7 +132,7 @@ msdiag - Diagnostic =================== This utility provides the function to display what Moxa Smartio/Industio - board found by driver in the system. + board was found by the driver in the system. msmon - Port Monitoring ======================= @@ -162,23 +162,23 @@ msterm - Terminal Emulation Supported Setserial parameters are listed as below. - ============== ========================================================= - uart set UART type(16450-->disable FIFO, 16550A-->enable FIFO) - close_delay set the amount of time(in 1/100 of a second) that DTR + ============== ============================================================= + uart set UART type(16450 --> disable FIFO, 16550A --> enable FIFO) + close_delay set the amount of time (in 1/100 of a second) that DTR should be kept low while being closed. - closing_wait set the amount of time(in 1/100 of a second) that the + closing_wait set the amount of time (in 1/100 of a second) that the serial port should wait for data to be drained while - being closed, before the receiver is disable. - spd_hi Use 57.6kb when the application requests 38.4kb. - spd_vhi Use 115.2kb when the application requests 38.4kb. - spd_shi Use 230.4kb when the application requests 38.4kb. - spd_warp Use 460.8kb when the application requests 38.4kb. - spd_normal Use 38.4kb when the application requests 38.4kb. - spd_cust Use the custom divisor to set the speed when the + being closed, before the receiver is disabled. + spd_hi Use 57.6kb when the application requests 38.4kb. + spd_vhi Use 115.2kb when the application requests 38.4kb. + spd_shi Use 230.4kb when the application requests 38.4kb. + spd_warp Use 460.8kb when the application requests 38.4kb. + spd_normal Use 38.4kb when the application requests 38.4kb. + spd_cust Use the custom divisor to set the speed when the application requests 38.4kb. - divisor This option set the custom division. - baud_base This option set the base baud rate. - ============== ========================================================= + divisor This option sets the custom division. + baud_base This option sets the base baud rate. + ============== ============================================================= 6. Troubleshooting ^^^^^^^^^^^^^^^^^^ From 18aaa97eee7ddb770963d84aeaf5e95a8f8af088 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 18 Jun 2021 08:15:16 +0200 Subject: [PATCH 215/227] MAINTAINERS: add me back as mxser maintainer I was given a few cards from MOXA (thanks a lot). Provided I can now test changes, I cleaned up the driver a bit and can continue maintaining it. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210618061516.662-71-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 54053c71785c..25d7d864cfbd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12389,7 +12389,8 @@ F: drivers/media/pci/meye/ F: include/uapi/linux/meye.h MOXA SMARTIO/INDUSTIO/INTELLIO SERIAL CARD -S: Orphan +M: Jiri Slaby +S: Maintained F: Documentation/driver-api/serial/moxa-smartio.rst F: drivers/tty/mxser.* From b61c8bf4694b5115766849378dcb8787ff54e65e Mon Sep 17 00:00:00 2001 From: Jason Li Date: Tue, 15 Jun 2021 09:57:48 -0700 Subject: [PATCH 216/227] tty: serial: Add UART driver for Cortina-Access platform This driver supports Cortina Access UART IP integrated in most all CAXXXX line of SoCs. Earlycom is also supported Signed-off-by: Jason Li Link: https://lore.kernel.org/r/20210615165750.31261-1-alex.nemirovsky@cortina-access.com Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 5 + drivers/tty/serial/Kconfig | 19 + drivers/tty/serial/Makefile | 1 + drivers/tty/serial/serial_cortina-access.c | 798 +++++++++++++++++++++ 4 files changed, 823 insertions(+) create mode 100644 drivers/tty/serial/serial_cortina-access.c diff --git a/MAINTAINERS b/MAINTAINERS index 25d7d864cfbd..f20502df69b8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4680,6 +4680,11 @@ S: Maintained W: http://www.fi.muni.cz/~kas/cosa/ F: drivers/net/wan/cosa* +CORTINA-ACCESS SERIAL CONSOLE DRIVER +M: Jason Li +S: Supported +F: drivers/tty/serial/serial_cortina-access.c + COUNTER SUBSYSTEM M: William Breathitt Gray L: linux-iio@vger.kernel.org diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 24282ad99d85..2fa39cd78c56 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1561,6 +1561,25 @@ config SERIAL_LITEUART_CONSOLE and warnings and which allows logins in single user mode). Otherwise, say 'N'. +config SERIAL_CORTINA_ACCESS + tristate "Cortina-Access serial port support" + select SERIAL_CORE + help + This driver is for Cortina-Access SoC's UART. If you have a machine + based on the Cortina-Access SoC and wish to use the serial port, + say 'Y' here. Otherwise, say 'N'. + +config SERIAL_CORTINA_ACCESS_CONSOLE + bool "Console on Cortina-ACCESS serial port" + depends on SERIAL_CORTINA_ACCESS=y + select SERIAL_CORE_CONSOLE + select SERIAL_EARLYCON + help + Say 'Y' here if you wish to use Cortina-Access UART as the system + console. (the system console is the device which receives all kernel + messages and warnings and which allows logins in single user mode) + /dev/ttyS* is default device node. + endmenu config SERIAL_MCTRL_GPIO diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index 7da0856cd198..f3f531a48854 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -87,6 +87,7 @@ obj-$(CONFIG_SERIAL_RDA) += rda-uart.o obj-$(CONFIG_SERIAL_MILBEAUT_USIO) += milbeaut_usio.o obj-$(CONFIG_SERIAL_SIFIVE) += sifive.o obj-$(CONFIG_SERIAL_LITEUART) += liteuart.o +obj-$(CONFIG_SERIAL_CORTINA_ACCESS) += serial_cortina-access.o # GPIOLIB helpers for modem control lines obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o diff --git a/drivers/tty/serial/serial_cortina-access.c b/drivers/tty/serial/serial_cortina-access.c new file mode 100644 index 000000000000..b4b9362bb4e6 --- /dev/null +++ b/drivers/tty/serial/serial_cortina-access.c @@ -0,0 +1,798 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * UART driver for Cortina-Access Soc platform + * Copyright (C) 2021 Cortina-Access Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*************************************** + * UART Related registers + ****************************************/ +/* register definitions */ +#define CFG 0x00 +#define FC 0x04 +#define RX_SAMPLE 0x08 +#define RT_TUNE 0x0C +#define TX_DAT 0x10 +#define RX_DAT 0x14 +#define INFO 0x18 +#define IE 0x1C +#define INT 0x24 +#define STATUS 0x2C + +/* CFG */ +#define CFG_STOP_2BIT BIT(2) +#define CFG_PARITY_EVEN BIT(3) +#define CFG_PARITY_EN BIT(4) +#define CFG_TX_EN BIT(5) +#define CFG_RX_EN BIT(6) +#define CFG_UART_EN BIT(7) +#define CFG_BAUD_SART_SHIFT 8 + +/* INFO */ +#define INFO_TX_EMPTY BIT(3) +#define INFO_TX_FULL BIT(2) +#define INFO_RX_EMPTY BIT(1) +#define INFO_RX_FULL BIT(0) + +/* Interrupt */ +#define RX_BREAK BIT(7) +#define RX_FIFO_NONEMPTYE BIT(6) +#define TX_FIFO_EMPTYE BIT(5) +#define RX_FIFO_UNDERRUNE BIT(4) +#define RX_FIFO_OVERRUNE BIT(3) +#define RX_PARITY_ERRE BIT(2) +#define RX_STOP_ERRE BIT(1) +#define TX_FIFO_OVERRUNE BIT(0) + +#define TX_TIMEOUT 5000 +#define UART_NR 4 +#define CA_UART_NAME_LEN 32 +struct cortina_uart_port { + struct uart_port uart; + char name[CA_UART_NAME_LEN]; + char has_bi; + unsigned int may_wakeup; +}; + +static struct cortina_uart_port *cortina_uart_ports; + +static irqreturn_t cortina_uart_interrupt(int irq, void *dev_id); + +/* Return uart_port pointer base on index */ +struct cortina_uart_port *cortina_uart_get_port(unsigned int index) +{ + struct cortina_uart_port *pca_port = cortina_uart_ports; + + if (index >= UART_NR) { + /* return 1st element if invalid index */ + index = 0; + } + + pca_port += index; + + return pca_port; +} + +/* uart_ops functions */ +static unsigned int cortina_uart_tx_empty(struct uart_port *port) +{ + /* Return 0 on FIXO condition, TIOCSER_TEMT otherwise */ + return (readl(port->membase + INFO) & INFO_TX_EMPTY) ? TIOCSER_TEMT : 0; +} + +static void cortina_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ +/* + * Even if we do not support configuring the modem control lines, this + * function must be proided to the serial core. + * port->ops->set_mctrl() be called in uart_configure_port() + */ +} + +static unsigned int cortina_uart_get_mctrl(struct uart_port *port) +{ + /* Unimplemented signals asserted, per Documentation/serial/driver */ + return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; +} + +static void cortina_uart_stop_tx(struct uart_port *port) +{ + /* Turn off Tx interrupts. The port lock is held at this point */ + unsigned int reg_v; + + reg_v = readl(port->membase + IE); + writel(reg_v & ~TX_FIFO_EMPTYE, port->membase + IE); +} + +static inline void cortina_transmit_buffer(struct uart_port *port) +{ + struct circ_buf *xmit = &port->state->xmit; + + if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { + cortina_uart_stop_tx(port); + return; + } + + do { + /* send xmit->buf[xmit->tail] out the port here */ + writel(xmit->buf[xmit->tail], port->membase + TX_DAT); + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + port->icount.tx++; + if ((readl(port->membase + INFO) & INFO_TX_FULL)) + break; + } while (!uart_circ_empty(xmit)); + + if (uart_circ_empty(xmit)) + cortina_uart_stop_tx(port); +} + +static void cortina_uart_start_tx(struct uart_port *port) +{ + /* Turn on Tx interrupts. The port lock is held at this point */ + unsigned int reg_v; + + reg_v = readl(port->membase + IE); + writel((reg_v | TX_FIFO_EMPTYE), port->membase + IE); + + reg_v = readl(port->membase + CFG); + writel(reg_v | CFG_TX_EN, port->membase + CFG); + + if (readl(port->membase + INFO) & INFO_TX_EMPTY) + cortina_transmit_buffer(port); +} + +static void cortina_uart_stop_rx(struct uart_port *port) +{ + /* Turn off Rx interrupts. The port lock is held at this point */ + unsigned int reg_v; + + reg_v = readl(port->membase + IE); + writel(reg_v & ~RX_FIFO_NONEMPTYE, port->membase + IE); +} + +static void cortina_uart_enable_ms(struct uart_port *port) +{ + /* Nope, you really can't hope to attach a modem to this */ +} + +static int cortina_uart_startup(struct uart_port *port) +{ + unsigned int reg_v; + int retval; + unsigned long flags; + + /* Disable interrupt */ + writel(0, port->membase + IE); + + retval = + request_irq(port->irq, cortina_uart_interrupt, 0, "cortina_uart", + port); + if (retval) + return retval; + + spin_lock_irqsave(&port->lock, flags); + + reg_v = readl(port->membase + CFG); + reg_v |= (CFG_UART_EN | CFG_TX_EN | CFG_RX_EN | 0x3 /* 8-bits data */); + writel(reg_v, port->membase + CFG); + reg_v = readl(port->membase + IE); + writel(reg_v | RX_FIFO_NONEMPTYE | TX_FIFO_EMPTYE, port->membase + IE); + + spin_unlock_irqrestore(&port->lock, flags); + return 0; +} + +static void cortina_uart_shutdown(struct uart_port *port) +{ + cortina_uart_stop_tx(port); + cortina_uart_stop_rx(port); + free_irq(port->irq, port); +} + +static void cortina_uart_set_termios(struct uart_port *port, + struct ktermios *termios, + struct ktermios *old) +{ + unsigned long flags; + int baud; + unsigned int reg_v, sample_freq = 0; + + baud = uart_get_baud_rate(port, termios, old, 0, 230400); + reg_v = readl(port->membase + CFG); + /* mask off the baud settings */ + reg_v &= 0xff; + reg_v |= (port->uartclk / baud) << CFG_BAUD_SART_SHIFT; + + /* Sampling rate should be half of baud count */ + sample_freq = (reg_v >> CFG_BAUD_SART_SHIFT) / 2; + + /* See include/uapi/asm-generic/termbits.h for CSIZE definition */ + /* mask off the data width */ + reg_v &= 0xfffffffc; + switch (termios->c_cflag & CSIZE) { + case CS5: + reg_v |= 0x0; + break; + case CS6: + reg_v |= 0x1; + break; + case CS7: + reg_v |= 0x2; + break; + case CS8: + default: + reg_v |= 0x3; + break; + } + + /* mask off Stop bits */ + reg_v &= ~(CFG_STOP_2BIT); + if (termios->c_cflag & CSTOPB) + reg_v |= CFG_STOP_2BIT; + + /* Parity */ + reg_v &= ~(CFG_PARITY_EN); + reg_v |= CFG_PARITY_EVEN; + if (termios->c_cflag & PARENB) { + reg_v |= CFG_PARITY_EN; + if (termios->c_cflag & PARODD) + reg_v &= ~(CFG_PARITY_EVEN); + } + + spin_lock_irqsave(&port->lock, flags); + writel(reg_v, port->membase + CFG); + writel(sample_freq, port->membase + RX_SAMPLE); + spin_unlock_irqrestore(&port->lock, flags); +} + +static const char *cortina_uart_type(struct uart_port *port) +{ + return container_of(port, struct cortina_uart_port, uart)->name; +} + +static void cortina_uart_config_port(struct uart_port *port, int flags) +{ + /* + * Driver core for serial ports forces a non-zero value for port type. + * Write an arbitrary value here to accommodate the serial core driver, + * as ID part of UAPI is redundant. + */ + port->type = 1; +} + +static int cortina_uart_verify_port(struct uart_port *port, + struct serial_struct *ser) +{ + if (ser->type != PORT_UNKNOWN && ser->type != 1) + return -EINVAL; + return 0; +} + +static void cortina_access_power(struct uart_port *port, unsigned int state, + unsigned int oldstate) +{ + unsigned int reg_v; + + /* Read Config register */ + reg_v = readl(port->membase + CFG); + switch (state) { + case UART_PM_STATE_ON: + reg_v |= CFG_UART_EN; + break; + case UART_PM_STATE_OFF: + reg_v &= ~CFG_UART_EN; + break; + default: + pr_err("cortina-access serial: Unknown PM state %d\n", state); + } + writel(reg_v, port->membase + CFG); +} + +#ifdef CONFIG_CONSOLE_POLL +static int cortina_poll_get_char(struct uart_port *port) +{ + unsigned int rx; + + if (readl(port->membase + INFO) & INFO_RX_EMPTY) + return NO_POLL_CHAR; + + rx = readl(port->membase + RX_DAT); + + return rx; +} + +static void cortina_poll_put_char(struct uart_port *port, unsigned char c) +{ + unsigned long time_out; + + time_out = jiffies + usecs_to_jiffies(TX_TIMEOUT); + + while (time_before(jiffies, time_out) && + (readl(port->membase + INFO) & INFO_TX_FULL)) + cpu_relax(); + + /* Give up if FIFO stuck! */ + if ((readl(port->membase + INFO) & INFO_TX_FULL)) + return; + + writel(c, port->membase + TX_DAT); +} + +#endif + +static const struct uart_ops cortina_uart_ops = { + .tx_empty = cortina_uart_tx_empty, + .set_mctrl = cortina_uart_set_mctrl, + .get_mctrl = cortina_uart_get_mctrl, + .stop_tx = cortina_uart_stop_tx, + .start_tx = cortina_uart_start_tx, + .stop_rx = cortina_uart_stop_rx, + .enable_ms = cortina_uart_enable_ms, + .startup = cortina_uart_startup, + .shutdown = cortina_uart_shutdown, + .set_termios = cortina_uart_set_termios, + .type = cortina_uart_type, + .config_port = cortina_uart_config_port, + .verify_port = cortina_uart_verify_port, + .pm = cortina_access_power, +#ifdef CONFIG_CONSOLE_POLL + .poll_get_char = cortina_poll_get_char, + .poll_put_char = cortina_poll_put_char, +#endif +}; + +static inline void cortina_uart_interrupt_rx_chars(struct uart_port *port, + unsigned long status) +{ + struct tty_port *ttyport = &port->state->port; + unsigned int ch; + unsigned int rx, flg; + struct cortina_uart_port *pca_port; + + rx = readl(port->membase + INFO); + if (INFO_RX_EMPTY & rx) + return; + + if (status & RX_FIFO_OVERRUNE) + port->icount.overrun++; + + pca_port = cortina_uart_get_port(port->line); + + /* Read the character while FIFO is not empty */ + do { + flg = TTY_NORMAL; + port->icount.rx++; + ch = readl(port->membase + RX_DAT); + if (status & RX_PARITY_ERRE) { + port->icount.parity++; + flg = TTY_PARITY; + } + + if (pca_port->has_bi) { + /* If BI supported ? */ + if (status & RX_BREAK) { + port->icount.brk++; + if (uart_handle_break(port)) + goto ignore; + } + } else { + /* Treat stop err as BI */ + if (status & RX_STOP_ERRE) { + port->icount.brk++; + if (uart_handle_break(port)) + goto ignore; + } + } + if (!(ch & 0x100)) /* RX char is not valid */ + goto ignore; + + if (uart_handle_sysrq_char(port, (unsigned char)ch)) + goto ignore; + + tty_insert_flip_char(ttyport, ch, flg); + ignore: + rx = readl(port->membase + INFO); + } while (!(INFO_RX_EMPTY & rx)); + + spin_unlock(&port->lock); + tty_flip_buffer_push(ttyport); + spin_lock(&port->lock); +} + +static inline void cortina_uart_interrupt_tx_chars(struct uart_port *port) +{ + struct circ_buf *xmit = &port->state->xmit; + + /* Process out of band chars */ + if (port->x_char) { + /* Send next char */ + writel(port->x_char, port->membase + TX_DAT); + goto done; + } + + /* Nothing to do ? */ + if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { + cortina_uart_stop_tx(port); + goto done; + } + + cortina_transmit_buffer(port); + + /* Wake up */ + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(port); + + /* Maybe we're done after all */ + if (uart_circ_empty(xmit)) + cortina_uart_stop_tx(port); + + done: + return; +} + +irqreturn_t cortina_uart_interrupt(int irq, void *dev_id) +{ + struct uart_port *port = (struct uart_port *)dev_id; + unsigned int irq_status; + + spin_lock(&port->lock); + + /* Clear interrupt! */ + irq_status = readl(port->membase + INT); + writel(irq_status, port->membase + INT); + + /* Process any Rx chars first */ + cortina_uart_interrupt_rx_chars(port, irq_status); + /* Then use any Tx space */ + cortina_uart_interrupt_tx_chars(port); + + spin_unlock(&port->lock); + + return IRQ_HANDLED; +} + +#ifdef CONFIG_SERIAL_CORTINA_ACCESS_CONSOLE +void cortina_console_write(struct console *co, const char *s, + unsigned int count) +{ + struct uart_port *port; + struct cortina_uart_port *pca_port; + unsigned int i, previous; + unsigned long flags; + int locked; + + pca_port = cortina_uart_get_port(co->index); + port = &pca_port->uart; + + local_irq_save(flags); + if (port->sysrq) { + locked = 0; + } else if (oops_in_progress) { + locked = spin_trylock(&port->lock); + } else { + spin_lock(&port->lock); + locked = 1; + } + + /* Save current state */ + previous = readl(port->membase + IE); + /* Disable Tx interrupts so this all goes out in one go */ + cortina_uart_stop_tx(port); + + /* Write all the chars */ + for (i = 0; i < count; i++) { + /* Wait the TX buffer to be empty, which can't take forever */ + while (!(readl(port->membase + INFO) & INFO_TX_EMPTY)) + cpu_relax(); + + /* Send the char */ + writel(*s, port->membase + TX_DAT); + + /* CR/LF stuff */ + if (*s++ == '\n') { + /* Wait the TX buffer to be empty */ + while (!(readl(port->membase + INFO) & INFO_TX_EMPTY)) + cpu_relax(); + writel('\r', port->membase + TX_DAT); + } + } + + writel(previous, port->membase + IE); /* Put it all back */ + + if (locked) + spin_unlock(&port->lock); + local_irq_restore(flags); +} + +static int __init cortina_console_setup(struct console *co, char *options) +{ + struct uart_port *port; + struct cortina_uart_port *pca_port; + int baud = 115200; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + + if (co->index < 0 || co->index >= UART_NR) + return -ENODEV; + + pca_port = cortina_uart_get_port(co->index); + port = &pca_port->uart; + + /* This isn't going to do much, but it might change the baud rate. */ + if (options) + uart_parse_options(options, &baud, &parity, &bits, &flow); + + return uart_set_options(port, co, baud, parity, bits, flow); +} + +static struct uart_driver cortina_uart_driver; + +static struct console cortina_console = { + .name = "ttyS", + .write = cortina_console_write, + .device = uart_console_device, + .setup = cortina_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, /* Only possible option. */ + .data = &cortina_uart_driver, +}; +#define CORTINA_CONSOLE (&cortina_console) + +/* Support EARLYCON */ +static void cortina_putc(struct uart_port *port, int c) +{ + unsigned int tmout; + + /* No jiffie at early boot stage! + * Wait up to 5ms for the character to be sent. + */ + tmout = TX_TIMEOUT; + while (--tmout) { + if (!(readl(port->membase + INFO) & INFO_TX_FULL)) + break; + udelay(1); + } + + /* Give up if FIFO stuck! */ + while ((readl(port->membase + INFO) & INFO_TX_FULL)) + return; + + /* Send the char */ + writel(c, port->membase + TX_DAT); +} + +static void cortina_early_write(struct console *con, const char *s, + unsigned int n) +{ + struct earlycon_device *dev = con->data; + + uart_console_write(&dev->port, s, n, cortina_putc); +} + +static int __init cortina_early_console_setup(struct earlycon_device *device, + const char *opt) +{ + if (!device->port.membase) + return -ENODEV; + + device->con->write = cortina_early_write; + return 0; +} + +EARLYCON_DECLARE(serial, cortina_early_console_setup); +OF_EARLYCON_DECLARE(serial, "cortina-access,serial", cortina_early_console_setup); +#else +#define CORTINA_CONSOLE NULL +#endif + +static struct uart_driver cortina_uart_driver = { + .owner = THIS_MODULE, + .driver_name = "cortina-access_uart", + .dev_name = "ttyS", + .major = TTY_MAJOR, + .minor = 64, + .nr = UART_NR, + .cons = CORTINA_CONSOLE, +}; + +/* Match table for of_platform binding */ +static const struct of_device_id cortina_uart_of_match[] = { + {.compatible = "cortina-access,serial",}, + {} +}; +MODULE_DEVICE_TABLE(of, cortina_uart_of_match); + +static int serial_cortina_probe(struct platform_device *pdev) +{ + int ret; + void __iomem *base; + struct cortina_uart_port *port; + const struct of_device_id *match; + + /* assign DT node pointer */ + struct device_node *np = pdev->dev.of_node; + struct resource mem_resource; + u32 of_clock_frequency; + struct clk *pclk_info; + int uart_idx; + + /* search DT for a match */ + match = of_match_device(cortina_uart_of_match, &pdev->dev); + if (!match) + return -EINVAL; + + if (cortina_uart_ports == NULL) + cortina_uart_ports = kzalloc(UART_NR * sizeof(struct cortina_uart_port), + GFP_KERNEL); + + port = cortina_uart_ports; + for (uart_idx = 0; uart_idx < UART_NR; ++uart_idx) { + /* Find first empty slot */ + if (strlen(port->name) == 0) + break; + port++; + } + + if (uart_idx >= UART_NR) + return -EINVAL; + + snprintf(port->name, sizeof(port->name), "Cortina-Access UART%d", uart_idx); + + /* Retrieve HW base address */ + ret = of_address_to_resource(np, 0, &mem_resource); + if (ret) { + dev_warn(&pdev->dev, "invalid address %d\n", ret); + return ret; + } + + base = devm_ioremap(&pdev->dev, mem_resource.start, + resource_size(&mem_resource)); + if (!base) { + devm_kfree(&pdev->dev, port); + return -ENOMEM; + } + + /* assign reg base and irq from DT */ + port->uart.irq = irq_of_parse_and_map(np, 0); + port->uart.membase = base; + port->uart.mapbase = mem_resource.start; + port->uart.ops = &cortina_uart_ops; + port->uart.dev = &pdev->dev; + port->uart.line = uart_idx; + port->uart.has_sysrq = IS_ENABLED(CONFIG_SERIAL_CORTINA_ACCESS_CONSOLE); + + /* get clock-freqency tuple from DT and store value */ + if (of_property_read_u32(np, "clock-frequency", &of_clock_frequency)) { + /* If we are here, it means DT node did not contain + * clock-frequency tuple. Therefore, instead try to get + * clk rate through the clk driver that DT has stated + * we are consuming. + */ + pclk_info = clk_get(&pdev->dev, NULL); + if (IS_ERR(pclk_info)) { + dev_warn(&pdev->dev, + "clk or clock-frequency not defined\n"); + return PTR_ERR(pclk_info); + } + + clk_prepare_enable(pclk_info); + of_clock_frequency = clk_get_rate(pclk_info); + } + port->uart.uartclk = of_clock_frequency; + + if (of_property_read_bool(np, "wakeup-source")) + port->may_wakeup = true; + if (of_property_read_bool(np, "break-indicator")) + port->has_bi = true; + + port->uart.type = PORT_UNKNOWN; + + if (port->may_wakeup) + device_init_wakeup(&pdev->dev, true); + + ret = uart_add_one_port(&cortina_uart_driver, &port->uart); + if (ret) + return ret; + + platform_set_drvdata(pdev, port); + + return 0; +} + +static int serial_cortina_remove(struct platform_device *pdev) +{ + struct uart_port *port = platform_get_drvdata(pdev); + struct cortina_uart_port *pca_port; + + if (port) { + pca_port = cortina_uart_get_port(port->line); + memset(pca_port->name, 0, CA_UART_NAME_LEN); + uart_remove_one_port(&cortina_uart_driver, port); + } + + platform_set_drvdata(pdev, NULL); + return 0; +} + +#ifdef CONFIG_PM +static int serial_cortina_suspend(struct platform_device *pdev, + pm_message_t state) +{ + struct cortina_uart_port *p = + (struct cortina_uart_port *)pdev->dev.driver_data; + + uart_suspend_port(&cortina_uart_driver, &p->uart); + + return 0; +} + +static int serial_cortina_resume(struct platform_device *pdev) +{ + struct cortina_uart_port *p = + (struct cortina_uart_port *)pdev->dev.driver_data; + + uart_resume_port(&cortina_uart_driver, &p->uart); + + return 0; +} +#else +#define serial_cortina_suspend NULL +#define serial_cortina_resume NULL +#endif + +static struct platform_driver serial_cortina_driver = { + .probe = serial_cortina_probe, + .remove = serial_cortina_remove, +#ifdef CONFIG_PM + .suspend = serial_cortina_suspend, + .resume = serial_cortina_resume, +#endif + .driver = { + .name = "cortina-access_serial", + .owner = THIS_MODULE, + .of_match_table = cortina_uart_of_match, + }, +}; + +static int __init cortina_uart_init(void) +{ + int ret; + + ret = uart_register_driver(&cortina_uart_driver); + if (ret) + return ret; + + ret = platform_driver_register(&serial_cortina_driver); + if (ret) + uart_unregister_driver(&cortina_uart_driver); + + return ret; +} + +static void __exit cortina_uart_exit(void) +{ + platform_driver_unregister(&serial_cortina_driver); + uart_unregister_driver(&cortina_uart_driver); +} + +module_init(cortina_uart_init); +module_exit(cortina_uart_exit); + +MODULE_AUTHOR("Cortina-Access Inc."); +MODULE_DESCRIPTION(" Cortina-Access UART driver"); +MODULE_LICENSE("GPL"); From cddd53e8aa4fc442e26a7a7be183593ce31453ca Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 24 Jun 2021 14:46:32 +0200 Subject: [PATCH 217/227] Revert "tty: serial: Add UART driver for Cortina-Access platform" This reverts commit b61c8bf4694b5115766849378dcb8787ff54e65e. It never made it to a public mailing list and still needs some work based on the review comments. So revert it for now. Reported-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/CAMuHMdXA9-ajoAza2JAW5879ECieMm1dbBbKHgJhDa7=3kWu3w@mail.gmail.com Cc: Jason Li Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 5 - drivers/tty/serial/Kconfig | 19 - drivers/tty/serial/Makefile | 1 - drivers/tty/serial/serial_cortina-access.c | 798 --------------------- 4 files changed, 823 deletions(-) delete mode 100644 drivers/tty/serial/serial_cortina-access.c diff --git a/MAINTAINERS b/MAINTAINERS index f20502df69b8..25d7d864cfbd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4680,11 +4680,6 @@ S: Maintained W: http://www.fi.muni.cz/~kas/cosa/ F: drivers/net/wan/cosa* -CORTINA-ACCESS SERIAL CONSOLE DRIVER -M: Jason Li -S: Supported -F: drivers/tty/serial/serial_cortina-access.c - COUNTER SUBSYSTEM M: William Breathitt Gray L: linux-iio@vger.kernel.org diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 2fa39cd78c56..24282ad99d85 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1561,25 +1561,6 @@ config SERIAL_LITEUART_CONSOLE and warnings and which allows logins in single user mode). Otherwise, say 'N'. -config SERIAL_CORTINA_ACCESS - tristate "Cortina-Access serial port support" - select SERIAL_CORE - help - This driver is for Cortina-Access SoC's UART. If you have a machine - based on the Cortina-Access SoC and wish to use the serial port, - say 'Y' here. Otherwise, say 'N'. - -config SERIAL_CORTINA_ACCESS_CONSOLE - bool "Console on Cortina-ACCESS serial port" - depends on SERIAL_CORTINA_ACCESS=y - select SERIAL_CORE_CONSOLE - select SERIAL_EARLYCON - help - Say 'Y' here if you wish to use Cortina-Access UART as the system - console. (the system console is the device which receives all kernel - messages and warnings and which allows logins in single user mode) - /dev/ttyS* is default device node. - endmenu config SERIAL_MCTRL_GPIO diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index f3f531a48854..7da0856cd198 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -87,7 +87,6 @@ obj-$(CONFIG_SERIAL_RDA) += rda-uart.o obj-$(CONFIG_SERIAL_MILBEAUT_USIO) += milbeaut_usio.o obj-$(CONFIG_SERIAL_SIFIVE) += sifive.o obj-$(CONFIG_SERIAL_LITEUART) += liteuart.o -obj-$(CONFIG_SERIAL_CORTINA_ACCESS) += serial_cortina-access.o # GPIOLIB helpers for modem control lines obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o diff --git a/drivers/tty/serial/serial_cortina-access.c b/drivers/tty/serial/serial_cortina-access.c deleted file mode 100644 index b4b9362bb4e6..000000000000 --- a/drivers/tty/serial/serial_cortina-access.c +++ /dev/null @@ -1,798 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * UART driver for Cortina-Access Soc platform - * Copyright (C) 2021 Cortina-Access Inc. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/*************************************** - * UART Related registers - ****************************************/ -/* register definitions */ -#define CFG 0x00 -#define FC 0x04 -#define RX_SAMPLE 0x08 -#define RT_TUNE 0x0C -#define TX_DAT 0x10 -#define RX_DAT 0x14 -#define INFO 0x18 -#define IE 0x1C -#define INT 0x24 -#define STATUS 0x2C - -/* CFG */ -#define CFG_STOP_2BIT BIT(2) -#define CFG_PARITY_EVEN BIT(3) -#define CFG_PARITY_EN BIT(4) -#define CFG_TX_EN BIT(5) -#define CFG_RX_EN BIT(6) -#define CFG_UART_EN BIT(7) -#define CFG_BAUD_SART_SHIFT 8 - -/* INFO */ -#define INFO_TX_EMPTY BIT(3) -#define INFO_TX_FULL BIT(2) -#define INFO_RX_EMPTY BIT(1) -#define INFO_RX_FULL BIT(0) - -/* Interrupt */ -#define RX_BREAK BIT(7) -#define RX_FIFO_NONEMPTYE BIT(6) -#define TX_FIFO_EMPTYE BIT(5) -#define RX_FIFO_UNDERRUNE BIT(4) -#define RX_FIFO_OVERRUNE BIT(3) -#define RX_PARITY_ERRE BIT(2) -#define RX_STOP_ERRE BIT(1) -#define TX_FIFO_OVERRUNE BIT(0) - -#define TX_TIMEOUT 5000 -#define UART_NR 4 -#define CA_UART_NAME_LEN 32 -struct cortina_uart_port { - struct uart_port uart; - char name[CA_UART_NAME_LEN]; - char has_bi; - unsigned int may_wakeup; -}; - -static struct cortina_uart_port *cortina_uart_ports; - -static irqreturn_t cortina_uart_interrupt(int irq, void *dev_id); - -/* Return uart_port pointer base on index */ -struct cortina_uart_port *cortina_uart_get_port(unsigned int index) -{ - struct cortina_uart_port *pca_port = cortina_uart_ports; - - if (index >= UART_NR) { - /* return 1st element if invalid index */ - index = 0; - } - - pca_port += index; - - return pca_port; -} - -/* uart_ops functions */ -static unsigned int cortina_uart_tx_empty(struct uart_port *port) -{ - /* Return 0 on FIXO condition, TIOCSER_TEMT otherwise */ - return (readl(port->membase + INFO) & INFO_TX_EMPTY) ? TIOCSER_TEMT : 0; -} - -static void cortina_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) -{ -/* - * Even if we do not support configuring the modem control lines, this - * function must be proided to the serial core. - * port->ops->set_mctrl() be called in uart_configure_port() - */ -} - -static unsigned int cortina_uart_get_mctrl(struct uart_port *port) -{ - /* Unimplemented signals asserted, per Documentation/serial/driver */ - return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; -} - -static void cortina_uart_stop_tx(struct uart_port *port) -{ - /* Turn off Tx interrupts. The port lock is held at this point */ - unsigned int reg_v; - - reg_v = readl(port->membase + IE); - writel(reg_v & ~TX_FIFO_EMPTYE, port->membase + IE); -} - -static inline void cortina_transmit_buffer(struct uart_port *port) -{ - struct circ_buf *xmit = &port->state->xmit; - - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - cortina_uart_stop_tx(port); - return; - } - - do { - /* send xmit->buf[xmit->tail] out the port here */ - writel(xmit->buf[xmit->tail], port->membase + TX_DAT); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - if ((readl(port->membase + INFO) & INFO_TX_FULL)) - break; - } while (!uart_circ_empty(xmit)); - - if (uart_circ_empty(xmit)) - cortina_uart_stop_tx(port); -} - -static void cortina_uart_start_tx(struct uart_port *port) -{ - /* Turn on Tx interrupts. The port lock is held at this point */ - unsigned int reg_v; - - reg_v = readl(port->membase + IE); - writel((reg_v | TX_FIFO_EMPTYE), port->membase + IE); - - reg_v = readl(port->membase + CFG); - writel(reg_v | CFG_TX_EN, port->membase + CFG); - - if (readl(port->membase + INFO) & INFO_TX_EMPTY) - cortina_transmit_buffer(port); -} - -static void cortina_uart_stop_rx(struct uart_port *port) -{ - /* Turn off Rx interrupts. The port lock is held at this point */ - unsigned int reg_v; - - reg_v = readl(port->membase + IE); - writel(reg_v & ~RX_FIFO_NONEMPTYE, port->membase + IE); -} - -static void cortina_uart_enable_ms(struct uart_port *port) -{ - /* Nope, you really can't hope to attach a modem to this */ -} - -static int cortina_uart_startup(struct uart_port *port) -{ - unsigned int reg_v; - int retval; - unsigned long flags; - - /* Disable interrupt */ - writel(0, port->membase + IE); - - retval = - request_irq(port->irq, cortina_uart_interrupt, 0, "cortina_uart", - port); - if (retval) - return retval; - - spin_lock_irqsave(&port->lock, flags); - - reg_v = readl(port->membase + CFG); - reg_v |= (CFG_UART_EN | CFG_TX_EN | CFG_RX_EN | 0x3 /* 8-bits data */); - writel(reg_v, port->membase + CFG); - reg_v = readl(port->membase + IE); - writel(reg_v | RX_FIFO_NONEMPTYE | TX_FIFO_EMPTYE, port->membase + IE); - - spin_unlock_irqrestore(&port->lock, flags); - return 0; -} - -static void cortina_uart_shutdown(struct uart_port *port) -{ - cortina_uart_stop_tx(port); - cortina_uart_stop_rx(port); - free_irq(port->irq, port); -} - -static void cortina_uart_set_termios(struct uart_port *port, - struct ktermios *termios, - struct ktermios *old) -{ - unsigned long flags; - int baud; - unsigned int reg_v, sample_freq = 0; - - baud = uart_get_baud_rate(port, termios, old, 0, 230400); - reg_v = readl(port->membase + CFG); - /* mask off the baud settings */ - reg_v &= 0xff; - reg_v |= (port->uartclk / baud) << CFG_BAUD_SART_SHIFT; - - /* Sampling rate should be half of baud count */ - sample_freq = (reg_v >> CFG_BAUD_SART_SHIFT) / 2; - - /* See include/uapi/asm-generic/termbits.h for CSIZE definition */ - /* mask off the data width */ - reg_v &= 0xfffffffc; - switch (termios->c_cflag & CSIZE) { - case CS5: - reg_v |= 0x0; - break; - case CS6: - reg_v |= 0x1; - break; - case CS7: - reg_v |= 0x2; - break; - case CS8: - default: - reg_v |= 0x3; - break; - } - - /* mask off Stop bits */ - reg_v &= ~(CFG_STOP_2BIT); - if (termios->c_cflag & CSTOPB) - reg_v |= CFG_STOP_2BIT; - - /* Parity */ - reg_v &= ~(CFG_PARITY_EN); - reg_v |= CFG_PARITY_EVEN; - if (termios->c_cflag & PARENB) { - reg_v |= CFG_PARITY_EN; - if (termios->c_cflag & PARODD) - reg_v &= ~(CFG_PARITY_EVEN); - } - - spin_lock_irqsave(&port->lock, flags); - writel(reg_v, port->membase + CFG); - writel(sample_freq, port->membase + RX_SAMPLE); - spin_unlock_irqrestore(&port->lock, flags); -} - -static const char *cortina_uart_type(struct uart_port *port) -{ - return container_of(port, struct cortina_uart_port, uart)->name; -} - -static void cortina_uart_config_port(struct uart_port *port, int flags) -{ - /* - * Driver core for serial ports forces a non-zero value for port type. - * Write an arbitrary value here to accommodate the serial core driver, - * as ID part of UAPI is redundant. - */ - port->type = 1; -} - -static int cortina_uart_verify_port(struct uart_port *port, - struct serial_struct *ser) -{ - if (ser->type != PORT_UNKNOWN && ser->type != 1) - return -EINVAL; - return 0; -} - -static void cortina_access_power(struct uart_port *port, unsigned int state, - unsigned int oldstate) -{ - unsigned int reg_v; - - /* Read Config register */ - reg_v = readl(port->membase + CFG); - switch (state) { - case UART_PM_STATE_ON: - reg_v |= CFG_UART_EN; - break; - case UART_PM_STATE_OFF: - reg_v &= ~CFG_UART_EN; - break; - default: - pr_err("cortina-access serial: Unknown PM state %d\n", state); - } - writel(reg_v, port->membase + CFG); -} - -#ifdef CONFIG_CONSOLE_POLL -static int cortina_poll_get_char(struct uart_port *port) -{ - unsigned int rx; - - if (readl(port->membase + INFO) & INFO_RX_EMPTY) - return NO_POLL_CHAR; - - rx = readl(port->membase + RX_DAT); - - return rx; -} - -static void cortina_poll_put_char(struct uart_port *port, unsigned char c) -{ - unsigned long time_out; - - time_out = jiffies + usecs_to_jiffies(TX_TIMEOUT); - - while (time_before(jiffies, time_out) && - (readl(port->membase + INFO) & INFO_TX_FULL)) - cpu_relax(); - - /* Give up if FIFO stuck! */ - if ((readl(port->membase + INFO) & INFO_TX_FULL)) - return; - - writel(c, port->membase + TX_DAT); -} - -#endif - -static const struct uart_ops cortina_uart_ops = { - .tx_empty = cortina_uart_tx_empty, - .set_mctrl = cortina_uart_set_mctrl, - .get_mctrl = cortina_uart_get_mctrl, - .stop_tx = cortina_uart_stop_tx, - .start_tx = cortina_uart_start_tx, - .stop_rx = cortina_uart_stop_rx, - .enable_ms = cortina_uart_enable_ms, - .startup = cortina_uart_startup, - .shutdown = cortina_uart_shutdown, - .set_termios = cortina_uart_set_termios, - .type = cortina_uart_type, - .config_port = cortina_uart_config_port, - .verify_port = cortina_uart_verify_port, - .pm = cortina_access_power, -#ifdef CONFIG_CONSOLE_POLL - .poll_get_char = cortina_poll_get_char, - .poll_put_char = cortina_poll_put_char, -#endif -}; - -static inline void cortina_uart_interrupt_rx_chars(struct uart_port *port, - unsigned long status) -{ - struct tty_port *ttyport = &port->state->port; - unsigned int ch; - unsigned int rx, flg; - struct cortina_uart_port *pca_port; - - rx = readl(port->membase + INFO); - if (INFO_RX_EMPTY & rx) - return; - - if (status & RX_FIFO_OVERRUNE) - port->icount.overrun++; - - pca_port = cortina_uart_get_port(port->line); - - /* Read the character while FIFO is not empty */ - do { - flg = TTY_NORMAL; - port->icount.rx++; - ch = readl(port->membase + RX_DAT); - if (status & RX_PARITY_ERRE) { - port->icount.parity++; - flg = TTY_PARITY; - } - - if (pca_port->has_bi) { - /* If BI supported ? */ - if (status & RX_BREAK) { - port->icount.brk++; - if (uart_handle_break(port)) - goto ignore; - } - } else { - /* Treat stop err as BI */ - if (status & RX_STOP_ERRE) { - port->icount.brk++; - if (uart_handle_break(port)) - goto ignore; - } - } - if (!(ch & 0x100)) /* RX char is not valid */ - goto ignore; - - if (uart_handle_sysrq_char(port, (unsigned char)ch)) - goto ignore; - - tty_insert_flip_char(ttyport, ch, flg); - ignore: - rx = readl(port->membase + INFO); - } while (!(INFO_RX_EMPTY & rx)); - - spin_unlock(&port->lock); - tty_flip_buffer_push(ttyport); - spin_lock(&port->lock); -} - -static inline void cortina_uart_interrupt_tx_chars(struct uart_port *port) -{ - struct circ_buf *xmit = &port->state->xmit; - - /* Process out of band chars */ - if (port->x_char) { - /* Send next char */ - writel(port->x_char, port->membase + TX_DAT); - goto done; - } - - /* Nothing to do ? */ - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - cortina_uart_stop_tx(port); - goto done; - } - - cortina_transmit_buffer(port); - - /* Wake up */ - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); - - /* Maybe we're done after all */ - if (uart_circ_empty(xmit)) - cortina_uart_stop_tx(port); - - done: - return; -} - -irqreturn_t cortina_uart_interrupt(int irq, void *dev_id) -{ - struct uart_port *port = (struct uart_port *)dev_id; - unsigned int irq_status; - - spin_lock(&port->lock); - - /* Clear interrupt! */ - irq_status = readl(port->membase + INT); - writel(irq_status, port->membase + INT); - - /* Process any Rx chars first */ - cortina_uart_interrupt_rx_chars(port, irq_status); - /* Then use any Tx space */ - cortina_uart_interrupt_tx_chars(port); - - spin_unlock(&port->lock); - - return IRQ_HANDLED; -} - -#ifdef CONFIG_SERIAL_CORTINA_ACCESS_CONSOLE -void cortina_console_write(struct console *co, const char *s, - unsigned int count) -{ - struct uart_port *port; - struct cortina_uart_port *pca_port; - unsigned int i, previous; - unsigned long flags; - int locked; - - pca_port = cortina_uart_get_port(co->index); - port = &pca_port->uart; - - local_irq_save(flags); - if (port->sysrq) { - locked = 0; - } else if (oops_in_progress) { - locked = spin_trylock(&port->lock); - } else { - spin_lock(&port->lock); - locked = 1; - } - - /* Save current state */ - previous = readl(port->membase + IE); - /* Disable Tx interrupts so this all goes out in one go */ - cortina_uart_stop_tx(port); - - /* Write all the chars */ - for (i = 0; i < count; i++) { - /* Wait the TX buffer to be empty, which can't take forever */ - while (!(readl(port->membase + INFO) & INFO_TX_EMPTY)) - cpu_relax(); - - /* Send the char */ - writel(*s, port->membase + TX_DAT); - - /* CR/LF stuff */ - if (*s++ == '\n') { - /* Wait the TX buffer to be empty */ - while (!(readl(port->membase + INFO) & INFO_TX_EMPTY)) - cpu_relax(); - writel('\r', port->membase + TX_DAT); - } - } - - writel(previous, port->membase + IE); /* Put it all back */ - - if (locked) - spin_unlock(&port->lock); - local_irq_restore(flags); -} - -static int __init cortina_console_setup(struct console *co, char *options) -{ - struct uart_port *port; - struct cortina_uart_port *pca_port; - int baud = 115200; - int bits = 8; - int parity = 'n'; - int flow = 'n'; - - if (co->index < 0 || co->index >= UART_NR) - return -ENODEV; - - pca_port = cortina_uart_get_port(co->index); - port = &pca_port->uart; - - /* This isn't going to do much, but it might change the baud rate. */ - if (options) - uart_parse_options(options, &baud, &parity, &bits, &flow); - - return uart_set_options(port, co, baud, parity, bits, flow); -} - -static struct uart_driver cortina_uart_driver; - -static struct console cortina_console = { - .name = "ttyS", - .write = cortina_console_write, - .device = uart_console_device, - .setup = cortina_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, /* Only possible option. */ - .data = &cortina_uart_driver, -}; -#define CORTINA_CONSOLE (&cortina_console) - -/* Support EARLYCON */ -static void cortina_putc(struct uart_port *port, int c) -{ - unsigned int tmout; - - /* No jiffie at early boot stage! - * Wait up to 5ms for the character to be sent. - */ - tmout = TX_TIMEOUT; - while (--tmout) { - if (!(readl(port->membase + INFO) & INFO_TX_FULL)) - break; - udelay(1); - } - - /* Give up if FIFO stuck! */ - while ((readl(port->membase + INFO) & INFO_TX_FULL)) - return; - - /* Send the char */ - writel(c, port->membase + TX_DAT); -} - -static void cortina_early_write(struct console *con, const char *s, - unsigned int n) -{ - struct earlycon_device *dev = con->data; - - uart_console_write(&dev->port, s, n, cortina_putc); -} - -static int __init cortina_early_console_setup(struct earlycon_device *device, - const char *opt) -{ - if (!device->port.membase) - return -ENODEV; - - device->con->write = cortina_early_write; - return 0; -} - -EARLYCON_DECLARE(serial, cortina_early_console_setup); -OF_EARLYCON_DECLARE(serial, "cortina-access,serial", cortina_early_console_setup); -#else -#define CORTINA_CONSOLE NULL -#endif - -static struct uart_driver cortina_uart_driver = { - .owner = THIS_MODULE, - .driver_name = "cortina-access_uart", - .dev_name = "ttyS", - .major = TTY_MAJOR, - .minor = 64, - .nr = UART_NR, - .cons = CORTINA_CONSOLE, -}; - -/* Match table for of_platform binding */ -static const struct of_device_id cortina_uart_of_match[] = { - {.compatible = "cortina-access,serial",}, - {} -}; -MODULE_DEVICE_TABLE(of, cortina_uart_of_match); - -static int serial_cortina_probe(struct platform_device *pdev) -{ - int ret; - void __iomem *base; - struct cortina_uart_port *port; - const struct of_device_id *match; - - /* assign DT node pointer */ - struct device_node *np = pdev->dev.of_node; - struct resource mem_resource; - u32 of_clock_frequency; - struct clk *pclk_info; - int uart_idx; - - /* search DT for a match */ - match = of_match_device(cortina_uart_of_match, &pdev->dev); - if (!match) - return -EINVAL; - - if (cortina_uart_ports == NULL) - cortina_uart_ports = kzalloc(UART_NR * sizeof(struct cortina_uart_port), - GFP_KERNEL); - - port = cortina_uart_ports; - for (uart_idx = 0; uart_idx < UART_NR; ++uart_idx) { - /* Find first empty slot */ - if (strlen(port->name) == 0) - break; - port++; - } - - if (uart_idx >= UART_NR) - return -EINVAL; - - snprintf(port->name, sizeof(port->name), "Cortina-Access UART%d", uart_idx); - - /* Retrieve HW base address */ - ret = of_address_to_resource(np, 0, &mem_resource); - if (ret) { - dev_warn(&pdev->dev, "invalid address %d\n", ret); - return ret; - } - - base = devm_ioremap(&pdev->dev, mem_resource.start, - resource_size(&mem_resource)); - if (!base) { - devm_kfree(&pdev->dev, port); - return -ENOMEM; - } - - /* assign reg base and irq from DT */ - port->uart.irq = irq_of_parse_and_map(np, 0); - port->uart.membase = base; - port->uart.mapbase = mem_resource.start; - port->uart.ops = &cortina_uart_ops; - port->uart.dev = &pdev->dev; - port->uart.line = uart_idx; - port->uart.has_sysrq = IS_ENABLED(CONFIG_SERIAL_CORTINA_ACCESS_CONSOLE); - - /* get clock-freqency tuple from DT and store value */ - if (of_property_read_u32(np, "clock-frequency", &of_clock_frequency)) { - /* If we are here, it means DT node did not contain - * clock-frequency tuple. Therefore, instead try to get - * clk rate through the clk driver that DT has stated - * we are consuming. - */ - pclk_info = clk_get(&pdev->dev, NULL); - if (IS_ERR(pclk_info)) { - dev_warn(&pdev->dev, - "clk or clock-frequency not defined\n"); - return PTR_ERR(pclk_info); - } - - clk_prepare_enable(pclk_info); - of_clock_frequency = clk_get_rate(pclk_info); - } - port->uart.uartclk = of_clock_frequency; - - if (of_property_read_bool(np, "wakeup-source")) - port->may_wakeup = true; - if (of_property_read_bool(np, "break-indicator")) - port->has_bi = true; - - port->uart.type = PORT_UNKNOWN; - - if (port->may_wakeup) - device_init_wakeup(&pdev->dev, true); - - ret = uart_add_one_port(&cortina_uart_driver, &port->uart); - if (ret) - return ret; - - platform_set_drvdata(pdev, port); - - return 0; -} - -static int serial_cortina_remove(struct platform_device *pdev) -{ - struct uart_port *port = platform_get_drvdata(pdev); - struct cortina_uart_port *pca_port; - - if (port) { - pca_port = cortina_uart_get_port(port->line); - memset(pca_port->name, 0, CA_UART_NAME_LEN); - uart_remove_one_port(&cortina_uart_driver, port); - } - - platform_set_drvdata(pdev, NULL); - return 0; -} - -#ifdef CONFIG_PM -static int serial_cortina_suspend(struct platform_device *pdev, - pm_message_t state) -{ - struct cortina_uart_port *p = - (struct cortina_uart_port *)pdev->dev.driver_data; - - uart_suspend_port(&cortina_uart_driver, &p->uart); - - return 0; -} - -static int serial_cortina_resume(struct platform_device *pdev) -{ - struct cortina_uart_port *p = - (struct cortina_uart_port *)pdev->dev.driver_data; - - uart_resume_port(&cortina_uart_driver, &p->uart); - - return 0; -} -#else -#define serial_cortina_suspend NULL -#define serial_cortina_resume NULL -#endif - -static struct platform_driver serial_cortina_driver = { - .probe = serial_cortina_probe, - .remove = serial_cortina_remove, -#ifdef CONFIG_PM - .suspend = serial_cortina_suspend, - .resume = serial_cortina_resume, -#endif - .driver = { - .name = "cortina-access_serial", - .owner = THIS_MODULE, - .of_match_table = cortina_uart_of_match, - }, -}; - -static int __init cortina_uart_init(void) -{ - int ret; - - ret = uart_register_driver(&cortina_uart_driver); - if (ret) - return ret; - - ret = platform_driver_register(&serial_cortina_driver); - if (ret) - uart_unregister_driver(&cortina_uart_driver); - - return ret; -} - -static void __exit cortina_uart_exit(void) -{ - platform_driver_unregister(&serial_cortina_driver); - uart_unregister_driver(&cortina_uart_driver); -} - -module_init(cortina_uart_init); -module_exit(cortina_uart_exit); - -MODULE_AUTHOR("Cortina-Access Inc."); -MODULE_DESCRIPTION(" Cortina-Access UART driver"); -MODULE_LICENSE("GPL"); From 08b0adb1ae5456a7785ac3c8fdfdc351206f99c3 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 22 Jun 2021 00:15:28 +0300 Subject: [PATCH 218/227] serial: qcom_geni_serial: use DT aliases according to DT bindings Device tree bindings do not specify "hsuart" aliases, instead all serial ports should use "serial" alias name as noted by Rob Herring [1]. Make qcom_geni_serial driver use "serial" alias and fallback to "hsuart" if one is not found. [1] https://lore.kernel.org/linux-arm-msm/6dd1f5cd-03c7-5945-9fa2-1c2698405110@linaro.org/ Cc: Rob Herring Reviewed-by: Bjorn Andersson Signed-off-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20210621211528.1607516-1-dmitry.baryshkov@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/qcom_geni_serial.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 379ab15daa85..aedc38893e6c 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -1340,7 +1340,9 @@ static int qcom_geni_serial_probe(struct platform_device *pdev) line = of_alias_get_id(pdev->dev.of_node, "serial"); } else { drv = &qcom_geni_uart_driver; - line = of_alias_get_id(pdev->dev.of_node, "hsuart"); + line = of_alias_get_id(pdev->dev.of_node, "serial"); + if (line == -ENODEV) /* compat with non-standard aliases */ + line = of_alias_get_id(pdev->dev.of_node, "hsuart"); } port = get_port_from_line(line, console); From b67e830d38fa9335d927fe67e812e3ed81b4689c Mon Sep 17 00:00:00 2001 From: Vignesh Raghavendra Date: Tue, 22 Jun 2021 20:27:04 +0530 Subject: [PATCH 219/227] serial: 8250: 8250_omap: Fix possible interrupt storm on K3 SoCs On K3 family of SoCs (which includes AM654 SoC), it is observed that RX TIMEOUT is signalled after RX FIFO has been drained, in which case a dummy read of RX FIFO is required to clear RX TIMEOUT condition. Otherwise, this would lead to an interrupt storm. Fix this by introducing UART_RX_TIMEOUT_QUIRK flag and doing a dummy read in IRQ handler when RX TIMEOUT is reported with no data in RX FIFO. Fixes: be70874498f3 ("serial: 8250_omap: Add support for AM654 UART controller") Reported-by: Jan Kiszka Tested-by: Jan Kiszka Signed-off-by: Vignesh Raghavendra Link: https://lore.kernel.org/r/20210622145704.11168-1-vigneshr@ti.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_omap.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index c06631ced414..79418d4beb48 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -43,6 +43,7 @@ #define UART_ERRATA_CLOCK_DISABLE (1 << 3) #define UART_HAS_EFR2 BIT(4) #define UART_HAS_RHR_IT_DIS BIT(5) +#define UART_RX_TIMEOUT_QUIRK BIT(6) #define OMAP_UART_FCR_RX_TRIG 6 #define OMAP_UART_FCR_TX_TRIG 4 @@ -104,6 +105,9 @@ #define UART_OMAP_EFR2 0x23 #define UART_OMAP_EFR2_TIMEOUT_BEHAVE BIT(6) +/* RX FIFO occupancy indicator */ +#define UART_OMAP_RX_LVL 0x64 + struct omap8250_priv { int line; u8 habit; @@ -611,6 +615,7 @@ static int omap_8250_dma_handle_irq(struct uart_port *port); static irqreturn_t omap8250_irq(int irq, void *dev_id) { struct uart_port *port = dev_id; + struct omap8250_priv *priv = port->private_data; struct uart_8250_port *up = up_to_u8250p(port); unsigned int iir; int ret; @@ -625,6 +630,18 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id) serial8250_rpm_get(up); iir = serial_port_in(port, UART_IIR); ret = serial8250_handle_irq(port, iir); + + /* + * On K3 SoCs, it is observed that RX TIMEOUT is signalled after + * FIFO has been drained, in which case a dummy read of RX FIFO + * is required to clear RX TIMEOUT condition. + */ + if (priv->habit & UART_RX_TIMEOUT_QUIRK && + (iir & UART_IIR_RX_TIMEOUT) == UART_IIR_RX_TIMEOUT && + serial_port_in(port, UART_OMAP_RX_LVL) == 0) { + serial_port_in(port, UART_RX); + } + serial8250_rpm_put(up); return IRQ_RETVAL(ret); @@ -1218,7 +1235,8 @@ static struct omap8250_dma_params am33xx_dma = { static struct omap8250_platdata am654_platdata = { .dma_params = &am654_dma, - .habit = UART_HAS_EFR2 | UART_HAS_RHR_IT_DIS, + .habit = UART_HAS_EFR2 | UART_HAS_RHR_IT_DIS | + UART_RX_TIMEOUT_QUIRK, }; static struct omap8250_platdata am33xx_platdata = { From 5607fa6c3da3189de1bac356c73bc4fcaf4c0234 Mon Sep 17 00:00:00 2001 From: Jinchao Wang Date: Thu, 24 Jun 2021 10:12:07 +0800 Subject: [PATCH 220/227] serial: Prefer unsigned int to bare use of unsigned Fix checkpatch warnings: WARNING: Prefer 'unsigned int' to bare use of 'unsigned' Signed-off-by: Jinchao Wang Link: https://lore.kernel.org/r/20210624021207.58059-1-wjc@cdjrlc.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mvebu-uart.c | 2 +- drivers/tty/serial/xilinx_uartps.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c index 51b0ecabf2ec..04c41689d81c 100644 --- a/drivers/tty/serial/mvebu-uart.c +++ b/drivers/tty/serial/mvebu-uart.c @@ -617,7 +617,7 @@ static void mvebu_uart_putc(struct uart_port *port, int c) static void mvebu_uart_putc_early_write(struct console *con, const char *s, - unsigned n) + unsigned int n) { struct earlycon_device *dev = con->data; diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index bafdf75c1fa8..962e522ccc45 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -1149,7 +1149,7 @@ static void cdns_uart_console_putchar(struct uart_port *port, int ch) } static void cdns_early_write(struct console *con, const char *s, - unsigned n) + unsigned int n) { struct earlycon_device *dev = con->data; From 4834446035a1011ff1231626ef33555d64c4fd78 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 25 Jun 2021 09:35:11 +0200 Subject: [PATCH 221/227] tty: make linux/tty_flip.h self-contained If someone includes linux/tty_flip.h before linux/tty.h, they see many compiler errors like: include/linux/tty_flip.h:23:30: error: invalid use of undefined type 'struct tty_port' include/linux/tty_flip.h:26:14: error: invalid use of undefined type 'struct tty_buffer' tty_flip.h actually lexicographically sorts before tty.h. So if people sort includes (as I tried in amiserial), the compilation suddenly breaks. Solve this by including linux/tty.h from linux/tty_flip.h, so that everything is defined as needed. Another alternative would be to uninline tty_insert_flip_char and just insert forward declarations of tty_port and tty_buffer structs into tty_flip.h as that inline is the only real user. But that would mean slowing down the fast path without any good reason. (Provided the fix is that easy and there were no real problems with this until now.) Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210625073511.4514-1-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- include/linux/tty_flip.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h index d6729281ec50..67d78dc553e1 100644 --- a/include/linux/tty_flip.h +++ b/include/linux/tty_flip.h @@ -2,6 +2,8 @@ #ifndef _LINUX_TTY_FLIP_H #define _LINUX_TTY_FLIP_H +#include + extern int tty_buffer_set_limit(struct tty_port *port, int limit); extern unsigned int tty_buffer_space_avail(struct tty_port *port); extern int tty_buffer_request_room(struct tty_port *port, size_t size); From 9078204ca5c33ba20443a8623a41a68a9995a70d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 25 Jun 2021 00:49:00 +0200 Subject: [PATCH 222/227] serial: mvebu-uart: fix calculation of clock divisor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The clock divisor should be rounded to the closest value. Signed-off-by: Pali Rohár Fixes: 68a0db1d7da2 ("serial: mvebu-uart: add function to change baudrate") Cc: stable@vger.kernel.org # 0e4cf69ede87 ("serial: mvebu-uart: clarify the baud rate derivation") Link: https://lore.kernel.org/r/20210624224909.6350-2-pali@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mvebu-uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c index 04c41689d81c..f3ecbcf495ee 100644 --- a/drivers/tty/serial/mvebu-uart.c +++ b/drivers/tty/serial/mvebu-uart.c @@ -463,7 +463,7 @@ static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud) * makes use of D to configure the desired baudrate. */ m_divisor = OSAMP_DEFAULT_DIVISOR; - d_divisor = DIV_ROUND_UP(port->uartclk, baud * m_divisor); + d_divisor = DIV_ROUND_CLOSEST(port->uartclk, baud * m_divisor); brdv = readl(port->membase + UART_BRDV); brdv &= ~BRDV_BAUD_MASK; From ecd6b010d81f97b06b2f64d2d4f50ebf5acddaa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 25 Jun 2021 00:49:01 +0200 Subject: [PATCH 223/227] serial: mvebu-uart: do not allow changing baudrate when uartclk is not available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Testing mvuart->clk for non-error is not enough as mvuart->clk may contain valid clk pointer but when clk_prepare_enable(mvuart->clk) failed then port->uartclk is zero. When mvuart->clk is not available then port->uartclk is zero too. Parent clock rate port->uartclk is needed to calculate UART clock divisor and without it is not possible to change baudrate. So fix test condition when it is possible to change baudrate. Signed-off-by: Pali Rohár Fixes: 68a0db1d7da2 ("serial: mvebu-uart: add function to change baudrate") Link: https://lore.kernel.org/r/20210624224909.6350-3-pali@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mvebu-uart.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c index f3ecbcf495ee..1789a6651ec6 100644 --- a/drivers/tty/serial/mvebu-uart.c +++ b/drivers/tty/serial/mvebu-uart.c @@ -445,12 +445,11 @@ static void mvebu_uart_shutdown(struct uart_port *port) static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud) { - struct mvebu_uart *mvuart = to_mvuart(port); unsigned int d_divisor, m_divisor; u32 brdv, osamp; - if (IS_ERR(mvuart->clk)) - return -PTR_ERR(mvuart->clk); + if (!port->uartclk) + return -EOPNOTSUPP; /* * The baudrate is derived from the UART clock thanks to two divisors: From deeaf963569a0d9d1b08babb771f61bb501a5704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 25 Jun 2021 00:49:02 +0200 Subject: [PATCH 224/227] serial: mvebu-uart: correctly calculate minimal possible baudrate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For default (x16) scheme which is currently used by mvebu-uart.c driver, maximal divisor of UART base clock is 1023*16. Therefore there is limit for minimal supported baudrate. This change calculate it correctly and prevents setting invalid divisor 0 into hardware registers. Signed-off-by: Pali Rohár Fixes: 68a0db1d7da2 ("serial: mvebu-uart: add function to change baudrate") Link: https://lore.kernel.org/r/20210624224909.6350-4-pali@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mvebu-uart.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c index 1789a6651ec6..0e169ad06fa7 100644 --- a/drivers/tty/serial/mvebu-uart.c +++ b/drivers/tty/serial/mvebu-uart.c @@ -481,7 +481,7 @@ static void mvebu_uart_set_termios(struct uart_port *port, struct ktermios *old) { unsigned long flags; - unsigned int baud; + unsigned int baud, min_baud, max_baud; spin_lock_irqsave(&port->lock, flags); @@ -500,16 +500,21 @@ static void mvebu_uart_set_termios(struct uart_port *port, port->ignore_status_mask |= STAT_RX_RDY(port) | STAT_BRK_ERR; /* + * Maximal divisor is 1023 * 16 when using default (x16) scheme. * Maximum achievable frequency with simple baudrate divisor is 230400. * Since the error per bit frame would be of more than 15%, achieving * higher frequencies would require to implement the fractional divisor * feature. */ - baud = uart_get_baud_rate(port, termios, old, 0, 230400); + min_baud = DIV_ROUND_UP(port->uartclk, 1023 * 16); + max_baud = 230400; + + baud = uart_get_baud_rate(port, termios, old, min_baud, max_baud); if (mvebu_uart_baud_rate_set(port, baud)) { /* No clock available, baudrate cannot be changed */ if (old) - baud = uart_get_baud_rate(port, old, NULL, 0, 230400); + baud = uart_get_baud_rate(port, old, NULL, + min_baud, max_baud); } else { tty_termios_encode_baud_rate(termios, baud, baud); uart_update_timeout(port, termios->c_cflag, baud); From 56b3276954f0e3b32760997a904fcbaec25bc005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 25 Jun 2021 00:49:03 +0200 Subject: [PATCH 225/227] dt-bindings: mvebu-uart: fix documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both UARTs support higher baudrates and are not limited to baudrate 230400. Only current kernel driver implementation has limitation for both UARTs in maximal baudrate 230400. This limitation will be removed in next patches. So remove incorrect information about (hardware) limitation from bindings. UART1 (standard variant with DT node name 'uart0') has register space 0x12000-0x12018 and not whole size 0x200. So fix also this in example. Signed-off-by: Pali Rohár Fixes: d160c3413478 ("dt-bindings: mvebu-uart: update documentation with extended UART") Link: https://lore.kernel.org/r/20210624224909.6350-5-pali@kernel.org Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/mvebu-uart.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/serial/mvebu-uart.txt b/Documentation/devicetree/bindings/serial/mvebu-uart.txt index b7e0e32b9ac6..2d0dbdf32d1d 100644 --- a/Documentation/devicetree/bindings/serial/mvebu-uart.txt +++ b/Documentation/devicetree/bindings/serial/mvebu-uart.txt @@ -5,10 +5,10 @@ Required properties: - compatible: - "marvell,armada-3700-uart" for the standard variant of the UART (32 bytes FIFO, no DMA, level interrupts, 8-bit access to the - FIFO, baudrate limited to 230400). + FIFO), called also UART1. - "marvell,armada-3700-uart-ext" for the extended variant of the UART (128 bytes FIFO, DMA, front interrupts, 8-bit or 32-bit - accesses to the FIFO, baudrate unlimited by the dividers). + accesses to the FIFO), called also UART2. - reg: offset and length of the register set for the device. - clocks: UART reference clock used to derive the baudrate. If no clock is provided (possible only with the "marvell,armada-3700-uart" @@ -33,7 +33,7 @@ Required properties: Example: uart0: serial@12000 { compatible = "marvell,armada-3700-uart"; - reg = <0x12000 0x200>; + reg = <0x12000 0x18>; clocks = <&xtalclk>; interrupts = , From 2cbfdedef39fb5994b8f1e1df068eb8440165975 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 25 Jun 2021 00:49:04 +0200 Subject: [PATCH 226/227] arm64: dts: marvell: armada-37xx: Fix reg for standard variant of UART MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UART1 (standard variant with DT node name 'uart0') has register space 0x12000-0x12018 and not whole size 0x200. So fix also this in example. Signed-off-by: Pali Rohár Fixes: c737abc193d1 ("arm64: dts: marvell: Fix A37xx UART0 register size") Link: https://lore.kernel.org/r/20210624224909.6350-6-pali@kernel.org Signed-off-by: Greg Kroah-Hartman --- arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi index 456dcd4a7793..6ffbb099fcac 100644 --- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi @@ -134,7 +134,7 @@ uart0: serial@12000 { compatible = "marvell,armada-3700-uart"; - reg = <0x12000 0x200>; + reg = <0x12000 0x18>; clocks = <&xtalclk>; interrupts = , From 15279ebe99d7c6142d9f1a6ae4ded66c0f168678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 25 Jun 2021 00:49:05 +0200 Subject: [PATCH 227/227] serial: mvebu-uart: remove unused member nb from struct mvebu_uart MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Member nb in struct mvebu_uart is not set nor read. So remove it completely. Signed-off-by: Pali Rohár Link: https://lore.kernel.org/r/20210624224909.6350-7-pali@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mvebu-uart.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c index 0e169ad06fa7..231de29a6452 100644 --- a/drivers/tty/serial/mvebu-uart.c +++ b/drivers/tty/serial/mvebu-uart.c @@ -128,7 +128,6 @@ struct mvebu_uart { struct uart_port *port; struct clk *clk; int irq[UART_IRQ_COUNT]; - unsigned char __iomem *nb; struct mvebu_uart_driver_data *data; #if defined(CONFIG_PM) struct mvebu_uart_pm_regs pm_regs;