Commit de758035 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'tty-5.10-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty

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
...@@ -49,15 +49,25 @@ static int spk_ttyio_ldisc_open(struct tty_struct *tty) ...@@ -49,15 +49,25 @@ static int spk_ttyio_ldisc_open(struct tty_struct *tty)
if (!tty->ops->write) if (!tty->ops->write)
return -EOPNOTSUPP; return -EOPNOTSUPP;
mutex_lock(&speakup_tty_mutex);
if (speakup_tty) {
mutex_unlock(&speakup_tty_mutex);
return -EBUSY;
}
speakup_tty = tty; speakup_tty = tty;
ldisc_data = kmalloc(sizeof(*ldisc_data), GFP_KERNEL); ldisc_data = kmalloc(sizeof(*ldisc_data), GFP_KERNEL);
if (!ldisc_data) if (!ldisc_data) {
speakup_tty = NULL;
mutex_unlock(&speakup_tty_mutex);
return -ENOMEM; return -ENOMEM;
}
init_completion(&ldisc_data->completion); init_completion(&ldisc_data->completion);
ldisc_data->buf_free = true; ldisc_data->buf_free = true;
speakup_tty->disc_data = ldisc_data; speakup_tty->disc_data = ldisc_data;
mutex_unlock(&speakup_tty_mutex);
return 0; return 0;
} }
......
...@@ -789,8 +789,10 @@ static int ar933x_uart_probe(struct platform_device *pdev) ...@@ -789,8 +789,10 @@ static int ar933x_uart_probe(struct platform_device *pdev)
goto err_disable_clk; goto err_disable_clk;
up->gpios = mctrl_gpio_init(port, 0); up->gpios = mctrl_gpio_init(port, 0);
if (IS_ERR(up->gpios) && PTR_ERR(up->gpios) != -ENOSYS) if (IS_ERR(up->gpios) && PTR_ERR(up->gpios) != -ENOSYS) {
return PTR_ERR(up->gpios); ret = PTR_ERR(up->gpios);
goto err_disable_clk;
}
up->rts_gpiod = mctrl_gpio_to_gpiod(up->gpios, UART_GPIO_RTS); up->rts_gpiod = mctrl_gpio_to_gpiod(up->gpios, UART_GPIO_RTS);
......
...@@ -942,8 +942,14 @@ static irqreturn_t imx_uart_int(int irq, void *dev_id) ...@@ -942,8 +942,14 @@ static irqreturn_t imx_uart_int(int irq, void *dev_id)
struct imx_port *sport = dev_id; struct imx_port *sport = dev_id;
unsigned int usr1, usr2, ucr1, ucr2, ucr3, ucr4; unsigned int usr1, usr2, ucr1, ucr2, ucr3, ucr4;
irqreturn_t ret = IRQ_NONE; 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); usr1 = imx_uart_readl(sport, USR1);
usr2 = imx_uart_readl(sport, USR2); usr2 = imx_uart_readl(sport, USR2);
...@@ -1013,7 +1019,7 @@ static irqreturn_t imx_uart_int(int irq, void *dev_id) ...@@ -1013,7 +1019,7 @@ static irqreturn_t imx_uart_int(int irq, void *dev_id)
ret = IRQ_HANDLED; ret = IRQ_HANDLED;
} }
spin_unlock(&sport->port.lock); spin_unlock_irqrestore(&sport->port.lock, flags);
return ret; return ret;
} }
...@@ -2002,16 +2008,6 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count) ...@@ -2002,16 +2008,6 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count)
unsigned int ucr1; unsigned int ucr1;
unsigned long flags = 0; unsigned long flags = 0;
int locked = 1; 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) if (sport->port.sysrq)
locked = 0; locked = 0;
...@@ -2047,9 +2043,6 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count) ...@@ -2047,9 +2043,6 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count)
if (locked) if (locked)
spin_unlock_irqrestore(&sport->port.lock, flags); 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) ...@@ -2150,15 +2143,14 @@ imx_uart_console_setup(struct console *co, char *options)
retval = uart_set_options(&sport->port, co, baud, parity, bits, flow); retval = uart_set_options(&sport->port, co, baud, parity, bits, flow);
clk_disable(sport->clk_ipg);
if (retval) { if (retval) {
clk_unprepare(sport->clk_ipg); clk_disable_unprepare(sport->clk_ipg);
goto error_console; goto error_console;
} }
retval = clk_prepare(sport->clk_per); retval = clk_prepare_enable(sport->clk_per);
if (retval) if (retval)
clk_unprepare(sport->clk_ipg); clk_disable_unprepare(sport->clk_ipg);
error_console: error_console:
return retval; return retval;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment