Skip to content

Commit 6560ca4

Browse files
committed
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
2 parents 5e15d39 + 5d7f77e commit 6560ca4

File tree

9 files changed

+42
-5
lines changed

9 files changed

+42
-5
lines changed

drivers/tty/n_tty.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2180,6 +2180,12 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
21802180
}
21812181
if (tty_hung_up_p(file))
21822182
break;
2183+
/*
2184+
* Abort readers for ttys which never actually
2185+
* get hung up. See __tty_hangup().
2186+
*/
2187+
if (test_bit(TTY_HUPPING, &tty->flags))
2188+
break;
21832189
if (!timeout)
21842190
break;
21852191
if (file->f_flags & O_NONBLOCK) {

drivers/tty/serial/8250/8250_pci.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3387,11 +3387,9 @@ static int serial_pci_is_class_communication(struct pci_dev *dev)
33873387
/*
33883388
* If it is not a communications device or the programming
33893389
* interface is greater than 6, give up.
3390-
*
3391-
* (Should we try to make guesses for multiport serial devices
3392-
* later?)
33933390
*/
33943391
if ((((dev->class >> 8) != PCI_CLASS_COMMUNICATION_SERIAL) &&
3392+
((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MULTISERIAL) &&
33953393
((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MODEM)) ||
33963394
(dev->class & 0xff) > 6)
33973395
return -ENODEV;
@@ -3428,6 +3426,12 @@ serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board)
34283426
{
34293427
int num_iomem, num_port, first_port = -1, i;
34303428

3429+
/*
3430+
* Should we try to make guesses for multiport serial devices later?
3431+
*/
3432+
if ((dev->class >> 8) == PCI_CLASS_COMMUNICATION_MULTISERIAL)
3433+
return -ENODEV;
3434+
34313435
num_iomem = num_port = 0;
34323436
for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) {
34333437
if (pci_resource_flags(dev, i) & IORESOURCE_IO) {
@@ -4698,6 +4702,17 @@ static const struct pci_device_id serial_pci_tbl[] = {
46984702
{ PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS400,
46994703
PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0dc0 */
47004704
pbn_b2_4_115200 },
4705+
/*
4706+
* BrainBoxes UC-260
4707+
*/
4708+
{ PCI_VENDOR_ID_INTASHIELD, 0x0D21,
4709+
PCI_ANY_ID, PCI_ANY_ID,
4710+
PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00,
4711+
pbn_b2_4_115200 },
4712+
{ PCI_VENDOR_ID_INTASHIELD, 0x0E34,
4713+
PCI_ANY_ID, PCI_ANY_ID,
4714+
PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00,
4715+
pbn_b2_4_115200 },
47014716
/*
47024717
* Perle PCI-RAS cards
47034718
*/

drivers/tty/serial/atmel_serial.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1734,6 +1734,7 @@ static void atmel_get_ip_name(struct uart_port *port)
17341734
switch (version) {
17351735
case 0x302:
17361736
case 0x10213:
1737+
case 0x10302:
17371738
dev_dbg(port->dev, "This version is usart\n");
17381739
atmel_port->has_frac_baudrate = true;
17391740
atmel_port->has_hw_timer = true;

drivers/tty/serial/earlycon.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,11 +245,12 @@ int __init of_setup_earlycon(const struct earlycon_id *match,
245245
}
246246
port->mapbase = addr;
247247
port->uartclk = BASE_BAUD * 16;
248-
port->membase = earlycon_map(port->mapbase, SZ_4K);
249248

250249
val = of_get_flat_dt_prop(node, "reg-offset", NULL);
251250
if (val)
252251
port->mapbase += be32_to_cpu(*val);
252+
port->membase = earlycon_map(port->mapbase, SZ_4K);
253+
253254
val = of_get_flat_dt_prop(node, "reg-shift", NULL);
254255
if (val)
255256
port->regshift = be32_to_cpu(*val);

drivers/tty/serial/imx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2093,7 +2093,7 @@ static int serial_imx_probe(struct platform_device *pdev)
20932093
uart_get_rs485_mode(&pdev->dev, &sport->port.rs485);
20942094

20952095
if (sport->port.rs485.flags & SER_RS485_ENABLED &&
2096-
(!sport->have_rtscts || !sport->have_rtsgpio))
2096+
(!sport->have_rtscts && !sport->have_rtsgpio))
20972097
dev_err(&pdev->dev, "no RTS control, disabling rs485\n");
20982098

20992099
imx_rs485_config(&sport->port, &sport->port.rs485);

drivers/tty/serial/serial_core.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,8 @@ static int uart_do_autoconfig(struct tty_struct *tty,struct uart_state *state)
11441144
uport->ops->config_port(uport, flags);
11451145

11461146
ret = uart_startup(tty, state, 1);
1147+
if (ret == 0)
1148+
tty_port_set_initialized(port, true);
11471149
if (ret > 0)
11481150
ret = 0;
11491151
}

drivers/tty/serial/sh-sci.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,8 @@ static void sci_receive_chars(struct uart_port *port)
885885
/* Tell the rest of the system the news. New characters! */
886886
tty_flip_buffer_push(tport);
887887
} else {
888+
/* TTY buffers full; read from RX reg to prevent lockup */
889+
serial_port_in(port, SCxRDR);
888890
serial_port_in(port, SCxSR); /* dummy read */
889891
sci_clear_SCxSR(port, SCxSR_RDxF_CLEAR(port));
890892
}

drivers/tty/tty_io.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,14 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session)
586586
return;
587587
}
588588

589+
/*
590+
* Some console devices aren't actually hung up for technical and
591+
* historical reasons, which can lead to indefinite interruptible
592+
* sleep in n_tty_read(). The following explicitly tells
593+
* n_tty_read() to abort readers.
594+
*/
595+
set_bit(TTY_HUPPING, &tty->flags);
596+
589597
/* inuse_filps is protected by the single tty lock,
590598
this really needs to change if we want to flush the
591599
workqueue with the lock held */
@@ -640,6 +648,7 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session)
640648
* from the ldisc side, which is now guaranteed.
641649
*/
642650
set_bit(TTY_HUPPED, &tty->flags);
651+
clear_bit(TTY_HUPPING, &tty->flags);
643652
tty_unlock(tty);
644653

645654
if (f)

include/linux/tty.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,7 @@ struct tty_file_private {
364364
#define TTY_PTY_LOCK 16 /* pty private */
365365
#define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */
366366
#define TTY_HUPPED 18 /* Post driver->hangup() */
367+
#define TTY_HUPPING 19 /* Hangup in progress */
367368
#define TTY_LDISC_HALTED 22 /* Line discipline is halted */
368369

369370
/* Values for tty->flow_change */

0 commit comments

Comments
 (0)