Commit 37cc6bb8 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull tty/serial driver fixes from Greg KH:
 "Here are a number of small tty and serial driver fixes for reported
  issues for 4.9-rc3. Nothing major, but they do resolve a bunch of
  problems with the tty core changes that are in 4.9-rc1, and finally
  the atmel serial driver is back working properly.

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

* tag 'tty-4.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
  tty: serial_core: fix NULL struct tty pointer access in uart_write_wakeup
  tty: serial_core: Fix serial console crash on port shutdown
  tty/serial: at91: fix hardware handshake on Atmel platforms
  vt: clear selection before resizing
  sc16is7xx: always write state when configuring GPIO as an output
  sh-sci: document R8A7743/5 support
  tty: serial: 8250: 8250_core: NXP SC16C2552 workaround
  tty: limit terminal size to 4M chars
  tty: serial: fsl_lpuart: Fix Tx DMA edge case
  serial: 8250_lpss: enable MSI for sure
  serial: core: fix console problems on uart_close
  serial: 8250_uniphier: fix clearing divisor latch access bit
  serial: 8250_uniphier: fix more unterminated string
  serial: pch_uart: add terminate entry for dmi_system_id tables
  devicetree: bindings: uart: Add new compatible string for ZynqMP
  serial: xuartps: Add new compatible string for ZynqMP
  serial: SERIAL_STM32 should depend on HAS_DMA
  serial: stm32: Fix comparisons with undefined register
  tty: vt, fix bogus division in csi_J
parents 9af6f26a d0f4bce2
Binding for Cadence UART Controller Binding for Cadence UART Controller
Required properties: Required properties:
- compatible : should be "cdns,uart-r1p8", or "xlnx,xuartps" - compatible :
Use "xlnx,xuartps","cdns,uart-r1p8" for Zynq-7xxx SoC.
Use "xlnx,zynqmp-uart","cdns,uart-r1p12" for Zynq Ultrascale+ MPSoC.
- reg: Should contain UART controller registers location and length. - reg: Should contain UART controller registers location and length.
- interrupts: Should contain UART controller interrupts. - interrupts: Should contain UART controller interrupts.
- clocks: Must contain phandles to the UART clocks - clocks: Must contain phandles to the UART clocks
......
...@@ -9,6 +9,14 @@ Required properties: ...@@ -9,6 +9,14 @@ Required properties:
- "renesas,scifb-r8a73a4" for R8A73A4 (R-Mobile APE6) SCIFB compatible UART. - "renesas,scifb-r8a73a4" for R8A73A4 (R-Mobile APE6) SCIFB compatible UART.
- "renesas,scifa-r8a7740" for R8A7740 (R-Mobile A1) SCIFA compatible UART. - "renesas,scifa-r8a7740" for R8A7740 (R-Mobile A1) SCIFA compatible UART.
- "renesas,scifb-r8a7740" for R8A7740 (R-Mobile A1) SCIFB compatible UART. - "renesas,scifb-r8a7740" for R8A7740 (R-Mobile A1) SCIFB compatible UART.
- "renesas,scif-r8a7743" for R8A7743 (RZ/G1M) SCIF compatible UART.
- "renesas,scifa-r8a7743" for R8A7743 (RZ/G1M) SCIFA compatible UART.
- "renesas,scifb-r8a7743" for R8A7743 (RZ/G1M) SCIFB compatible UART.
- "renesas,hscif-r8a7743" for R8A7743 (RZ/G1M) HSCIF compatible UART.
- "renesas,scif-r8a7745" for R8A7745 (RZ/G1E) SCIF compatible UART.
- "renesas,scifa-r8a7745" for R8A7745 (RZ/G1E) SCIFA compatible UART.
- "renesas,scifb-r8a7745" for R8A7745 (RZ/G1E) SCIFB compatible UART.
- "renesas,hscif-r8a7745" for R8A7745 (RZ/G1E) HSCIF compatible UART.
- "renesas,scif-r8a7778" for R8A7778 (R-Car M1) SCIF compatible UART. - "renesas,scif-r8a7778" for R8A7778 (R-Car M1) SCIF compatible UART.
- "renesas,scif-r8a7779" for R8A7779 (R-Car H1) SCIF compatible UART. - "renesas,scif-r8a7779" for R8A7779 (R-Car H1) SCIF compatible UART.
- "renesas,scif-r8a7790" for R8A7790 (R-Car H2) SCIF compatible UART. - "renesas,scif-r8a7790" for R8A7790 (R-Car H2) SCIF compatible UART.
......
...@@ -213,7 +213,7 @@ static int qrk_serial_setup(struct lpss8250 *lpss, struct uart_port *port) ...@@ -213,7 +213,7 @@ static int qrk_serial_setup(struct lpss8250 *lpss, struct uart_port *port)
struct pci_dev *pdev = to_pci_dev(port->dev); struct pci_dev *pdev = to_pci_dev(port->dev);
int ret; int ret;
ret = pci_alloc_irq_vectors(pdev, 1, 1, 0); ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
if (ret < 0) if (ret < 0)
return ret; return ret;
......
...@@ -83,7 +83,8 @@ static const struct serial8250_config uart_config[] = { ...@@ -83,7 +83,8 @@ static const struct serial8250_config uart_config[] = {
.name = "16550A", .name = "16550A",
.fifo_size = 16, .fifo_size = 16,
.tx_loadsz = 16, .tx_loadsz = 16,
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 |
UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT,
.rxtrig_bytes = {1, 4, 8, 14}, .rxtrig_bytes = {1, 4, 8, 14},
.flags = UART_CAP_FIFO, .flags = UART_CAP_FIFO,
}, },
......
...@@ -99,7 +99,7 @@ static void uniphier_serial_out(struct uart_port *p, int offset, int value) ...@@ -99,7 +99,7 @@ static void uniphier_serial_out(struct uart_port *p, int offset, int value)
case UART_LCR: case UART_LCR:
valshift = UNIPHIER_UART_LCR_SHIFT; valshift = UNIPHIER_UART_LCR_SHIFT;
/* Divisor latch access bit does not exist. */ /* Divisor latch access bit does not exist. */
value &= ~(UART_LCR_DLAB << valshift); value &= ~UART_LCR_DLAB;
/* fall through */ /* fall through */
case UART_MCR: case UART_MCR:
offset = UNIPHIER_UART_LCR_MCR; offset = UNIPHIER_UART_LCR_MCR;
...@@ -199,7 +199,7 @@ static int uniphier_uart_probe(struct platform_device *pdev) ...@@ -199,7 +199,7 @@ static int uniphier_uart_probe(struct platform_device *pdev)
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!regs) { if (!regs) {
dev_err(dev, "failed to get memory resource"); dev_err(dev, "failed to get memory resource\n");
return -EINVAL; return -EINVAL;
} }
......
...@@ -1625,6 +1625,7 @@ config SERIAL_SPRD_CONSOLE ...@@ -1625,6 +1625,7 @@ config SERIAL_SPRD_CONSOLE
config SERIAL_STM32 config SERIAL_STM32
tristate "STMicroelectronics STM32 serial port support" tristate "STMicroelectronics STM32 serial port support"
select SERIAL_CORE select SERIAL_CORE
depends on HAS_DMA
depends on ARM || COMPILE_TEST depends on ARM || COMPILE_TEST
help help
This driver is for the on-chip Serial Controller on This driver is for the on-chip Serial Controller on
......
...@@ -2132,11 +2132,29 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, ...@@ -2132,11 +2132,29 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
mode |= ATMEL_US_USMODE_RS485; mode |= ATMEL_US_USMODE_RS485;
} else if (termios->c_cflag & CRTSCTS) { } else if (termios->c_cflag & CRTSCTS) {
/* RS232 with hardware handshake (RTS/CTS) */ /* RS232 with hardware handshake (RTS/CTS) */
if (atmel_use_dma_rx(port) && !atmel_use_fifo(port)) { if (atmel_use_fifo(port) &&
dev_info(port->dev, "not enabling hardware flow control because DMA is used"); !mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_CTS)) {
termios->c_cflag &= ~CRTSCTS; /*
} else { * with ATMEL_US_USMODE_HWHS set, the controller will
* be able to drive the RTS pin high/low when the RX
* FIFO is above RXFTHRES/below RXFTHRES2.
* It will also disable the transmitter when the CTS
* pin is high.
* This mode is not activated if CTS pin is a GPIO
* because in this case, the transmitter is always
* disabled (there must be an internal pull-up
* responsible for this behaviour).
* If the RTS pin is a GPIO, the controller won't be
* able to drive it according to the FIFO thresholds,
* but it will be handled by the driver.
*/
mode |= ATMEL_US_USMODE_HWHS; mode |= ATMEL_US_USMODE_HWHS;
} else {
/*
* For platforms without FIFO, the flow control is
* handled by the driver.
*/
mode |= ATMEL_US_USMODE_NORMAL;
} }
} else { } else {
/* RS232 without hadware handshake */ /* RS232 without hadware handshake */
......
...@@ -328,7 +328,7 @@ static void lpuart_dma_tx(struct lpuart_port *sport) ...@@ -328,7 +328,7 @@ static void lpuart_dma_tx(struct lpuart_port *sport)
sport->dma_tx_bytes = uart_circ_chars_pending(xmit); sport->dma_tx_bytes = uart_circ_chars_pending(xmit);
if (xmit->tail < xmit->head) { if (xmit->tail < xmit->head || xmit->head == 0) {
sport->dma_tx_nents = 1; sport->dma_tx_nents = 1;
sg_init_one(sgl, xmit->buf + xmit->tail, sport->dma_tx_bytes); sg_init_one(sgl, xmit->buf + xmit->tail, sport->dma_tx_bytes);
} else { } else {
...@@ -359,7 +359,6 @@ static void lpuart_dma_tx(struct lpuart_port *sport) ...@@ -359,7 +359,6 @@ static void lpuart_dma_tx(struct lpuart_port *sport)
sport->dma_tx_in_progress = true; sport->dma_tx_in_progress = true;
sport->dma_tx_cookie = dmaengine_submit(sport->dma_tx_desc); sport->dma_tx_cookie = dmaengine_submit(sport->dma_tx_desc);
dma_async_issue_pending(sport->dma_tx_chan); dma_async_issue_pending(sport->dma_tx_chan);
} }
static void lpuart_dma_tx_complete(void *arg) static void lpuart_dma_tx_complete(void *arg)
......
...@@ -419,6 +419,7 @@ static struct dmi_system_id pch_uart_dmi_table[] = { ...@@ -419,6 +419,7 @@ static struct dmi_system_id pch_uart_dmi_table[] = {
}, },
(void *)MINNOW_UARTCLK, (void *)MINNOW_UARTCLK,
}, },
{ }
}; };
/* Return UART clock, checking for board specific clocks. */ /* Return UART clock, checking for board specific clocks. */
......
...@@ -1130,9 +1130,13 @@ static int sc16is7xx_gpio_direction_output(struct gpio_chip *chip, ...@@ -1130,9 +1130,13 @@ static int sc16is7xx_gpio_direction_output(struct gpio_chip *chip,
{ {
struct sc16is7xx_port *s = gpiochip_get_data(chip); struct sc16is7xx_port *s = gpiochip_get_data(chip);
struct uart_port *port = &s->p[0].port; struct uart_port *port = &s->p[0].port;
u8 state = sc16is7xx_port_read(port, SC16IS7XX_IOSTATE_REG);
sc16is7xx_port_update(port, SC16IS7XX_IOSTATE_REG, BIT(offset), if (val)
val ? BIT(offset) : 0); state |= BIT(offset);
else
state &= ~BIT(offset);
sc16is7xx_port_write(port, SC16IS7XX_IOSTATE_REG, state);
sc16is7xx_port_update(port, SC16IS7XX_IODIR_REG, BIT(offset), sc16is7xx_port_update(port, SC16IS7XX_IODIR_REG, BIT(offset),
BIT(offset)); BIT(offset));
......
...@@ -111,7 +111,7 @@ void uart_write_wakeup(struct uart_port *port) ...@@ -111,7 +111,7 @@ void uart_write_wakeup(struct uart_port *port)
* closed. No cookie for you. * closed. No cookie for you.
*/ */
BUG_ON(!state); BUG_ON(!state);
tty_wakeup(state->port.tty); tty_port_tty_wakeup(&state->port);
} }
static void uart_stop(struct tty_struct *tty) static void uart_stop(struct tty_struct *tty)
...@@ -632,7 +632,7 @@ static void uart_flush_buffer(struct tty_struct *tty) ...@@ -632,7 +632,7 @@ static void uart_flush_buffer(struct tty_struct *tty)
if (port->ops->flush_buffer) if (port->ops->flush_buffer)
port->ops->flush_buffer(port); port->ops->flush_buffer(port);
uart_port_unlock(port, flags); uart_port_unlock(port, flags);
tty_wakeup(tty); tty_port_tty_wakeup(&state->port);
} }
/* /*
...@@ -2746,8 +2746,6 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) ...@@ -2746,8 +2746,6 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
uport->cons = drv->cons; uport->cons = drv->cons;
uport->minor = drv->tty_driver->minor_start + uport->line; uport->minor = drv->tty_driver->minor_start + uport->line;
port->console = uart_console(uport);
/* /*
* If this port is a console, then the spinlock is already * If this port is a console, then the spinlock is already
* initialised. * initialised.
...@@ -2761,6 +2759,8 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) ...@@ -2761,6 +2759,8 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
uart_configure_port(drv, state, uport); uart_configure_port(drv, state, uport);
port->console = uart_console(uport);
num_groups = 2; num_groups = 2;
if (uport->attr_group) if (uport->attr_group)
num_groups++; num_groups++;
......
...@@ -31,7 +31,7 @@ struct stm32_usart_info { ...@@ -31,7 +31,7 @@ struct stm32_usart_info {
struct stm32_usart_config cfg; struct stm32_usart_config cfg;
}; };
#define UNDEF_REG ~0 #define UNDEF_REG 0xff
/* Register offsets */ /* Register offsets */
struct stm32_usart_info stm32f4_info = { struct stm32_usart_info stm32f4_info = {
......
...@@ -1200,6 +1200,7 @@ static int __init cdns_early_console_setup(struct earlycon_device *device, ...@@ -1200,6 +1200,7 @@ static int __init cdns_early_console_setup(struct earlycon_device *device,
OF_EARLYCON_DECLARE(cdns, "xlnx,xuartps", cdns_early_console_setup); OF_EARLYCON_DECLARE(cdns, "xlnx,xuartps", cdns_early_console_setup);
OF_EARLYCON_DECLARE(cdns, "cdns,uart-r1p8", cdns_early_console_setup); OF_EARLYCON_DECLARE(cdns, "cdns,uart-r1p8", cdns_early_console_setup);
OF_EARLYCON_DECLARE(cdns, "cdns,uart-r1p12", cdns_early_console_setup); OF_EARLYCON_DECLARE(cdns, "cdns,uart-r1p12", cdns_early_console_setup);
OF_EARLYCON_DECLARE(cdns, "xlnx,zynqmp-uart", cdns_early_console_setup);
/** /**
* cdns_uart_console_write - perform write operation * cdns_uart_console_write - perform write operation
...@@ -1438,6 +1439,7 @@ static const struct of_device_id cdns_uart_of_match[] = { ...@@ -1438,6 +1439,7 @@ static const struct of_device_id cdns_uart_of_match[] = {
{ .compatible = "xlnx,xuartps", }, { .compatible = "xlnx,xuartps", },
{ .compatible = "cdns,uart-r1p8", }, { .compatible = "cdns,uart-r1p8", },
{ .compatible = "cdns,uart-r1p12", .data = &zynqmp_uart_def }, { .compatible = "cdns,uart-r1p12", .data = &zynqmp_uart_def },
{ .compatible = "xlnx,zynqmp-uart", .data = &zynqmp_uart_def },
{} {}
}; };
MODULE_DEVICE_TABLE(of, cdns_uart_of_match); MODULE_DEVICE_TABLE(of, cdns_uart_of_match);
......
...@@ -870,10 +870,15 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, ...@@ -870,10 +870,15 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
if (new_cols == vc->vc_cols && new_rows == vc->vc_rows) if (new_cols == vc->vc_cols && new_rows == vc->vc_rows)
return 0; return 0;
if (new_screen_size > (4 << 20))
return -EINVAL;
newscreen = kmalloc(new_screen_size, GFP_USER); newscreen = kmalloc(new_screen_size, GFP_USER);
if (!newscreen) if (!newscreen)
return -ENOMEM; return -ENOMEM;
if (vc == sel_cons)
clear_selection();
old_rows = vc->vc_rows; old_rows = vc->vc_rows;
old_row_size = vc->vc_size_row; old_row_size = vc->vc_size_row;
...@@ -1176,7 +1181,7 @@ static void csi_J(struct vc_data *vc, int vpar) ...@@ -1176,7 +1181,7 @@ static void csi_J(struct vc_data *vc, int vpar)
break; break;
case 3: /* erase scroll-back buffer (and whole display) */ case 3: /* erase scroll-back buffer (and whole display) */
scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char, scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char,
vc->vc_screenbuf_size >> 1); vc->vc_screenbuf_size);
set_origin(vc); set_origin(vc);
if (con_is_visible(vc)) if (con_is_visible(vc))
update_screen(vc); update_screen(vc);
......
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