TTY/serial fixes for 4.10-rc4

Here are some small tty/serial driver fixes for 4.10-rc4 to resolve a
 number of reported issues.
 
 Nothing major here at all, one revert of a problematic patch, and some
 other tiny bugfixes.  Full details are in the shortlog below.
 
 All have been in linux-next with no reported issues.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCWHtshA8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+ym6PQCeJtdwrkIQmisQZYcMpAZrnQnpF9YAnjrcqWZ4
 2glC2IsH8mDm5DR81axE
 =GIdT
 -----END PGP SIGNATURE-----

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

Pull tty/serial fixes from Greg KH:
 "Here are some small tty/serial driver fixes for 4.10-rc4 to resolve a
  number of reported issues.

  Nothing major here at all, one revert of a problematic patch, and some
  other tiny bugfixes. Full details are in the shortlog below.

  All have been in linux-next with no reported issues"

* tag 'tty-4.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
  sysrq: attach sysrq handler correctly for 32-bit kernel
  Revert "tty: serial: 8250: add CON_CONSDEV to flags"
  Clearing FIFOs in RS485 emulation mode causes subsequent transmits to break
  8250_pci: Fix potential use-after-free in error path
  tty/serial: atmel: RS485 half duplex w/DMA: enable RX after TX is done
  tty/serial: atmel_serial: BUG: stop DMA from transmitting in stop_tx
This commit is contained in:
Linus Torvalds 2017-01-15 12:36:32 -08:00
commit 7f138b9706
5 changed files with 25 additions and 17 deletions

View File

@ -675,7 +675,7 @@ static struct console univ8250_console = {
.device = uart_console_device, .device = uart_console_device,
.setup = univ8250_console_setup, .setup = univ8250_console_setup,
.match = univ8250_console_match, .match = univ8250_console_match,
.flags = CON_PRINTBUFFER | CON_ANYTIME | CON_CONSDEV, .flags = CON_PRINTBUFFER | CON_ANYTIME,
.index = -1, .index = -1,
.data = &serial8250_reg, .data = &serial8250_reg,
}; };

View File

@ -5642,17 +5642,15 @@ static pci_ers_result_t serial8250_io_slot_reset(struct pci_dev *dev)
static void serial8250_io_resume(struct pci_dev *dev) static void serial8250_io_resume(struct pci_dev *dev)
{ {
struct serial_private *priv = pci_get_drvdata(dev); struct serial_private *priv = pci_get_drvdata(dev);
const struct pciserial_board *board; struct serial_private *new;
if (!priv) if (!priv)
return; return;
board = priv->board; new = pciserial_init_ports(dev, priv->board);
kfree(priv); if (!IS_ERR(new)) {
priv = pciserial_init_ports(dev, board); pci_set_drvdata(dev, new);
kfree(priv);
if (!IS_ERR(priv)) {
pci_set_drvdata(dev, priv);
} }
} }

View File

@ -1413,7 +1413,7 @@ static void __do_stop_tx_rs485(struct uart_8250_port *p)
* Enable previously disabled RX interrupts. * Enable previously disabled RX interrupts.
*/ */
if (!(p->port.rs485.flags & SER_RS485_RX_DURING_TX)) { if (!(p->port.rs485.flags & SER_RS485_RX_DURING_TX)) {
serial8250_clear_fifos(p); serial8250_clear_and_reinit_fifos(p);
p->ier |= UART_IER_RLSI | UART_IER_RDI; p->ier |= UART_IER_RLSI | UART_IER_RDI;
serial_port_out(&p->port, UART_IER, p->ier); serial_port_out(&p->port, UART_IER, p->ier);

View File

@ -481,6 +481,14 @@ static void atmel_stop_tx(struct uart_port *port)
/* disable PDC transmit */ /* disable PDC transmit */
atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS); atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS);
} }
/*
* Disable the transmitter.
* This is mandatory when DMA is used, otherwise the DMA buffer
* is fully transmitted.
*/
atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXDIS);
/* Disable interrupts */ /* Disable interrupts */
atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask); atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask);
@ -513,6 +521,9 @@ static void atmel_start_tx(struct uart_port *port)
/* Enable interrupts */ /* Enable interrupts */
atmel_uart_writel(port, ATMEL_US_IER, atmel_port->tx_done_mask); atmel_uart_writel(port, ATMEL_US_IER, atmel_port->tx_done_mask);
/* re-enable the transmitter */
atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN);
} }
/* /*
@ -798,6 +809,11 @@ static void atmel_complete_tx_dma(void *arg)
*/ */
if (!uart_circ_empty(xmit)) if (!uart_circ_empty(xmit))
atmel_tasklet_schedule(atmel_port, &atmel_port->tasklet_tx); atmel_tasklet_schedule(atmel_port, &atmel_port->tasklet_tx);
else if ((port->rs485.flags & SER_RS485_ENABLED) &&
!(port->rs485.flags & SER_RS485_RX_DURING_TX)) {
/* DMA done, stop TX, start RX for RS485 */
atmel_start_rx(port);
}
spin_unlock_irqrestore(&port->lock, flags); spin_unlock_irqrestore(&port->lock, flags);
} }
@ -900,12 +916,6 @@ static void atmel_tx_dma(struct uart_port *port)
desc->callback = atmel_complete_tx_dma; desc->callback = atmel_complete_tx_dma;
desc->callback_param = atmel_port; desc->callback_param = atmel_port;
atmel_port->cookie_tx = dmaengine_submit(desc); atmel_port->cookie_tx = dmaengine_submit(desc);
} else {
if (port->rs485.flags & SER_RS485_ENABLED) {
/* DMA done, stop TX, start RX for RS485 */
atmel_start_rx(port);
}
} }
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)

View File

@ -946,8 +946,8 @@ static const struct input_device_id sysrq_ids[] = {
{ {
.flags = INPUT_DEVICE_ID_MATCH_EVBIT | .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
INPUT_DEVICE_ID_MATCH_KEYBIT, INPUT_DEVICE_ID_MATCH_KEYBIT,
.evbit = { BIT_MASK(EV_KEY) }, .evbit = { [BIT_WORD(EV_KEY)] = BIT_MASK(EV_KEY) },
.keybit = { BIT_MASK(KEY_LEFTALT) }, .keybit = { [BIT_WORD(KEY_LEFTALT)] = BIT_MASK(KEY_LEFTALT) },
}, },
{ }, { },
}; };