diff options
| -rw-r--r-- | sound/pci/hda/hda_codec.c | 33 | ||||
| -rw-r--r-- | sound/pci/hda/hda_codec.h | 2 |
2 files changed, 21 insertions, 14 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index dd8fb86c842b..3827092cc1d2 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
| @@ -589,6 +589,7 @@ int /*__devinit*/ snd_hda_bus_new(struct snd_card *card, | |||
| 589 | bus->ops = temp->ops; | 589 | bus->ops = temp->ops; |
| 590 | 590 | ||
| 591 | mutex_init(&bus->cmd_mutex); | 591 | mutex_init(&bus->cmd_mutex); |
| 592 | mutex_init(&bus->prepare_mutex); | ||
| 592 | INIT_LIST_HEAD(&bus->codec_list); | 593 | INIT_LIST_HEAD(&bus->codec_list); |
| 593 | 594 | ||
| 594 | snprintf(bus->workq_name, sizeof(bus->workq_name), | 595 | snprintf(bus->workq_name, sizeof(bus->workq_name), |
| @@ -1068,7 +1069,6 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, | |||
| 1068 | codec->addr = codec_addr; | 1069 | codec->addr = codec_addr; |
| 1069 | mutex_init(&codec->spdif_mutex); | 1070 | mutex_init(&codec->spdif_mutex); |
| 1070 | mutex_init(&codec->control_mutex); | 1071 | mutex_init(&codec->control_mutex); |
| 1071 | mutex_init(&codec->prepare_mutex); | ||
| 1072 | init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); | 1072 | init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); |
| 1073 | init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); | 1073 | init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); |
| 1074 | snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32); | 1074 | snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32); |
| @@ -1213,6 +1213,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
| 1213 | u32 stream_tag, | 1213 | u32 stream_tag, |
| 1214 | int channel_id, int format) | 1214 | int channel_id, int format) |
| 1215 | { | 1215 | { |
| 1216 | struct hda_codec *c; | ||
| 1216 | struct hda_cvt_setup *p; | 1217 | struct hda_cvt_setup *p; |
| 1217 | unsigned int oldval, newval; | 1218 | unsigned int oldval, newval; |
| 1218 | int i; | 1219 | int i; |
| @@ -1253,10 +1254,12 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
| 1253 | p->dirty = 0; | 1254 | p->dirty = 0; |
| 1254 | 1255 | ||
| 1255 | /* make other inactive cvts with the same stream-tag dirty */ | 1256 | /* make other inactive cvts with the same stream-tag dirty */ |
| 1256 | for (i = 0; i < codec->cvt_setups.used; i++) { | 1257 | list_for_each_entry(c, &codec->bus->codec_list, list) { |
| 1257 | p = snd_array_elem(&codec->cvt_setups, i); | 1258 | for (i = 0; i < c->cvt_setups.used; i++) { |
| 1258 | if (!p->active && p->stream_tag == stream_tag) | 1259 | p = snd_array_elem(&c->cvt_setups, i); |
| 1259 | p->dirty = 1; | 1260 | if (!p->active && p->stream_tag == stream_tag) |
| 1261 | p->dirty = 1; | ||
| 1262 | } | ||
| 1260 | } | 1263 | } |
| 1261 | } | 1264 | } |
| 1262 | EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream); | 1265 | EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream); |
| @@ -1306,12 +1309,16 @@ static void really_cleanup_stream(struct hda_codec *codec, | |||
| 1306 | /* clean up the all conflicting obsolete streams */ | 1309 | /* clean up the all conflicting obsolete streams */ |
| 1307 | static void purify_inactive_streams(struct hda_codec *codec) | 1310 | static void purify_inactive_streams(struct hda_codec *codec) |
| 1308 | { | 1311 | { |
| 1312 | struct hda_codec *c; | ||
| 1309 | int i; | 1313 | int i; |
| 1310 | 1314 | ||
| 1311 | for (i = 0; i < codec->cvt_setups.used; i++) { | 1315 | list_for_each_entry(c, &codec->bus->codec_list, list) { |
| 1312 | struct hda_cvt_setup *p = snd_array_elem(&codec->cvt_setups, i); | 1316 | for (i = 0; i < c->cvt_setups.used; i++) { |
| 1313 | if (p->dirty) | 1317 | struct hda_cvt_setup *p; |
| 1314 | really_cleanup_stream(codec, p); | 1318 | p = snd_array_elem(&c->cvt_setups, i); |
| 1319 | if (p->dirty) | ||
| 1320 | really_cleanup_stream(c, p); | ||
| 1321 | } | ||
| 1315 | } | 1322 | } |
| 1316 | } | 1323 | } |
| 1317 | 1324 | ||
| @@ -3502,11 +3509,11 @@ int snd_hda_codec_prepare(struct hda_codec *codec, | |||
| 3502 | struct snd_pcm_substream *substream) | 3509 | struct snd_pcm_substream *substream) |
| 3503 | { | 3510 | { |
| 3504 | int ret; | 3511 | int ret; |
| 3505 | mutex_lock(&codec->prepare_mutex); | 3512 | mutex_lock(&codec->bus->prepare_mutex); |
| 3506 | ret = hinfo->ops.prepare(hinfo, codec, stream, format, substream); | 3513 | ret = hinfo->ops.prepare(hinfo, codec, stream, format, substream); |
| 3507 | if (ret >= 0) | 3514 | if (ret >= 0) |
| 3508 | purify_inactive_streams(codec); | 3515 | purify_inactive_streams(codec); |
| 3509 | mutex_unlock(&codec->prepare_mutex); | 3516 | mutex_unlock(&codec->bus->prepare_mutex); |
| 3510 | return ret; | 3517 | return ret; |
| 3511 | } | 3518 | } |
| 3512 | EXPORT_SYMBOL_HDA(snd_hda_codec_prepare); | 3519 | EXPORT_SYMBOL_HDA(snd_hda_codec_prepare); |
| @@ -3515,9 +3522,9 @@ void snd_hda_codec_cleanup(struct hda_codec *codec, | |||
| 3515 | struct hda_pcm_stream *hinfo, | 3522 | struct hda_pcm_stream *hinfo, |
| 3516 | struct snd_pcm_substream *substream) | 3523 | struct snd_pcm_substream *substream) |
| 3517 | { | 3524 | { |
| 3518 | mutex_lock(&codec->prepare_mutex); | 3525 | mutex_lock(&codec->bus->prepare_mutex); |
| 3519 | hinfo->ops.cleanup(hinfo, codec, substream); | 3526 | hinfo->ops.cleanup(hinfo, codec, substream); |
| 3520 | mutex_unlock(&codec->prepare_mutex); | 3527 | mutex_unlock(&codec->bus->prepare_mutex); |
| 3521 | } | 3528 | } |
| 3522 | EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup); | 3529 | EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup); |
| 3523 | 3530 | ||
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 4303353feda9..62c702240108 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
| @@ -648,6 +648,7 @@ struct hda_bus { | |||
| 648 | struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1]; | 648 | struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1]; |
| 649 | 649 | ||
| 650 | struct mutex cmd_mutex; | 650 | struct mutex cmd_mutex; |
| 651 | struct mutex prepare_mutex; | ||
| 651 | 652 | ||
| 652 | /* unsolicited event queue */ | 653 | /* unsolicited event queue */ |
| 653 | struct hda_bus_unsolicited *unsol; | 654 | struct hda_bus_unsolicited *unsol; |
| @@ -826,7 +827,6 @@ struct hda_codec { | |||
| 826 | 827 | ||
| 827 | struct mutex spdif_mutex; | 828 | struct mutex spdif_mutex; |
| 828 | struct mutex control_mutex; | 829 | struct mutex control_mutex; |
| 829 | struct mutex prepare_mutex; | ||
| 830 | unsigned int spdif_status; /* IEC958 status bits */ | 830 | unsigned int spdif_status; /* IEC958 status bits */ |
| 831 | unsigned short spdif_ctls; /* SPDIF control bits */ | 831 | unsigned short spdif_ctls; /* SPDIF control bits */ |
| 832 | unsigned int spdif_in_enable; /* SPDIF input enable? */ | 832 | unsigned int spdif_in_enable; /* SPDIF input enable? */ |
