Merge tag 'tty-4.12-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty

Pull tty/serial fixes from Greg KH:
"Here are some serial and tty fixes for 4.12-rc3. They are a bit bigger
than normal, which is why I had them bake in linux-next for a few
weeks and didn't send them to you for -rc2.

They revert a few of the serdev patches from 4.12-rc1, and bring
things back to how they were in 4.11, to try to make things a bit more
stable there. Rob and Johan both agree that this is the way forward,
so this isn't people squabbling over semantics. Other than that, just
a few minor serial driver fixes that people have had problems with.

All of these have been in linux-next for a few weeks with no reported
issues"

* tag 'tty-4.12-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
serial: altera_uart: call iounmap() at driver remove
serial: imx: ensure UCR3 and UFCR are setup correctly
MAINTAINERS/serial: Change maintainer of jsm driver
serial: enable serdev support
tty/serdev: add serdev registration interface
serdev: Restore serdev_device_write_buf for atomic context
serial: core: fix crash in uart_suspend_port
tty: fix port buffer locking
tty: ehv_bytechan: clean up init error handling
serial: ifx6x60: fix use-after-free on module unload
serial: altera_jtaguart: adding iounmap()
serial: exar: Fix stuck MSIs
serial: efm32: Fix parity management in 'efm32_uart_console_get_options()'
serdev: fix tty-port client deregistration
Revert "tty_port: register tty ports with serdev bus"
drivers/tty: 8250: only call fintek_8250_probe when doing port I/O

+1 -1
MAINTAINERS
··· 7143 7143 F: drivers/media/platform/rcar_jpu.c 7144 7144 7145 7145 JSM Neo PCI based serial card 7146 - M: Gabriel Krisman Bertazi <krisman@linux.vnet.ibm.com> 7146 + M: Guilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com> 7147 7147 L: linux-serial@vger.kernel.org 7148 7148 S: Maintained 7149 7149 F: drivers/tty/serial/jsm/
+8 -9
drivers/tty/ehv_bytechan.c
··· 764 764 ehv_bc_driver = alloc_tty_driver(count); 765 765 if (!ehv_bc_driver) { 766 766 ret = -ENOMEM; 767 - goto error; 767 + goto err_free_bcs; 768 768 } 769 769 770 770 ehv_bc_driver->driver_name = "ehv-bc"; ··· 778 778 ret = tty_register_driver(ehv_bc_driver); 779 779 if (ret) { 780 780 pr_err("ehv-bc: could not register tty driver (ret=%i)\n", ret); 781 - goto error; 781 + goto err_put_tty_driver; 782 782 } 783 783 784 784 ret = platform_driver_register(&ehv_bc_tty_driver); 785 785 if (ret) { 786 786 pr_err("ehv-bc: could not register platform driver (ret=%i)\n", 787 787 ret); 788 - goto error; 788 + goto err_deregister_tty_driver; 789 789 } 790 790 791 791 return 0; 792 792 793 - error: 794 - if (ehv_bc_driver) { 795 - tty_unregister_driver(ehv_bc_driver); 796 - put_tty_driver(ehv_bc_driver); 797 - } 798 - 793 + err_deregister_tty_driver: 794 + tty_unregister_driver(ehv_bc_driver); 795 + err_put_tty_driver: 796 + put_tty_driver(ehv_bc_driver); 797 + err_free_bcs: 799 798 kfree(bcs); 800 799 801 800 return ret;
+12
drivers/tty/serdev/core.c
··· 122 122 } 123 123 EXPORT_SYMBOL_GPL(serdev_device_write_wakeup); 124 124 125 + int serdev_device_write_buf(struct serdev_device *serdev, 126 + const unsigned char *buf, size_t count) 127 + { 128 + struct serdev_controller *ctrl = serdev->ctrl; 129 + 130 + if (!ctrl || !ctrl->ops->write_buf) 131 + return -EINVAL; 132 + 133 + return ctrl->ops->write_buf(ctrl, buf, count); 134 + } 135 + EXPORT_SYMBOL_GPL(serdev_device_write_buf); 136 + 125 137 int serdev_device_write(struct serdev_device *serdev, 126 138 const unsigned char *buf, size_t count, 127 139 unsigned long timeout)
+14 -7
drivers/tty/serdev/serdev-ttyport.c
··· 102 102 return PTR_ERR(tty); 103 103 serport->tty = tty; 104 104 105 - serport->port->client_ops = &client_ops; 106 - serport->port->client_data = ctrl; 107 - 108 105 if (tty->ops->open) 109 106 tty->ops->open(serport->tty, NULL); 110 107 else ··· 212 215 struct device *parent, 213 216 struct tty_driver *drv, int idx) 214 217 { 218 + const struct tty_port_client_operations *old_ops; 215 219 struct serdev_controller *ctrl; 216 220 struct serport *serport; 217 221 int ret; ··· 231 233 232 234 ctrl->ops = &ctrl_ops; 233 235 236 + old_ops = port->client_ops; 237 + port->client_ops = &client_ops; 238 + port->client_data = ctrl; 239 + 234 240 ret = serdev_controller_add(ctrl); 235 241 if (ret) 236 - goto err_controller_put; 242 + goto err_reset_data; 237 243 238 244 dev_info(&ctrl->dev, "tty port %s%d registered\n", drv->name, idx); 239 245 return &ctrl->dev; 240 246 241 - err_controller_put: 247 + err_reset_data: 248 + port->client_data = NULL; 249 + port->client_ops = old_ops; 242 250 serdev_controller_put(ctrl); 251 + 243 252 return ERR_PTR(ret); 244 253 } 245 254 246 - void serdev_tty_port_unregister(struct tty_port *port) 255 + int serdev_tty_port_unregister(struct tty_port *port) 247 256 { 248 257 struct serdev_controller *ctrl = port->client_data; 249 258 struct serport *serport = serdev_controller_get_drvdata(ctrl); 250 259 251 260 if (!serport) 252 - return; 261 + return -ENODEV; 253 262 254 263 serdev_controller_remove(ctrl); 255 264 port->client_ops = NULL; 256 265 port->client_data = NULL; 257 266 serdev_controller_put(ctrl); 267 + 268 + return 0; 258 269 }
+11 -10
drivers/tty/serial/8250/8250_port.c
··· 47 47 /* 48 48 * These are definitions for the Exar XR17V35X and XR17(C|D)15X 49 49 */ 50 + #define UART_EXAR_INT0 0x80 50 51 #define UART_EXAR_SLEEP 0x8b /* Sleep mode */ 51 52 #define UART_EXAR_DVID 0x8d /* Device identification */ 52 53 ··· 1338 1337 /* 1339 1338 * Check if the device is a Fintek F81216A 1340 1339 */ 1341 - if (port->type == PORT_16550A) 1340 + if (port->type == PORT_16550A && port->iotype == UPIO_PORT) 1342 1341 fintek_8250_probe(up); 1343 1342 1344 1343 if (up->capabilities != old_capabilities) { ··· 1870 1869 static int exar_handle_irq(struct uart_port *port) 1871 1870 { 1872 1871 unsigned int iir = serial_port_in(port, UART_IIR); 1873 - int ret; 1872 + int ret = 0; 1874 1873 1875 - ret = serial8250_handle_irq(port, iir); 1874 + if (((port->type == PORT_XR17V35X) || (port->type == PORT_XR17D15X)) && 1875 + serial_port_in(port, UART_EXAR_INT0) != 0) 1876 + ret = 1; 1876 1877 1877 - if ((port->type == PORT_XR17V35X) || 1878 - (port->type == PORT_XR17D15X)) { 1879 - serial_port_in(port, 0x80); 1880 - serial_port_in(port, 0x81); 1881 - serial_port_in(port, 0x82); 1882 - serial_port_in(port, 0x83); 1883 - } 1878 + ret |= serial8250_handle_irq(port, iir); 1884 1879 1885 1880 return ret; 1886 1881 } ··· 2174 2177 serial_port_in(port, UART_RX); 2175 2178 serial_port_in(port, UART_IIR); 2176 2179 serial_port_in(port, UART_MSR); 2180 + if ((port->type == PORT_XR17V35X) || (port->type == PORT_XR17D15X)) 2181 + serial_port_in(port, UART_EXAR_INT0); 2177 2182 2178 2183 /* 2179 2184 * At this point, there's no way the LSR could still be 0xff; ··· 2334 2335 serial_port_in(port, UART_RX); 2335 2336 serial_port_in(port, UART_IIR); 2336 2337 serial_port_in(port, UART_MSR); 2338 + if ((port->type == PORT_XR17V35X) || (port->type == PORT_XR17D15X)) 2339 + serial_port_in(port, UART_EXAR_INT0); 2337 2340 up->lsr_saved_flags = 0; 2338 2341 up->msr_saved_flags = 0; 2339 2342
+1
drivers/tty/serial/altera_jtaguart.c
··· 478 478 479 479 port = &altera_jtaguart_ports[i].port; 480 480 uart_remove_one_port(&altera_jtaguart_driver, port); 481 + iounmap(port->membase); 481 482 482 483 return 0; 483 484 }
+1
drivers/tty/serial/altera_uart.c
··· 615 615 if (port) { 616 616 uart_remove_one_port(&altera_uart_driver, port); 617 617 port->mapbase = 0; 618 + iounmap(port->membase); 618 619 } 619 620 620 621 return 0;
+8 -3
drivers/tty/serial/efm32-uart.c
··· 27 27 #define UARTn_FRAME 0x04 28 28 #define UARTn_FRAME_DATABITS__MASK 0x000f 29 29 #define UARTn_FRAME_DATABITS(n) ((n) - 3) 30 + #define UARTn_FRAME_PARITY__MASK 0x0300 30 31 #define UARTn_FRAME_PARITY_NONE 0x0000 31 32 #define UARTn_FRAME_PARITY_EVEN 0x0200 32 33 #define UARTn_FRAME_PARITY_ODD 0x0300 ··· 573 572 16 * (4 + (clkdiv >> 6))); 574 573 575 574 frame = efm32_uart_read32(efm_port, UARTn_FRAME); 576 - if (frame & UARTn_FRAME_PARITY_ODD) 575 + switch (frame & UARTn_FRAME_PARITY__MASK) { 576 + case UARTn_FRAME_PARITY_ODD: 577 577 *parity = 'o'; 578 - else if (frame & UARTn_FRAME_PARITY_EVEN) 578 + break; 579 + case UARTn_FRAME_PARITY_EVEN: 579 580 *parity = 'e'; 580 - else 581 + break; 582 + default: 581 583 *parity = 'n'; 584 + } 582 585 583 586 *bits = (frame & UARTn_FRAME_DATABITS__MASK) - 584 587 UARTn_FRAME_DATABITS(4) + 4;
+1 -1
drivers/tty/serial/ifx6x60.c
··· 1382 1382 static void __exit ifx_spi_exit(void) 1383 1383 { 1384 1384 /* unregister */ 1385 + spi_unregister_driver(&ifx_spi_driver); 1385 1386 tty_unregister_driver(tty_drv); 1386 1387 put_tty_driver(tty_drv); 1387 - spi_unregister_driver(&ifx_spi_driver); 1388 1388 unregister_reboot_notifier(&ifx_modem_reboot_notifier_block); 1389 1389 } 1390 1390
+12 -2
drivers/tty/serial/imx.c
··· 2184 2184 * and DCD (when they are outputs) or enables the respective 2185 2185 * irqs. So set this bit early, i.e. before requesting irqs. 2186 2186 */ 2187 - writel(UFCR_DCEDTE, sport->port.membase + UFCR); 2187 + reg = readl(sport->port.membase + UFCR); 2188 + if (!(reg & UFCR_DCEDTE)) 2189 + writel(reg | UFCR_DCEDTE, sport->port.membase + UFCR); 2188 2190 2189 2191 /* 2190 2192 * Disable UCR3_RI and UCR3_DCD irqs. They are also not ··· 2197 2195 sport->port.membase + UCR3); 2198 2196 2199 2197 } else { 2200 - writel(0, sport->port.membase + UFCR); 2198 + unsigned long ucr3 = UCR3_DSR; 2199 + 2200 + reg = readl(sport->port.membase + UFCR); 2201 + if (reg & UFCR_DCEDTE) 2202 + writel(reg & ~UFCR_DCEDTE, sport->port.membase + UFCR); 2203 + 2204 + if (!is_imx1_uart(sport)) 2205 + ucr3 |= IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP; 2206 + writel(ucr3, sport->port.membase + UCR3); 2201 2207 } 2202 2208 2203 2209 clk_disable_unprepare(sport->clk_ipg);
+3 -3
drivers/tty/serial/serial_core.c
··· 2083 2083 mutex_lock(&port->mutex); 2084 2084 2085 2085 tty_dev = device_find_child(uport->dev, &match, serial_match_port); 2086 - if (device_may_wakeup(tty_dev)) { 2086 + if (tty_dev && device_may_wakeup(tty_dev)) { 2087 2087 if (!enable_irq_wake(uport->irq)) 2088 2088 uport->irq_wake = 1; 2089 2089 put_device(tty_dev); ··· 2782 2782 * Register the port whether it's detected or not. This allows 2783 2783 * setserial to be used to alter this port's parameters. 2784 2784 */ 2785 - tty_dev = tty_port_register_device_attr(port, drv->tty_driver, 2785 + tty_dev = tty_port_register_device_attr_serdev(port, drv->tty_driver, 2786 2786 uport->line, uport->dev, port, uport->tty_groups); 2787 2787 if (likely(!IS_ERR(tty_dev))) { 2788 2788 device_set_wakeup_capable(tty_dev, 1); ··· 2845 2845 /* 2846 2846 * Remove the devices from the tty layer 2847 2847 */ 2848 - tty_unregister_device(drv->tty_driver, uport->line); 2848 + tty_port_unregister_device(port, drv->tty_driver, uport->line); 2849 2849 2850 2850 tty = tty_port_tty_get(port); 2851 2851 if (tty) {
+70 -5
drivers/tty/tty_port.c
··· 34 34 if (!disc) 35 35 return 0; 36 36 37 + mutex_lock(&tty->atomic_write_lock); 37 38 ret = tty_ldisc_receive_buf(disc, p, (char *)f, count); 39 + mutex_unlock(&tty->atomic_write_lock); 38 40 39 41 tty_ldisc_deref(disc); 40 42 ··· 131 129 struct device *device, void *drvdata, 132 130 const struct attribute_group **attr_grp) 133 131 { 132 + tty_port_link_device(port, driver, index); 133 + return tty_register_device_attr(driver, index, device, drvdata, 134 + attr_grp); 135 + } 136 + EXPORT_SYMBOL_GPL(tty_port_register_device_attr); 137 + 138 + /** 139 + * tty_port_register_device_attr_serdev - register tty or serdev device 140 + * @port: tty_port of the device 141 + * @driver: tty_driver for this device 142 + * @index: index of the tty 143 + * @device: parent if exists, otherwise NULL 144 + * @drvdata: driver data for the device 145 + * @attr_grp: attribute group for the device 146 + * 147 + * Register a serdev or tty device depending on if the parent device has any 148 + * defined serdev clients or not. 149 + */ 150 + struct device *tty_port_register_device_attr_serdev(struct tty_port *port, 151 + struct tty_driver *driver, unsigned index, 152 + struct device *device, void *drvdata, 153 + const struct attribute_group **attr_grp) 154 + { 134 155 struct device *dev; 135 156 136 157 tty_port_link_device(port, driver, index); 137 158 138 159 dev = serdev_tty_port_register(port, device, driver, index); 139 - if (PTR_ERR(dev) != -ENODEV) 160 + if (PTR_ERR(dev) != -ENODEV) { 140 161 /* Skip creating cdev if we registered a serdev device */ 141 162 return dev; 163 + } 142 164 143 165 return tty_register_device_attr(driver, index, device, drvdata, 144 166 attr_grp); 145 167 } 146 - EXPORT_SYMBOL_GPL(tty_port_register_device_attr); 168 + EXPORT_SYMBOL_GPL(tty_port_register_device_attr_serdev); 169 + 170 + /** 171 + * tty_port_register_device_serdev - register tty or serdev device 172 + * @port: tty_port of the device 173 + * @driver: tty_driver for this device 174 + * @index: index of the tty 175 + * @device: parent if exists, otherwise NULL 176 + * 177 + * Register a serdev or tty device depending on if the parent device has any 178 + * defined serdev clients or not. 179 + */ 180 + struct device *tty_port_register_device_serdev(struct tty_port *port, 181 + struct tty_driver *driver, unsigned index, 182 + struct device *device) 183 + { 184 + return tty_port_register_device_attr_serdev(port, driver, index, 185 + device, NULL, NULL); 186 + } 187 + EXPORT_SYMBOL_GPL(tty_port_register_device_serdev); 188 + 189 + /** 190 + * tty_port_unregister_device - deregister a tty or serdev device 191 + * @port: tty_port of the device 192 + * @driver: tty_driver for this device 193 + * @index: index of the tty 194 + * 195 + * If a tty or serdev device is registered with a call to 196 + * tty_port_register_device_serdev() then this function must be called when 197 + * the device is gone. 198 + */ 199 + void tty_port_unregister_device(struct tty_port *port, 200 + struct tty_driver *driver, unsigned index) 201 + { 202 + int ret; 203 + 204 + ret = serdev_tty_port_unregister(port); 205 + if (ret == 0) 206 + return; 207 + 208 + tty_unregister_device(driver, index); 209 + } 210 + EXPORT_SYMBOL_GPL(tty_port_unregister_device); 147 211 148 212 int tty_port_alloc_xmit_buf(struct tty_port *port) 149 213 { ··· 257 189 /* check if last port ref was dropped before tty release */ 258 190 if (WARN_ON(port->itty)) 259 191 return; 260 - 261 - serdev_tty_port_unregister(port); 262 - 263 192 if (port->xmit_buf) 264 193 free_page((unsigned long)port->xmit_buf); 265 194 tty_port_destroy(port);
+11 -8
include/linux/serdev.h
··· 195 195 void serdev_device_close(struct serdev_device *); 196 196 unsigned int serdev_device_set_baudrate(struct serdev_device *, unsigned int); 197 197 void serdev_device_set_flow_control(struct serdev_device *, bool); 198 + int serdev_device_write_buf(struct serdev_device *, const unsigned char *, size_t); 198 199 void serdev_device_wait_until_sent(struct serdev_device *, long); 199 200 int serdev_device_get_tiocm(struct serdev_device *); 200 201 int serdev_device_set_tiocm(struct serdev_device *, int, int); ··· 237 236 return 0; 238 237 } 239 238 static inline void serdev_device_set_flow_control(struct serdev_device *sdev, bool enable) {} 239 + static inline int serdev_device_write_buf(struct serdev_device *serdev, 240 + const unsigned char *buf, 241 + size_t count) 242 + { 243 + return -ENODEV; 244 + } 240 245 static inline void serdev_device_wait_until_sent(struct serdev_device *sdev, long timeout) {} 241 246 static inline int serdev_device_get_tiocm(struct serdev_device *serdev) 242 247 { ··· 308 301 struct device *serdev_tty_port_register(struct tty_port *port, 309 302 struct device *parent, 310 303 struct tty_driver *drv, int idx); 311 - void serdev_tty_port_unregister(struct tty_port *port); 304 + int serdev_tty_port_unregister(struct tty_port *port); 312 305 #else 313 306 static inline struct device *serdev_tty_port_register(struct tty_port *port, 314 307 struct device *parent, ··· 316 309 { 317 310 return ERR_PTR(-ENODEV); 318 311 } 319 - static inline void serdev_tty_port_unregister(struct tty_port *port) {} 320 - #endif /* CONFIG_SERIAL_DEV_CTRL_TTYPORT */ 321 - 322 - static inline int serdev_device_write_buf(struct serdev_device *serdev, 323 - const unsigned char *data, 324 - size_t count) 312 + static inline int serdev_tty_port_unregister(struct tty_port *port) 325 313 { 326 - return serdev_device_write(serdev, data, count, 0); 314 + return -ENODEV; 327 315 } 316 + #endif /* CONFIG_SERIAL_DEV_CTRL_TTYPORT */ 328 317 329 318 #endif /*_LINUX_SERDEV_H */
+9
include/linux/tty.h
··· 558 558 struct tty_driver *driver, unsigned index, 559 559 struct device *device, void *drvdata, 560 560 const struct attribute_group **attr_grp); 561 + extern struct device *tty_port_register_device_serdev(struct tty_port *port, 562 + struct tty_driver *driver, unsigned index, 563 + struct device *device); 564 + extern struct device *tty_port_register_device_attr_serdev(struct tty_port *port, 565 + struct tty_driver *driver, unsigned index, 566 + struct device *device, void *drvdata, 567 + const struct attribute_group **attr_grp); 568 + extern void tty_port_unregister_device(struct tty_port *port, 569 + struct tty_driver *driver, unsigned index); 561 570 extern int tty_port_alloc_xmit_buf(struct tty_port *port); 562 571 extern void tty_port_free_xmit_buf(struct tty_port *port); 563 572 extern void tty_port_destroy(struct tty_port *port);