summaryrefslogtreecommitdiffstats
path: root/recipes-kernel/linux/linux-fslc-imx-rt/0003-Work-around-CPU-stalls-in-the-imx-sdma-driver.patch
diff options
context:
space:
mode:
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.patch126
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 @@
1From f7cba8d49a980909cea48c5b9dcfefc6e13fef0b Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Dominic=20Sacr=C3=A9?= <dominic.sacre@gmx.de>
3Date: Fri, 29 Apr 2016 15:48:40 +0200
4Subject: [PATCH] Work around CPU stalls in the imx-sdma driver
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9Replace spinlocks with raw spinlocks. This prevents preemption during
10the spinlock's critical section, as is the case on non PREEMPT_RT kernels.
11
12Without this patch, the following error can occur, for example when
13using the audio codec on an i.MX6Q SabreSD board:
14
15INFO: rcu_preempt self-detected stall on CPU { 0} (t=2100 jiffies g=106 c=105 q=93)
16CPU: 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)
30Exception stack(0xa840feb8 to 0xa840ff00)
31fea0: a8007a28 00000002
32fec0: 00000001 0000a6a6 a80079c0 a8007a28 a83ea080 00000000 a80079c0 a83ea080
33fee0: 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
41Upstream-Status: Pending
42
43Signed-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
48diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
49index 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--
1252.8.1
126