Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+116 -59
+2 -12
drivers/tty/pty.c
··· 111 111 static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c) 112 112 { 113 113 struct tty_struct *to = tty->link; 114 - unsigned long flags; 115 114 116 - if (tty->flow.stopped) 115 + if (tty->flow.stopped || !c) 117 116 return 0; 118 117 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); 129 119 } 130 120 131 121 /**
+4
drivers/tty/serial/8250/8250_core.c
··· 23 23 #include <linux/sysrq.h> 24 24 #include <linux/delay.h> 25 25 #include <linux/platform_device.h> 26 + #include <linux/pm_runtime.h> 26 27 #include <linux/tty.h> 27 28 #include <linux/ratelimit.h> 28 29 #include <linux/tty_flip.h> ··· 559 558 continue; 560 559 561 560 up->port.dev = dev; 561 + 562 + if (uart_console_enabled(&up->port)) 563 + pm_runtime_get_sync(up->port.dev); 562 564 563 565 serial8250_apply_quirks(up); 564 566 uart_add_one_port(drv, &up->port);
+3 -3
drivers/tty/serial/8250/8250_dma.c
··· 106 106 UART_XMIT_SIZE, DMA_TO_DEVICE); 107 107 108 108 dma_async_issue_pending(dma->txchan); 109 - if (dma->tx_err) { 109 + serial8250_clear_THRI(p); 110 + if (dma->tx_err) 110 111 dma->tx_err = 0; 111 - serial8250_clear_THRI(p); 112 - } 112 + 113 113 return 0; 114 114 err: 115 115 dma->tx_err = 1;
+13 -13
drivers/tty/serial/8250/8250_dw.c
··· 47 47 #define RZN1_UART_xDMACR_DMA_EN BIT(0) 48 48 #define RZN1_UART_xDMACR_1_WORD_BURST (0 << 1) 49 49 #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) 51 51 #define RZN1_UART_xDMACR_BLK_SZ(x) ((x) << 3) 52 52 53 53 /* Quirks */ ··· 773 773 MODULE_DEVICE_TABLE(of, dw8250_of_match); 774 774 775 775 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 }, 788 788 { }, 789 789 }; 790 790 MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match);
+4 -2
drivers/tty/serial/8250/8250_port.c
··· 1949 1949 if ((status & UART_LSR_THRE) && (up->ier & UART_IER_THRI)) { 1950 1950 if (!up->dma || up->dma->tx_err) 1951 1951 serial8250_tx_chars(up); 1952 - else 1952 + else if (!up->dma->tx_running) 1953 1953 __stop_tx(up); 1954 1954 } 1955 1955 ··· 2975 2975 case UPIO_MEM32BE: 2976 2976 case UPIO_MEM16: 2977 2977 case UPIO_MEM: 2978 - if (!port->mapbase) 2978 + if (!port->mapbase) { 2979 + ret = -EINVAL; 2979 2980 break; 2981 + } 2980 2982 2981 2983 if (!request_mem_region(port->mapbase, size, "serial")) { 2982 2984 ret = -EBUSY;
+21 -2
drivers/tty/serial/amba-pl011.c
··· 1367 1367 pl011_dma_rx_stop(uap); 1368 1368 } 1369 1369 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 + 1370 1379 static void pl011_enable_ms(struct uart_port *port) 1371 1380 { 1372 1381 struct uart_amba_port *uap = ··· 1797 1788 */ 1798 1789 static void pl011_enable_interrupts(struct uart_amba_port *uap) 1799 1790 { 1791 + unsigned long flags; 1800 1792 unsigned int i; 1801 1793 1802 - spin_lock_irq(&uap->port.lock); 1794 + spin_lock_irqsave(&uap->port.lock, flags); 1803 1795 1804 1796 /* Clear out any spuriously appearing RX interrupts */ 1805 1797 pl011_write(UART011_RTIS | UART011_RXIS, uap, REG_ICR); ··· 1822 1812 if (!pl011_dma_rx_running(uap)) 1823 1813 uap->im |= UART011_RXIM; 1824 1814 pl011_write(uap->im, uap, REG_IMSC); 1825 - spin_unlock_irq(&uap->port.lock); 1815 + spin_unlock_irqrestore(&uap->port.lock, flags); 1816 + } 1817 + 1818 + static void pl011_unthrottle_rx(struct uart_port *port) 1819 + { 1820 + struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); 1821 + 1822 + pl011_enable_interrupts(uap); 1826 1823 } 1827 1824 1828 1825 static int pl011_startup(struct uart_port *port) ··· 2242 2225 .stop_tx = pl011_stop_tx, 2243 2226 .start_tx = pl011_start_tx, 2244 2227 .stop_rx = pl011_stop_rx, 2228 + .throttle = pl011_throttle_rx, 2229 + .unthrottle = pl011_unthrottle_rx, 2245 2230 .enable_ms = pl011_enable_ms, 2246 2231 .break_ctl = pl011_break_ctl, 2247 2232 .startup = pl011_startup,
+13 -12
drivers/tty/serial/mvebu-uart.c
··· 470 470 } 471 471 } 472 472 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) 474 474 { 475 475 unsigned int d_divisor, m_divisor; 476 476 unsigned long flags; 477 477 u32 brdv, osamp; 478 478 479 479 if (!port->uartclk) 480 - return -EOPNOTSUPP; 480 + return 0; 481 481 482 482 /* 483 483 * The baudrate is derived from the UART clock thanks to divisors: ··· 548 548 (m_divisor << 16) | (m_divisor << 24); 549 549 writel(osamp, port->membase + UART_OSAMP); 550 550 551 - return 0; 551 + return DIV_ROUND_CLOSEST(port->uartclk, d_divisor * m_divisor); 552 552 } 553 553 554 554 static void mvebu_uart_set_termios(struct uart_port *port, ··· 587 587 max_baud = port->uartclk / 80; 588 588 589 589 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); 599 595 600 596 /* Only the following flag changes are supported */ 601 597 if (old) { ··· 600 604 termios->c_cflag &= CREAD | CBAUD; 601 605 termios->c_cflag |= old->c_cflag & ~(CREAD | CBAUD); 602 606 termios->c_cflag |= CS8; 607 + } 608 + 609 + if (baud != 0) { 610 + tty_termios_encode_baud_rate(termios, baud, baud); 611 + uart_update_timeout(port, termios->c_cflag, baud); 603 612 } 604 613 605 614 spin_unlock_irqrestore(&port->lock, flags);
+2 -3
drivers/tty/serial/samsung_tty.c
··· 377 377 /* Enable tx dma mode */ 378 378 ucon = rd_regl(port, S3C2410_UCON); 379 379 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; 382 381 ucon |= S3C64XX_UCON_TXMODE_DMA; 383 382 wr_regl(port, S3C2410_UCON, ucon); 384 383 ··· 673 674 S3C64XX_UCON_DMASUS_EN | 674 675 S3C64XX_UCON_TIMEOUT_EN | 675 676 S3C64XX_UCON_RXMODE_MASK); 676 - ucon |= S3C64XX_UCON_RXBURST_16 | 677 + ucon |= S3C64XX_UCON_RXBURST_1 | 677 678 0xf << S3C64XX_UCON_TIMEOUT_SHIFT | 678 679 S3C64XX_UCON_EMPTYINT_EN | 679 680 S3C64XX_UCON_TIMEOUT_EN |
-5
drivers/tty/serial/serial_core.c
··· 1941 1941 } 1942 1942 #endif 1943 1943 1944 - static inline bool uart_console_enabled(struct uart_port *port) 1945 - { 1946 - return uart_console(port) && (port->cons->flags & CON_ENABLED); 1947 - } 1948 - 1949 1944 static void uart_port_spin_lock_init(struct uart_port *port) 1950 1945 { 1951 1946 spin_lock_init(&port->lock);
+2
drivers/tty/serial/stm32-usart.c
··· 72 72 *cr3 |= USART_CR3_DEM; 73 73 over8 = *cr1 & USART_CR1_OVER8; 74 74 75 + *cr1 &= ~(USART_CR1_DEDT_MASK | USART_CR1_DEAT_MASK); 76 + 75 77 if (over8) 76 78 rs485_deat_dedt = delay_ADE * baud * 8; 77 79 else
+3
drivers/tty/tty.h
··· 111 111 112 112 ssize_t redirected_tty_write(struct kiocb *, struct iov_iter *); 113 113 114 + int tty_insert_flip_string_and_push_buffer(struct tty_port *port, 115 + const unsigned char *chars, size_t cnt); 116 + 114 117 #endif
+41 -5
drivers/tty/tty_buffer.c
··· 532 532 533 533 } 534 534 535 + static inline void tty_flip_buffer_commit(struct tty_buffer *tail) 536 + { 537 + /* 538 + * Paired w/ acquire in flush_to_ldisc(); ensures flush_to_ldisc() sees 539 + * buffer data. 540 + */ 541 + smp_store_release(&tail->commit, tail->used); 542 + } 543 + 535 544 /** 536 545 * tty_flip_buffer_push - push terminal buffers 537 546 * @port: tty port to push ··· 555 546 { 556 547 struct tty_bufhead *buf = &port->buf; 557 548 558 - /* 559 - * Paired w/ acquire in flush_to_ldisc(); ensures flush_to_ldisc() sees 560 - * buffer data. 561 - */ 562 - smp_store_release(&buf->tail->commit, buf->tail->used); 549 + tty_flip_buffer_commit(buf->tail); 563 550 queue_work(system_unbound_wq, &buf->work); 564 551 } 565 552 EXPORT_SYMBOL(tty_flip_buffer_push); 553 + 554 + /** 555 + * tty_insert_flip_string_and_push_buffer - add characters to the tty buffer and 556 + * push 557 + * @port: tty port 558 + * @chars: characters 559 + * @size: size 560 + * 561 + * The function combines tty_insert_flip_string() and tty_flip_buffer_push() 562 + * with the exception of properly holding the @port->lock. 563 + * 564 + * To be used only internally (by pty currently). 565 + * 566 + * Returns: the number added. 567 + */ 568 + int tty_insert_flip_string_and_push_buffer(struct tty_port *port, 569 + const unsigned char *chars, size_t size) 570 + { 571 + struct tty_bufhead *buf = &port->buf; 572 + unsigned long flags; 573 + 574 + spin_lock_irqsave(&port->lock, flags); 575 + size = tty_insert_flip_string(port, chars, size); 576 + if (size) 577 + tty_flip_buffer_commit(buf->tail); 578 + spin_unlock_irqrestore(&port->lock, flags); 579 + 580 + queue_work(system_unbound_wq, &buf->work); 581 + 582 + return size; 583 + } 566 584 567 585 /** 568 586 * tty_buffer_init - prepare a tty buffer structure
+1 -1
drivers/tty/vt/vt.c
··· 855 855 unsigned short *p = (unsigned short *) vc->vc_pos; 856 856 857 857 vc_uniscr_delete(vc, nr); 858 - scr_memcpyw(p, p + nr, (vc->vc_cols - vc->state.x - nr) * 2); 858 + scr_memmovew(p, p + nr, (vc->vc_cols - vc->state.x - nr) * 2); 859 859 scr_memsetw(p + vc->vc_cols - vc->state.x - nr, vc->vc_video_erase_char, 860 860 nr * 2); 861 861 vc->vc_need_wrap = 0;
+5
include/linux/serial_core.h
··· 390 390 static inline int setup_earlycon(char *buf) { return 0; } 391 391 #endif 392 392 393 + static inline bool uart_console_enabled(struct uart_port *port) 394 + { 395 + return uart_console(port) && (port->cons->flags & CON_ENABLED); 396 + } 397 + 393 398 struct uart_port *uart_get_console(struct uart_port *ports, int nr, 394 399 struct console *c); 395 400 int uart_parse_earlycon(char *p, unsigned char *iotype, resource_size_t *addr,
+2 -1
include/uapi/linux/tty.h
··· 38 38 #define N_NULL 27 /* Null ldisc used for error handling */ 39 39 #define N_MCTP 28 /* MCTP-over-serial */ 40 40 #define N_DEVELOPMENT 29 /* Manual out-of-tree testing */ 41 + #define N_CAN327 30 /* ELM327 based OBD-II interfaces */ 41 42 42 43 /* Always the newest line discipline + 1 */ 43 - #define NR_LDISCS 30 44 + #define NR_LDISCS 31 44 45 45 46 #endif /* _UAPI_LINUX_TTY_H */