summaryrefslogtreecommitdiff
path: root/arch/arm/plat-mxc/sdma
diff options
context:
space:
mode:
authorZeng Zhaoming <b32542@freescale.com>2010-11-17 16:06:49 +0800
committerLily Zhang <r58066@freescale.com>2010-11-22 09:39:26 +0800
commit03d7293a10614be9f3a55589b0c25ab80ed0a80d (patch)
treebbdf32a72250f456ffac577c25926789b74a3fee /arch/arm/plat-mxc/sdma
parentfd7de4624d694a57c56c995eedd7f3a8c37b1c28 (diff)
ENGR00133737 MXC SDMA: fix system hangs when play audio with irq threaded
When apply rt patch or turn on hardirq threaded in kernel, play audio by application with realtime schedule policy hangs the system. It is caused by: Requesting SDMA channel, a specific channel is used to load script and context from memory. This load phase also uses sdma to transfer, then poll a complete flag within a while(1) loop. When application with realtime schedule policy request sdma channel, it will preempt threaded irqs and prevent complete flag to be set. So a deadlock appears. Signed-off-by: Zeng Zhaoming <b32542@freescale.com>
Diffstat (limited to 'arch/arm/plat-mxc/sdma')
-rw-r--r--arch/arm/plat-mxc/sdma/iapi/src/iapiLow.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/arch/arm/plat-mxc/sdma/iapi/src/iapiLow.c b/arch/arm/plat-mxc/sdma/iapi/src/iapiLow.c
index 92d3fa4ebf6e..47611fe52743 100644
--- a/arch/arm/plat-mxc/sdma/iapi/src/iapiLow.c
+++ b/arch/arm/plat-mxc/sdma/iapi/src/iapiLow.c
@@ -33,6 +33,8 @@
/* ****************************************************************************
* Include File Section
*****************************************************************************/
+#include <linux/preempt.h>
+#include <linux/hardirq.h>
#include "epm.h"
#include "iapiLow.h"
@@ -118,8 +120,12 @@ iapi_ChangeCallbackISR(channelDescriptor *cd_p,
*/
void iapi_lowSynchChannel(unsigned char channel)
{
- while (!((1UL << channel) & iapi_SDMAIntr))
- ;
+ if (preempt_count() || in_interrupt()) {
+ while (!((1UL << channel) & iapi_SDMAIntr))
+ ;
+ } else
+ GOTO_SLEEP(channel);
+
iapi_SDMAIntr &= ~(1UL << channel);
}