Commit 6560ca4a authored by Linus Torvalds's avatar Linus Torvalds

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

Pull tty/serial driver fixes from Greg KH:
 "Here are some small tty core and serial driver fixes for 4.16-rc6.

  They resolve some newly reported bugs, as well as some very old ones,
  which is always nice to see. There is also a new device id added in
  here for good measure.

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

* tag 'tty-4.16-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
  serial: imx: fix bogus dev_err
  serial: sh-sci: prevent lockup on full TTY buffers
  serial: 8250_pci: Add Brainboxes UC-260 4 port serial device
  earlycon: add reg-offset to physical address before mapping
  serial: core: mark port as initialized in autoconfig
  serial: 8250_pci: Don't fail on multiport card class
  tty/serial: atmel: add new version check for usart
  tty: make n_tty_read() always abort if hangup is in progress
parents 5e15d39f 5d7f77ec
...@@ -2180,6 +2180,12 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, ...@@ -2180,6 +2180,12 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
} }
if (tty_hung_up_p(file)) if (tty_hung_up_p(file))
break; break;
/*
* Abort readers for ttys which never actually
* get hung up. See __tty_hangup().
*/
if (test_bit(TTY_HUPPING, &tty->flags))
break;
if (!timeout) if (!timeout)
break; break;
if (file->f_flags & O_NONBLOCK) { if (file->f_flags & O_NONBLOCK) {
......
...@@ -3387,11 +3387,9 @@ static int serial_pci_is_class_communication(struct pci_dev *dev) ...@@ -3387,11 +3387,9 @@ static int serial_pci_is_class_communication(struct pci_dev *dev)
/* /*
* If it is not a communications device or the programming * If it is not a communications device or the programming
* interface is greater than 6, give up. * interface is greater than 6, give up.
*
* (Should we try to make guesses for multiport serial devices
* later?)
*/ */
if ((((dev->class >> 8) != PCI_CLASS_COMMUNICATION_SERIAL) && if ((((dev->class >> 8) != PCI_CLASS_COMMUNICATION_SERIAL) &&
((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MULTISERIAL) &&
((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MODEM)) || ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MODEM)) ||
(dev->class & 0xff) > 6) (dev->class & 0xff) > 6)
return -ENODEV; return -ENODEV;
...@@ -3428,6 +3426,12 @@ serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) ...@@ -3428,6 +3426,12 @@ serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board)
{ {
int num_iomem, num_port, first_port = -1, i; int num_iomem, num_port, first_port = -1, i;
/*
* Should we try to make guesses for multiport serial devices later?
*/
if ((dev->class >> 8) == PCI_CLASS_COMMUNICATION_MULTISERIAL)
return -ENODEV;
num_iomem = num_port = 0; num_iomem = num_port = 0;
for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) { for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) {
if (pci_resource_flags(dev, i) & IORESOURCE_IO) { if (pci_resource_flags(dev, i) & IORESOURCE_IO) {
...@@ -4698,6 +4702,17 @@ static const struct pci_device_id serial_pci_tbl[] = { ...@@ -4698,6 +4702,17 @@ static const struct pci_device_id serial_pci_tbl[] = {
{ PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS400, { PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS400,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0dc0 */ PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0dc0 */
pbn_b2_4_115200 }, pbn_b2_4_115200 },
/*
* BrainBoxes UC-260
*/
{ PCI_VENDOR_ID_INTASHIELD, 0x0D21,
PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00,
pbn_b2_4_115200 },
{ PCI_VENDOR_ID_INTASHIELD, 0x0E34,
PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00,
pbn_b2_4_115200 },
/* /*
* Perle PCI-RAS cards * Perle PCI-RAS cards
*/ */
......
...@@ -1734,6 +1734,7 @@ static void atmel_get_ip_name(struct uart_port *port) ...@@ -1734,6 +1734,7 @@ static void atmel_get_ip_name(struct uart_port *port)
switch (version) { switch (version) {
case 0x302: case 0x302:
case 0x10213: case 0x10213:
case 0x10302:
dev_dbg(port->dev, "This version is usart\n"); dev_dbg(port->dev, "This version is usart\n");
atmel_port->has_frac_baudrate = true; atmel_port->has_frac_baudrate = true;
atmel_port->has_hw_timer = true; atmel_port->has_hw_timer = true;
......
...@@ -245,11 +245,12 @@ int __init of_setup_earlycon(const struct earlycon_id *match, ...@@ -245,11 +245,12 @@ int __init of_setup_earlycon(const struct earlycon_id *match,
} }
port->mapbase = addr; port->mapbase = addr;
port->uartclk = BASE_BAUD * 16; port->uartclk = BASE_BAUD * 16;
port->membase = earlycon_map(port->mapbase, SZ_4K);
val = of_get_flat_dt_prop(node, "reg-offset", NULL); val = of_get_flat_dt_prop(node, "reg-offset", NULL);
if (val) if (val)
port->mapbase += be32_to_cpu(*val); port->mapbase += be32_to_cpu(*val);
port->membase = earlycon_map(port->mapbase, SZ_4K);
val = of_get_flat_dt_prop(node, "reg-shift", NULL); val = of_get_flat_dt_prop(node, "reg-shift", NULL);
if (val) if (val)
port->regshift = be32_to_cpu(*val); port->regshift = be32_to_cpu(*val);
......
...@@ -2093,7 +2093,7 @@ static int serial_imx_probe(struct platform_device *pdev) ...@@ -2093,7 +2093,7 @@ static int serial_imx_probe(struct platform_device *pdev)
uart_get_rs485_mode(&pdev->dev, &sport->port.rs485); uart_get_rs485_mode(&pdev->dev, &sport->port.rs485);
if (sport->port.rs485.flags & SER_RS485_ENABLED && if (sport->port.rs485.flags & SER_RS485_ENABLED &&
(!sport->have_rtscts || !sport->have_rtsgpio)) (!sport->have_rtscts && !sport->have_rtsgpio))
dev_err(&pdev->dev, "no RTS control, disabling rs485\n"); dev_err(&pdev->dev, "no RTS control, disabling rs485\n");
imx_rs485_config(&sport->port, &sport->port.rs485); imx_rs485_config(&sport->port, &sport->port.rs485);
......
...@@ -1144,6 +1144,8 @@ static int uart_do_autoconfig(struct tty_struct *tty,struct uart_state *state) ...@@ -1144,6 +1144,8 @@ static int uart_do_autoconfig(struct tty_struct *tty,struct uart_state *state)
uport->ops->config_port(uport, flags); uport->ops->config_port(uport, flags);
ret = uart_startup(tty, state, 1); ret = uart_startup(tty, state, 1);
if (ret == 0)
tty_port_set_initialized(port, true);
if (ret > 0) if (ret > 0)
ret = 0; ret = 0;
} }
......
...@@ -885,6 +885,8 @@ static void sci_receive_chars(struct uart_port *port) ...@@ -885,6 +885,8 @@ static void sci_receive_chars(struct uart_port *port)
/* Tell the rest of the system the news. New characters! */ /* Tell the rest of the system the news. New characters! */
tty_flip_buffer_push(tport); tty_flip_buffer_push(tport);
} else { } else {
/* TTY buffers full; read from RX reg to prevent lockup */
serial_port_in(port, SCxRDR);
serial_port_in(port, SCxSR); /* dummy read */ serial_port_in(port, SCxSR); /* dummy read */
sci_clear_SCxSR(port, SCxSR_RDxF_CLEAR(port)); sci_clear_SCxSR(port, SCxSR_RDxF_CLEAR(port));
} }
......
...@@ -586,6 +586,14 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session) ...@@ -586,6 +586,14 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session)
return; return;
} }
/*
* Some console devices aren't actually hung up for technical and
* historical reasons, which can lead to indefinite interruptible
* sleep in n_tty_read(). The following explicitly tells
* n_tty_read() to abort readers.
*/
set_bit(TTY_HUPPING, &tty->flags);
/* inuse_filps is protected by the single tty lock, /* inuse_filps is protected by the single tty lock,
this really needs to change if we want to flush the this really needs to change if we want to flush the
workqueue with the lock held */ workqueue with the lock held */
...@@ -640,6 +648,7 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session) ...@@ -640,6 +648,7 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session)
* from the ldisc side, which is now guaranteed. * from the ldisc side, which is now guaranteed.
*/ */
set_bit(TTY_HUPPED, &tty->flags); set_bit(TTY_HUPPED, &tty->flags);
clear_bit(TTY_HUPPING, &tty->flags);
tty_unlock(tty); tty_unlock(tty);
if (f) if (f)
......
...@@ -364,6 +364,7 @@ struct tty_file_private { ...@@ -364,6 +364,7 @@ struct tty_file_private {
#define TTY_PTY_LOCK 16 /* pty private */ #define TTY_PTY_LOCK 16 /* pty private */
#define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */ #define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */
#define TTY_HUPPED 18 /* Post driver->hangup() */ #define TTY_HUPPED 18 /* Post driver->hangup() */
#define TTY_HUPPING 19 /* Hangup in progress */
#define TTY_LDISC_HALTED 22 /* Line discipline is halted */ #define TTY_LDISC_HALTED 22 /* Line discipline is halted */
/* Values for tty->flow_change */ /* Values for tty->flow_change */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment