Skip to content

Commit

Permalink
Merge tag 'tty-4.12-rc3' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/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
  • Loading branch information
Linus Torvalds committed May 27, 2017
2 parents 6f68a6a + 59fe2cc commit 249f1ef
Show file tree
Hide file tree
Showing 14 changed files with 162 additions and 49 deletions.
2 changes: 1 addition & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -7143,7 +7143,7 @@ S: Maintained
F: drivers/media/platform/rcar_jpu.c

JSM Neo PCI based serial card
M: Gabriel Krisman Bertazi <krisman@linux.vnet.ibm.com>
M: Guilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com>
L: linux-serial@vger.kernel.org
S: Maintained
F: drivers/tty/serial/jsm/
Expand Down
17 changes: 8 additions & 9 deletions drivers/tty/ehv_bytechan.c
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,7 @@ static int __init ehv_bc_init(void)
ehv_bc_driver = alloc_tty_driver(count);
if (!ehv_bc_driver) {
ret = -ENOMEM;
goto error;
goto err_free_bcs;
}

ehv_bc_driver->driver_name = "ehv-bc";
Expand All @@ -778,24 +778,23 @@ static int __init ehv_bc_init(void)
ret = tty_register_driver(ehv_bc_driver);
if (ret) {
pr_err("ehv-bc: could not register tty driver (ret=%i)\n", ret);
goto error;
goto err_put_tty_driver;
}

ret = platform_driver_register(&ehv_bc_tty_driver);
if (ret) {
pr_err("ehv-bc: could not register platform driver (ret=%i)\n",
ret);
goto error;
goto err_deregister_tty_driver;
}

return 0;

error:
if (ehv_bc_driver) {
tty_unregister_driver(ehv_bc_driver);
put_tty_driver(ehv_bc_driver);
}

err_deregister_tty_driver:
tty_unregister_driver(ehv_bc_driver);
err_put_tty_driver:
put_tty_driver(ehv_bc_driver);
err_free_bcs:
kfree(bcs);

return ret;
Expand Down
12 changes: 12 additions & 0 deletions drivers/tty/serdev/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,18 @@ void serdev_device_write_wakeup(struct serdev_device *serdev)
}
EXPORT_SYMBOL_GPL(serdev_device_write_wakeup);

int serdev_device_write_buf(struct serdev_device *serdev,
const unsigned char *buf, size_t count)
{
struct serdev_controller *ctrl = serdev->ctrl;

if (!ctrl || !ctrl->ops->write_buf)
return -EINVAL;

return ctrl->ops->write_buf(ctrl, buf, count);
}
EXPORT_SYMBOL_GPL(serdev_device_write_buf);

int serdev_device_write(struct serdev_device *serdev,
const unsigned char *buf, size_t count,
unsigned long timeout)
Expand Down
21 changes: 14 additions & 7 deletions drivers/tty/serdev/serdev-ttyport.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,6 @@ static int ttyport_open(struct serdev_controller *ctrl)
return PTR_ERR(tty);
serport->tty = tty;

serport->port->client_ops = &client_ops;
serport->port->client_data = ctrl;

if (tty->ops->open)
tty->ops->open(serport->tty, NULL);
else
Expand Down Expand Up @@ -215,6 +212,7 @@ struct device *serdev_tty_port_register(struct tty_port *port,
struct device *parent,
struct tty_driver *drv, int idx)
{
const struct tty_port_client_operations *old_ops;
struct serdev_controller *ctrl;
struct serport *serport;
int ret;
Expand All @@ -233,28 +231,37 @@ struct device *serdev_tty_port_register(struct tty_port *port,

ctrl->ops = &ctrl_ops;

old_ops = port->client_ops;
port->client_ops = &client_ops;
port->client_data = ctrl;

ret = serdev_controller_add(ctrl);
if (ret)
goto err_controller_put;
goto err_reset_data;

dev_info(&ctrl->dev, "tty port %s%d registered\n", drv->name, idx);
return &ctrl->dev;

err_controller_put:
err_reset_data:
port->client_data = NULL;
port->client_ops = old_ops;
serdev_controller_put(ctrl);

return ERR_PTR(ret);
}

void serdev_tty_port_unregister(struct tty_port *port)
int serdev_tty_port_unregister(struct tty_port *port)
{
struct serdev_controller *ctrl = port->client_data;
struct serport *serport = serdev_controller_get_drvdata(ctrl);

if (!serport)
return;
return -ENODEV;

serdev_controller_remove(ctrl);
port->client_ops = NULL;
port->client_data = NULL;
serdev_controller_put(ctrl);

return 0;
}
21 changes: 11 additions & 10 deletions drivers/tty/serial/8250/8250_port.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
/*
* These are definitions for the Exar XR17V35X and XR17(C|D)15X
*/
#define UART_EXAR_INT0 0x80
#define UART_EXAR_SLEEP 0x8b /* Sleep mode */
#define UART_EXAR_DVID 0x8d /* Device identification */

Expand Down Expand Up @@ -1337,7 +1338,7 @@ static void autoconfig(struct uart_8250_port *up)
/*
* Check if the device is a Fintek F81216A
*/
if (port->type == PORT_16550A)
if (port->type == PORT_16550A && port->iotype == UPIO_PORT)
fintek_8250_probe(up);

if (up->capabilities != old_capabilities) {
Expand Down Expand Up @@ -1869,17 +1870,13 @@ static int serial8250_default_handle_irq(struct uart_port *port)
static int exar_handle_irq(struct uart_port *port)
{
unsigned int iir = serial_port_in(port, UART_IIR);
int ret;
int ret = 0;

ret = serial8250_handle_irq(port, iir);
if (((port->type == PORT_XR17V35X) || (port->type == PORT_XR17D15X)) &&
serial_port_in(port, UART_EXAR_INT0) != 0)
ret = 1;

if ((port->type == PORT_XR17V35X) ||
(port->type == PORT_XR17D15X)) {
serial_port_in(port, 0x80);
serial_port_in(port, 0x81);
serial_port_in(port, 0x82);
serial_port_in(port, 0x83);
}
ret |= serial8250_handle_irq(port, iir);

return ret;
}
Expand Down Expand Up @@ -2177,6 +2174,8 @@ int serial8250_do_startup(struct uart_port *port)
serial_port_in(port, UART_RX);
serial_port_in(port, UART_IIR);
serial_port_in(port, UART_MSR);
if ((port->type == PORT_XR17V35X) || (port->type == PORT_XR17D15X))
serial_port_in(port, UART_EXAR_INT0);

/*
* At this point, there's no way the LSR could still be 0xff;
Expand Down Expand Up @@ -2335,6 +2334,8 @@ int serial8250_do_startup(struct uart_port *port)
serial_port_in(port, UART_RX);
serial_port_in(port, UART_IIR);
serial_port_in(port, UART_MSR);
if ((port->type == PORT_XR17V35X) || (port->type == PORT_XR17D15X))
serial_port_in(port, UART_EXAR_INT0);
up->lsr_saved_flags = 0;
up->msr_saved_flags = 0;

Expand Down
1 change: 1 addition & 0 deletions drivers/tty/serial/altera_jtaguart.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,7 @@ static int altera_jtaguart_remove(struct platform_device *pdev)

port = &altera_jtaguart_ports[i].port;
uart_remove_one_port(&altera_jtaguart_driver, port);
iounmap(port->membase);

return 0;
}
Expand Down
1 change: 1 addition & 0 deletions drivers/tty/serial/altera_uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,7 @@ static int altera_uart_remove(struct platform_device *pdev)
if (port) {
uart_remove_one_port(&altera_uart_driver, port);
port->mapbase = 0;
iounmap(port->membase);
}

return 0;
Expand Down
11 changes: 8 additions & 3 deletions drivers/tty/serial/efm32-uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#define UARTn_FRAME 0x04
#define UARTn_FRAME_DATABITS__MASK 0x000f
#define UARTn_FRAME_DATABITS(n) ((n) - 3)
#define UARTn_FRAME_PARITY__MASK 0x0300
#define UARTn_FRAME_PARITY_NONE 0x0000
#define UARTn_FRAME_PARITY_EVEN 0x0200
#define UARTn_FRAME_PARITY_ODD 0x0300
Expand Down Expand Up @@ -572,12 +573,16 @@ static void efm32_uart_console_get_options(struct efm32_uart_port *efm_port,
16 * (4 + (clkdiv >> 6)));

frame = efm32_uart_read32(efm_port, UARTn_FRAME);
if (frame & UARTn_FRAME_PARITY_ODD)
switch (frame & UARTn_FRAME_PARITY__MASK) {
case UARTn_FRAME_PARITY_ODD:
*parity = 'o';
else if (frame & UARTn_FRAME_PARITY_EVEN)
break;
case UARTn_FRAME_PARITY_EVEN:
*parity = 'e';
else
break;
default:
*parity = 'n';
}

*bits = (frame & UARTn_FRAME_DATABITS__MASK) -
UARTn_FRAME_DATABITS(4) + 4;
Expand Down
2 changes: 1 addition & 1 deletion drivers/tty/serial/ifx6x60.c
Original file line number Diff line number Diff line change
Expand Up @@ -1382,9 +1382,9 @@ static struct spi_driver ifx_spi_driver = {
static void __exit ifx_spi_exit(void)
{
/* unregister */
spi_unregister_driver(&ifx_spi_driver);
tty_unregister_driver(tty_drv);
put_tty_driver(tty_drv);
spi_unregister_driver(&ifx_spi_driver);
unregister_reboot_notifier(&ifx_modem_reboot_notifier_block);
}

Expand Down
14 changes: 12 additions & 2 deletions drivers/tty/serial/imx.c
Original file line number Diff line number Diff line change
Expand Up @@ -2184,7 +2184,9 @@ static int serial_imx_probe(struct platform_device *pdev)
* and DCD (when they are outputs) or enables the respective
* irqs. So set this bit early, i.e. before requesting irqs.
*/
writel(UFCR_DCEDTE, sport->port.membase + UFCR);
reg = readl(sport->port.membase + UFCR);
if (!(reg & UFCR_DCEDTE))
writel(reg | UFCR_DCEDTE, sport->port.membase + UFCR);

/*
* Disable UCR3_RI and UCR3_DCD irqs. They are also not
Expand All @@ -2195,7 +2197,15 @@ static int serial_imx_probe(struct platform_device *pdev)
sport->port.membase + UCR3);

} else {
writel(0, sport->port.membase + UFCR);
unsigned long ucr3 = UCR3_DSR;

reg = readl(sport->port.membase + UFCR);
if (reg & UFCR_DCEDTE)
writel(reg & ~UFCR_DCEDTE, sport->port.membase + UFCR);

if (!is_imx1_uart(sport))
ucr3 |= IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP;
writel(ucr3, sport->port.membase + UCR3);
}

clk_disable_unprepare(sport->clk_ipg);
Expand Down
6 changes: 3 additions & 3 deletions drivers/tty/serial/serial_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2083,7 +2083,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
mutex_lock(&port->mutex);

tty_dev = device_find_child(uport->dev, &match, serial_match_port);
if (device_may_wakeup(tty_dev)) {
if (tty_dev && device_may_wakeup(tty_dev)) {
if (!enable_irq_wake(uport->irq))
uport->irq_wake = 1;
put_device(tty_dev);
Expand Down Expand Up @@ -2782,7 +2782,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
* Register the port whether it's detected or not. This allows
* setserial to be used to alter this port's parameters.
*/
tty_dev = tty_port_register_device_attr(port, drv->tty_driver,
tty_dev = tty_port_register_device_attr_serdev(port, drv->tty_driver,
uport->line, uport->dev, port, uport->tty_groups);
if (likely(!IS_ERR(tty_dev))) {
device_set_wakeup_capable(tty_dev, 1);
Expand Down Expand Up @@ -2845,7 +2845,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)
/*
* Remove the devices from the tty layer
*/
tty_unregister_device(drv->tty_driver, uport->line);
tty_port_unregister_device(port, drv->tty_driver, uport->line);

tty = tty_port_tty_get(port);
if (tty) {
Expand Down
Loading

0 comments on commit 249f1ef

Please sign in to comment.