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.17-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty

Pull tty/serial driver fixes from Greg KH:
"Here are some small bug fixes and reverts for reported problems with
the tty core and drivers. They include:

- revert the fifo use for the 8250 console mode. It caused too many
regressions and problems, and had a bug in it as well. This is
being reworked and should show up in a later -rc1 release, but it's
not ready for 5.17

- rpmsg tty race fix

- restore the cyclades.h uapi header file. Turns out a compiler test
suite used it for some unknown reason. Bring it back just for the
parts that are used by the builder test so they continue to build.
No functionality is restored as no one actually has this hardware
anymore, nor is it really tested.

- stm32 driver fixes

- n_gsm flow control fixes

- pl011 driver fix

- rs485 initialization fix

All of these have been in linux-next this week with no reported
problems"

* tag 'tty-5.17-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
kbuild: remove include/linux/cyclades.h from header file check
serial: core: Initialize rs485 RTS polarity already on probe
serial: pl011: Fix incorrect rs485 RTS polarity on set_mctrl
serial: stm32: fix software flow control transfer
serial: stm32: prevent TDR register overwrite when sending x_char
tty: n_gsm: fix SW flow control encoding/handling
serial: 8250: of: Fix mapped region size when using reg-offset property
tty: rpmsg: Fix race condition releasing tty port
tty: Partially revert the removal of the Cyclades public API
tty: Add support for Brainboxes UC cards.
Revert "tty: serial: Use fifo in 8250 console driver"

+205 -106
+3 -1
drivers/tty/n_gsm.c
··· 322 322 #define GSM1_ESCAPE_BITS 0x20 323 323 #define XON 0x11 324 324 #define XOFF 0x13 325 + #define ISO_IEC_646_MASK 0x7F 325 326 326 327 static const struct tty_port_operations gsm_port_ops; 327 328 ··· 532 531 int olen = 0; 533 532 while (len--) { 534 533 if (*input == GSM1_SOF || *input == GSM1_ESCAPE 535 - || *input == XON || *input == XOFF) { 534 + || (*input & ISO_IEC_646_MASK) == XON 535 + || (*input & ISO_IEC_646_MASK) == XOFF) { 536 536 *output++ = GSM1_ESCAPE; 537 537 *output++ = *input++ ^ GSM1_ESCAPE_BITS; 538 538 olen++;
+26 -14
drivers/tty/rpmsg_tty.c
··· 50 50 static int rpmsg_tty_install(struct tty_driver *driver, struct tty_struct *tty) 51 51 { 52 52 struct rpmsg_tty_port *cport = idr_find(&tty_idr, tty->index); 53 + struct tty_port *port; 53 54 54 55 tty->driver_data = cport; 55 56 56 - return tty_port_install(&cport->port, driver, tty); 57 + port = tty_port_get(&cport->port); 58 + return tty_port_install(port, driver, tty); 59 + } 60 + 61 + static void rpmsg_tty_cleanup(struct tty_struct *tty) 62 + { 63 + tty_port_put(tty->port); 57 64 } 58 65 59 66 static int rpmsg_tty_open(struct tty_struct *tty, struct file *filp) ··· 113 106 return size; 114 107 } 115 108 109 + static void rpmsg_tty_hangup(struct tty_struct *tty) 110 + { 111 + tty_port_hangup(tty->port); 112 + } 113 + 116 114 static const struct tty_operations rpmsg_tty_ops = { 117 115 .install = rpmsg_tty_install, 118 116 .open = rpmsg_tty_open, 119 117 .close = rpmsg_tty_close, 120 118 .write = rpmsg_tty_write, 121 119 .write_room = rpmsg_tty_write_room, 120 + .hangup = rpmsg_tty_hangup, 121 + .cleanup = rpmsg_tty_cleanup, 122 122 }; 123 123 124 124 static struct rpmsg_tty_port *rpmsg_tty_alloc_cport(void) ··· 151 137 return cport; 152 138 } 153 139 154 - static void rpmsg_tty_release_cport(struct rpmsg_tty_port *cport) 140 + static void rpmsg_tty_destruct_port(struct tty_port *port) 155 141 { 142 + struct rpmsg_tty_port *cport = container_of(port, struct rpmsg_tty_port, port); 143 + 156 144 mutex_lock(&idr_lock); 157 145 idr_remove(&tty_idr, cport->id); 158 146 mutex_unlock(&idr_lock); ··· 162 146 kfree(cport); 163 147 } 164 148 165 - static const struct tty_port_operations rpmsg_tty_port_ops = { }; 149 + static const struct tty_port_operations rpmsg_tty_port_ops = { 150 + .destruct = rpmsg_tty_destruct_port, 151 + }; 152 + 166 153 167 154 static int rpmsg_tty_probe(struct rpmsg_device *rpdev) 168 155 { ··· 185 166 cport->id, dev); 186 167 if (IS_ERR(tty_dev)) { 187 168 ret = dev_err_probe(dev, PTR_ERR(tty_dev), "Failed to register tty port\n"); 188 - goto err_destroy; 169 + tty_port_put(&cport->port); 170 + return ret; 189 171 } 190 172 191 173 cport->rpdev = rpdev; ··· 197 177 rpdev->src, rpdev->dst, cport->id); 198 178 199 179 return 0; 200 - 201 - err_destroy: 202 - tty_port_destroy(&cport->port); 203 - rpmsg_tty_release_cport(cport); 204 - 205 - return ret; 206 180 } 207 181 208 182 static void rpmsg_tty_remove(struct rpmsg_device *rpdev) ··· 206 192 dev_dbg(&rpdev->dev, "Removing rpmsg tty device %d\n", cport->id); 207 193 208 194 /* User hang up to release the tty */ 209 - if (tty_port_initialized(&cport->port)) 210 - tty_port_tty_hangup(&cport->port, false); 195 + tty_port_tty_hangup(&cport->port, false); 211 196 212 197 tty_unregister_device(rpmsg_tty_driver, cport->id); 213 198 214 - tty_port_destroy(&cport->port); 215 - rpmsg_tty_release_cport(cport); 199 + tty_port_put(&cport->port); 216 200 } 217 201 218 202 static struct rpmsg_device_id rpmsg_driver_tty_id_table[] = {
+10 -1
drivers/tty/serial/8250/8250_of.c
··· 83 83 port->mapsize = resource_size(&resource); 84 84 85 85 /* Check for shifted address mapping */ 86 - if (of_property_read_u32(np, "reg-offset", &prop) == 0) 86 + if (of_property_read_u32(np, "reg-offset", &prop) == 0) { 87 + if (prop >= port->mapsize) { 88 + dev_warn(&ofdev->dev, "reg-offset %u exceeds region size %pa\n", 89 + prop, &port->mapsize); 90 + ret = -EINVAL; 91 + goto err_unprepare; 92 + } 93 + 87 94 port->mapbase += prop; 95 + port->mapsize -= prop; 96 + } 88 97 89 98 port->iotype = UPIO_MEM; 90 99 if (of_property_read_u32(np, "reg-io-width", &prop) == 0) {
+98 -2
drivers/tty/serial/8250/8250_pci.c
··· 4779 4779 { PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS400, 4780 4780 PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0dc0 */ 4781 4781 pbn_b2_4_115200 }, 4782 + /* Brainboxes Devices */ 4782 4783 /* 4783 - * BrainBoxes UC-260 4784 + * Brainboxes UC-101 4785 + */ 4786 + { PCI_VENDOR_ID_INTASHIELD, 0x0BA1, 4787 + PCI_ANY_ID, PCI_ANY_ID, 4788 + 0, 0, 4789 + pbn_b2_2_115200 }, 4790 + /* 4791 + * Brainboxes UC-235/246 4792 + */ 4793 + { PCI_VENDOR_ID_INTASHIELD, 0x0AA1, 4794 + PCI_ANY_ID, PCI_ANY_ID, 4795 + 0, 0, 4796 + pbn_b2_1_115200 }, 4797 + /* 4798 + * Brainboxes UC-257 4799 + */ 4800 + { PCI_VENDOR_ID_INTASHIELD, 0x0861, 4801 + PCI_ANY_ID, PCI_ANY_ID, 4802 + 0, 0, 4803 + pbn_b2_2_115200 }, 4804 + /* 4805 + * Brainboxes UC-260/271/701/756 4784 4806 */ 4785 4807 { PCI_VENDOR_ID_INTASHIELD, 0x0D21, 4786 4808 PCI_ANY_ID, PCI_ANY_ID, ··· 4810 4788 pbn_b2_4_115200 }, 4811 4789 { PCI_VENDOR_ID_INTASHIELD, 0x0E34, 4812 4790 PCI_ANY_ID, PCI_ANY_ID, 4813 - PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00, 4791 + PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00, 4792 + pbn_b2_4_115200 }, 4793 + /* 4794 + * Brainboxes UC-268 4795 + */ 4796 + { PCI_VENDOR_ID_INTASHIELD, 0x0841, 4797 + PCI_ANY_ID, PCI_ANY_ID, 4798 + 0, 0, 4799 + pbn_b2_4_115200 }, 4800 + /* 4801 + * Brainboxes UC-275/279 4802 + */ 4803 + { PCI_VENDOR_ID_INTASHIELD, 0x0881, 4804 + PCI_ANY_ID, PCI_ANY_ID, 4805 + 0, 0, 4806 + pbn_b2_8_115200 }, 4807 + /* 4808 + * Brainboxes UC-302 4809 + */ 4810 + { PCI_VENDOR_ID_INTASHIELD, 0x08E1, 4811 + PCI_ANY_ID, PCI_ANY_ID, 4812 + 0, 0, 4813 + pbn_b2_2_115200 }, 4814 + /* 4815 + * Brainboxes UC-310 4816 + */ 4817 + { PCI_VENDOR_ID_INTASHIELD, 0x08C1, 4818 + PCI_ANY_ID, PCI_ANY_ID, 4819 + 0, 0, 4820 + pbn_b2_2_115200 }, 4821 + /* 4822 + * Brainboxes UC-313 4823 + */ 4824 + { PCI_VENDOR_ID_INTASHIELD, 0x08A3, 4825 + PCI_ANY_ID, PCI_ANY_ID, 4826 + 0, 0, 4827 + pbn_b2_2_115200 }, 4828 + /* 4829 + * Brainboxes UC-320/324 4830 + */ 4831 + { PCI_VENDOR_ID_INTASHIELD, 0x0A61, 4832 + PCI_ANY_ID, PCI_ANY_ID, 4833 + 0, 0, 4834 + pbn_b2_1_115200 }, 4835 + /* 4836 + * Brainboxes UC-346 4837 + */ 4838 + { PCI_VENDOR_ID_INTASHIELD, 0x0B02, 4839 + PCI_ANY_ID, PCI_ANY_ID, 4840 + 0, 0, 4841 + pbn_b2_4_115200 }, 4842 + /* 4843 + * Brainboxes UC-357 4844 + */ 4845 + { PCI_VENDOR_ID_INTASHIELD, 0x0A81, 4846 + PCI_ANY_ID, PCI_ANY_ID, 4847 + 0, 0, 4848 + pbn_b2_2_115200 }, 4849 + { PCI_VENDOR_ID_INTASHIELD, 0x0A83, 4850 + PCI_ANY_ID, PCI_ANY_ID, 4851 + 0, 0, 4852 + pbn_b2_2_115200 }, 4853 + /* 4854 + * Brainboxes UC-368 4855 + */ 4856 + { PCI_VENDOR_ID_INTASHIELD, 0x0C41, 4857 + PCI_ANY_ID, PCI_ANY_ID, 4858 + 0, 0, 4859 + pbn_b2_4_115200 }, 4860 + /* 4861 + * Brainboxes UC-420/431 4862 + */ 4863 + { PCI_VENDOR_ID_INTASHIELD, 0x0921, 4864 + PCI_ANY_ID, PCI_ANY_ID, 4865 + 0, 0, 4814 4866 pbn_b2_4_115200 }, 4815 4867 /* 4816 4868 * Perle PCI-RAS cards
+6 -55
drivers/tty/serial/8250/8250_port.c
··· 2056 2056 serial8250_rpm_put(up); 2057 2057 } 2058 2058 2059 - static void wait_for_lsr(struct uart_8250_port *up, int bits) 2059 + /* 2060 + * Wait for transmitter & holding register to empty 2061 + */ 2062 + static void wait_for_xmitr(struct uart_8250_port *up, int bits) 2060 2063 { 2061 2064 unsigned int status, tmout = 10000; 2062 2065 ··· 2076 2073 udelay(1); 2077 2074 touch_nmi_watchdog(); 2078 2075 } 2079 - } 2080 - 2081 - /* 2082 - * Wait for transmitter & holding register to empty 2083 - */ 2084 - static void wait_for_xmitr(struct uart_8250_port *up, int bits) 2085 - { 2086 - unsigned int tmout; 2087 - 2088 - wait_for_lsr(up, bits); 2089 2076 2090 2077 /* Wait up to 1s for flow control if necessary */ 2091 2078 if (up->port.flags & UPF_CONS_FLOW) { ··· 3326 3333 } 3327 3334 3328 3335 /* 3329 - * Print a string to the serial port using the device FIFO 3330 - * 3331 - * It sends fifosize bytes and then waits for the fifo 3332 - * to get empty. 3333 - */ 3334 - static void serial8250_console_fifo_write(struct uart_8250_port *up, 3335 - const char *s, unsigned int count) 3336 - { 3337 - int i; 3338 - const char *end = s + count; 3339 - unsigned int fifosize = up->port.fifosize; 3340 - bool cr_sent = false; 3341 - 3342 - while (s != end) { 3343 - wait_for_lsr(up, UART_LSR_THRE); 3344 - 3345 - for (i = 0; i < fifosize && s != end; ++i) { 3346 - if (*s == '\n' && !cr_sent) { 3347 - serial_out(up, UART_TX, '\r'); 3348 - cr_sent = true; 3349 - } else { 3350 - serial_out(up, UART_TX, *s++); 3351 - cr_sent = false; 3352 - } 3353 - } 3354 - } 3355 - } 3356 - 3357 - /* 3358 3336 * Print a string to the serial port trying not to disturb 3359 3337 * any possible real use of the port... 3360 3338 * ··· 3340 3376 struct uart_8250_em485 *em485 = up->em485; 3341 3377 struct uart_port *port = &up->port; 3342 3378 unsigned long flags; 3343 - unsigned int ier, use_fifo; 3379 + unsigned int ier; 3344 3380 int locked = 1; 3345 3381 3346 3382 touch_nmi_watchdog(); ··· 3372 3408 mdelay(port->rs485.delay_rts_before_send); 3373 3409 } 3374 3410 3375 - use_fifo = (up->capabilities & UART_CAP_FIFO) && 3376 - port->fifosize > 1 && 3377 - (serial_port_in(port, UART_FCR) & UART_FCR_ENABLE_FIFO) && 3378 - /* 3379 - * After we put a data in the fifo, the controller will send 3380 - * it regardless of the CTS state. Therefore, only use fifo 3381 - * if we don't use control flow. 3382 - */ 3383 - !(up->port.flags & UPF_CONS_FLOW); 3384 - 3385 - if (likely(use_fifo)) 3386 - serial8250_console_fifo_write(up, s, count); 3387 - else 3388 - uart_console_write(port, s, count, serial8250_console_putchar); 3411 + uart_console_write(port, s, count, serial8250_console_putchar); 3389 3412 3390 3413 /* 3391 3414 * Finally, wait for transmitter to become empty
+1 -10
drivers/tty/serial/amba-pl011.c
··· 1582 1582 container_of(port, struct uart_amba_port, port); 1583 1583 unsigned int cr; 1584 1584 1585 - if (port->rs485.flags & SER_RS485_ENABLED) 1586 - mctrl &= ~TIOCM_RTS; 1587 - 1588 1585 cr = pl011_read(uap, REG_CR); 1589 1586 1590 1587 #define TIOCMBIT(tiocmbit, uartbit) \ ··· 1805 1808 cr &= UART011_CR_RTS | UART011_CR_DTR; 1806 1809 cr |= UART01x_CR_UARTEN | UART011_CR_RXE; 1807 1810 1808 - if (port->rs485.flags & SER_RS485_ENABLED) { 1809 - if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) 1810 - cr &= ~UART011_CR_RTS; 1811 - else 1812 - cr |= UART011_CR_RTS; 1813 - } else { 1811 + if (!(port->rs485.flags & SER_RS485_ENABLED)) 1814 1812 cr |= UART011_CR_TXE; 1815 - } 1816 1813 1817 1814 pl011_write(cr, uap, REG_CR); 1818 1815
+12 -22
drivers/tty/serial/serial_core.c
··· 144 144 unsigned long flags; 145 145 unsigned int old; 146 146 147 + if (port->rs485.flags & SER_RS485_ENABLED) { 148 + set &= ~TIOCM_RTS; 149 + clear &= ~TIOCM_RTS; 150 + } 151 + 147 152 spin_lock_irqsave(&port->lock, flags); 148 153 old = port->mctrl; 149 154 port->mctrl = (old & ~clear) | set; ··· 162 157 163 158 static void uart_port_dtr_rts(struct uart_port *uport, int raise) 164 159 { 165 - int rs485_on = uport->rs485_config && 166 - (uport->rs485.flags & SER_RS485_ENABLED); 167 - int RTS_after_send = !!(uport->rs485.flags & SER_RS485_RTS_AFTER_SEND); 168 - 169 - if (raise) { 170 - if (rs485_on && RTS_after_send) { 171 - uart_set_mctrl(uport, TIOCM_DTR); 172 - uart_clear_mctrl(uport, TIOCM_RTS); 173 - } else { 174 - uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS); 175 - } 176 - } else { 177 - unsigned int clear = TIOCM_DTR; 178 - 179 - clear |= (!rs485_on || RTS_after_send) ? TIOCM_RTS : 0; 180 - uart_clear_mctrl(uport, clear); 181 - } 160 + if (raise) 161 + uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS); 162 + else 163 + uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); 182 164 } 183 165 184 166 /* ··· 1067 1075 goto out; 1068 1076 1069 1077 if (!tty_io_error(tty)) { 1070 - if (uport->rs485.flags & SER_RS485_ENABLED) { 1071 - set &= ~TIOCM_RTS; 1072 - clear &= ~TIOCM_RTS; 1073 - } 1074 - 1075 1078 uart_update_mctrl(uport, set, clear); 1076 1079 ret = 0; 1077 1080 } ··· 2377 2390 */ 2378 2391 spin_lock_irqsave(&port->lock, flags); 2379 2392 port->mctrl &= TIOCM_DTR; 2393 + if (port->rs485.flags & SER_RS485_ENABLED && 2394 + !(port->rs485.flags & SER_RS485_RTS_AFTER_SEND)) 2395 + port->mctrl |= TIOCM_RTS; 2380 2396 port->ops->set_mctrl(port, port->mctrl); 2381 2397 spin_unlock_irqrestore(&port->lock, flags); 2382 2398
+13 -1
drivers/tty/serial/stm32-usart.c
··· 550 550 struct stm32_port *stm32_port = to_stm32_port(port); 551 551 const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; 552 552 struct circ_buf *xmit = &port->state->xmit; 553 + u32 isr; 554 + int ret; 553 555 554 556 if (port->x_char) { 555 557 if (stm32_usart_tx_dma_started(stm32_port) && 556 558 stm32_usart_tx_dma_enabled(stm32_port)) 557 559 stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT); 560 + 561 + /* Check that TDR is empty before filling FIFO */ 562 + ret = 563 + readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr, 564 + isr, 565 + (isr & USART_SR_TXE), 566 + 10, 1000); 567 + if (ret) 568 + dev_warn(port->dev, "1 character may be erased\n"); 569 + 558 570 writel_relaxed(port->x_char, port->membase + ofs->tdr); 559 571 port->x_char = 0; 560 572 port->icount.tx++; ··· 742 730 struct serial_rs485 *rs485conf = &port->rs485; 743 731 struct circ_buf *xmit = &port->state->xmit; 744 732 745 - if (uart_circ_empty(xmit)) 733 + if (uart_circ_empty(xmit) && !port->x_char) 746 734 return; 747 735 748 736 if (rs485conf->flags & SER_RS485_ENABLED) {
+35
include/uapi/linux/cyclades.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 + 3 + #ifndef _UAPI_LINUX_CYCLADES_H 4 + #define _UAPI_LINUX_CYCLADES_H 5 + 6 + #warning "Support for features provided by this header has been removed" 7 + #warning "Please consider updating your code" 8 + 9 + struct cyclades_monitor { 10 + unsigned long int_count; 11 + unsigned long char_count; 12 + unsigned long char_max; 13 + unsigned long char_last; 14 + }; 15 + 16 + #define CYGETMON 0x435901 17 + #define CYGETTHRESH 0x435902 18 + #define CYSETTHRESH 0x435903 19 + #define CYGETDEFTHRESH 0x435904 20 + #define CYSETDEFTHRESH 0x435905 21 + #define CYGETTIMEOUT 0x435906 22 + #define CYSETTIMEOUT 0x435907 23 + #define CYGETDEFTIMEOUT 0x435908 24 + #define CYSETDEFTIMEOUT 0x435909 25 + #define CYSETRFLOW 0x43590a 26 + #define CYGETRFLOW 0x43590b 27 + #define CYSETRTSDTR_INV 0x43590c 28 + #define CYGETRTSDTR_INV 0x43590d 29 + #define CYZSETPOLLCYCLE 0x43590e 30 + #define CYZGETPOLLCYCLE 0x43590f 31 + #define CYGETCD1400VER 0x435910 32 + #define CYSETWAIT 0x435912 33 + #define CYGETWAIT 0x435913 34 + 35 + #endif /* _UAPI_LINUX_CYCLADES_H */
+1
usr/include/Makefile
··· 28 28 no-header-test += linux/android/binder.h 29 29 no-header-test += linux/android/binderfs.h 30 30 no-header-test += linux/coda.h 31 + no-header-test += linux/cyclades.h 31 32 no-header-test += linux/errqueue.h 32 33 no-header-test += linux/fsmap.h 33 34 no-header-test += linux/hdlc/ioctl.h