diff options
Diffstat (limited to 'drivers/tty')
| -rw-r--r-- | drivers/tty/serdev/serdev-ttyport.c | 26 | ||||
| -rw-r--r-- | drivers/tty/serial/8250/8250_early.c | 14 | ||||
| -rw-r--r-- | drivers/tty/serial/8250/8250_pci.c | 3 | 
3 files changed, 34 insertions, 9 deletions
| diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serdev-ttyport.c index ce7ad0acee7a..247788a16f0b 100644 --- a/drivers/tty/serdev/serdev-ttyport.c +++ b/drivers/tty/serdev/serdev-ttyport.c @@ -27,23 +27,41 @@ static int ttyport_receive_buf(struct tty_port *port, const unsigned char *cp,  {  	struct serdev_controller *ctrl = port->client_data;  	struct serport *serport = serdev_controller_get_drvdata(ctrl); +	int ret;  	if (!test_bit(SERPORT_ACTIVE, &serport->flags))  		return 0; -	return serdev_controller_receive_buf(ctrl, cp, count); +	ret = serdev_controller_receive_buf(ctrl, cp, count); + +	dev_WARN_ONCE(&ctrl->dev, ret < 0 || ret > count, +				"receive_buf returns %d (count = %zu)\n", +				ret, count); +	if (ret < 0) +		return 0; +	else if (ret > count) +		return count; + +	return ret;  }  static void ttyport_write_wakeup(struct tty_port *port)  {  	struct serdev_controller *ctrl = port->client_data;  	struct serport *serport = serdev_controller_get_drvdata(ctrl); +	struct tty_struct *tty; + +	tty = tty_port_tty_get(port); +	if (!tty) +		return; -	if (test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &port->tty->flags) && +	if (test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&  	    test_bit(SERPORT_ACTIVE, &serport->flags))  		serdev_controller_write_wakeup(ctrl); -	wake_up_interruptible_poll(&port->tty->write_wait, POLLOUT); +	wake_up_interruptible_poll(&tty->write_wait, POLLOUT); + +	tty_kref_put(tty);  }  static const struct tty_port_client_operations client_ops = { @@ -136,8 +154,10 @@ static void ttyport_close(struct serdev_controller *ctrl)  	clear_bit(SERPORT_ACTIVE, &serport->flags); +	tty_lock(tty);  	if (tty->ops->close)  		tty->ops->close(tty, NULL); +	tty_unlock(tty);  	tty_release_struct(tty, serport->tty_idx);  } diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c index 362c25ff188a..ae6a256524d8 100644 --- a/drivers/tty/serial/8250/8250_early.c +++ b/drivers/tty/serial/8250/8250_early.c @@ -122,12 +122,14 @@ static void __init init_port(struct earlycon_device *device)  	serial8250_early_out(port, UART_FCR, 0);	/* no fifo */  	serial8250_early_out(port, UART_MCR, 0x3);	/* DTR + RTS */ -	divisor = DIV_ROUND_CLOSEST(port->uartclk, 16 * device->baud); -	c = serial8250_early_in(port, UART_LCR); -	serial8250_early_out(port, UART_LCR, c | UART_LCR_DLAB); -	serial8250_early_out(port, UART_DLL, divisor & 0xff); -	serial8250_early_out(port, UART_DLM, (divisor >> 8) & 0xff); -	serial8250_early_out(port, UART_LCR, c & ~UART_LCR_DLAB); +	if (port->uartclk && device->baud) { +		divisor = DIV_ROUND_CLOSEST(port->uartclk, 16 * device->baud); +		c = serial8250_early_in(port, UART_LCR); +		serial8250_early_out(port, UART_LCR, c | UART_LCR_DLAB); +		serial8250_early_out(port, UART_DLL, divisor & 0xff); +		serial8250_early_out(port, UART_DLM, (divisor >> 8) & 0xff); +		serial8250_early_out(port, UART_LCR, c & ~UART_LCR_DLAB); +	}  }  int __init early_serial8250_setup(struct earlycon_device *device, diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index b7e0e3416641..54adf8d56350 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -5135,6 +5135,9 @@ static const struct pci_device_id serial_pci_tbl[] = {  	{ PCI_DEVICE(0x1601, 0x0800), .driver_data = pbn_b0_4_1250000 },  	{ PCI_DEVICE(0x1601, 0xa801), .driver_data = pbn_b0_4_1250000 }, +	/* Amazon PCI serial device */ +	{ PCI_DEVICE(0x1d0f, 0x8250), .driver_data = pbn_b0_1_115200 }, +  	/*  	 * These entries match devices with class COMMUNICATION_SERIAL,  	 * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL |