Commit 6811a466 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull tty/serial driver fixes from Greg KH:
 "Here are some small tty n_gsm and serial driver fixes for 5.18-rc7
  that resolve reported problems. They include:

   - n_gsm fixes for reported issues

   - 8250_mtk driver fixes for some platforms

   - fsl_lpuart driver fix for reported problem.

   - digicolor driver fix for reported problem.

  All have been in linux-next for a while with no reported problems"

* tag 'tty-5.18-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
  fsl_lpuart: Don't enable interrupts too early
  tty: n_gsm: fix invalid gsmtty_write_room() result
  tty: n_gsm: fix mux activation issues in gsm_config()
  tty: n_gsm: fix buffer over-read in gsm_dlci_data()
  serial: 8250_mtk: Fix register address for XON/XOFF character
  serial: 8250_mtk: Make sure to select the right FEATURE_SEL
  serial: 8250_mtk: Fix UART_EFR register address
  tty/serial: digicolor: fix possible null-ptr-deref in digicolor_uart_probe()
parents fc49583c 401fb66a
Loading
Loading
Loading
Loading
+12 −8
Original line number Diff line number Diff line
@@ -137,6 +137,7 @@ struct gsm_dlci {
	int retries;
	/* Uplink tty if active */
	struct tty_port port;	/* The tty bound to this DLCI if there is one */
#define TX_SIZE		4096    /* Must be power of 2. */
	struct kfifo fifo;	/* Queue fifo for the DLCI */
	int adaption;		/* Adaption layer in use */
	int prev_adaption;
@@ -1658,6 +1659,7 @@ static void gsm_dlci_data(struct gsm_dlci *dlci, const u8 *data, int clen)
			if (len == 0)
				return;
		}
		len--;
		slen++;
		tty = tty_port_tty_get(port);
		if (tty) {
@@ -1730,7 +1732,7 @@ static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr)
		return NULL;
	spin_lock_init(&dlci->lock);
	mutex_init(&dlci->mutex);
	if (kfifo_alloc(&dlci->fifo, 4096, GFP_KERNEL) < 0) {
	if (kfifo_alloc(&dlci->fifo, TX_SIZE, GFP_KERNEL) < 0) {
		kfree(dlci);
		return NULL;
	}
@@ -2351,6 +2353,7 @@ static void gsm_copy_config_values(struct gsm_mux *gsm,

static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c)
{
	int ret = 0;
	int need_close = 0;
	int need_restart = 0;

@@ -2418,10 +2421,13 @@ static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c)
	 * FIXME: We need to separate activation/deactivation from adding
	 * and removing from the mux array
	 */
	if (need_restart)
		gsm_activate_mux(gsm);
	if (gsm->initiator && need_close)
	if (gsm->dead) {
		ret = gsm_activate_mux(gsm);
		if (ret)
			return ret;
		if (gsm->initiator)
			gsm_dlci_begin_open(gsm->dlci[0]);
	}
	return 0;
}

@@ -2971,8 +2977,6 @@ static struct tty_ldisc_ops tty_ldisc_packet = {
 *	Virtual tty side
 */

#define TX_SIZE		512

/**
 *	gsm_modem_upd_via_data	-	send modem bits via convergence layer
 *	@dlci: channel
@@ -3212,7 +3216,7 @@ static unsigned int gsmtty_write_room(struct tty_struct *tty)
	struct gsm_dlci *dlci = tty->driver_data;
	if (dlci->state == DLCI_CLOSED)
		return 0;
	return TX_SIZE - kfifo_len(&dlci->fifo);
	return kfifo_avail(&dlci->fifo);
}

static unsigned int gsmtty_chars_in_buffer(struct tty_struct *tty)
+20 −9
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
#define MTK_UART_IER_RTSI	0x40	/* Enable RTS Modem status interrupt */
#define MTK_UART_IER_CTSI	0x80	/* Enable CTS Modem status interrupt */

#define MTK_UART_EFR		38	/* I/O: Extended Features Register */
#define MTK_UART_EFR_EN		0x10	/* Enable enhancement feature */
#define MTK_UART_EFR_RTS	0x40	/* Enable hardware rx flow control */
#define MTK_UART_EFR_CTS	0x80	/* Enable hardware tx flow control */
@@ -53,6 +54,12 @@
#define MTK_UART_TX_TRIGGER	1
#define MTK_UART_RX_TRIGGER	MTK_UART_RX_SIZE

#define MTK_UART_FEATURE_SEL	39	/* Feature Selection register */
#define MTK_UART_FEAT_NEWRMAP	BIT(0)	/* Use new register map */

#define MTK_UART_XON1		40	/* I/O: Xon character 1 */
#define MTK_UART_XOFF1		42	/* I/O: Xoff character 1 */

#ifdef CONFIG_SERIAL_8250_DMA
enum dma_rx_status {
	DMA_RX_START = 0,
@@ -169,7 +176,7 @@ static void mtk8250_dma_enable(struct uart_8250_port *up)
		   MTK_UART_DMA_EN_RX | MTK_UART_DMA_EN_TX);

	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
	serial_out(up, UART_EFR, UART_EFR_ECB);
	serial_out(up, MTK_UART_EFR, UART_EFR_ECB);
	serial_out(up, UART_LCR, lcr);

	if (dmaengine_slave_config(dma->rxchan, &dma->rxconf) != 0)
@@ -232,7 +239,7 @@ static void mtk8250_set_flow_ctrl(struct uart_8250_port *up, int mode)
	int lcr = serial_in(up, UART_LCR);

	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
	serial_out(up, UART_EFR, UART_EFR_ECB);
	serial_out(up, MTK_UART_EFR, UART_EFR_ECB);
	serial_out(up, UART_LCR, lcr);
	lcr = serial_in(up, UART_LCR);

@@ -241,7 +248,7 @@ static void mtk8250_set_flow_ctrl(struct uart_8250_port *up, int mode)
		serial_out(up, MTK_UART_ESCAPE_DAT, MTK_UART_ESCAPE_CHAR);
		serial_out(up, MTK_UART_ESCAPE_EN, 0x00);
		serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
		serial_out(up, UART_EFR, serial_in(up, UART_EFR) &
		serial_out(up, MTK_UART_EFR, serial_in(up, MTK_UART_EFR) &
			(~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK)));
		serial_out(up, UART_LCR, lcr);
		mtk8250_disable_intrs(up, MTK_UART_IER_XOFFI |
@@ -255,8 +262,8 @@ static void mtk8250_set_flow_ctrl(struct uart_8250_port *up, int mode)
		serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);

		/*enable hw flow control*/
		serial_out(up, UART_EFR, MTK_UART_EFR_HW_FC |
			(serial_in(up, UART_EFR) &
		serial_out(up, MTK_UART_EFR, MTK_UART_EFR_HW_FC |
			(serial_in(up, MTK_UART_EFR) &
			(~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK))));

		serial_out(up, UART_LCR, lcr);
@@ -270,12 +277,12 @@ static void mtk8250_set_flow_ctrl(struct uart_8250_port *up, int mode)
		serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);

		/*enable sw flow control */
		serial_out(up, UART_EFR, MTK_UART_EFR_XON1_XOFF1 |
			(serial_in(up, UART_EFR) &
		serial_out(up, MTK_UART_EFR, MTK_UART_EFR_XON1_XOFF1 |
			(serial_in(up, MTK_UART_EFR) &
			(~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK))));

		serial_out(up, UART_XON1, START_CHAR(port->state->port.tty));
		serial_out(up, UART_XOFF1, STOP_CHAR(port->state->port.tty));
		serial_out(up, MTK_UART_XON1, START_CHAR(port->state->port.tty));
		serial_out(up, MTK_UART_XOFF1, STOP_CHAR(port->state->port.tty));
		serial_out(up, UART_LCR, lcr);
		mtk8250_disable_intrs(up, MTK_UART_IER_CTSI|MTK_UART_IER_RTSI);
		mtk8250_enable_intrs(up, MTK_UART_IER_XOFFI);
@@ -568,6 +575,10 @@ static int mtk8250_probe(struct platform_device *pdev)
		uart.dma = data->dma;
#endif

	/* Set AP UART new register map */
	writel(MTK_UART_FEAT_NEWRMAP, uart.port.membase +
	       (MTK_UART_FEATURE_SEL << uart.port.regshift));

	/* Disable Rate Fix function */
	writel(0x0, uart.port.membase +
			(MTK_UART_RATE_FIX << uart.port.regshift));
+2 −3
Original line number Diff line number Diff line
@@ -471,11 +471,10 @@ static int digicolor_uart_probe(struct platform_device *pdev)
	if (IS_ERR(uart_clk))
		return PTR_ERR(uart_clk);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	dp->port.mapbase = res->start;
	dp->port.membase = devm_ioremap_resource(&pdev->dev, res);
	dp->port.membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
	if (IS_ERR(dp->port.membase))
		return PTR_ERR(dp->port.membase);
	dp->port.mapbase = res->start;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
+9 −9
Original line number Diff line number Diff line
@@ -2664,6 +2664,7 @@ static int lpuart_probe(struct platform_device *pdev)
	struct device_node *np = pdev->dev.of_node;
	struct lpuart_port *sport;
	struct resource *res;
	irq_handler_t handler;
	int ret;

	sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL);
@@ -2741,17 +2742,11 @@ static int lpuart_probe(struct platform_device *pdev)

	if (lpuart_is_32(sport)) {
		lpuart_reg.cons = LPUART32_CONSOLE;
		ret = devm_request_irq(&pdev->dev, sport->port.irq, lpuart32_int, 0,
					DRIVER_NAME, sport);
		handler = lpuart32_int;
	} else {
		lpuart_reg.cons = LPUART_CONSOLE;
		ret = devm_request_irq(&pdev->dev, sport->port.irq, lpuart_int, 0,
					DRIVER_NAME, sport);
		handler = lpuart_int;
	}

	if (ret)
		goto failed_irq_request;

	ret = uart_add_one_port(&lpuart_reg, &sport->port);
	if (ret)
		goto failed_attach_port;
@@ -2773,13 +2768,18 @@ static int lpuart_probe(struct platform_device *pdev)

	sport->port.rs485_config(&sport->port, &sport->port.rs485);

	ret = devm_request_irq(&pdev->dev, sport->port.irq, handler, 0,
				DRIVER_NAME, sport);
	if (ret)
		goto failed_irq_request;

	return 0;

failed_irq_request:
failed_get_rs485:
failed_reset:
	uart_remove_one_port(&lpuart_reg, &sport->port);
failed_attach_port:
failed_irq_request:
	lpuart_disable_clks(sport);
failed_clock_enable:
failed_out_of_range: