aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-06-16 11:38:40 -0400
committerTakashi Iwai <tiwai@suse.de>2009-06-16 11:38:40 -0400
commit3d2aa66ddaa3008ae2c71bca07eb5e8b08170c4a (patch)
tree4d9bfc4017f038a7f94358c4061afcb264ba6d08 /sound
parent21ce3cd63365b0d07794adeb4325944bfa86fb4e (diff)
parent8dca419721d188bfee5f19fad45275856c619a5c (diff)
Merge branch 'topic/ctxfi' into for-linus
* topic/ctxfi: ALSA: ctxfi - Fix deadlock with xfi-timer ALSA: ctxfi - Replace atc lock to mutex
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/ctxfi/ctatc.c22
-rw-r--r--sound/pci/ctxfi/ctatc.h4
-rw-r--r--sound/pci/ctxfi/cttimer.c18
3 files changed, 21 insertions, 23 deletions
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index 80fb2baed7a7..b0adc8094009 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -259,7 +259,6 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
259 int n_amixer = apcm->substream->runtime->channels, i = 0; 259 int n_amixer = apcm->substream->runtime->channels, i = 0;
260 int device = apcm->substream->pcm->device; 260 int device = apcm->substream->pcm->device;
261 unsigned int pitch; 261 unsigned int pitch;
262 unsigned long flags;
263 262
264 if (NULL != apcm->src) { 263 if (NULL != apcm->src) {
265 /* Prepared pcm playback */ 264 /* Prepared pcm playback */
@@ -311,10 +310,10 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
311 src = apcm->src; 310 src = apcm->src;
312 for (i = 0; i < n_amixer; i++) { 311 for (i = 0; i < n_amixer; i++) {
313 amixer = apcm->amixers[i]; 312 amixer = apcm->amixers[i];
314 spin_lock_irqsave(&atc->atc_lock, flags); 313 mutex_lock(&atc->atc_mutex);
315 amixer->ops->setup(amixer, &src->rsc, 314 amixer->ops->setup(amixer, &src->rsc,
316 INIT_VOL, atc->pcm[i+device*2]); 315 INIT_VOL, atc->pcm[i+device*2]);
317 spin_unlock_irqrestore(&atc->atc_lock, flags); 316 mutex_unlock(&atc->atc_mutex);
318 src = src->ops->next_interleave(src); 317 src = src->ops->next_interleave(src);
319 if (NULL == src) 318 if (NULL == src)
320 src = apcm->src; 319 src = apcm->src;
@@ -865,7 +864,6 @@ static int
865spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm) 864spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm)
866{ 865{
867 struct dao *dao = container_of(atc->daios[SPDIFOO], struct dao, daio); 866 struct dao *dao = container_of(atc->daios[SPDIFOO], struct dao, daio);
868 unsigned long flags;
869 unsigned int rate = apcm->substream->runtime->rate; 867 unsigned int rate = apcm->substream->runtime->rate;
870 unsigned int status; 868 unsigned int status;
871 int err; 869 int err;
@@ -885,7 +883,7 @@ spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm)
885 return -ENOENT; 883 return -ENOENT;
886 } 884 }
887 885
888 spin_lock_irqsave(&atc->atc_lock, flags); 886 mutex_lock(&atc->atc_mutex);
889 dao->ops->get_spos(dao, &status); 887 dao->ops->get_spos(dao, &status);
890 if (((status >> 24) & IEC958_AES3_CON_FS) != iec958_con_fs) { 888 if (((status >> 24) & IEC958_AES3_CON_FS) != iec958_con_fs) {
891 status &= ((~IEC958_AES3_CON_FS) << 24); 889 status &= ((~IEC958_AES3_CON_FS) << 24);
@@ -895,7 +893,7 @@ spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm)
895 } 893 }
896 if ((rate != atc->pll_rate) && (32000 != rate)) 894 if ((rate != atc->pll_rate) && (32000 != rate))
897 err = atc_pll_init(atc, rate); 895 err = atc_pll_init(atc, rate);
898 spin_unlock_irqrestore(&atc->atc_lock, flags); 896 mutex_unlock(&atc->atc_mutex);
899 897
900 return err; 898 return err;
901} 899}
@@ -908,7 +906,6 @@ spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
908 struct dao *dao; 906 struct dao *dao;
909 int err; 907 int err;
910 int i; 908 int i;
911 unsigned long flags;
912 909
913 if (NULL != apcm->src) 910 if (NULL != apcm->src)
914 return 0; 911 return 0;
@@ -934,13 +931,13 @@ spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
934 src = apcm->src; 931 src = apcm->src;
935 } 932 }
936 /* Connect to SPDIFOO */ 933 /* Connect to SPDIFOO */
937 spin_lock_irqsave(&atc->atc_lock, flags); 934 mutex_lock(&atc->atc_mutex);
938 dao = container_of(atc->daios[SPDIFOO], struct dao, daio); 935 dao = container_of(atc->daios[SPDIFOO], struct dao, daio);
939 amixer = apcm->amixers[0]; 936 amixer = apcm->amixers[0];
940 dao->ops->set_left_input(dao, &amixer->rsc); 937 dao->ops->set_left_input(dao, &amixer->rsc);
941 amixer = apcm->amixers[1]; 938 amixer = apcm->amixers[1];
942 dao->ops->set_right_input(dao, &amixer->rsc); 939 dao->ops->set_right_input(dao, &amixer->rsc);
943 spin_unlock_irqrestore(&atc->atc_lock, flags); 940 mutex_unlock(&atc->atc_mutex);
944 941
945 ct_timer_prepare(apcm->timer); 942 ct_timer_prepare(apcm->timer);
946 943
@@ -1088,7 +1085,6 @@ static int atc_spdif_out_set_status(struct ct_atc *atc, unsigned int status)
1088 1085
1089static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state) 1086static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state)
1090{ 1087{
1091 unsigned long flags;
1092 struct dao_desc da_dsc = {0}; 1088 struct dao_desc da_dsc = {0};
1093 struct dao *dao; 1089 struct dao *dao;
1094 int err; 1090 int err;
@@ -1096,7 +1092,7 @@ static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state)
1096 struct rsc *rscs[2] = {NULL}; 1092 struct rsc *rscs[2] = {NULL};
1097 unsigned int spos = 0; 1093 unsigned int spos = 0;
1098 1094
1099 spin_lock_irqsave(&atc->atc_lock, flags); 1095 mutex_lock(&atc->atc_mutex);
1100 dao = container_of(atc->daios[SPDIFOO], struct dao, daio); 1096 dao = container_of(atc->daios[SPDIFOO], struct dao, daio);
1101 da_dsc.msr = state ? 1 : atc->msr; 1097 da_dsc.msr = state ? 1 : atc->msr;
1102 da_dsc.passthru = state ? 1 : 0; 1098 da_dsc.passthru = state ? 1 : 0;
@@ -1114,7 +1110,7 @@ static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state)
1114 } 1110 }
1115 dao->ops->set_spos(dao, spos); 1111 dao->ops->set_spos(dao, spos);
1116 dao->ops->commit_write(dao); 1112 dao->ops->commit_write(dao);
1117 spin_unlock_irqrestore(&atc->atc_lock, flags); 1113 mutex_unlock(&atc->atc_mutex);
1118 1114
1119 return err; 1115 return err;
1120} 1116}
@@ -1572,7 +1568,7 @@ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
1572 atc->msr = msr; 1568 atc->msr = msr;
1573 atc->chip_type = chip_type; 1569 atc->chip_type = chip_type;
1574 1570
1575 spin_lock_init(&atc->atc_lock); 1571 mutex_init(&atc->atc_mutex);
1576 1572
1577 /* Find card model */ 1573 /* Find card model */
1578 err = atc_identify_card(atc); 1574 err = atc_identify_card(atc);
diff --git a/sound/pci/ctxfi/ctatc.h b/sound/pci/ctxfi/ctatc.h
index a03347232e84..9fe620ea5f3f 100644
--- a/sound/pci/ctxfi/ctatc.h
+++ b/sound/pci/ctxfi/ctatc.h
@@ -19,7 +19,7 @@
19#define CTATC_H 19#define CTATC_H
20 20
21#include <linux/types.h> 21#include <linux/types.h>
22#include <linux/spinlock_types.h> 22#include <linux/mutex.h>
23#include <linux/pci.h> 23#include <linux/pci.h>
24#include <linux/timer.h> 24#include <linux/timer.h>
25#include <sound/core.h> 25#include <sound/core.h>
@@ -90,7 +90,7 @@ struct ct_atc {
90 void (*unmap_audio_buffer)(struct ct_atc *atc, struct ct_atc_pcm *apcm); 90 void (*unmap_audio_buffer)(struct ct_atc *atc, struct ct_atc_pcm *apcm);
91 unsigned long (*get_ptp_phys)(struct ct_atc *atc, int index); 91 unsigned long (*get_ptp_phys)(struct ct_atc *atc, int index);
92 92
93 spinlock_t atc_lock; 93 struct mutex atc_mutex;
94 94
95 int (*pcm_playback_prepare)(struct ct_atc *atc, 95 int (*pcm_playback_prepare)(struct ct_atc *atc,
96 struct ct_atc_pcm *apcm); 96 struct ct_atc_pcm *apcm);
diff --git a/sound/pci/ctxfi/cttimer.c b/sound/pci/ctxfi/cttimer.c
index 779c6c3591a5..93b0aedc36d4 100644
--- a/sound/pci/ctxfi/cttimer.c
+++ b/sound/pci/ctxfi/cttimer.c
@@ -180,7 +180,7 @@ static inline unsigned int ct_xfitimer_get_wc(struct ct_timer *atimer)
180 * 180 *
181 * call this inside the lock and irq disabled 181 * call this inside the lock and irq disabled
182 */ 182 */
183static int ct_xfitimer_reprogram(struct ct_timer *atimer) 183static int ct_xfitimer_reprogram(struct ct_timer *atimer, int can_update)
184{ 184{
185 struct ct_timer_instance *ti; 185 struct ct_timer_instance *ti;
186 unsigned int min_intr = (unsigned int)-1; 186 unsigned int min_intr = (unsigned int)-1;
@@ -216,6 +216,8 @@ static int ct_xfitimer_reprogram(struct ct_timer *atimer)
216 ti->frag_count = div_u64((u64)pos * CT_TIMER_FREQ + 216 ti->frag_count = div_u64((u64)pos * CT_TIMER_FREQ +
217 rate - 1, rate); 217 rate - 1, rate);
218 } 218 }
219 if (ti->need_update && !can_update)
220 min_intr = 0; /* pending to the next irq */
219 if (ti->frag_count < min_intr) 221 if (ti->frag_count < min_intr)
220 min_intr = ti->frag_count; 222 min_intr = ti->frag_count;
221 } 223 }
@@ -235,7 +237,7 @@ static void ct_xfitimer_check_period(struct ct_timer *atimer)
235 237
236 spin_lock_irqsave(&atimer->list_lock, flags); 238 spin_lock_irqsave(&atimer->list_lock, flags);
237 list_for_each_entry(ti, &atimer->instance_head, instance_list) { 239 list_for_each_entry(ti, &atimer->instance_head, instance_list) {
238 if (ti->need_update) { 240 if (ti->running && ti->need_update) {
239 ti->need_update = 0; 241 ti->need_update = 0;
240 ti->apcm->interrupt(ti->apcm); 242 ti->apcm->interrupt(ti->apcm);
241 } 243 }
@@ -252,7 +254,7 @@ static void ct_xfitimer_callback(struct ct_timer *atimer)
252 spin_lock_irqsave(&atimer->lock, flags); 254 spin_lock_irqsave(&atimer->lock, flags);
253 atimer->irq_handling = 1; 255 atimer->irq_handling = 1;
254 do { 256 do {
255 update = ct_xfitimer_reprogram(atimer); 257 update = ct_xfitimer_reprogram(atimer, 1);
256 spin_unlock(&atimer->lock); 258 spin_unlock(&atimer->lock);
257 if (update) 259 if (update)
258 ct_xfitimer_check_period(atimer); 260 ct_xfitimer_check_period(atimer);
@@ -265,6 +267,7 @@ static void ct_xfitimer_callback(struct ct_timer *atimer)
265static void ct_xfitimer_prepare(struct ct_timer_instance *ti) 267static void ct_xfitimer_prepare(struct ct_timer_instance *ti)
266{ 268{
267 ti->frag_count = ti->substream->runtime->period_size; 269 ti->frag_count = ti->substream->runtime->period_size;
270 ti->running = 0;
268 ti->need_update = 0; 271 ti->need_update = 0;
269} 272}
270 273
@@ -273,7 +276,6 @@ static void ct_xfitimer_prepare(struct ct_timer_instance *ti)
273static void ct_xfitimer_update(struct ct_timer *atimer) 276static void ct_xfitimer_update(struct ct_timer *atimer)
274{ 277{
275 unsigned long flags; 278 unsigned long flags;
276 int update;
277 279
278 spin_lock_irqsave(&atimer->lock, flags); 280 spin_lock_irqsave(&atimer->lock, flags);
279 if (atimer->irq_handling) { 281 if (atimer->irq_handling) {
@@ -284,10 +286,8 @@ static void ct_xfitimer_update(struct ct_timer *atimer)
284 } 286 }
285 287
286 ct_xfitimer_irq_stop(atimer); 288 ct_xfitimer_irq_stop(atimer);
287 update = ct_xfitimer_reprogram(atimer); 289 ct_xfitimer_reprogram(atimer, 0);
288 spin_unlock_irqrestore(&atimer->lock, flags); 290 spin_unlock_irqrestore(&atimer->lock, flags);
289 if (update)
290 ct_xfitimer_check_period(atimer);
291} 291}
292 292
293static void ct_xfitimer_start(struct ct_timer_instance *ti) 293static void ct_xfitimer_start(struct ct_timer_instance *ti)
@@ -298,6 +298,8 @@ static void ct_xfitimer_start(struct ct_timer_instance *ti)
298 spin_lock_irqsave(&atimer->lock, flags); 298 spin_lock_irqsave(&atimer->lock, flags);
299 if (list_empty(&ti->running_list)) 299 if (list_empty(&ti->running_list))
300 atimer->wc = ct_xfitimer_get_wc(atimer); 300 atimer->wc = ct_xfitimer_get_wc(atimer);
301 ti->running = 1;
302 ti->need_update = 0;
301 list_add(&ti->running_list, &atimer->running_head); 303 list_add(&ti->running_list, &atimer->running_head);
302 spin_unlock_irqrestore(&atimer->lock, flags); 304 spin_unlock_irqrestore(&atimer->lock, flags);
303 ct_xfitimer_update(atimer); 305 ct_xfitimer_update(atimer);
@@ -310,7 +312,7 @@ static void ct_xfitimer_stop(struct ct_timer_instance *ti)
310 312
311 spin_lock_irqsave(&atimer->lock, flags); 313 spin_lock_irqsave(&atimer->lock, flags);
312 list_del_init(&ti->running_list); 314 list_del_init(&ti->running_list);
313 ti->need_update = 0; 315 ti->running = 0;
314 spin_unlock_irqrestore(&atimer->lock, flags); 316 spin_unlock_irqrestore(&atimer->lock, flags);
315 ct_xfitimer_update(atimer); 317 ct_xfitimer_update(atimer);
316} 318}