Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 52afe190 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 8d02a9a8 f4e68d58
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@ Required properties:
  * "mediatek,mt8127-uart" for MT8127 compatible UARTS
  * "mediatek,mt8127-uart" for MT8127 compatible UARTS
  * "mediatek,mt8135-uart" for MT8135 compatible UARTS
  * "mediatek,mt8135-uart" for MT8135 compatible UARTS
  * "mediatek,mt8173-uart" for MT8173 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
  * "mediatek,mt6577-uart" for MT6577 and all of the above


- reg: The base address of the UART register bank.
- reg: The base address of the UART register bank.
+8 −16
Original line number Original line Diff line number Diff line
@@ -49,11 +49,6 @@ struct ar933x_uart_port {
	struct clk		*clk;
	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,
static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up,
					    int offset)
					    int offset)
{
{
@@ -508,6 +503,7 @@ static const struct uart_ops ar933x_uart_ops = {
	.verify_port	= ar933x_uart_verify_port,
	.verify_port	= ar933x_uart_verify_port,
};
};


#ifdef CONFIG_SERIAL_AR933X_CONSOLE
static struct ar933x_uart_port *
static struct ar933x_uart_port *
ar933x_console_ports[CONFIG_SERIAL_AR933X_NR_UARTS];
ar933x_console_ports[CONFIG_SERIAL_AR933X_NR_UARTS];


@@ -604,14 +600,7 @@ static struct console ar933x_uart_console = {
	.index		= -1,
	.index		= -1,
	.data		= &ar933x_uart_driver,
	.data		= &ar933x_uart_driver,
};
};

#endif /* CONFIG_SERIAL_AR933X_CONSOLE */
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;
}


static struct uart_driver ar933x_uart_driver = {
static struct uart_driver ar933x_uart_driver = {
	.owner		= THIS_MODULE,
	.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);
	baud = ar933x_uart_get_baud(port->uartclk, 0, AR933X_UART_MAX_STEP);
	up->max_baud = min_t(unsigned int, baud, AR933X_UART_MAX_BAUD);
	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);
	ret = uart_add_one_port(&ar933x_uart_driver, &up->port);
	if (ret)
	if (ret)
@@ -749,8 +740,9 @@ static int __init ar933x_uart_init(void)
{
{
	int ret;
	int ret;


	if (ar933x_uart_console_enabled())
#ifdef CONFIG_SERIAL_AR933X_CONSOLE
	ar933x_uart_driver.cons = &ar933x_uart_console;
	ar933x_uart_driver.cons = &ar933x_uart_console;
#endif


	ret = uart_register_driver(&ar933x_uart_driver);
	ret = uart_register_driver(&ar933x_uart_driver);
	if (ret)
	if (ret)
+37 −15
Original line number Original line Diff line number Diff line
@@ -166,6 +166,8 @@ struct atmel_uart_port {
	unsigned int		pending_status;
	unsigned int		pending_status;
	spinlock_t		lock_suspended;
	spinlock_t		lock_suspended;


	bool			hd_start_rx;	/* can start RX during half-duplex operation */

	/* ISO7816 */
	/* ISO7816 */
	unsigned int		fidi_min;
	unsigned int		fidi_min;
	unsigned int		fidi_max;
	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);
	__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
#ifdef CONFIG_SERIAL_ATMEL_PDC
static bool atmel_use_pdc_rx(struct uart_port *port)
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 */
	/* 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);


	if (((port->rs485.flags & SER_RS485_ENABLED) &&
	if (atmel_uart_is_half_duplex(port))
	     !(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
	    port->iso7816.flags & SER_ISO7816_ENABLED)
		atmel_start_rx(port);
		atmel_start_rx(port);

}
}


/*
/*
@@ -628,9 +636,7 @@ static void atmel_start_tx(struct uart_port *port)
		return;
		return;


	if (atmel_use_pdc_tx(port) || atmel_use_dma_tx(port))
	if (atmel_use_pdc_tx(port) || atmel_use_dma_tx(port))
		if (((port->rs485.flags & SER_RS485_ENABLED) &&
		if (atmel_uart_is_half_duplex(port))
		     !(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
		    port->iso7816.flags & SER_ISO7816_ENABLED)
			atmel_stop_rx(port);
			atmel_stop_rx(port);


	if (atmel_use_pdc_tx(port))
	if (atmel_use_pdc_tx(port))
@@ -928,11 +934,14 @@ 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) &&
	else if (atmel_uart_is_half_duplex(port)) {
		  !(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
		/*
		 port->iso7816.flags & SER_ISO7816_ENABLED) {
		 * DMA done, re-enable TXEMPTY and signal that we can stop
		/* DMA done, stop TX, start RX for RS485 */
		 * TX and start RX for RS485
		atmel_start_rx(port);
		 */
		atmel_port->hd_start_rx = true;
		atmel_uart_writel(port, ATMEL_US_IER,
				  atmel_port->tx_done_mask);
	}
	}


	spin_unlock_irqrestore(&port->lock, flags);
	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,
					 sg_dma_len(&atmel_port->sg_rx)/2,
					 DMA_DEV_TO_MEM,
					 DMA_DEV_TO_MEM,
					 DMA_PREP_INTERRUPT);
					 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 = atmel_complete_rx_dma;
	desc->callback_param = port;
	desc->callback_param = port;
	atmel_port->desc_rx = desc;
	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);
	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);


	if (pending & atmel_port->tx_done_mask) {
	if (pending & atmel_port->tx_done_mask) {
		/* Either PDC or interrupt transmission */
		atmel_uart_writel(port, ATMEL_US_IDR,
		atmel_uart_writel(port, ATMEL_US_IDR,
				  atmel_port->tx_done_mask);
				  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);
		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_uart_writel(port, ATMEL_US_IER,
				  atmel_port->tx_done_mask);
				  atmel_port->tx_done_mask);
	} else {
	} else {
		if (((port->rs485.flags & SER_RS485_ENABLED) &&
		if (atmel_uart_is_half_duplex(port)) {
		     !(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
		    port->iso7816.flags & SER_ISO7816_ENABLED) {
			/* DMA done, stop TX, start RX for RS485 */
			/* DMA done, stop TX, start RX for RS485 */
			atmel_start_rx(port);
			atmel_start_rx(port);
		}
		}
+3 −1
Original line number Original line Diff line number Diff line
@@ -148,8 +148,10 @@ static int configure_kgdboc(void)
	char *cptr = config;
	char *cptr = config;
	struct console *cons;
	struct console *cons;


	if (!strlen(config) || isspace(config[0]))
	if (!strlen(config) || isspace(config[0])) {
		err = 0;
		goto noconfig;
		goto noconfig;
	}


	kgdboc_io_ops.is_console = 0;
	kgdboc_io_ops.is_console = 0;
	kgdb_tty_driver = NULL;
	kgdb_tty_driver = NULL;
+2 −0
Original line number Original line Diff line number Diff line
@@ -1415,6 +1415,8 @@ static int max310x_spi_probe(struct spi_device *spi)
	if (spi->dev.of_node) {
	if (spi->dev.of_node) {
		const struct of_device_id *of_id =
		const struct of_device_id *of_id =
			of_match_device(max310x_dt_ids, &spi->dev);
			of_match_device(max310x_dt_ids, &spi->dev);
		if (!of_id)
			return -ENODEV;


		devtype = (struct max310x_devtype *)of_id->data;
		devtype = (struct max310x_devtype *)of_id->data;
	} else {
	} else {
Loading