summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c')
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c51
1 files changed, 35 insertions, 16 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c
index 50c7da943e..c8c1283d12 100644
--- a/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c
+++ b/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c
@@ -109,20 +109,33 @@ static void play_dma_callback(void)
109 109
110void pcm_play_lock(void) 110void pcm_play_lock(void)
111{ 111{
112 /* Need to prevent DVFS from causing interrupt priority inversion if audio
113 * is locked and a DVFS interrupt fires, blocking reenabling of audio by a
114 * low-priority mode for at least the duration of the lengthy DVFS routine.
115 * Not really an issue with state changes but lockout when playing.
116 *
117 * Keep direct use of DVFS code away from here though. This could provide
118 * more services in the future anyway. */
119 kernel_audio_locking(true);
112 ++dma_play_data.locked; 120 ++dma_play_data.locked;
113} 121}
114 122
115void pcm_play_unlock(void) 123void pcm_play_unlock(void)
116{ 124{
117 if (--dma_play_data.locked == 0 && dma_play_data.state != 0) 125 if (--dma_play_data.locked == 0)
118 { 126 {
119 int oldstatus = disable_irq_save(); 127 if (dma_play_data.state != 0)
120 int pending = dma_play_data.callback_pending; 128 {
121 dma_play_data.callback_pending = 0; 129 int oldstatus = disable_irq_save();
122 restore_irq(oldstatus); 130 int pending = dma_play_data.callback_pending;
123 131 dma_play_data.callback_pending = 0;
124 if (pending != 0) 132 restore_irq(oldstatus);
125 play_dma_callback(); 133
134 if (pending != 0)
135 play_dma_callback();
136 }
137
138 kernel_audio_locking(false);
126 } 139 }
127} 140}
128 141
@@ -442,20 +455,26 @@ static void rec_dma_callback(void)
442 455
443void pcm_rec_lock(void) 456void pcm_rec_lock(void)
444{ 457{
458 kernel_audio_locking(true);
445 ++dma_rec_data.locked; 459 ++dma_rec_data.locked;
446} 460}
447 461
448void pcm_rec_unlock(void) 462void pcm_rec_unlock(void)
449{ 463{
450 if (--dma_rec_data.locked == 0 && dma_rec_data.state != 0) 464 if (--dma_rec_data.locked == 0)
451 { 465 {
452 int oldstatus = disable_irq_save(); 466 if (dma_rec_data.state != 0)
453 int pending = dma_rec_data.callback_pending; 467 {
454 dma_rec_data.callback_pending = 0; 468 int oldstatus = disable_irq_save();
455 restore_irq(oldstatus); 469 int pending = dma_rec_data.callback_pending;
456 470 dma_rec_data.callback_pending = 0;
457 if (pending != 0) 471 restore_irq(oldstatus);
458 rec_dma_callback(); 472
473 if (pending != 0)
474 rec_dma_callback();
475 }
476
477 kernel_audio_locking(false);
459 } 478 }
460} 479}
461 480