aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2011-06-23 08:39:00 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-07-01 18:36:42 -0400
commit9c00c6e7f9137b669e691219ea871eeb2c67c3d0 (patch)
tree0558798d5c7ebe8f072b6779685bb9cf0e6d6576 /drivers/tty
parentf2934c3c519b58f84082652447e62ab4a76c53ec (diff)
serial: mrst_max3110: initialize waitqueue earlier
The driver went to initialize its waitqueue at the start of the main processing thread. However, it is possible that this thread is not scheduled on a CPU before the write function is called which leads to a following error: BUG: spinlock bad magic on CPU#1, swapper/1 lock: f5f3ebdc, .magic: 00000000, .owner: <none>/-1, .owner_cpu: 0 Pid: 1, comm: swapper Not tainted 3.0.0-rc2+ #67 Call Trace: [<c1289663>] spin_bug+0xa3/0xf0 [<c12897ad>] do_raw_spin_lock+0x7d/0x150 [<c1490006>] ? init_idle+0x8d/0x20c [<c14963de>] _raw_spin_lock_irqsave+0x4e/0x60 [<c102f2bb>] ? __wake_up+0x1b/0x50 [<c102f2bb>] __wake_up+0x1b/0x50 [<c12d03bc>] ? uart_console_write+0x4c/0x60 [<c12d36c0>] ? serial_m3110_enable_ms+0x10/0x10 [<c12d3715>] serial_m3110_con_write+0x55/0x60 [<c1041575>] __call_console_drivers+0x75/0x90 [<c10415d9>] _call_console_drivers+0x49/0x80 [<c1041baa>] console_unlock+0xca/0x1f0 [<c10420ef>] vprintk+0x18f/0x4f0 [<c10787cb>] ? trace_hardirqs_on+0xb/0x10 [<c14928a3>] printk+0x18/0x1a [<c1042730>] register_console+0x2e0/0x350 [<c12d098e>] uart_add_one_port+0x33e/0x3d0 [<c10787cb>] ? trace_hardirqs_on+0xb/0x10 [<c103e10b>] ? try_to_wake_up+0x18b/0x250 [<c1485ba6>] serial_m3110_probe+0x1c2/0x1df [<c12d3d20>] ? serial_m3110_suspend+0x40/0x40 [<c1303db7>] spi_drv_probe+0x17/0x20 ... We fix this by initializing the waitqueue before the main thread is created. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/mrst_max3110.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/drivers/tty/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c
index 3be1b0dd6f22..a764bf99743b 100644
--- a/drivers/tty/serial/mrst_max3110.c
+++ b/drivers/tty/serial/mrst_max3110.c
@@ -421,7 +421,6 @@ static int max3110_main_thread(void *_max)
421 int ret = 0; 421 int ret = 0;
422 struct circ_buf *xmit = &max->con_xmit; 422 struct circ_buf *xmit = &max->con_xmit;
423 423
424 init_waitqueue_head(wq);
425 pr_info(PR_FMT "start main thread\n"); 424 pr_info(PR_FMT "start main thread\n");
426 425
427 do { 426 do {
@@ -838,6 +837,8 @@ static int __devinit serial_m3110_probe(struct spi_device *spi)
838 max->con_xmit.head = 0; 837 max->con_xmit.head = 0;
839 max->con_xmit.tail = 0; 838 max->con_xmit.tail = 0;
840 839
840 init_waitqueue_head(&max->wq);
841
841 max->main_thread = kthread_run(max3110_main_thread, 842 max->main_thread = kthread_run(max3110_main_thread,
842 max, "max3110_main"); 843 max, "max3110_main");
843 if (IS_ERR(max->main_thread)) { 844 if (IS_ERR(max->main_thread)) {