Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 249f1efd authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 6f68a6ae 59fe2cc8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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/
+8 −9
Original line number Diff line number Diff line
@@ -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";
@@ -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) {
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;
+12 −0
Original line number Diff line number Diff line
@@ -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)
+14 −7
Original line number Diff line number Diff line
@@ -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
@@ -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;
@@ -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;
}
+11 −10
Original line number Diff line number Diff line
@@ -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 */

@@ -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) {
@@ -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;
}
@@ -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;
@@ -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;

Loading