From: Luwei Zhou Date: Wed, 13 Nov 2013 08:21:02 +0000 (+0800) Subject: ENGR00287826 mxc: mlb: Fix MLB rcu stall issue when MITB is not set correctly X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=34965e33576c3f7c6b368769bf6bc44b13e4e9e6;p=karo-tx-linux.git ENGR00287826 mxc: mlb: Fix MLB rcu stall issue when MITB is not set correctly 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 --- diff --git a/drivers/mxc/mlb/mxc_mlb150.c b/drivers/mxc/mlb/mxc_mlb150.c index daf578299601..c81de3834a18 100755 --- a/drivers/mxc/mlb/mxc_mlb150.c +++ b/drivers/mxc/mlb/mxc_mlb150.c @@ -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) {