]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00270037 mxc: mlb: Fix MLB crash when testing abnormally
authorLuwei Zhou <b45643@freescale.com>
Tue, 19 Nov 2013 09:32:35 +0000 (17:32 +0800)
committerLuwei Zhou <b45643@freescale.com>
Wed, 20 Nov 2013 05:43:23 +0000 (13:43 +0800)
If quit the test program via CTRL+c during the test and leaving
the MITB still running, kernel crash sometimes happen when launching
the test program for a second time. This patch fix this issue. The
main modification is:

* Initialize the wait queue head dynamically not statically
* Enable/Disalbe IRQ when necessary

Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = 80004000
[00000000] *pgd=00000000
Internal error: Oops: 80000007 [#1] SMP ARM
Modules linked in: mxc_mlb150
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.10.17-16879-g5d48ab5 #227
task: 80c2d908 ti: 80c22000 task.ti: 80c22000
PC is at 0x0
LR is at __wake_up_common+0x54/0x94
pc : [<00000000>]    lr : [<8004b9fc>]    psr: 90000193
sp : 80c23e18  ip : dc86ff1c  fp : 80c23e44
r10: 00000000  r9 : 00000001  r8 : 00000000
r7 : 00000000  r6 : 7f002fe0  r5 : 7f0017fc  r4 : dcaff0f4
r3 : 00000000  r2 : 00000000  r1 : 00000001  r0 : dc86ff1c
Flags: NzcV  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
Control: 10c53c7d  Table: 6c90004a  DAC: 00000015
Process swapper/0 (pid: 0, stack limit = 0x80c22238)
Stack: (0x80c23e18 to 0x80c24000)
3e00:                                                       00000000 00000001
3e20: dc1d14c0 7f002fdc 20000193 00000001 00000001 00000000 00000000 80c7018e
3e40: 80c23e6c 8004bbf4 00000000 8004bbf4 00000004 0091a840 7f002f80 7f002e1c
3e60: 00000004 fffffff9 00000001 7f001054 ffffae63 00000009 0000005a 00000000
3e80: ffffffff 00000010 00000095 00000000 00000000 00000095 dc011180 7f001168
3ea0: dc482e40 80073c08 00000015 80c2a770 80c1e7e0 dc011180 00000095 00000000
3ec0: f4000100 00000000 00000000 80c22000 80c2a4d8 80073d70 00000000 dc011180
3ee0: 00000095 80076ae8 00000095 800733d0 80c1ee3c 8000e848 f400010c 80c2a8b8
3f00: 80c23f20 80008570 8005a15c 804299d0 60000013 ffffffff 80c23f54 8000dbc0
3f20: 80c23f68 0000005a 3437dc5e 00000015 34373d83 00000015 81aef080 80c30050
3f40: 00000000 00000000 80c22000 80c2a4d8 00000017 80c23f68 8005a15c 804299d0
3f60: 60000013 ffffffff 3437dc5e 00000015 80cc41a4 806152ac 81aef080 80cc41a4
3f80: 00000000 80c30050 00000000 80429b10 00000001 80c7017a 80c2a524 806152ac
3fa0: 80c22000 80c7017a 80c22000 8000eb7c 00067162 800599f0 000000d9 80c12ef0
3fc0: 00000000 80bd6a9c ffffffff ffffffff 80bd6548 00000000 00000000 80c12ef0
3fe0: 10c53c7d 80c2a4a0 80c12eec 80c2e6ec 1000406a 10008074 00000000 00000000
[<8004b9fc>] (__wake_up_common+0x54/0x94) from [<8004bbf4>] (__wake_up+0x3c/0x50)
[<8004bbf4>] (__wake_up+0x3c/0x50) from [<7f001054>] (mlb_tx_isr+0xa0/0xf4 [mxc_mlb150])
[<7f001054>] (mlb_tx_isr+0xa0/0xf4 [mxc_mlb150]) from [<7f001168>] (mlb_ahb_isr+0xc0/0x134 [mxc_mlb150])
[<7f001168>] (mlb_ahb_isr+0xc0/0x134 [mxc_mlb150]) from [<80073c08>] (handle_irq_event_percpu+0x54/0x17c)
[<80073c08>] (handle_irq_event_percpu+0x54/0x17c) from [<80073d70>] (handle_irq_event+0x40/0x60)
[<80073d70>] (handle_irq_event+0x40/0x60) from [<80076ae8>] (handle_fasteoi_irq+0x80/0x158)
[<80076ae8>] (handle_fasteoi_irq+0x80/0x158) from [<800733d0>] (generic_handle_irq+0x2c/0x3c)
[<800733d0>] (generic_handle_irq+0x2c/0x3c) from [<8000e848>] (handle_IRQ+0x40/0x90)
[<8000e848>] (handle_IRQ+0x40/0x90) from [<80008570>] (gic_handle_irq+0x2c/0x5c)
[<80008570>] (gic_handle_irq+0x2c/0x5c) from [<8000dbc0>] (__irq_svc+0x40/0x50

Signed-off-by: Luwei Zhou <b45643@freescale.com>
drivers/mxc/mlb/mxc_mlb150.c

index c81de3834a187c0d639ff74bf910ce52d35541bf..57708f1267dcea6d1382b2e48fce225857753823 100755 (executable)
@@ -441,8 +441,6 @@ static struct mlb_dev_info mlb_devinfo[MLB_MINOR_DEVICES] = {
        .buf_size = CH_SYNC_BUF_SZ,
        .on = ATOMIC_INIT(0),
        .opencnt = ATOMIC_INIT(0),
-       .rx_wq = __WAIT_QUEUE_HEAD_INITIALIZER(mlb_devinfo[0].rx_wq),
-       .tx_wq = __WAIT_QUEUE_HEAD_INITIALIZER(mlb_devinfo[0].tx_wq),
        .event_lock = __SPIN_LOCK_UNLOCKED(mlb_devinfo[0].event_lock),
        },
        {
@@ -474,8 +472,6 @@ static struct mlb_dev_info mlb_devinfo[MLB_MINOR_DEVICES] = {
        .buf_size = CH_CTRL_BUF_SZ,
        .on = ATOMIC_INIT(0),
        .opencnt = ATOMIC_INIT(0),
-       .rx_wq = __WAIT_QUEUE_HEAD_INITIALIZER(mlb_devinfo[1].rx_wq),
-       .tx_wq = __WAIT_QUEUE_HEAD_INITIALIZER(mlb_devinfo[1].tx_wq),
        .event_lock = __SPIN_LOCK_UNLOCKED(mlb_devinfo[1].event_lock),
        },
        {
@@ -507,8 +503,6 @@ static struct mlb_dev_info mlb_devinfo[MLB_MINOR_DEVICES] = {
        .buf_size = CH_ASYNC_BUF_SZ,
        .on = ATOMIC_INIT(0),
        .opencnt = ATOMIC_INIT(0),
-       .rx_wq = __WAIT_QUEUE_HEAD_INITIALIZER(mlb_devinfo[2].rx_wq),
-       .tx_wq = __WAIT_QUEUE_HEAD_INITIALIZER(mlb_devinfo[2].tx_wq),
        .event_lock = __SPIN_LOCK_UNLOCKED(mlb_devinfo[2].event_lock),
        },
        {
@@ -540,8 +534,6 @@ static struct mlb_dev_info mlb_devinfo[MLB_MINOR_DEVICES] = {
        .buf_size = CH_ISOC_BUF_SZ,
        .on = ATOMIC_INIT(0),
        .opencnt = ATOMIC_INIT(0),
-       .rx_wq = __WAIT_QUEUE_HEAD_INITIALIZER(mlb_devinfo[3].rx_wq),
-       .tx_wq = __WAIT_QUEUE_HEAD_INITIALIZER(mlb_devinfo[3].tx_wq),
        .event_lock = __SPIN_LOCK_UNLOCKED(mlb_devinfo[3].event_lock),
        .isoc_blksz = CH_ISOC_BLK_SIZE_188,
        },
@@ -1555,6 +1547,22 @@ static s32 mlb150_trans_complete_check(struct mlb_dev_info *pdevinfo)
        return 0;
 }
 
+/*
+ * Enable/Disable the MLB IRQ
+ */
+static void mxc_mlb150_irq_enable(struct mlb_data *drvdata, u8 enable)
+{
+       if (enable) {
+               enable_irq(drvdata->irq_ahb0);
+               enable_irq(drvdata->irq_ahb1);
+               enable_irq(drvdata->irq_mlb);
+       } else {
+               disable_irq(drvdata->irq_ahb0);
+               disable_irq(drvdata->irq_ahb1);
+               disable_irq(drvdata->irq_mlb);
+       }
+}
+
 /*
  * Enable the MLB channel
  */
@@ -1967,8 +1975,12 @@ static int mxc_mlb150_open(struct inode *inode, struct file *filp)
        pdevinfo->ex_event = 0;
        pdevinfo->tx_ok = 0;
 
+       init_waitqueue_head(&pdevinfo->rx_wq);
+       init_waitqueue_head(&pdevinfo->tx_wq);
+
        drvdata = container_of(inode->i_cdev, struct mlb_data, cdev);
        drvdata->devinfo = pdevinfo;
+       mxc_mlb150_irq_enable(drvdata, 1);
        filp->private_data = drvdata;
 
        return 0;
@@ -1981,6 +1993,7 @@ static int mxc_mlb150_release(struct inode *inode, struct file *filp)
        struct mlb_dev_info *pdevinfo = drvdata->devinfo;
 
        minor = MINOR(inode->i_rdev);
+       mxc_mlb150_irq_enable(drvdata, 0);
 
 #ifdef DEBUG
        mlb150_dev_dump_reg();
@@ -2633,6 +2646,7 @@ static int mxc_mlb150_probe(struct platform_device *pdev)
        }
 
        drvdata->devinfo = NULL;
+       mxc_mlb150_irq_enable(drvdata, 0);
        platform_set_drvdata(pdev, drvdata);
        return 0;