summaryrefslogtreecommitdiff
path: root/arch/arm/plat-mxc/sdma/sdma.c
diff options
context:
space:
mode:
authorZeng Zhaoming <b32542@freescale.com>2011-01-26 10:35:15 +0800
committerAlan Tull <alan.tull@freescale.com>2011-01-27 10:50:15 -0600
commit27fdf7bae11978d21e8aba09bb635f49b07edd4a (patch)
tree8b1fca432377457b3f317b79fe853bc7da910c02 /arch/arm/plat-mxc/sdma/sdma.c
parent75c58543ebb278a4a7896548f39381a323f6715e (diff)
ENGR00138121 Fix system hangs when arecord/aplay continuouslyrel_imx_2.6.35_11.01.00
Sdma iapi start loading sdma script by write HSTART register as memory. When instruction reorder and IRQ delay may let the next synchronize operation wait forever. We change it by using writel() to access sdma registers, and introduce timeout to show this error. HSTART and STOP_STAT contain bits that are reset by hardware. So if we read-modify-write, we are in danger of setting a bit after SDMA has cleared it. The spec calls these registers "write-ones" register. So the ARM can write a 1 to any bit, but does not need to worry about clearing any bits that were previously set. SDMA hardware keeps track of all bits that were set. Signed-off-by: Zeng Zhaoming <b32542@freescale.com> Signed-off-by: Alan Tull <alan.tull@freescale.com>
Diffstat (limited to 'arch/arm/plat-mxc/sdma/sdma.c')
-rw-r--r--arch/arm/plat-mxc/sdma/sdma.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/arch/arm/plat-mxc/sdma/sdma.c b/arch/arm/plat-mxc/sdma/sdma.c
index 8a9e8e7faf48..7b3d7ae92eb8 100644
--- a/arch/arm/plat-mxc/sdma/sdma.c
+++ b/arch/arm/plat-mxc/sdma/sdma.c
@@ -134,9 +134,13 @@ static void sdma_init_sleep(int channel)
static void sdma_sleep_channel(int channel)
{
while ((iapi_SDMAIntr & (1 << channel)) == 0) {
- wait_event_interruptible(sdma_sleep_queue[channel],
- ((iapi_SDMAIntr & (1 << channel)) !=
- 0));
+ int timeout = 10; /* timeout 10ms */
+ timeout = wait_event_interruptible_timeout(
+ sdma_sleep_queue[channel],
+ ((iapi_SDMAIntr & (1 << channel)) !=
+ 0), timeout);
+ if (!timeout)
+ printk(KERN_WARNING "sdma channel timeout\n");
}
}