diff options
| -rw-r--r-- | recipes-kernel/linux/linux-imx-rt-3.14.28/0004-imx-sdma-channel-use-raw-spinlock.patch | 95 | ||||
| -rw-r--r-- | recipes-kernel/linux/linux-imx-rt_3.14.28.bb | 1 |
2 files changed, 96 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-imx-rt-3.14.28/0004-imx-sdma-channel-use-raw-spinlock.patch b/recipes-kernel/linux/linux-imx-rt-3.14.28/0004-imx-sdma-channel-use-raw-spinlock.patch new file mode 100644 index 000000000..da36213cf --- /dev/null +++ b/recipes-kernel/linux/linux-imx-rt-3.14.28/0004-imx-sdma-channel-use-raw-spinlock.patch | |||
| @@ -0,0 +1,95 @@ | |||
| 1 | Work around CPU stalls in the imx-sdma driver by replacing spinlocks | ||
| 2 | with raw spinlocks. This prevents preemption during the spinlock's | ||
| 3 | critical section, as is the case on non PREEMPT_RT kernels. | ||
| 4 | |||
| 5 | Without this patch, the following error can occur, for example when | ||
| 6 | using the audio codec on an iMX6Q Sabre SD board: | ||
| 7 | |||
| 8 | INFO: rcu_preempt self-detected stall on CPU { 0} (t=2100 jiffies g=106 c=105 q=93) | ||
| 9 | CPU: 0 PID: 120 Comm: irq/34-sdma Not tainted 3.14.28-rt25-1.0.0_ga+g91cf351 #1 | ||
| 10 | [<80014a8c>] (unwind_backtrace) from [<8001173c>] (show_stack+0x10/0x14) | ||
| 11 | [<8001173c>] (show_stack) from [<806ee750>] (dump_stack+0x7c/0xc8) | ||
| 12 | [<806ee750>] (dump_stack) from [<800771c8>] (rcu_check_callbacks+0x454/0x888) | ||
| 13 | [<800771c8>] (rcu_check_callbacks) from [<80037f28>] (update_process_times+0x40/0x5c) | ||
| 14 | [<80037f28>] (update_process_times) from [<80082230>] (tick_sched_timer+0x4c/0x78) | ||
| 15 | [<80082230>] (tick_sched_timer) from [<8004bf30>] (__run_hrtimer.isra.34+0x74/0x124) | ||
| 16 | [<8004bf30>] (__run_hrtimer.isra.34) from [<8004cbb0>] (hrtimer_interrupt+0x154/0x3ac) | ||
| 17 | [<8004cbb0>] (hrtimer_interrupt) from [<80014464>] (twd_handler+0x30/0x38) | ||
| 18 | [<80014464>] (twd_handler) from [<8006fa2c>] (handle_percpu_devid_irq+0x6c/0x84) | ||
| 19 | [<8006fa2c>] (handle_percpu_devid_irq) from [<8006bc64>] (generic_handle_irq+0x2c/0x3c) | ||
| 20 | [<8006bc64>] (generic_handle_irq) from [<8000ed8c>] (handle_IRQ+0x40/0x90) | ||
| 21 | [<8000ed8c>] (handle_IRQ) from [<8000856c>] (gic_handle_irq+0x2c/0x5c) | ||
| 22 | [<8000856c>] (gic_handle_irq) from [<80012240>] (__irq_svc+0x40/0x84) | ||
| 23 | Exception stack(0xa840feb8 to 0xa840ff00) | ||
| 24 | fea0: a8007a28 00000002 | ||
| 25 | fec0: 00000001 0000a6a6 a80079c0 a8007a28 a83ea080 00000000 a80079c0 a83ea080 | ||
| 26 | fee0: 285190f0 00000000 00000000 a840ff00 8006d04c 806f3070 20030113 ffffffff | ||
| 27 | [<80012240>] (__irq_svc) from [<806f3070>] (_raw_spin_unlock_irq+0x20/0x60) | ||
| 28 | [<806f3070>] (_raw_spin_unlock_irq) from [<8006d04c>] (irq_finalize_oneshot.part.37+0x70/0xcc) | ||
| 29 | [<8006d04c>] (irq_finalize_oneshot.part.37) from [<8006d148>] (irq_forced_thread_fn+0x60/0x64) | ||
| 30 | [<8006d148>] (irq_forced_thread_fn) from [<8006d3dc>] (irq_thread+0x138/0x1a4) | ||
| 31 | [<8006d3dc>] (irq_thread) from [<8004913c>] (kthread+0xbc/0xd4) | ||
| 32 | [<8004913c>] (kthread) from [<8000e538>] (ret_from_fork+0x14/0x3c) | ||
| 33 | |||
| 34 | Upstream-Status: Pending | ||
| 35 | |||
| 36 | Signed-off-by: Dominic Sacré <dominic.sacre@gmx.de> | ||
| 37 | |||
| 38 | diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c | ||
| 39 | index bae2ea8..74ff5a0 100644 | ||
| 40 | --- a/drivers/dma/imx-sdma.c | ||
| 41 | +++ b/drivers/dma/imx-sdma.c | ||
| 42 | @@ -343,7 +343,7 @@ struct sdma_engine { | ||
| 43 | struct dma_device dma_device; | ||
| 44 | struct clk *clk_ipg; | ||
| 45 | struct clk *clk_ahb; | ||
| 46 | - spinlock_t channel_0_lock; | ||
| 47 | + raw_spinlock_t channel_0_lock; | ||
| 48 | u32 script_number; | ||
| 49 | struct sdma_script_start_addrs *script_addrs; | ||
| 50 | const struct sdma_driver_data *drvdata; | ||
| 51 | @@ -593,7 +593,7 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size, | ||
| 52 | return -ENOMEM; | ||
| 53 | } | ||
| 54 | |||
| 55 | - spin_lock_irqsave(&sdma->channel_0_lock, flags); | ||
| 56 | + raw_spin_lock_irqsave(&sdma->channel_0_lock, flags); | ||
| 57 | |||
| 58 | bd0->mode.command = C0_SETPM; | ||
| 59 | bd0->mode.status = BD_DONE | BD_INTR | BD_WRAP | BD_EXTD; | ||
| 60 | @@ -605,7 +605,7 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size, | ||
| 61 | |||
| 62 | ret = sdma_run_channel0(sdma); | ||
| 63 | |||
| 64 | - spin_unlock_irqrestore(&sdma->channel_0_lock, flags); | ||
| 65 | + raw_spin_unlock_irqrestore(&sdma->channel_0_lock, flags); | ||
| 66 | |||
| 67 | if (use_iram) | ||
| 68 | gen_pool_free(sdma->iram_pool, (unsigned long)buf_virt, size); | ||
| 69 | @@ -880,7 +880,7 @@ static int sdma_load_context(struct sdma_channel *sdmac) | ||
| 70 | dev_dbg(sdma->dev, "event_mask0 = 0x%08x\n", (u32)sdmac->event_mask[0]); | ||
| 71 | dev_dbg(sdma->dev, "event_mask1 = 0x%08x\n", (u32)sdmac->event_mask[1]); | ||
| 72 | |||
| 73 | - spin_lock_irqsave(&sdma->channel_0_lock, flags); | ||
| 74 | + raw_spin_lock_irqsave(&sdma->channel_0_lock, flags); | ||
| 75 | |||
| 76 | memset(context, 0, sizeof(*context)); | ||
| 77 | context->channel_state.pc = load_address; | ||
| 78 | @@ -906,7 +906,7 @@ static int sdma_load_context(struct sdma_channel *sdmac) | ||
| 79 | bd0->ext_buffer_addr = 2048 + (sizeof(*context) / 4) * channel; | ||
| 80 | ret = sdma_run_channel0(sdma); | ||
| 81 | |||
| 82 | - spin_unlock_irqrestore(&sdma->channel_0_lock, flags); | ||
| 83 | + raw_spin_unlock_irqrestore(&sdma->channel_0_lock, flags); | ||
| 84 | |||
| 85 | return ret; | ||
| 86 | } | ||
| 87 | @@ -1881,7 +1881,7 @@ static int __init sdma_probe(struct platform_device *pdev) | ||
| 88 | if (!sdma) | ||
| 89 | return -ENOMEM; | ||
| 90 | |||
| 91 | - spin_lock_init(&sdma->channel_0_lock); | ||
| 92 | + raw_spin_lock_init(&sdma->channel_0_lock); | ||
| 93 | |||
| 94 | sdma->dev = &pdev->dev; | ||
| 95 | sdma->drvdata = drvdata; | ||
diff --git a/recipes-kernel/linux/linux-imx-rt_3.14.28.bb b/recipes-kernel/linux/linux-imx-rt_3.14.28.bb index f5cb58060..b9a8bf0c2 100644 --- a/recipes-kernel/linux/linux-imx-rt_3.14.28.bb +++ b/recipes-kernel/linux/linux-imx-rt_3.14.28.bb | |||
| @@ -23,6 +23,7 @@ SRC_URI += "\ | |||
| 23 | file://0001-fix-build.patch \ | 23 | file://0001-fix-build.patch \ |
| 24 | file://0002-fix-build-with-rt-enabled.patch \ | 24 | file://0002-fix-build-with-rt-enabled.patch \ |
| 25 | file://0003-no-split-ptlocks.patch \ | 25 | file://0003-no-split-ptlocks.patch \ |
| 26 | file://0004-imx-sdma-channel-use-raw-spinlock.patch \ | ||
| 26 | " | 27 | " |
| 27 | 28 | ||
| 28 | SRC_URI[rt-patch1.md5sum] = "28bfd1e14ccab1ea1fb48f56f982d80c" | 29 | SRC_URI[rt-patch1.md5sum] = "28bfd1e14ccab1ea1fb48f56f982d80c" |
