diff options
author | Mika Westerberg <mika.westerberg@linux.intel.com> | 2011-06-23 13:39:00 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-06-23 08:54:10 -0700 |
commit | 33b1e6939f5c37ab8e64280fd3d54046607b5c80 (patch) | |
tree | c53385b58148cc1bc397e67afafaef6e5ebc898b /drivers/tty | |
parent | 0bb04bf3dfdfe1c981087cdfb0d9d772c3a0ba55 (diff) | |
download | op-kernel-dev-33b1e6939f5c37ab8e64280fd3d54046607b5c80.zip op-kernel-dev-33b1e6939f5c37ab8e64280fd3d54046607b5c80.tar.gz |
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
[<c14963de>] _raw_spin_lock_irqsave+0x4e/0x60
[<c102f2bb>] __wake_up+0x1b/0x50
[<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
[<c14928a3>] printk+0x18/0x1a
[<c1042730>] register_console+0x2e0/0x350
[<c12d098e>] uart_add_one_port+0x33e/0x3d0
[<c1485ba6>] serial_m3110_probe+0x1c2/0x1df
[<c1303db7>] spi_drv_probe+0x17/0x20
...
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: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/mrst_max3110.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/drivers/tty/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c index 3be1b0d..a764bf9 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) int ret = 0; struct circ_buf *xmit = &max->con_xmit; - init_waitqueue_head(wq); pr_info(PR_FMT "start main thread\n"); do { @@ -838,6 +837,8 @@ static int __devinit serial_m3110_probe(struct spi_device *spi) max->con_xmit.head = 0; max->con_xmit.tail = 0; + init_waitqueue_head(&max->wq); + max->main_thread = kthread_run(max3110_main_thread, max, "max3110_main"); if (IS_ERR(max->main_thread)) { |