diff options
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.c | 53 |
1 files changed, 17 insertions, 36 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 76789a7dbd..7304bdcff3 100644 --- a/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c +++ b/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c | |||
@@ -104,7 +104,7 @@ static void play_dma_callback(void) | |||
104 | PCM_DMAST_ERR_DMA : PCM_DMAST_OK; | 104 | PCM_DMAST_ERR_DMA : PCM_DMAST_OK; |
105 | const void *addr; | 105 | const void *addr; |
106 | size_t size; | 106 | size_t size; |
107 | 107 | ||
108 | if (pcm_play_dma_complete_callback(status, &addr, &size)) | 108 | if (pcm_play_dma_complete_callback(status, &addr, &size)) |
109 | { | 109 | { |
110 | play_start_dma(addr, size); | 110 | play_start_dma(addr, size); |
@@ -114,33 +114,20 @@ static void play_dma_callback(void) | |||
114 | 114 | ||
115 | void pcm_play_lock(void) | 115 | void pcm_play_lock(void) |
116 | { | 116 | { |
117 | /* Need to prevent DVFS from causing interrupt priority inversion if audio | ||
118 | * is locked and a DVFS interrupt fires, blocking reenabling of audio by a | ||
119 | * low-priority mode for at least the duration of the lengthy DVFS routine. | ||
120 | * Not really an issue with state changes but lockout when playing. | ||
121 | * | ||
122 | * Keep direct use of DVFS code away from here though. This could provide | ||
123 | * more services in the future anyway. */ | ||
124 | kernel_audio_locking(true); | ||
125 | ++dma_play_data.locked; | 117 | ++dma_play_data.locked; |
126 | } | 118 | } |
127 | 119 | ||
128 | void pcm_play_unlock(void) | 120 | void pcm_play_unlock(void) |
129 | { | 121 | { |
130 | if (--dma_play_data.locked == 0) | 122 | if (--dma_play_data.locked == 0 && dma_play_data.state != 0) |
131 | { | 123 | { |
132 | if (dma_play_data.state != 0) | 124 | int oldstatus = disable_irq_save(); |
133 | { | 125 | int pending = dma_play_data.callback_pending; |
134 | int oldstatus = disable_irq_save(); | 126 | dma_play_data.callback_pending = 0; |
135 | int pending = dma_play_data.callback_pending; | 127 | restore_irq(oldstatus); |
136 | dma_play_data.callback_pending = 0; | 128 | |
137 | restore_irq(oldstatus); | 129 | if (pending != 0) |
138 | 130 | play_dma_callback(); | |
139 | if (pending != 0) | ||
140 | play_dma_callback(); | ||
141 | } | ||
142 | |||
143 | kernel_audio_locking(false); | ||
144 | } | 131 | } |
145 | } | 132 | } |
146 | 133 | ||
@@ -368,26 +355,20 @@ static void rec_dma_callback(void) | |||
368 | 355 | ||
369 | void pcm_rec_lock(void) | 356 | void pcm_rec_lock(void) |
370 | { | 357 | { |
371 | kernel_audio_locking(true); | ||
372 | ++dma_rec_data.locked; | 358 | ++dma_rec_data.locked; |
373 | } | 359 | } |
374 | 360 | ||
375 | void pcm_rec_unlock(void) | 361 | void pcm_rec_unlock(void) |
376 | { | 362 | { |
377 | if (--dma_rec_data.locked == 0) | 363 | if (--dma_rec_data.locked == 0 && dma_rec_data.state != 0) |
378 | { | 364 | { |
379 | if (dma_rec_data.state != 0) | 365 | int oldstatus = disable_irq_save(); |
380 | { | 366 | int pending = dma_rec_data.callback_pending; |
381 | int oldstatus = disable_irq_save(); | 367 | dma_rec_data.callback_pending = 0; |
382 | int pending = dma_rec_data.callback_pending; | 368 | restore_irq(oldstatus); |
383 | dma_rec_data.callback_pending = 0; | 369 | |
384 | restore_irq(oldstatus); | 370 | if (pending != 0) |
385 | 371 | rec_dma_callback(); | |
386 | if (pending != 0) | ||
387 | rec_dma_callback(); | ||
388 | } | ||
389 | |||
390 | kernel_audio_locking(false); | ||
391 | } | 372 | } |
392 | } | 373 | } |
393 | 374 | ||