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:
commit
84dda2965d
|
@ -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
|
||||
|
|
|
@ -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 */
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue