aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/samsung.c
diff options
context:
space:
mode:
authorMark Brown <broonie@sirena.org.uk>2009-04-14 06:06:49 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-04-15 05:01:02 -0400
commit41609ff43005de11dadfb0ccadb344f0e2966829 (patch)
treea84bf697eb3f1d2535c9f243e71308caa53939e6 /drivers/serial/samsung.c
parent9fa264d0d327a67db4913b400bcfb174d929054c (diff)
[ARM] 5449/1: S3C: Use disable_irq_nosync() to fix boot lockups
With 2.6.30-rc1 on SMDK6410 I experience a soft lockup on bootup when the Samsung serial driver attempts to disable the transmit interrupt from within the transmit interrupt handler: it calls disable_irq() which locks up due to attempting to synchronise with the running handler. Fix this by using disable_irq_nosync(). Also make the same change in the recieve path. Backtrace: [<c002a914>] (__irq_svc+0x34/0x80) from [<c00696c0>] (synchr) [<c00696c0>] (synchronize_irq+0xc/0xcc) from [<c018d434>] (s) [<c018d434>] (s3c24xx_serial_stop_tx+0x1c/0x3c) from [<c018d) [<c018d54c>] (s3c24xx_serial_tx_chars+0xf8/0x104) from [<c00) [<c0068bcc>] (handle_IRQ_event+0x74/0x118) from [<c006ab04>]) [<c006ab04>] (handle_level_irq+0x100/0x118) from [<c00349c4>) [<c00349c4>] (s3c_irq_demux_uart+0x94/0xc4) from [<c002a050>) [<c002a050>] (_text+0x50/0x6c) from [<c002a914>] (__irq_svc+) Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Acked-by: Ben Dooks <ben-linux@fluff.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/serial/samsung.c')
-rw-r--r--drivers/serial/samsung.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c
index 41ac94872b8d..e06686ae858b 100644
--- a/drivers/serial/samsung.c
+++ b/drivers/serial/samsung.c
@@ -127,7 +127,7 @@ static void s3c24xx_serial_stop_tx(struct uart_port *port)
127 struct s3c24xx_uart_port *ourport = to_ourport(port); 127 struct s3c24xx_uart_port *ourport = to_ourport(port);
128 128
129 if (tx_enabled(port)) { 129 if (tx_enabled(port)) {
130 disable_irq(ourport->tx_irq); 130 disable_irq_nosync(ourport->tx_irq);
131 tx_enabled(port) = 0; 131 tx_enabled(port) = 0;
132 if (port->flags & UPF_CONS_FLOW) 132 if (port->flags & UPF_CONS_FLOW)
133 s3c24xx_serial_rx_enable(port); 133 s3c24xx_serial_rx_enable(port);
@@ -154,7 +154,7 @@ static void s3c24xx_serial_stop_rx(struct uart_port *port)
154 154
155 if (rx_enabled(port)) { 155 if (rx_enabled(port)) {
156 dbg("s3c24xx_serial_stop_rx: port=%p\n", port); 156 dbg("s3c24xx_serial_stop_rx: port=%p\n", port);
157 disable_irq(ourport->rx_irq); 157 disable_irq_nosync(ourport->rx_irq);
158 rx_enabled(port) = 0; 158 rx_enabled(port) = 0;
159 } 159 }
160} 160}