Commit de758035 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull tty fixes from Greg KH:
 "Here are some small tty/serial fixes for 5.10-rc5 that resolve some
  reported issues:

   - speakup crash when telling the kernel to use a device that isn't
     really there

   - imx serial driver fixes for reported problems

   - ar933x_uart driver fix for probe error handling path

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

* tag 'tty-5.10-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
  serial: ar933x_uart: disable clk on error handling path in probe
  tty: serial: imx: keep console clocks always on
  speakup: Do not let the line discipline be used several times
  tty: serial: imx: fix potential deadlock
parents a7f07fc1 425af483
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -49,15 +49,25 @@ static int spk_ttyio_ldisc_open(struct tty_struct *tty)

	if (!tty->ops->write)
		return -EOPNOTSUPP;

	mutex_lock(&speakup_tty_mutex);
	if (speakup_tty) {
		mutex_unlock(&speakup_tty_mutex);
		return -EBUSY;
	}
	speakup_tty = tty;

	ldisc_data = kmalloc(sizeof(*ldisc_data), GFP_KERNEL);
	if (!ldisc_data)
	if (!ldisc_data) {
		speakup_tty = NULL;
		mutex_unlock(&speakup_tty_mutex);
		return -ENOMEM;
	}

	init_completion(&ldisc_data->completion);
	ldisc_data->buf_free = true;
	speakup_tty->disc_data = ldisc_data;
	mutex_unlock(&speakup_tty_mutex);

	return 0;
}
+4 −2
Original line number Diff line number Diff line
@@ -789,8 +789,10 @@ static int ar933x_uart_probe(struct platform_device *pdev)
		goto err_disable_clk;

	up->gpios = mctrl_gpio_init(port, 0);
	if (IS_ERR(up->gpios) && PTR_ERR(up->gpios) != -ENOSYS)
		return PTR_ERR(up->gpios);
	if (IS_ERR(up->gpios) && PTR_ERR(up->gpios) != -ENOSYS) {
		ret = PTR_ERR(up->gpios);
		goto err_disable_clk;
	}

	up->rts_gpiod = mctrl_gpio_to_gpiod(up->gpios, UART_GPIO_RTS);

+11 −19
Original line number Diff line number Diff line
@@ -942,8 +942,14 @@ static irqreturn_t imx_uart_int(int irq, void *dev_id)
	struct imx_port *sport = dev_id;
	unsigned int usr1, usr2, ucr1, ucr2, ucr3, ucr4;
	irqreturn_t ret = IRQ_NONE;
	unsigned long flags = 0;

	spin_lock(&sport->port.lock);
	/*
	 * IRQs might not be disabled upon entering this interrupt handler,
	 * e.g. when interrupt handlers are forced to be threaded. To support
	 * this scenario as well, disable IRQs when acquiring the spinlock.
	 */
	spin_lock_irqsave(&sport->port.lock, flags);

	usr1 = imx_uart_readl(sport, USR1);
	usr2 = imx_uart_readl(sport, USR2);
@@ -1013,7 +1019,7 @@ static irqreturn_t imx_uart_int(int irq, void *dev_id)
		ret = IRQ_HANDLED;
	}

	spin_unlock(&sport->port.lock);
	spin_unlock_irqrestore(&sport->port.lock, flags);

	return ret;
}
@@ -2002,16 +2008,6 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count)
	unsigned int ucr1;
	unsigned long flags = 0;
	int locked = 1;
	int retval;

	retval = clk_enable(sport->clk_per);
	if (retval)
		return;
	retval = clk_enable(sport->clk_ipg);
	if (retval) {
		clk_disable(sport->clk_per);
		return;
	}

	if (sport->port.sysrq)
		locked = 0;
@@ -2047,9 +2043,6 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count)

	if (locked)
		spin_unlock_irqrestore(&sport->port.lock, flags);

	clk_disable(sport->clk_ipg);
	clk_disable(sport->clk_per);
}

/*
@@ -2150,15 +2143,14 @@ imx_uart_console_setup(struct console *co, char *options)

	retval = uart_set_options(&sport->port, co, baud, parity, bits, flow);

	clk_disable(sport->clk_ipg);
	if (retval) {
		clk_unprepare(sport->clk_ipg);
		clk_disable_unprepare(sport->clk_ipg);
		goto error_console;
	}

	retval = clk_prepare(sport->clk_per);
	retval = clk_prepare_enable(sport->clk_per);
	if (retval)
		clk_unprepare(sport->clk_ipg);
		clk_disable_unprepare(sport->clk_ipg);

error_console:
	return retval;