diff options
Diffstat (limited to 'recipes-kernel/linux/linux-fslc-imx-rt/0003-Work-around-CPU-stalls-in-the-imx-sdma-driver.patch')
-rw-r--r-- | recipes-kernel/linux/linux-fslc-imx-rt/0003-Work-around-CPU-stalls-in-the-imx-sdma-driver.patch | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-fslc-imx-rt/0003-Work-around-CPU-stalls-in-the-imx-sdma-driver.patch b/recipes-kernel/linux/linux-fslc-imx-rt/0003-Work-around-CPU-stalls-in-the-imx-sdma-driver.patch new file mode 100644 index 0000000..93200c6 --- /dev/null +++ b/recipes-kernel/linux/linux-fslc-imx-rt/0003-Work-around-CPU-stalls-in-the-imx-sdma-driver.patch | |||
@@ -0,0 +1,126 @@ | |||
1 | From f7cba8d49a980909cea48c5b9dcfefc6e13fef0b Mon Sep 17 00:00:00 2001 | ||
2 | From: =?UTF-8?q?Dominic=20Sacr=C3=A9?= <dominic.sacre@gmx.de> | ||
3 | Date: Fri, 29 Apr 2016 15:48:40 +0200 | ||
4 | Subject: [PATCH] Work around CPU stalls in the imx-sdma driver | ||
5 | MIME-Version: 1.0 | ||
6 | Content-Type: text/plain; charset=UTF-8 | ||
7 | Content-Transfer-Encoding: 8bit | ||
8 | |||
9 | Replace spinlocks with raw spinlocks. This prevents preemption during | ||
10 | the spinlock's critical section, as is the case on non PREEMPT_RT kernels. | ||
11 | |||
12 | Without this patch, the following error can occur, for example when | ||
13 | using the audio codec on an i.MX6Q SabreSD board: | ||
14 | |||
15 | INFO: rcu_preempt self-detected stall on CPU { 0} (t=2100 jiffies g=106 c=105 q=93) | ||
16 | CPU: 0 PID: 120 Comm: irq/34-sdma Not tainted 3.14.28-rt25-1.0.0_ga+g91cf351 #1 | ||
17 | [<80014a8c>] (unwind_backtrace) from [<8001173c>] (show_stack+0x10/0x14) | ||
18 | [<8001173c>] (show_stack) from [<806ee750>] (dump_stack+0x7c/0xc8) | ||
19 | [<806ee750>] (dump_stack) from [<800771c8>] (rcu_check_callbacks+0x454/0x888) | ||
20 | [<800771c8>] (rcu_check_callbacks) from [<80037f28>] (update_process_times+0x40/0x5c) | ||
21 | [<80037f28>] (update_process_times) from [<80082230>] (tick_sched_timer+0x4c/0x78) | ||
22 | [<80082230>] (tick_sched_timer) from [<8004bf30>] (__run_hrtimer.isra.34+0x74/0x124) | ||
23 | [<8004bf30>] (__run_hrtimer.isra.34) from [<8004cbb0>] (hrtimer_interrupt+0x154/0x3ac) | ||
24 | [<8004cbb0>] (hrtimer_interrupt) from [<80014464>] (twd_handler+0x30/0x38) | ||
25 | [<80014464>] (twd_handler) from [<8006fa2c>] (handle_percpu_devid_irq+0x6c/0x84) | ||
26 | [<8006fa2c>] (handle_percpu_devid_irq) from [<8006bc64>] (generic_handle_irq+0x2c/0x3c) | ||
27 | [<8006bc64>] (generic_handle_irq) from [<8000ed8c>] (handle_IRQ+0x40/0x90) | ||
28 | [<8000ed8c>] (handle_IRQ) from [<8000856c>] (gic_handle_irq+0x2c/0x5c) | ||
29 | [<8000856c>] (gic_handle_irq) from [<80012240>] (__irq_svc+0x40/0x84) | ||
30 | Exception stack(0xa840feb8 to 0xa840ff00) | ||
31 | fea0: a8007a28 00000002 | ||
32 | fec0: 00000001 0000a6a6 a80079c0 a8007a28 a83ea080 00000000 a80079c0 a83ea080 | ||
33 | fee0: 285190f0 00000000 00000000 a840ff00 8006d04c 806f3070 20030113 ffffffff | ||
34 | [<80012240>] (__irq_svc) from [<806f3070>] (_raw_spin_unlock_irq+0x20/0x60) | ||
35 | [<806f3070>] (_raw_spin_unlock_irq) from [<8006d04c>] (irq_finalize_oneshot.part.37+0x70/0xcc) | ||
36 | [<8006d04c>] (irq_finalize_oneshot.part.37) from [<8006d148>] (irq_forced_thread_fn+0x60/0x64) | ||
37 | [<8006d148>] (irq_forced_thread_fn) from [<8006d3dc>] (irq_thread+0x138/0x1a4) | ||
38 | [<8006d3dc>] (irq_thread) from [<8004913c>] (kthread+0xbc/0xd4) | ||
39 | [<8004913c>] (kthread) from [<8000e538>] (ret_from_fork+0x14/0x3c) | ||
40 | |||
41 | Upstream-Status: Pending | ||
42 | |||
43 | Signed-off-by: Dominic Sacré <dominic.sacre@gmx.de> | ||
44 | --- | ||
45 | drivers/dma/imx-sdma.c | 16 ++++++++-------- | ||
46 | 1 file changed, 8 insertions(+), 8 deletions(-) | ||
47 | |||
48 | diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c | ||
49 | index 31b7fed..bb7d6aa 100644 | ||
50 | --- a/drivers/dma/imx-sdma.c | ||
51 | +++ b/drivers/dma/imx-sdma.c | ||
52 | @@ -408,7 +408,7 @@ struct sdma_engine { | ||
53 | struct dma_device dma_device; | ||
54 | struct clk *clk_ipg; | ||
55 | struct clk *clk_ahb; | ||
56 | - spinlock_t channel_0_lock; | ||
57 | + raw_spinlock_t channel_0_lock; | ||
58 | u32 script_number; | ||
59 | struct sdma_script_start_addrs *script_addrs; | ||
60 | const struct sdma_driver_data *drvdata; | ||
61 | @@ -700,7 +700,7 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size, | ||
62 | return -ENOMEM; | ||
63 | } | ||
64 | |||
65 | - spin_lock_irqsave(&sdma->channel_0_lock, flags); | ||
66 | + raw_spin_lock_irqsave(&sdma->channel_0_lock, flags); | ||
67 | |||
68 | bd0->mode.command = C0_SETPM; | ||
69 | bd0->mode.status = BD_DONE | BD_INTR | BD_WRAP | BD_EXTD; | ||
70 | @@ -712,7 +712,7 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size, | ||
71 | |||
72 | ret = sdma_run_channel0(sdma); | ||
73 | |||
74 | - spin_unlock_irqrestore(&sdma->channel_0_lock, flags); | ||
75 | + raw_spin_unlock_irqrestore(&sdma->channel_0_lock, flags); | ||
76 | |||
77 | if (use_iram) | ||
78 | gen_pool_free(sdma->iram_pool, (unsigned long)buf_virt, size); | ||
79 | @@ -979,7 +979,7 @@ static int sdma_load_context(struct sdma_channel *sdmac) | ||
80 | dev_dbg(sdma->dev, "event_mask0 = 0x%08x\n", (u32)sdmac->event_mask[0]); | ||
81 | dev_dbg(sdma->dev, "event_mask1 = 0x%08x\n", (u32)sdmac->event_mask[1]); | ||
82 | |||
83 | - spin_lock_irqsave(&sdma->channel_0_lock, flags); | ||
84 | + raw_spin_lock_irqsave(&sdma->channel_0_lock, flags); | ||
85 | |||
86 | memset(context, 0, sizeof(*context)); | ||
87 | context->channel_state.pc = load_address; | ||
88 | @@ -1005,7 +1005,7 @@ static int sdma_load_context(struct sdma_channel *sdmac) | ||
89 | bd0->ext_buffer_addr = 2048 + (sizeof(*context) / 4) * channel; | ||
90 | ret = sdma_run_channel0(sdma); | ||
91 | |||
92 | - spin_unlock_irqrestore(&sdma->channel_0_lock, flags); | ||
93 | + raw_spin_unlock_irqrestore(&sdma->channel_0_lock, flags); | ||
94 | |||
95 | sdmac->context_loaded = true; | ||
96 | |||
97 | @@ -1019,7 +1019,7 @@ static int sdma_save_restore_context(struct sdma_engine *sdma, bool save) | ||
98 | unsigned long flags; | ||
99 | int ret; | ||
100 | |||
101 | - spin_lock_irqsave(&sdma->channel_0_lock, flags); | ||
102 | + raw_spin_lock_irqsave(&sdma->channel_0_lock, flags); | ||
103 | |||
104 | if (save) | ||
105 | bd0->mode.command = C0_GETDM; | ||
106 | @@ -1032,7 +1032,7 @@ static int sdma_save_restore_context(struct sdma_engine *sdma, bool save) | ||
107 | bd0->ext_buffer_addr = 2048; | ||
108 | ret = sdma_run_channel0(sdma); | ||
109 | |||
110 | - spin_unlock_irqrestore(&sdma->channel_0_lock, flags); | ||
111 | + raw_spin_unlock_irqrestore(&sdma->channel_0_lock, flags); | ||
112 | |||
113 | return ret; | ||
114 | } | ||
115 | @@ -2152,7 +2152,7 @@ static int sdma_probe(struct platform_device *pdev) | ||
116 | if (!sdma) | ||
117 | return -ENOMEM; | ||
118 | |||
119 | - spin_lock_init(&sdma->channel_0_lock); | ||
120 | + raw_spin_lock_init(&sdma->channel_0_lock); | ||
121 | |||
122 | sdma->dev = &pdev->dev; | ||
123 | sdma->drvdata = drvdata; | ||
124 | -- | ||
125 | 2.8.1 | ||
126 | |||