TTY/Serial driver fixes for 4.15-rc3

Here are some small serdev and serial fixes for 4.15-rc3.  They resolve
 some reported problems:
 	- a number of serdev fixes to resolve crashes
 	- MIPS build fixes for their serial port
 	- a new 8250 device id
 
 All of these have been in linux-next for a while with no reported
 issues.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCWia9GQ8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+ynSEgCfZ/zINl1ItdXcMUr1cnznwNgFGhAAoIoIpmre
 +4qtH6PjV/+kq+2j2lmG
 =bxjP
 -----END PGP SIGNATURE-----

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

Pull tty/serial driver fixes from Greg KH:
 "Here are some small serdev and serial fixes for 4.15-rc3. They resolve
  some reported problems:

   - a number of serdev fixes to resolve crashes

   - MIPS build fixes for their serial port

   - a new 8250 device id

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

* tag 'tty-4.15-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
  MIPS: Add custom serial.h with BASE_BAUD override for generic kernel
  serdev: ttyport: fix tty locking in close
  serdev: ttyport: fix NULL-deref on hangup
  serdev: fix receive_buf return value when no callback
  serdev: ttyport: add missing receive_buf sanity checks
  serial: 8250_early: Only set divisor if valid clk & baud
  serial: 8250_pci: Add Amazon PCI serial device ID
This commit is contained in:
Linus Torvalds 2017-12-05 09:05:16 -08:00
commit 84dda2965d
6 changed files with 57 additions and 11 deletions

View File

@ -16,7 +16,6 @@ generic-y += qrwlock.h
generic-y += qspinlock.h
generic-y += sections.h
generic-y += segment.h
generic-y += serial.h
generic-y += trace_clock.h
generic-y += unaligned.h
generic-y += user.h

View File

@ -0,0 +1,22 @@
/*
* Copyright (C) 2017 MIPS Tech, LLC
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#ifndef __ASM__SERIAL_H
#define __ASM__SERIAL_H
#ifdef CONFIG_MIPS_GENERIC
/*
* Generic kernels cannot know a correct value for all platforms at
* compile time. Set it to 0 to prevent 8250_early using it
*/
#define BASE_BAUD 0
#else
#include <asm-generic/serial.h>
#endif
#endif /* __ASM__SERIAL_H */

View File

@ -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;
if (test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &port->tty->flags) &&
tty = tty_port_tty_get(port);
if (!tty)
return;
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);
}

View File

@ -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,

View File

@ -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

View File

@ -184,7 +184,7 @@ static inline int serdev_controller_receive_buf(struct serdev_controller *ctrl,
struct serdev_device *serdev = ctrl->serdev;
if (!serdev || !serdev->ops->receive_buf)
return -EINVAL;
return 0;
return serdev->ops->receive_buf(serdev, data, count);
}