Skip to content

Commit 8c91723

Browse files
committed
Merge tag 'tty-5.19-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty and serial driver fixes from Greg KH: "Here are some TTY and Serial driver fixes for 5.19-rc7. They resolve a number of reported problems including: - longtime bug in pty_write() that has been reported in the past. - 8250 driver fixes - new serial device ids - vt overlapping data copy bugfix - other tiny serial driver bugfixes All of these have been in linux-next for a while with no reported problems" * tag 'tty-5.19-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: tty: use new tty_insert_flip_string_and_push_buffer() in pty_write() tty: extract tty_flip_buffer_commit() from tty_flip_buffer_push() serial: 8250: dw: Fix the macro RZN1_UART_xDMACR_8_WORD_BURST vt: fix memory overlapping when deleting chars in the buffer serial: mvebu-uart: correctly report configured baudrate value serial: 8250: Fix PM usage_count for console handover serial: 8250: fix return error code in serial8250_request_std_resource() serial: stm32: Clear prev values before setting RTS delays tty: Add N_CAN327 line discipline ID for ELM327 based CAN driver serial: 8250: Fix __stop_tx() & DMA Tx restart races serial: pl011: UPSTAT_AUTORTS requires .throttle/unthrottle tty: serial: samsung_tty: set dma burst_size to 1 serial: 8250: dw: enable using pdata with ACPI
2 parents c658cab + a501ab7 commit 8c91723

File tree

15 files changed

+116
-59
lines changed

15 files changed

+116
-59
lines changed

drivers/tty/pty.c

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -111,21 +111,11 @@ static void pty_unthrottle(struct tty_struct *tty)
111111
static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c)
112112
{
113113
struct tty_struct *to = tty->link;
114-
unsigned long flags;
115114

116-
if (tty->flow.stopped)
115+
if (tty->flow.stopped || !c)
117116
return 0;
118117

119-
if (c > 0) {
120-
spin_lock_irqsave(&to->port->lock, flags);
121-
/* Stuff the data into the input queue of the other end */
122-
c = tty_insert_flip_string(to->port, buf, c);
123-
spin_unlock_irqrestore(&to->port->lock, flags);
124-
/* And shovel */
125-
if (c)
126-
tty_flip_buffer_push(to->port);
127-
}
128-
return c;
118+
return tty_insert_flip_string_and_push_buffer(to->port, buf, c);
129119
}
130120

131121
/**

drivers/tty/serial/8250/8250_core.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <linux/sysrq.h>
2424
#include <linux/delay.h>
2525
#include <linux/platform_device.h>
26+
#include <linux/pm_runtime.h>
2627
#include <linux/tty.h>
2728
#include <linux/ratelimit.h>
2829
#include <linux/tty_flip.h>
@@ -559,6 +560,9 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev)
559560

560561
up->port.dev = dev;
561562

563+
if (uart_console_enabled(&up->port))
564+
pm_runtime_get_sync(up->port.dev);
565+
562566
serial8250_apply_quirks(up);
563567
uart_add_one_port(drv, &up->port);
564568
}

drivers/tty/serial/8250/8250_dma.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,10 @@ int serial8250_tx_dma(struct uart_8250_port *p)
106106
UART_XMIT_SIZE, DMA_TO_DEVICE);
107107

108108
dma_async_issue_pending(dma->txchan);
109-
if (dma->tx_err) {
109+
serial8250_clear_THRI(p);
110+
if (dma->tx_err)
110111
dma->tx_err = 0;
111-
serial8250_clear_THRI(p);
112-
}
112+
113113
return 0;
114114
err:
115115
dma->tx_err = 1;

drivers/tty/serial/8250/8250_dw.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
#define RZN1_UART_xDMACR_DMA_EN BIT(0)
4848
#define RZN1_UART_xDMACR_1_WORD_BURST (0 << 1)
4949
#define RZN1_UART_xDMACR_4_WORD_BURST (1 << 1)
50-
#define RZN1_UART_xDMACR_8_WORD_BURST (3 << 1)
50+
#define RZN1_UART_xDMACR_8_WORD_BURST (2 << 1)
5151
#define RZN1_UART_xDMACR_BLK_SZ(x) ((x) << 3)
5252

5353
/* Quirks */
@@ -773,18 +773,18 @@ static const struct of_device_id dw8250_of_match[] = {
773773
MODULE_DEVICE_TABLE(of, dw8250_of_match);
774774

775775
static const struct acpi_device_id dw8250_acpi_match[] = {
776-
{ "INT33C4", 0 },
777-
{ "INT33C5", 0 },
778-
{ "INT3434", 0 },
779-
{ "INT3435", 0 },
780-
{ "80860F0A", 0 },
781-
{ "8086228A", 0 },
782-
{ "APMC0D08", 0},
783-
{ "AMD0020", 0 },
784-
{ "AMDI0020", 0 },
785-
{ "AMDI0022", 0 },
786-
{ "BRCM2032", 0 },
787-
{ "HISI0031", 0 },
776+
{ "80860F0A", (kernel_ulong_t)&dw8250_dw_apb },
777+
{ "8086228A", (kernel_ulong_t)&dw8250_dw_apb },
778+
{ "AMD0020", (kernel_ulong_t)&dw8250_dw_apb },
779+
{ "AMDI0020", (kernel_ulong_t)&dw8250_dw_apb },
780+
{ "AMDI0022", (kernel_ulong_t)&dw8250_dw_apb },
781+
{ "APMC0D08", (kernel_ulong_t)&dw8250_dw_apb},
782+
{ "BRCM2032", (kernel_ulong_t)&dw8250_dw_apb },
783+
{ "HISI0031", (kernel_ulong_t)&dw8250_dw_apb },
784+
{ "INT33C4", (kernel_ulong_t)&dw8250_dw_apb },
785+
{ "INT33C5", (kernel_ulong_t)&dw8250_dw_apb },
786+
{ "INT3434", (kernel_ulong_t)&dw8250_dw_apb },
787+
{ "INT3435", (kernel_ulong_t)&dw8250_dw_apb },
788788
{ },
789789
};
790790
MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match);

drivers/tty/serial/8250/8250_port.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1949,7 +1949,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
19491949
if ((status & UART_LSR_THRE) && (up->ier & UART_IER_THRI)) {
19501950
if (!up->dma || up->dma->tx_err)
19511951
serial8250_tx_chars(up);
1952-
else
1952+
else if (!up->dma->tx_running)
19531953
__stop_tx(up);
19541954
}
19551955

@@ -2975,8 +2975,10 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
29752975
case UPIO_MEM32BE:
29762976
case UPIO_MEM16:
29772977
case UPIO_MEM:
2978-
if (!port->mapbase)
2978+
if (!port->mapbase) {
2979+
ret = -EINVAL;
29792980
break;
2981+
}
29802982

29812983
if (!request_mem_region(port->mapbase, size, "serial")) {
29822984
ret = -EBUSY;

drivers/tty/serial/amba-pl011.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1367,6 +1367,15 @@ static void pl011_stop_rx(struct uart_port *port)
13671367
pl011_dma_rx_stop(uap);
13681368
}
13691369

1370+
static void pl011_throttle_rx(struct uart_port *port)
1371+
{
1372+
unsigned long flags;
1373+
1374+
spin_lock_irqsave(&port->lock, flags);
1375+
pl011_stop_rx(port);
1376+
spin_unlock_irqrestore(&port->lock, flags);
1377+
}
1378+
13701379
static void pl011_enable_ms(struct uart_port *port)
13711380
{
13721381
struct uart_amba_port *uap =
@@ -1788,9 +1797,10 @@ static int pl011_allocate_irq(struct uart_amba_port *uap)
17881797
*/
17891798
static void pl011_enable_interrupts(struct uart_amba_port *uap)
17901799
{
1800+
unsigned long flags;
17911801
unsigned int i;
17921802

1793-
spin_lock_irq(&uap->port.lock);
1803+
spin_lock_irqsave(&uap->port.lock, flags);
17941804

17951805
/* Clear out any spuriously appearing RX interrupts */
17961806
pl011_write(UART011_RTIS | UART011_RXIS, uap, REG_ICR);
@@ -1812,7 +1822,14 @@ static void pl011_enable_interrupts(struct uart_amba_port *uap)
18121822
if (!pl011_dma_rx_running(uap))
18131823
uap->im |= UART011_RXIM;
18141824
pl011_write(uap->im, uap, REG_IMSC);
1815-
spin_unlock_irq(&uap->port.lock);
1825+
spin_unlock_irqrestore(&uap->port.lock, flags);
1826+
}
1827+
1828+
static void pl011_unthrottle_rx(struct uart_port *port)
1829+
{
1830+
struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port);
1831+
1832+
pl011_enable_interrupts(uap);
18161833
}
18171834

18181835
static int pl011_startup(struct uart_port *port)
@@ -2225,6 +2242,8 @@ static const struct uart_ops amba_pl011_pops = {
22252242
.stop_tx = pl011_stop_tx,
22262243
.start_tx = pl011_start_tx,
22272244
.stop_rx = pl011_stop_rx,
2245+
.throttle = pl011_throttle_rx,
2246+
.unthrottle = pl011_unthrottle_rx,
22282247
.enable_ms = pl011_enable_ms,
22292248
.break_ctl = pl011_break_ctl,
22302249
.startup = pl011_startup,

drivers/tty/serial/mvebu-uart.c

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -470,14 +470,14 @@ static void mvebu_uart_shutdown(struct uart_port *port)
470470
}
471471
}
472472

473-
static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
473+
static unsigned int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
474474
{
475475
unsigned int d_divisor, m_divisor;
476476
unsigned long flags;
477477
u32 brdv, osamp;
478478

479479
if (!port->uartclk)
480-
return -EOPNOTSUPP;
480+
return 0;
481481

482482
/*
483483
* The baudrate is derived from the UART clock thanks to divisors:
@@ -548,7 +548,7 @@ static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
548548
(m_divisor << 16) | (m_divisor << 24);
549549
writel(osamp, port->membase + UART_OSAMP);
550550

551-
return 0;
551+
return DIV_ROUND_CLOSEST(port->uartclk, d_divisor * m_divisor);
552552
}
553553

554554
static void mvebu_uart_set_termios(struct uart_port *port,
@@ -587,15 +587,11 @@ static void mvebu_uart_set_termios(struct uart_port *port,
587587
max_baud = port->uartclk / 80;
588588

589589
baud = uart_get_baud_rate(port, termios, old, min_baud, max_baud);
590-
if (mvebu_uart_baud_rate_set(port, baud)) {
591-
/* No clock available, baudrate cannot be changed */
592-
if (old)
593-
baud = uart_get_baud_rate(port, old, NULL,
594-
min_baud, max_baud);
595-
} else {
596-
tty_termios_encode_baud_rate(termios, baud, baud);
597-
uart_update_timeout(port, termios->c_cflag, baud);
598-
}
590+
baud = mvebu_uart_baud_rate_set(port, baud);
591+
592+
/* In case baudrate cannot be changed, report previous old value */
593+
if (baud == 0 && old)
594+
baud = tty_termios_baud_rate(old);
599595

600596
/* Only the following flag changes are supported */
601597
if (old) {
@@ -606,6 +602,11 @@ static void mvebu_uart_set_termios(struct uart_port *port,
606602
termios->c_cflag |= CS8;
607603
}
608604

605+
if (baud != 0) {
606+
tty_termios_encode_baud_rate(termios, baud, baud);
607+
uart_update_timeout(port, termios->c_cflag, baud);
608+
}
609+
609610
spin_unlock_irqrestore(&port->lock, flags);
610611
}
611612

drivers/tty/serial/samsung_tty.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -377,8 +377,7 @@ static void enable_tx_dma(struct s3c24xx_uart_port *ourport)
377377
/* Enable tx dma mode */
378378
ucon = rd_regl(port, S3C2410_UCON);
379379
ucon &= ~(S3C64XX_UCON_TXBURST_MASK | S3C64XX_UCON_TXMODE_MASK);
380-
ucon |= (dma_get_cache_alignment() >= 16) ?
381-
S3C64XX_UCON_TXBURST_16 : S3C64XX_UCON_TXBURST_1;
380+
ucon |= S3C64XX_UCON_TXBURST_1;
382381
ucon |= S3C64XX_UCON_TXMODE_DMA;
383382
wr_regl(port, S3C2410_UCON, ucon);
384383

@@ -674,7 +673,7 @@ static void enable_rx_dma(struct s3c24xx_uart_port *ourport)
674673
S3C64XX_UCON_DMASUS_EN |
675674
S3C64XX_UCON_TIMEOUT_EN |
676675
S3C64XX_UCON_RXMODE_MASK);
677-
ucon |= S3C64XX_UCON_RXBURST_16 |
676+
ucon |= S3C64XX_UCON_RXBURST_1 |
678677
0xf << S3C64XX_UCON_TIMEOUT_SHIFT |
679678
S3C64XX_UCON_EMPTYINT_EN |
680679
S3C64XX_UCON_TIMEOUT_EN |

drivers/tty/serial/serial_core.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1941,11 +1941,6 @@ static int uart_proc_show(struct seq_file *m, void *v)
19411941
}
19421942
#endif
19431943

1944-
static inline bool uart_console_enabled(struct uart_port *port)
1945-
{
1946-
return uart_console(port) && (port->cons->flags & CON_ENABLED);
1947-
}
1948-
19491944
static void uart_port_spin_lock_init(struct uart_port *port)
19501945
{
19511946
spin_lock_init(&port->lock);

drivers/tty/serial/stm32-usart.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ static void stm32_usart_config_reg_rs485(u32 *cr1, u32 *cr3, u32 delay_ADE,
7272
*cr3 |= USART_CR3_DEM;
7373
over8 = *cr1 & USART_CR1_OVER8;
7474

75+
*cr1 &= ~(USART_CR1_DEDT_MASK | USART_CR1_DEAT_MASK);
76+
7577
if (over8)
7678
rs485_deat_dedt = delay_ADE * baud * 8;
7779
else

0 commit comments

Comments
 (0)