TTY/Serial fixes for 5.1-rc3
Here are some small tty and serial driver fixes for 5.1-rc3. Nothing major here, just a number of potential problems fixes for error handling paths, as well as some other minor bugfixes for reported issues with 5.1-rc1. All of these have been in linux-next with no reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCXJ8wCg8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ylWigCfSPVnxuGsNFTZIN8CUMBH4I5cmjkAnjrN3NdS Sumt55mskpi/Ht+5UWmw =LFqo -----END PGP SIGNATURE----- Merge tag 'tty-5.1-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty Pull tty/serial fixes from Greg KH: "Here are some small tty and serial driver fixes for 5.1-rc3. Nothing major here, just a number of potential problems fixes for error handling paths, as well as some other minor bugfixes for reported issues with 5.1-rc1. All of these have been in linux-next with no reported issues" * tag 'tty-5.1-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: tty: fix NULL pointer issue when tty_port ops is not set Disable kgdboc failed by echo space to /sys/module/kgdboc/parameters/kgdboc dt-bindings: serial: Add compatible for Mediatek MT8183 tty/serial: atmel: RS485 HD w/DMA: enable RX after TX is stopped tty/serial: atmel: Add is_half_duplex helper serial: sh-sci: Fix setting SCSCR_TIE while transferring data serial: ar933x_uart: Fix build failure with disabled console tty: serial: qcom_geni_serial: Initialize baud in qcom_geni_console_setup sc16is7xx: missing unregister/delete driver on error in sc16is7xx_init() tty: mxs-auart: fix a potential NULL pointer dereference tty: atmel_serial: fix a potential NULL pointer dereference serial: max310x: Fix to avoid potential NULL pointer dereference serial: mvebu-uart: Fix to avoid a potential NULL pointer dereference
This commit is contained in:
commit
52afe190ff
|
@ -16,6 +16,7 @@ Required properties:
|
|||
* "mediatek,mt8127-uart" for MT8127 compatible UARTS
|
||||
* "mediatek,mt8135-uart" for MT8135 compatible UARTS
|
||||
* "mediatek,mt8173-uart" for MT8173 compatible UARTS
|
||||
* "mediatek,mt8183-uart", "mediatek,mt6577-uart" for MT8183 compatible UARTS
|
||||
* "mediatek,mt6577-uart" for MT6577 and all of the above
|
||||
|
||||
- reg: The base address of the UART register bank.
|
||||
|
|
|
@ -49,11 +49,6 @@ struct ar933x_uart_port {
|
|||
struct clk *clk;
|
||||
};
|
||||
|
||||
static inline bool ar933x_uart_console_enabled(void)
|
||||
{
|
||||
return IS_ENABLED(CONFIG_SERIAL_AR933X_CONSOLE);
|
||||
}
|
||||
|
||||
static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up,
|
||||
int offset)
|
||||
{
|
||||
|
@ -508,6 +503,7 @@ static const struct uart_ops ar933x_uart_ops = {
|
|||
.verify_port = ar933x_uart_verify_port,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SERIAL_AR933X_CONSOLE
|
||||
static struct ar933x_uart_port *
|
||||
ar933x_console_ports[CONFIG_SERIAL_AR933X_NR_UARTS];
|
||||
|
||||
|
@ -604,14 +600,7 @@ static struct console ar933x_uart_console = {
|
|||
.index = -1,
|
||||
.data = &ar933x_uart_driver,
|
||||
};
|
||||
|
||||
static void ar933x_uart_add_console_port(struct ar933x_uart_port *up)
|
||||
{
|
||||
if (!ar933x_uart_console_enabled())
|
||||
return;
|
||||
|
||||
ar933x_console_ports[up->port.line] = up;
|
||||
}
|
||||
#endif /* CONFIG_SERIAL_AR933X_CONSOLE */
|
||||
|
||||
static struct uart_driver ar933x_uart_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
|
@ -700,7 +689,9 @@ static int ar933x_uart_probe(struct platform_device *pdev)
|
|||
baud = ar933x_uart_get_baud(port->uartclk, 0, AR933X_UART_MAX_STEP);
|
||||
up->max_baud = min_t(unsigned int, baud, AR933X_UART_MAX_BAUD);
|
||||
|
||||
ar933x_uart_add_console_port(up);
|
||||
#ifdef CONFIG_SERIAL_AR933X_CONSOLE
|
||||
ar933x_console_ports[up->port.line] = up;
|
||||
#endif
|
||||
|
||||
ret = uart_add_one_port(&ar933x_uart_driver, &up->port);
|
||||
if (ret)
|
||||
|
@ -749,8 +740,9 @@ static int __init ar933x_uart_init(void)
|
|||
{
|
||||
int ret;
|
||||
|
||||
if (ar933x_uart_console_enabled())
|
||||
ar933x_uart_driver.cons = &ar933x_uart_console;
|
||||
#ifdef CONFIG_SERIAL_AR933X_CONSOLE
|
||||
ar933x_uart_driver.cons = &ar933x_uart_console;
|
||||
#endif
|
||||
|
||||
ret = uart_register_driver(&ar933x_uart_driver);
|
||||
if (ret)
|
||||
|
|
|
@ -166,6 +166,8 @@ struct atmel_uart_port {
|
|||
unsigned int pending_status;
|
||||
spinlock_t lock_suspended;
|
||||
|
||||
bool hd_start_rx; /* can start RX during half-duplex operation */
|
||||
|
||||
/* ISO7816 */
|
||||
unsigned int fidi_min;
|
||||
unsigned int fidi_max;
|
||||
|
@ -231,6 +233,13 @@ static inline void atmel_uart_write_char(struct uart_port *port, u8 value)
|
|||
__raw_writeb(value, port->membase + ATMEL_US_THR);
|
||||
}
|
||||
|
||||
static inline int atmel_uart_is_half_duplex(struct uart_port *port)
|
||||
{
|
||||
return ((port->rs485.flags & SER_RS485_ENABLED) &&
|
||||
!(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
|
||||
(port->iso7816.flags & SER_ISO7816_ENABLED);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SERIAL_ATMEL_PDC
|
||||
static bool atmel_use_pdc_rx(struct uart_port *port)
|
||||
{
|
||||
|
@ -608,10 +617,9 @@ static void atmel_stop_tx(struct uart_port *port)
|
|||
/* Disable interrupts */
|
||||
atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask);
|
||||
|
||||
if (((port->rs485.flags & SER_RS485_ENABLED) &&
|
||||
!(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
|
||||
port->iso7816.flags & SER_ISO7816_ENABLED)
|
||||
if (atmel_uart_is_half_duplex(port))
|
||||
atmel_start_rx(port);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -628,9 +636,7 @@ static void atmel_start_tx(struct uart_port *port)
|
|||
return;
|
||||
|
||||
if (atmel_use_pdc_tx(port) || atmel_use_dma_tx(port))
|
||||
if (((port->rs485.flags & SER_RS485_ENABLED) &&
|
||||
!(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
|
||||
port->iso7816.flags & SER_ISO7816_ENABLED)
|
||||
if (atmel_uart_is_half_duplex(port))
|
||||
atmel_stop_rx(port);
|
||||
|
||||
if (atmel_use_pdc_tx(port))
|
||||
|
@ -928,11 +934,14 @@ static void atmel_complete_tx_dma(void *arg)
|
|||
*/
|
||||
if (!uart_circ_empty(xmit))
|
||||
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)) ||
|
||||
port->iso7816.flags & SER_ISO7816_ENABLED) {
|
||||
/* DMA done, stop TX, start RX for RS485 */
|
||||
atmel_start_rx(port);
|
||||
else if (atmel_uart_is_half_duplex(port)) {
|
||||
/*
|
||||
* DMA done, re-enable TXEMPTY and signal that we can stop
|
||||
* TX and start RX for RS485
|
||||
*/
|
||||
atmel_port->hd_start_rx = true;
|
||||
atmel_uart_writel(port, ATMEL_US_IER,
|
||||
atmel_port->tx_done_mask);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
|
@ -1288,6 +1297,10 @@ static int atmel_prepare_rx_dma(struct uart_port *port)
|
|||
sg_dma_len(&atmel_port->sg_rx)/2,
|
||||
DMA_DEV_TO_MEM,
|
||||
DMA_PREP_INTERRUPT);
|
||||
if (!desc) {
|
||||
dev_err(port->dev, "Preparing DMA cyclic failed\n");
|
||||
goto chan_err;
|
||||
}
|
||||
desc->callback = atmel_complete_rx_dma;
|
||||
desc->callback_param = port;
|
||||
atmel_port->desc_rx = desc;
|
||||
|
@ -1376,9 +1389,20 @@ atmel_handle_transmit(struct uart_port *port, unsigned int pending)
|
|||
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
|
||||
|
||||
if (pending & atmel_port->tx_done_mask) {
|
||||
/* Either PDC or interrupt transmission */
|
||||
atmel_uart_writel(port, ATMEL_US_IDR,
|
||||
atmel_port->tx_done_mask);
|
||||
|
||||
/* Start RX if flag was set and FIFO is empty */
|
||||
if (atmel_port->hd_start_rx) {
|
||||
if (!(atmel_uart_readl(port, ATMEL_US_CSR)
|
||||
& ATMEL_US_TXEMPTY))
|
||||
dev_warn(port->dev, "Should start RX, but TX fifo is not empty\n");
|
||||
|
||||
atmel_port->hd_start_rx = false;
|
||||
atmel_start_rx(port);
|
||||
return;
|
||||
}
|
||||
|
||||
atmel_tasklet_schedule(atmel_port, &atmel_port->tasklet_tx);
|
||||
}
|
||||
}
|
||||
|
@ -1508,9 +1532,7 @@ static void atmel_tx_pdc(struct uart_port *port)
|
|||
atmel_uart_writel(port, ATMEL_US_IER,
|
||||
atmel_port->tx_done_mask);
|
||||
} else {
|
||||
if (((port->rs485.flags & SER_RS485_ENABLED) &&
|
||||
!(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
|
||||
port->iso7816.flags & SER_ISO7816_ENABLED) {
|
||||
if (atmel_uart_is_half_duplex(port)) {
|
||||
/* DMA done, stop TX, start RX for RS485 */
|
||||
atmel_start_rx(port);
|
||||
}
|
||||
|
|
|
@ -148,8 +148,10 @@ static int configure_kgdboc(void)
|
|||
char *cptr = config;
|
||||
struct console *cons;
|
||||
|
||||
if (!strlen(config) || isspace(config[0]))
|
||||
if (!strlen(config) || isspace(config[0])) {
|
||||
err = 0;
|
||||
goto noconfig;
|
||||
}
|
||||
|
||||
kgdboc_io_ops.is_console = 0;
|
||||
kgdb_tty_driver = NULL;
|
||||
|
|
|
@ -1415,6 +1415,8 @@ static int max310x_spi_probe(struct spi_device *spi)
|
|||
if (spi->dev.of_node) {
|
||||
const struct of_device_id *of_id =
|
||||
of_match_device(max310x_dt_ids, &spi->dev);
|
||||
if (!of_id)
|
||||
return -ENODEV;
|
||||
|
||||
devtype = (struct max310x_devtype *)of_id->data;
|
||||
} else {
|
||||
|
|
|
@ -810,6 +810,9 @@ static int mvebu_uart_probe(struct platform_device *pdev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!match)
|
||||
return -ENODEV;
|
||||
|
||||
/* Assume that all UART ports have a DT alias or none has */
|
||||
id = of_alias_get_id(pdev->dev.of_node, "serial");
|
||||
if (!pdev->dev.of_node || id < 0)
|
||||
|
|
|
@ -1686,6 +1686,10 @@ static int mxs_auart_probe(struct platform_device *pdev)
|
|||
|
||||
s->port.mapbase = r->start;
|
||||
s->port.membase = ioremap(r->start, resource_size(r));
|
||||
if (!s->port.membase) {
|
||||
ret = -ENOMEM;
|
||||
goto out_disable_clks;
|
||||
}
|
||||
s->port.ops = &mxs_auart_ops;
|
||||
s->port.iotype = UPIO_MEM;
|
||||
s->port.fifosize = MXS_AUART_FIFO_SIZE;
|
||||
|
|
|
@ -1050,7 +1050,7 @@ static int __init qcom_geni_console_setup(struct console *co, char *options)
|
|||
{
|
||||
struct uart_port *uport;
|
||||
struct qcom_geni_serial_port *port;
|
||||
int baud;
|
||||
int baud = 9600;
|
||||
int bits = 8;
|
||||
int parity = 'n';
|
||||
int flow = 'n';
|
||||
|
|
|
@ -1507,7 +1507,7 @@ static int __init sc16is7xx_init(void)
|
|||
ret = i2c_add_driver(&sc16is7xx_i2c_uart_driver);
|
||||
if (ret < 0) {
|
||||
pr_err("failed to init sc16is7xx i2c --> %d\n", ret);
|
||||
return ret;
|
||||
goto err_i2c;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1515,10 +1515,18 @@ static int __init sc16is7xx_init(void)
|
|||
ret = spi_register_driver(&sc16is7xx_spi_uart_driver);
|
||||
if (ret < 0) {
|
||||
pr_err("failed to init sc16is7xx spi --> %d\n", ret);
|
||||
return ret;
|
||||
goto err_spi;
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
|
||||
err_spi:
|
||||
#ifdef CONFIG_SERIAL_SC16IS7XX_I2C
|
||||
i2c_del_driver(&sc16is7xx_i2c_uart_driver);
|
||||
#endif
|
||||
err_i2c:
|
||||
uart_unregister_driver(&sc16is7xx_uart);
|
||||
return ret;
|
||||
}
|
||||
module_init(sc16is7xx_init);
|
||||
|
||||
|
|
|
@ -838,19 +838,9 @@ static void sci_transmit_chars(struct uart_port *port)
|
|||
|
||||
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
|
||||
uart_write_wakeup(port);
|
||||
if (uart_circ_empty(xmit)) {
|
||||
if (uart_circ_empty(xmit))
|
||||
sci_stop_tx(port);
|
||||
} else {
|
||||
ctrl = serial_port_in(port, SCSCR);
|
||||
|
||||
if (port->type != PORT_SCI) {
|
||||
serial_port_in(port, SCxSR); /* Dummy read */
|
||||
sci_clear_SCxSR(port, SCxSR_TDxE_CLEAR(port));
|
||||
}
|
||||
|
||||
ctrl |= SCSCR_TIE;
|
||||
serial_port_out(port, SCSCR, ctrl);
|
||||
}
|
||||
}
|
||||
|
||||
/* On SH3, SCIF may read end-of-break as a space->mark char */
|
||||
|
|
|
@ -325,7 +325,7 @@ static void tty_port_shutdown(struct tty_port *port, struct tty_struct *tty)
|
|||
if (tty && C_HUPCL(tty))
|
||||
tty_port_lower_dtr_rts(port);
|
||||
|
||||
if (port->ops->shutdown)
|
||||
if (port->ops && port->ops->shutdown)
|
||||
port->ops->shutdown(port);
|
||||
}
|
||||
out:
|
||||
|
@ -398,7 +398,7 @@ EXPORT_SYMBOL_GPL(tty_port_tty_wakeup);
|
|||
*/
|
||||
int tty_port_carrier_raised(struct tty_port *port)
|
||||
{
|
||||
if (port->ops->carrier_raised == NULL)
|
||||
if (!port->ops || !port->ops->carrier_raised)
|
||||
return 1;
|
||||
return port->ops->carrier_raised(port);
|
||||
}
|
||||
|
@ -414,7 +414,7 @@ EXPORT_SYMBOL(tty_port_carrier_raised);
|
|||
*/
|
||||
void tty_port_raise_dtr_rts(struct tty_port *port)
|
||||
{
|
||||
if (port->ops->dtr_rts)
|
||||
if (port->ops && port->ops->dtr_rts)
|
||||
port->ops->dtr_rts(port, 1);
|
||||
}
|
||||
EXPORT_SYMBOL(tty_port_raise_dtr_rts);
|
||||
|
@ -429,7 +429,7 @@ EXPORT_SYMBOL(tty_port_raise_dtr_rts);
|
|||
*/
|
||||
void tty_port_lower_dtr_rts(struct tty_port *port)
|
||||
{
|
||||
if (port->ops->dtr_rts)
|
||||
if (port->ops && port->ops->dtr_rts)
|
||||
port->ops->dtr_rts(port, 0);
|
||||
}
|
||||
EXPORT_SYMBOL(tty_port_lower_dtr_rts);
|
||||
|
@ -684,7 +684,7 @@ int tty_port_open(struct tty_port *port, struct tty_struct *tty,
|
|||
|
||||
if (!tty_port_initialized(port)) {
|
||||
clear_bit(TTY_IO_ERROR, &tty->flags);
|
||||
if (port->ops->activate) {
|
||||
if (port->ops && port->ops->activate) {
|
||||
int retval = port->ops->activate(port, tty);
|
||||
if (retval) {
|
||||
mutex_unlock(&port->mutex);
|
||||
|
|
Loading…
Reference in New Issue