Skip to content

Commit de75803

Browse files
committed
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
2 parents a7f07fc + 425af48 commit de75803

3 files changed

Lines changed: 26 additions & 22 deletions

File tree

drivers/accessibility/speakup/spk_ttyio.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,25 @@ static int spk_ttyio_ldisc_open(struct tty_struct *tty)
4949

5050
if (!tty->ops->write)
5151
return -EOPNOTSUPP;
52+
53+
mutex_lock(&speakup_tty_mutex);
54+
if (speakup_tty) {
55+
mutex_unlock(&speakup_tty_mutex);
56+
return -EBUSY;
57+
}
5258
speakup_tty = tty;
5359

5460
ldisc_data = kmalloc(sizeof(*ldisc_data), GFP_KERNEL);
55-
if (!ldisc_data)
61+
if (!ldisc_data) {
62+
speakup_tty = NULL;
63+
mutex_unlock(&speakup_tty_mutex);
5664
return -ENOMEM;
65+
}
5766

5867
init_completion(&ldisc_data->completion);
5968
ldisc_data->buf_free = true;
6069
speakup_tty->disc_data = ldisc_data;
70+
mutex_unlock(&speakup_tty_mutex);
6171

6272
return 0;
6373
}

drivers/tty/serial/ar933x_uart.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -789,8 +789,10 @@ static int ar933x_uart_probe(struct platform_device *pdev)
789789
goto err_disable_clk;
790790

791791
up->gpios = mctrl_gpio_init(port, 0);
792-
if (IS_ERR(up->gpios) && PTR_ERR(up->gpios) != -ENOSYS)
793-
return PTR_ERR(up->gpios);
792+
if (IS_ERR(up->gpios) && PTR_ERR(up->gpios) != -ENOSYS) {
793+
ret = PTR_ERR(up->gpios);
794+
goto err_disable_clk;
795+
}
794796

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

drivers/tty/serial/imx.c

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -942,8 +942,14 @@ static irqreturn_t imx_uart_int(int irq, void *dev_id)
942942
struct imx_port *sport = dev_id;
943943
unsigned int usr1, usr2, ucr1, ucr2, ucr3, ucr4;
944944
irqreturn_t ret = IRQ_NONE;
945+
unsigned long flags = 0;
945946

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

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

1016-
spin_unlock(&sport->port.lock);
1022+
spin_unlock_irqrestore(&sport->port.lock, flags);
10171023

10181024
return ret;
10191025
}
@@ -2002,16 +2008,6 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count)
20022008
unsigned int ucr1;
20032009
unsigned long flags = 0;
20042010
int locked = 1;
2005-
int retval;
2006-
2007-
retval = clk_enable(sport->clk_per);
2008-
if (retval)
2009-
return;
2010-
retval = clk_enable(sport->clk_ipg);
2011-
if (retval) {
2012-
clk_disable(sport->clk_per);
2013-
return;
2014-
}
20152011

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

20482044
if (locked)
20492045
spin_unlock_irqrestore(&sport->port.lock, flags);
2050-
2051-
clk_disable(sport->clk_ipg);
2052-
clk_disable(sport->clk_per);
20532046
}
20542047

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

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

2153-
clk_disable(sport->clk_ipg);
21542146
if (retval) {
2155-
clk_unprepare(sport->clk_ipg);
2147+
clk_disable_unprepare(sport->clk_ipg);
21562148
goto error_console;
21572149
}
21582150

2159-
retval = clk_prepare(sport->clk_per);
2151+
retval = clk_prepare_enable(sport->clk_per);
21602152
if (retval)
2161-
clk_unprepare(sport->clk_ipg);
2153+
clk_disable_unprepare(sport->clk_ipg);
21622154

21632155
error_console:
21642156
return retval;

0 commit comments

Comments
 (0)