]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00287826 mxc: mlb: Fix MLB rcu stall issue when MITB is not set correctly
authorLuwei Zhou <b45643@freescale.com>
Wed, 13 Nov 2013 08:21:02 +0000 (16:21 +0800)
committerLuwei Zhou <b45643@freescale.com>
Wed, 13 Nov 2013 08:42:36 +0000 (16:42 +0800)
MLB lock and clock check has logic issue in code. The timeout cann't work and
it will cause rcu-stall.

Exception stack(0xdca21e68 to 0xdca21eb0)
1e60:                   00000001 00000000 ffffff7f 0000270f 00002710 0000ffc0
1e80: 00000000 00000004 00000002 00000001 00000001 7f003b50 f0378000 dca21eb0
1ea0: 7f003b50 7f0009cc 20000013 ffffffff
[<8000dc04>] (__irq_svc+0x44/0x58) from [<7f0009cc>] (mlb150_dev_unmute_syn_ch
[<7f0009cc>] (mlb150_dev_unmute_syn_ch+0x34/0xd4 [mxc_mlb150]) from [<7f002584
[<7f002584>] (mxc_mlb150_ioctl+0x85c/0x898 [mxc_mlb150]) from [<800db86c>] (do_
[<800db86c>] (do_vfs_ioctl+0x40c/0x5e4) from [<800dba7c>] (SyS_ioctl+0x38/0x64)
[<800dba7c>] (SyS_ioctl+0x38/0x64) from [<8000e000>] (ret_fast_syscall+0x0/0x48
INFO: rcu_sched self-detected stall on CPU
        0: (14684 ticks this GP) idle=fdf/140000000000001/0 softirq=1555/1555
         (t=14720 jiffies g=2 c=1 q=22)
CPU: 0 PID: 628 Comm: mxc_mlb150_test Not tainted 3.10.17-16837-g187ed79-dirty
[<80013d7c>] (unwind_backtrace+0x0/0xf4) from [<80011798>] (show_stack+0x10/0x
[<80011798>] (show_stack+0x10/0x14) from [<8008575c>] (rcu_check_callbacks+0x3
[<8008575c>] (rcu_check_callbacks+0x3d0/0x7f8) from [<80033884>] (update_proce
[<80033884>] (update_process_times+0x40/0x6c) from [<80064f48>] (tick_sched_ti
[<80064f48>] (tick_sched_timer+0x4c/0x78) from [<80048508>] (__run_hrtimer.isr
[<80048508>] (__run_hrtimer.isra.32+0x44/0xd4) from [<80048de4>] (hrtimer_inte
[<80048de4>] (hrtimer_interrupt+0x108/0x294) from [<800136f0>] (twd_handler+0x
[<800136f0>] (twd_handler+0x34/0x44) from [<80080208>] (handle_percpu_devid_ir
[<80080208>] (handle_percpu_devid_irq+0x6c/0x84) from [<8007c958>] (generic_ha
[<8007c958>] (generic_handle_irq+0x2c/0x3c) from [<8000e908>] (handle_IRQ+0x40
[<8000e908>] (handle_IRQ+0x40/0x90) from [<8000856c>] (gic_handle_irq+0x2c/0x5
[<8000856c>] (gic_handle_irq+0x2c/0x5c) from [<8000dc04>] (__irq_svc+0x44/0x5.

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

index daf578299601741bc51395fd16ef8d79fcfefb55..c81de3834a187c0d639ff74bf910ce52d35541bf 100755 (executable)
@@ -1483,7 +1483,7 @@ static s32 mlb150_dev_unmute_syn_ch(u32 rx_ch, u32 rx_cl, u32 tx_ch, u32 tx_cl)
         * APB or I/O clock cycle and repeat the check
         */
        while ((__raw_readl(mlb_base + REG_MLBC1) & MLBC1_CLKM)
-                       || timeout--)
+                       && --timeout)
                __raw_writel(~MLBC1_CLKM, mlb_base + REG_MLBC1);
 
        if (0 == timeout)
@@ -1492,7 +1492,7 @@ static s32 mlb150_dev_unmute_syn_ch(u32 rx_ch, u32 rx_cl, u32 tx_ch, u32 tx_cl)
        timeout = 10000;
        /* Poll for MLB lock (MLBC0.MLBLK = 1) */
        while (!(__raw_readl(mlb_base + REG_MLBC0) & MLBC0_MLBLK)
-                       || timeout--)
+                       && --timeout)
                ;
 
        if (0 == timeout)
@@ -1558,7 +1558,7 @@ static s32 mlb150_trans_complete_check(struct mlb_dev_info *pdevinfo)
 /*
  * Enable the MLB channel
  */
-static void mlb_channel_enable(struct mlb_data *drvdata,
+static s32 mlb_channel_enable(struct mlb_data *drvdata,
                                int chan_dev_id, int on)
 {
        struct mlb_dev_info *pdevinfo = drvdata->devinfo;
@@ -1568,6 +1568,7 @@ static void mlb_channel_enable(struct mlb_data *drvdata,
        u32 rx_ch = rx_chinfo->address;
        u32 tx_cl = tx_chinfo->cl;
        u32 rx_cl = rx_chinfo->cl;
+       s32 ret = 0;
 
        /*
         * setup the direction, enable, channel type,
@@ -1586,8 +1587,12 @@ static void mlb_channel_enable(struct mlb_data *drvdata,
                mlb150_dev_dump_ctr_tbl(0, tx_chinfo->cl + 1);
 #endif
                /* Synchronize and unmute synchrouous channel */
-               if (MLB_CTYPE_SYNC == ctype)
-                       mlb150_dev_unmute_syn_ch(rx_ch, rx_cl, tx_ch, tx_cl);
+               if (MLB_CTYPE_SYNC == ctype) {
+                       ret = mlb150_dev_unmute_syn_ch(rx_ch, rx_cl,
+                                                       tx_ch, tx_cl);
+                       if (ret)
+                               return ret;
+               }
 
                mlb150_dev_enable_ctr_write(0x0, ADT_RDY1 | ADT_DNE1 |
                                ADT_ERR1 | ADT_PS1 |
@@ -1619,6 +1624,8 @@ static void mlb_channel_enable(struct mlb_data *drvdata,
                if (pdevinfo->fps >= CLK_2048FS)
                        mlb150_disable_pll(drvdata);
        }
+
+       return 0;
 }
 
 /*
@@ -2035,7 +2042,8 @@ static long mxc_mlb150_ioctl(struct file *filp,
                        pr_debug("mxc_mlb150: channel alreadly startup\n");
                        break;
                }
-               mlb_channel_enable(drvdata, minor, 1);
+               if (mlb_channel_enable(drvdata, minor, 1))
+                       return -EFAULT;
                break;
        case MLB_CHAN_SHUTDOWN:
                if (atomic_read(&pdevinfo->on) == 0) {