summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/gigabeat-s
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2009-02-09 03:13:04 +0000
committerMichael Sevakis <jethead71@rockbox.org>2009-02-09 03:13:04 +0000
commit9f5687c9e633dcc2caef7351747af9ee86689590 (patch)
tree9cd9d98cc02d54ed60e803cea0a8d89b8933d060 /firmware/target/arm/imx31/gigabeat-s
parent305d86d045a6336de893003fb5cffe940fd76eab (diff)
Gigabeat S: The PCM lockout routines needed a bit of polishing.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19952 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s')
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c36
1 files changed, 14 insertions, 22 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c b/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c
index 60801262b4..c5ba27ace6 100644
--- a/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c
@@ -54,10 +54,10 @@ static void play_dma_callback(void)
size_t size;
pcm_more_callback_type get_more = pcm_callback_for_more;
- if (dma_play_data.locked)
+ if (dma_play_data.locked != 0)
{
/* Callback is locked out */
- dma_play_data.callback_pending = 1;
+ dma_play_data.callback_pending = dma_play_data.state;
return;
}
@@ -92,22 +92,16 @@ void pcm_play_unlock(void)
{
if (--dma_play_data.locked == 0 && dma_play_data.state != 0)
{
- bool pending = false;
int oldstatus = disable_irq_save();
-
- if (dma_play_data.callback_pending)
- {
- pending = true;
- dma_play_data.callback_pending = 0;
- }
-
+ int pending = dma_play_data.callback_pending;
+ dma_play_data.callback_pending = 0;
SSI_SIER1 |= SSI_SIER_TDMAE;
restore_irq(oldstatus);
/* Should an interrupt be forced instead? The upper pcm layer can
* call producer's callback in thread context so technically this is
* acceptable. */
- if (pending)
+ if (pending != 0)
play_dma_callback();
}
}
@@ -258,6 +252,7 @@ static void play_stop_pcm(void)
SSI_STCR1 &= ~SSI_STCR_TFEN0;
SSI_SCR1 &= ~(SSI_SCR_TE | SSI_SCR_SSIEN);
+ /* Set state before pending to prevent race with interrupt */
/* Do not enable DMA requests on unlock */
dma_play_data.state = 0;
dma_play_data.callback_pending = 0;
@@ -370,6 +365,7 @@ static struct dma_data dma_rec_data =
{
/* Initialize to a locked, stopped state */
.locked = 0,
+ .callback_pending = 0,
.state = 0
};
@@ -378,9 +374,9 @@ static void rec_dma_callback(void)
pcm_more_callback_type2 more_ready;
int status = 0;
- if (dma_rec_data.locked)
+ if (dma_rec_data.locked != 0)
{
- dma_rec_data.callback_pending = 1;
+ dma_rec_data.callback_pending = dma_rec_data.state;
return; /* Callback is locked out */
}
@@ -410,22 +406,16 @@ void pcm_rec_unlock(void)
{
if (--dma_rec_data.locked == 0 && dma_rec_data.state != 0)
{
- bool pending = false;
int oldstatus = disable_irq_save();
-
- if (dma_rec_data.callback_pending)
- {
- pending = true;
- dma_rec_data.callback_pending = 0;
- }
-
+ int pending = dma_rec_data.callback_pending;
+ dma_rec_data.callback_pending = 0;
SSI_SIER2 |= SSI_SIER_RDMAE;
restore_irq(oldstatus);
/* Should an interrupt be forced instead? The upper pcm layer can
* call consumer's callback in thread context so technically this is
* acceptable. */
- if (pending)
+ if (pending != 0)
rec_dma_callback();
}
}
@@ -457,6 +447,8 @@ void pcm_rec_dma_stop(void)
SSI_SCR2 &= ~SSI_SCR_RE; /* Disable RX */
SSI_SRCR2 &= ~SSI_SRCR_RFEN0; /* Disable RX FIFO */
+ /* Set state before pending to prevent race with interrupt */
+ /* Do not enable DMA requests on unlock */
dma_rec_data.state = 0;
dma_rec_data.callback_pending = 0;
}