* ARM: iMX: lockup with irqs disabled in drivers/tty/imx.c
@ 2012-05-20 11:04 Michael McTernan
2012-06-04 16:54 ` manfred.schlaegl at gmx.at
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Michael McTernan @ 2012-05-20 11:04 UTC (permalink / raw)
To: linux-arm-kernel
Hi All,
I've found a lockup (interrupts disabled, infinite loop) in
drivers/tty/imx.c. This is on i.MX53 (Karo module), using the Karo BSP,
but having checked the arm-soc git tree, I think the bug is here too.
The Linaro tree(s) look the same.
I see the problem when the UART is setup to not have rtscts, so
port->have_rtscts = 0 in the driver. Additionally there is nothing
hanging on the serial port (in my case the peripheral isn't yet powered
up) so the rx line is low.
I can then trigger the lockup by simply booting the unit and issuing
"echo > /dev/ttymxc1". The same can be done on the other ports too.
Once locked, magic sys-req appears not to work, pinging the target is
dead etc...
The sequence of events in the kernel goes something like this:
1) imx_startup()
2) imx_int()
\-> imx_rxint()
|-> URXD0 returns 0xd800
\-> tty_insert_flip_char(tty, 0, TTY_BREAK)
...
3) imx_start_tx()
\-> imx_transmit_buffer()
Writes '^' '@'
4) imx_set_termios()
\-> hangs when waiting for USR2_TXDC
The problem is that UCR2_IRTS isn't yet set (that comes later in
imx_set_termios()), so the transmitter is waiting for the pin to be
asserted before it can serialise out from its FIFO and set the USR2_TXDC
bit. Since CTS/RTS will never come on this port, we end up spinning in
the following bit of code in imx_set_termios():948, having earlier
called spin_lock_irqsave():
while ( !(readl(sport->port.membase + USR2) & USR2_TXDC))
barrier();
The tx was a surprise to me; it looks like the receiver sees the low rx
pin as a break which then, I think, causes a local echo sending back
'^@', as per the following stack:
(imx_start_tx+0x60/0x12c) from (__uart_start+0x44/0x48)
(__uart_start+0x44/0x48) from (uart_start+0x20/0x4c)
(uart_start+0x20/0x4c) from (process_echoes+0x25c/0x260)
(process_echoes+0x25c/0x260) from (n_tty_receive_buf+0xc90/0xf04)
(n_tty_receive_buf+0xc90/0xf04) from (flush_to_ldisc+0xfc/0x1b0)
(flush_to_ldisc+0xfc/0x1b0) from (process_one_work+0x1fc/0x330)
(process_one_work+0x1fc/0x330) from (worker_thread+0x1d0/0x2f8)
(worker_thread+0x1d0/0x2f8) from (kthread+0x7c/0x84)
(kthread+0x7c/0x84) from (kernel_thread_exit+0x0/0x8)
Had imx_set_termios() been called prior to the imx_transmit_buffer(),
UCR2_IRTS would have been set and disaster avoided.
So one workaround is to set UCR2_IRTS in imx_startup() as per the patch
on the end of this email. This still wouldn't cater for other cases
where RTS/CTS is in use but not asserted by a peripheral (or the pin
mux/pad isn't correctly setup/routed), or that termios() is called while
data is blocked waiting for CTS/RTS. The drain loop should probably
implement a timeout and WARN(), but I'm not sure if it should also use a
completion and interrupt to be correct - other serial drivers don't
appear to do this though?
Anyway, the lockup is nasty, so hopefully can be triaged?
Regards,
Mike
Signed-off-by: Michael McTernan <Michael.McTernan.2001@cs.bris.ac.uk>
diff -Naurp orig/imx.c fixed/imx.c
--- orig/imx.c 2012-05-20 10:37:20.320041462 +0100
+++ fixed/imx.c 2012-05-20 11:18:28.512657377 +0100
@@ -741,6 +741,9 @@ static int imx_startup(struct uart_port
writel(temp, sport->port.membase + UCR1);
temp = readl(sport->port.membase + UCR2);
+ if (!sport->have_rtscts) {
+ temp |= UCR2_IRTS;
+ }
temp |= (UCR2_RXEN | UCR2_TXEN);
writel(temp, sport->port.membase + UCR2);
^ permalink raw reply [flat|nested] 5+ messages in thread
* ARM: iMX: lockup with irqs disabled in drivers/tty/imx.c
2012-05-20 11:04 ARM: iMX: lockup with irqs disabled in drivers/tty/imx.c Michael McTernan
@ 2012-06-04 16:54 ` manfred.schlaegl at gmx.at
2012-06-10 17:38 ` Fabio Estevam
2012-06-12 18:53 ` Fabio Estevam
2 siblings, 0 replies; 5+ messages in thread
From: manfred.schlaegl at gmx.at @ 2012-06-04 16:54 UTC (permalink / raw)
To: linux-arm-kernel
Hi!
Try to contact Sascha Hauer <sascha@saschahauer.de>.
see: http://www.pengutronix.de/software/linux-i.MX/index_de.html
Best Regards,
Manfred
^ permalink raw reply [flat|nested] 5+ messages in thread
* ARM: iMX: lockup with irqs disabled in drivers/tty/imx.c
2012-05-20 11:04 ARM: iMX: lockup with irqs disabled in drivers/tty/imx.c Michael McTernan
2012-06-04 16:54 ` manfred.schlaegl at gmx.at
@ 2012-06-10 17:38 ` Fabio Estevam
2012-06-12 18:53 ` Fabio Estevam
2 siblings, 0 replies; 5+ messages in thread
From: Fabio Estevam @ 2012-06-10 17:38 UTC (permalink / raw)
To: linux-arm-kernel
Hi Michael,
On Sun, May 20, 2012 at 8:04 AM, Michael McTernan
<Michael.McTernan.2001@cs.bris.ac.uk> wrote:
> Signed-off-by: Michael McTernan <Michael.McTernan.2001@cs.bris.ac.uk>
> diff -Naurp orig/imx.c fixed/imx.c
> --- orig/imx.c ?2012-05-20 10:37:20.320041462 +0100
> +++ fixed/imx.c 2012-05-20 11:18:28.512657377 +0100
> @@ -741,6 +741,9 @@ static int imx_startup(struct uart_port
> ? ? ? ?writel(temp, sport->port.membase + UCR1);
>
> ? ? ? ?temp = readl(sport->port.membase + UCR2);
> + ? ? ? if (!sport->have_rtscts) {
> + ? ? ? ? ? ? ? ? ? ? ? temp |= UCR2_IRTS;
> + ? ? ? }
> ? ? ? ?temp |= (UCR2_RXEN | UCR2_TXEN);
> ? ? ? ?writel(temp, sport->port.membase + UCR2);
Could you please re-submit this patch via git send-email and copy the
relevant lists and maintainers? (Hint: use ./scripts/get_maintainer.pl
)
You should also add kernel at pengutronix.de in Cc.
Regards,
Fabio Estevam
^ permalink raw reply [flat|nested] 5+ messages in thread
* ARM: iMX: lockup with irqs disabled in drivers/tty/imx.c
2012-05-20 11:04 ARM: iMX: lockup with irqs disabled in drivers/tty/imx.c Michael McTernan
2012-06-04 16:54 ` manfred.schlaegl at gmx.at
2012-06-10 17:38 ` Fabio Estevam
@ 2012-06-12 18:53 ` Fabio Estevam
2012-06-15 8:36 ` Michael McTernan
2 siblings, 1 reply; 5+ messages in thread
From: Fabio Estevam @ 2012-06-12 18:53 UTC (permalink / raw)
To: linux-arm-kernel
Michael,
On Sun, May 20, 2012 at 8:04 AM, Michael McTernan
<Michael.McTernan.2001@cs.bris.ac.uk> wrote:
> I can then trigger the lockup by simply booting the unit and issuing "echo >
> /dev/ttymxc1". ?The same can be done on the other ports too. Once locked,
> magic sys-req appears not to work, pinging the target is dead etc...
I did a 'echo "hello" > /dev/ttymxc1' and I am not able to see the
lockup on a mx31pdk running 3.5-rc1.
^ permalink raw reply [flat|nested] 5+ messages in thread
* ARM: iMX: lockup with irqs disabled in drivers/tty/imx.c
2012-06-12 18:53 ` Fabio Estevam
@ 2012-06-15 8:36 ` Michael McTernan
0 siblings, 0 replies; 5+ messages in thread
From: Michael McTernan @ 2012-06-15 8:36 UTC (permalink / raw)
To: linux-arm-kernel
On 06/12/2012 07:53 PM, Fabio Estevam wrote:
>> I can then trigger the lockup by simply booting the unit and issuing "echo>
>> /dev/ttymxc1". The same can be done on the other ports too. Once locked,
>> magic sys-req appears not to work, pinging the target is dead etc...
>
> I did a 'echo "hello"> /dev/ttymxc1' and I am not able to see the
> lockup on a mx31pdk running 3.5-rc1.
Depending on the setup and board, you may find that the RTS pin is
asserted so you don't hit the lockup, or more likely, that the Rx pin is
being driven by a RS232 level shifter so you don't get the early break
character which triggers the problem.
On my board the RTS will never be set and the Rx pin is pulled low so
generates a break condition and lockup reliably (prior to patching).
I don't have a i.MX31 reference manual or PDK schematic, but you may be
able to change the IO mux config to move the serial port Rx and RTS to
free pins with pull downs in order to reproduce the bug.
This bug is very much a corner case, and arguably the hardware
setup/board config isn't right, but for the sake of a few lines of code
it would seem better to avoid such as nasty lockup which isn't
straightforward to debug.
Regards,
Mike
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2012-06-15 8:36 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-05-20 11:04 ARM: iMX: lockup with irqs disabled in drivers/tty/imx.c Michael McTernan
2012-06-04 16:54 ` manfred.schlaegl at gmx.at
2012-06-10 17:38 ` Fabio Estevam
2012-06-12 18:53 ` Fabio Estevam
2012-06-15 8:36 ` Michael McTernan
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.