Skip to content

Commit

Permalink
Merge tag 'tty-5.16-rc4' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/gregkh/tty

Pull tty/serial fixes from Greg KH:
 "Here are some small TTY and Serial driver fixes for 5.16-rc4 to
  resolve a number of reported problems.

  They include:

   - liteuart serial driver fixes

   - 8250_pci serial driver fixes for pericom devices

   - 8250 RTS line control fix while in RS-485 mode

   - tegra serial driver fix

   - msm_serial driver fix

   - pl011 serial driver new id

   - fsl_lpuart revert of broken change

   - 8250_bcm7271 serial driver fix

   - MAINTAINERS file update for rpmsg tty driver that came in 5.16-rc1

   - vgacon fix for reported problem

  All of these, except for the 8250_bcm7271 fix have been in linux-next
  with no reported problem. The 8250_bcm7271 fix was added to the tree
  on Friday so no chance to be linux-next yet. But it should be fine as
  the affected developers submitted it"

* tag 'tty-5.16-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
  serial: 8250_bcm7271: UART errors after resuming from S2
  serial: 8250_pci: rewrite pericom_do_set_divisor()
  serial: 8250_pci: Fix ACCES entries in pci_serial_quirks array
  serial: 8250: Fix RTS modem control while in rs485 mode
  Revert "tty: serial: fsl_lpuart: drop earlycon entry for i.MX8QXP"
  serial: tegra: Change lower tolerance baud rate limit for tegra20 and tegra30
  serial: liteuart: relax compile-test dependencies
  serial: liteuart: fix minor-number leak on probe errors
  serial: liteuart: fix use-after-free and memleak on unbind
  serial: liteuart: Fix NULL pointer dereference in ->remove()
  vgacon: Propagate console boot parameters before calling `vc_resize'
  tty: serial: msm_serial: Deactivate RX DMA for polling support
  serial: pl011: Add ACPI SBSA UART match id
  serial: core: fix transmit-buffer reset and memleak
  MAINTAINERS: Add rpmsg tty driver maintainer
  • Loading branch information
torvalds committed Dec 5, 2021
2 parents 7587a4a + 9cabe26 commit 5163953
Show file tree
Hide file tree
Showing 12 changed files with 95 additions and 33 deletions.
6 changes: 6 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -16502,6 +16502,12 @@ T: git git://linuxtv.org/media_tree.git
F: Documentation/devicetree/bindings/media/allwinner,sun8i-a83t-de2-rotate.yaml
F: drivers/media/platform/sunxi/sun8i-rotate/

RPMSG TTY DRIVER
M: Arnaud Pouliquen <[email protected]>
L: [email protected]
S: Maintained
F: drivers/tty/rpmsg_tty.c

RTL2830 MEDIA DRIVER
M: Antti Palosaari <[email protected]>
L: [email protected]
Expand Down
13 changes: 13 additions & 0 deletions drivers/tty/serial/8250/8250_bcm7271.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ struct brcmuart_priv {
u32 rx_err;
u32 rx_timeout;
u32 rx_abort;
u32 saved_mctrl;
};

static struct dentry *brcmuart_debugfs_root;
Expand Down Expand Up @@ -1133,16 +1134,27 @@ static int brcmuart_remove(struct platform_device *pdev)
static int __maybe_unused brcmuart_suspend(struct device *dev)
{
struct brcmuart_priv *priv = dev_get_drvdata(dev);
struct uart_8250_port *up = serial8250_get_port(priv->line);
struct uart_port *port = &up->port;

serial8250_suspend_port(priv->line);
clk_disable_unprepare(priv->baud_mux_clk);

/*
* This will prevent resume from enabling RTS before the
* baud rate has been resored.
*/
priv->saved_mctrl = port->mctrl;
port->mctrl = 0;

return 0;
}

static int __maybe_unused brcmuart_resume(struct device *dev)
{
struct brcmuart_priv *priv = dev_get_drvdata(dev);
struct uart_8250_port *up = serial8250_get_port(priv->line);
struct uart_port *port = &up->port;
int ret;

ret = clk_prepare_enable(priv->baud_mux_clk);
Expand All @@ -1165,6 +1177,7 @@ static int __maybe_unused brcmuart_resume(struct device *dev)
start_rx_dma(serial8250_get_port(priv->line));
}
serial8250_resume_port(priv->line);
port->mctrl = priv->saved_mctrl;
return 0;
}

Expand Down
39 changes: 25 additions & 14 deletions drivers/tty/serial/8250/8250_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1324,29 +1324,33 @@ pericom_do_set_divisor(struct uart_port *port, unsigned int baud,
{
int scr;
int lcr;
int actual_baud;
int tolerance;

for (scr = 5 ; scr <= 15 ; scr++) {
actual_baud = 921600 * 16 / scr;
tolerance = actual_baud / 50;
for (scr = 16; scr > 4; scr--) {
unsigned int maxrate = port->uartclk / scr;
unsigned int divisor = max(maxrate / baud, 1U);
int delta = maxrate / divisor - baud;

if ((baud < actual_baud + tolerance) &&
(baud > actual_baud - tolerance)) {
if (baud > maxrate + baud / 50)
continue;

if (delta > baud / 50)
divisor++;

if (divisor > 0xffff)
continue;

/* Update delta due to possible divisor change */
delta = maxrate / divisor - baud;
if (abs(delta) < baud / 50) {
lcr = serial_port_in(port, UART_LCR);
serial_port_out(port, UART_LCR, lcr | 0x80);

serial_port_out(port, UART_DLL, 1);
serial_port_out(port, UART_DLM, 0);
serial_port_out(port, UART_DLL, divisor & 0xff);
serial_port_out(port, UART_DLM, divisor >> 8 & 0xff);
serial_port_out(port, 2, 16 - scr);
serial_port_out(port, UART_LCR, lcr);
return;
} else if (baud > actual_baud) {
break;
}
}
serial8250_do_set_divisor(port, baud, quot, quot_frac);
}
static int pci_pericom_setup(struct serial_private *priv,
const struct pciserial_board *board,
Expand Down Expand Up @@ -2291,12 +2295,19 @@ static struct pci_serial_quirk pci_serial_quirks[] = {
.setup = pci_pericom_setup_four_at_eight,
},
{
.vendor = PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4S,
.vendor = PCI_VENDOR_ID_ACCESIO,
.device = PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_4,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_pericom_setup_four_at_eight,
},
{
.vendor = PCI_VENDOR_ID_ACCESIO,
.device = PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4S,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_pericom_setup_four_at_eight,
},
{
.vendor = PCI_VENDOR_ID_ACCESIO,
.device = PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_4,
Expand Down
7 changes: 0 additions & 7 deletions drivers/tty/serial/8250/8250_port.c
Original file line number Diff line number Diff line change
Expand Up @@ -2024,13 +2024,6 @@ void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl)
struct uart_8250_port *up = up_to_u8250p(port);
unsigned char mcr;

if (port->rs485.flags & SER_RS485_ENABLED) {
if (serial8250_in_MCR(up) & UART_MCR_RTS)
mctrl |= TIOCM_RTS;
else
mctrl &= ~TIOCM_RTS;
}

mcr = serial8250_TIOCM_to_MCR(mctrl);

mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr;
Expand Down
2 changes: 1 addition & 1 deletion drivers/tty/serial/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1533,7 +1533,7 @@ config SERIAL_LITEUART
tristate "LiteUART serial port support"
depends on HAS_IOMEM
depends on OF || COMPILE_TEST
depends on LITEX
depends on LITEX || COMPILE_TEST
select SERIAL_CORE
help
This driver is for the FPGA-based LiteUART serial controller from LiteX
Expand Down
1 change: 1 addition & 0 deletions drivers/tty/serial/amba-pl011.c
Original file line number Diff line number Diff line change
Expand Up @@ -2947,6 +2947,7 @@ MODULE_DEVICE_TABLE(of, sbsa_uart_of_match);

static const struct acpi_device_id __maybe_unused sbsa_uart_acpi_match[] = {
{ "ARMH0011", 0 },
{ "ARMHB000", 0 },
{},
};
MODULE_DEVICE_TABLE(acpi, sbsa_uart_acpi_match);
Expand Down
1 change: 1 addition & 0 deletions drivers/tty/serial/fsl_lpuart.c
Original file line number Diff line number Diff line change
Expand Up @@ -2625,6 +2625,7 @@ OF_EARLYCON_DECLARE(lpuart, "fsl,vf610-lpuart", lpuart_early_console_setup);
OF_EARLYCON_DECLARE(lpuart32, "fsl,ls1021a-lpuart", lpuart32_early_console_setup);
OF_EARLYCON_DECLARE(lpuart32, "fsl,ls1028a-lpuart", ls1028a_early_console_setup);
OF_EARLYCON_DECLARE(lpuart32, "fsl,imx7ulp-lpuart", lpuart32_imx_early_console_setup);
OF_EARLYCON_DECLARE(lpuart32, "fsl,imx8qxp-lpuart", lpuart32_imx_early_console_setup);
EARLYCON_DECLARE(lpuart, lpuart_early_console_setup);
EARLYCON_DECLARE(lpuart32, lpuart32_early_console_setup);

Expand Down
20 changes: 17 additions & 3 deletions drivers/tty/serial/liteuart.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,10 @@ static int liteuart_probe(struct platform_device *pdev)

/* get membase */
port->membase = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
if (IS_ERR(port->membase))
return PTR_ERR(port->membase);
if (IS_ERR(port->membase)) {
ret = PTR_ERR(port->membase);
goto err_erase_id;
}

/* values not from device tree */
port->dev = &pdev->dev;
Expand All @@ -285,14 +287,26 @@ static int liteuart_probe(struct platform_device *pdev)
port->line = dev_id;
spin_lock_init(&port->lock);

return uart_add_one_port(&liteuart_driver, &uart->port);
platform_set_drvdata(pdev, port);

ret = uart_add_one_port(&liteuart_driver, &uart->port);
if (ret)
goto err_erase_id;

return 0;

err_erase_id:
xa_erase(&liteuart_array, uart->id);

return ret;
}

static int liteuart_remove(struct platform_device *pdev)
{
struct uart_port *port = platform_get_drvdata(pdev);
struct liteuart_port *uart = to_liteuart_port(port);

uart_remove_one_port(&liteuart_driver, port);
xa_erase(&liteuart_array, uart->id);

return 0;
Expand Down
3 changes: 3 additions & 0 deletions drivers/tty/serial/msm_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,9 @@ static void msm_start_rx_dma(struct msm_port *msm_port)
u32 val;
int ret;

if (IS_ENABLED(CONFIG_CONSOLE_POLL))
return;

if (!dma->chan)
return;

Expand Down
4 changes: 2 additions & 2 deletions drivers/tty/serial/serial-tegra.c
Original file line number Diff line number Diff line change
Expand Up @@ -1506,7 +1506,7 @@ static struct tegra_uart_chip_data tegra20_uart_chip_data = {
.fifo_mode_enable_status = false,
.uart_max_port = 5,
.max_dma_burst_bytes = 4,
.error_tolerance_low_range = 0,
.error_tolerance_low_range = -4,
.error_tolerance_high_range = 4,
};

Expand All @@ -1517,7 +1517,7 @@ static struct tegra_uart_chip_data tegra30_uart_chip_data = {
.fifo_mode_enable_status = false,
.uart_max_port = 5,
.max_dma_burst_bytes = 4,
.error_tolerance_low_range = 0,
.error_tolerance_low_range = -4,
.error_tolerance_high_range = 4,
};

Expand Down
18 changes: 17 additions & 1 deletion drivers/tty/serial/serial_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1075,6 +1075,11 @@ uart_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear)
goto out;

if (!tty_io_error(tty)) {
if (uport->rs485.flags & SER_RS485_ENABLED) {
set &= ~TIOCM_RTS;
clear &= ~TIOCM_RTS;
}

uart_update_mctrl(uport, set, clear);
ret = 0;
}
Expand Down Expand Up @@ -1549,6 +1554,7 @@ static void uart_tty_port_shutdown(struct tty_port *port)
{
struct uart_state *state = container_of(port, struct uart_state, port);
struct uart_port *uport = uart_port_check(state);
char *buf;

/*
* At this point, we stop accepting input. To do this, we
Expand All @@ -1570,8 +1576,18 @@ static void uart_tty_port_shutdown(struct tty_port *port)
*/
tty_port_set_suspended(port, 0);

uart_change_pm(state, UART_PM_STATE_OFF);
/*
* Free the transmit buffer.
*/
spin_lock_irq(&uport->lock);
buf = state->xmit.buf;
state->xmit.buf = NULL;
spin_unlock_irq(&uport->lock);

if (buf)
free_page((unsigned long)buf);

uart_change_pm(state, UART_PM_STATE_OFF);
}

static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
Expand Down
14 changes: 9 additions & 5 deletions drivers/video/console/vgacon.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,11 +366,17 @@ static void vgacon_init(struct vc_data *c, int init)
struct uni_pagedir *p;

/*
* We cannot be loaded as a module, therefore init is always 1,
* but vgacon_init can be called more than once, and init will
* not be 1.
* We cannot be loaded as a module, therefore init will be 1
* if we are the default console, however if we are a fallback
* console, for example if fbcon has failed registration, then
* init will be 0, so we need to make sure our boot parameters
* have been copied to the console structure for vgacon_resize
* ultimately called by vc_resize. Any subsequent calls to
* vgacon_init init will have init set to 0 too.
*/
c->vc_can_do_color = vga_can_do_color;
c->vc_scan_lines = vga_scan_lines;
c->vc_font.height = c->vc_cell_height = vga_video_font_height;

/* set dimensions manually if init != 0 since vc_resize() will fail */
if (init) {
Expand All @@ -379,8 +385,6 @@ static void vgacon_init(struct vc_data *c, int init)
} else
vc_resize(c, vga_video_num_columns, vga_video_num_lines);

c->vc_scan_lines = vga_scan_lines;
c->vc_font.height = c->vc_cell_height = vga_video_font_height;
c->vc_complement_mask = 0x7700;
if (vga_512_chars)
c->vc_hi_font_mask = 0x0800;
Expand Down

0 comments on commit 5163953

Please sign in to comment.