aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-02-27 11:43:19 -0500
committerTakashi Iwai <tiwai@suse.de>2015-03-03 05:26:24 -0500
commitbbbc7e8502c95237dbd86cc4d0a12ca9a6b18c8f (patch)
tree71d5973b321c194ca5b9fd76592844eb37c4c9ed
parentf4de8fe6cffb449a779dff61f071bd1af9e18e0f (diff)
ALSA: hda - Allocate hda_pcm objects dynamically
So far, the hda_codec object kept the hda_pcm list in an array, and the codec driver was expected to assign the array. However, this makes the object life cycle management harder, because the assigned array is freed at the codec driver detach while it might be still accessed by the opened streams. In this patch, we allocate each hda_pcm object dynamically and manage it as a linked list. Each object has a kref refcount, and both the codec driver binder and the PCM open/close touches it, so that the object won't be freed while in use. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/hda_codec.c116
-rw-r--r--sound/pci/hda/hda_codec.h18
-rw-r--r--sound/pci/hda/hda_generic.c28
-rw-r--r--sound/pci/hda/hda_generic.h2
-rw-r--r--sound/pci/hda/hda_proc.c6
-rw-r--r--sound/pci/hda/patch_ca0132.c29
-rw-r--r--sound/pci/hda/patch_hdmi.c30
-rw-r--r--sound/pci/hda/patch_realtek.c2
-rw-r--r--sound/pci/hda/patch_si3054.c11
-rw-r--r--sound/pci/hda/patch_via.c6
10 files changed, 145 insertions, 103 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 262c41a8f96e..20283bead10a 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1117,6 +1117,60 @@ get_hda_cvt_setup(struct hda_codec *codec, hda_nid_t nid)
1117} 1117}
1118 1118
1119/* 1119/*
1120 * PCM device
1121 */
1122static void release_pcm(struct kref *kref)
1123{
1124 struct hda_pcm *pcm = container_of(kref, struct hda_pcm, kref);
1125
1126 if (pcm->pcm)
1127 snd_device_free(pcm->codec->card, pcm->pcm);
1128 clear_bit(pcm->device, pcm->codec->bus->pcm_dev_bits);
1129 kfree(pcm->name);
1130 kfree(pcm);
1131}
1132
1133void snd_hda_codec_pcm_put(struct hda_pcm *pcm)
1134{
1135 kref_put(&pcm->kref, release_pcm);
1136}
1137EXPORT_SYMBOL_GPL(snd_hda_codec_pcm_put);
1138
1139struct hda_pcm *snd_hda_codec_pcm_new(struct hda_codec *codec,
1140 const char *fmt, ...)
1141{
1142 struct hda_pcm *pcm;
1143 va_list args;
1144
1145 va_start(args, fmt);
1146 pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
1147 if (!pcm)
1148 return NULL;
1149
1150 pcm->codec = codec;
1151 kref_init(&pcm->kref);
1152 pcm->name = kvasprintf(GFP_KERNEL, fmt, args);
1153 if (!pcm->name) {
1154 kfree(pcm);
1155 return NULL;
1156 }
1157
1158 list_add_tail(&pcm->list, &codec->pcm_list_head);
1159 return pcm;
1160}
1161EXPORT_SYMBOL_GPL(snd_hda_codec_pcm_new);
1162
1163static void codec_release_pcms(struct hda_codec *codec)
1164{
1165 struct hda_pcm *pcm, *n;
1166
1167 list_for_each_entry_safe(pcm, n, &codec->pcm_list_head, list) {
1168 list_del_init(&pcm->list);
1169 snd_hda_codec_pcm_put(pcm);
1170 }
1171}
1172
1173/*
1120 * codec destructor 1174 * codec destructor
1121 */ 1175 */
1122static void snd_hda_codec_free(struct hda_codec *codec) 1176static void snd_hda_codec_free(struct hda_codec *codec)
@@ -1124,6 +1178,7 @@ static void snd_hda_codec_free(struct hda_codec *codec)
1124 if (!codec) 1178 if (!codec)
1125 return; 1179 return;
1126 cancel_delayed_work_sync(&codec->jackpoll_work); 1180 cancel_delayed_work_sync(&codec->jackpoll_work);
1181 codec_release_pcms(codec);
1127 if (device_is_registered(hda_codec_dev(codec))) 1182 if (device_is_registered(hda_codec_dev(codec)))
1128 device_del(hda_codec_dev(codec)); 1183 device_del(hda_codec_dev(codec));
1129 snd_hda_jack_tbl_clear(codec); 1184 snd_hda_jack_tbl_clear(codec);
@@ -1251,6 +1306,7 @@ int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
1251 snd_array_init(&codec->jacktbl, sizeof(struct hda_jack_tbl), 16); 1306 snd_array_init(&codec->jacktbl, sizeof(struct hda_jack_tbl), 16);
1252 snd_array_init(&codec->verbs, sizeof(struct hda_verb *), 8); 1307 snd_array_init(&codec->verbs, sizeof(struct hda_verb *), 8);
1253 INIT_LIST_HEAD(&codec->conn_list); 1308 INIT_LIST_HEAD(&codec->conn_list);
1309 INIT_LIST_HEAD(&codec->pcm_list_head);
1254 1310
1255 INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work); 1311 INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work);
1256 codec->depop_delay = -1; 1312 codec->depop_delay = -1;
@@ -2370,9 +2426,8 @@ int snd_hda_lock_devices(struct hda_bus *bus)
2370 goto err_clear; 2426 goto err_clear;
2371 2427
2372 list_for_each_entry(codec, &bus->codec_list, list) { 2428 list_for_each_entry(codec, &bus->codec_list, list) {
2373 int pcm; 2429 struct hda_pcm *cpcm;
2374 for (pcm = 0; pcm < codec->num_pcms; pcm++) { 2430 list_for_each_entry(cpcm, &codec->pcm_list_head, list) {
2375 struct hda_pcm *cpcm = &codec->pcm_info[pcm];
2376 if (!cpcm->pcm) 2431 if (!cpcm->pcm)
2377 continue; 2432 continue;
2378 if (cpcm->pcm->streams[0].substream_opened || 2433 if (cpcm->pcm->streams[0].substream_opened ||
@@ -2419,8 +2474,6 @@ EXPORT_SYMBOL_GPL(snd_hda_unlock_devices);
2419int snd_hda_codec_reset(struct hda_codec *codec) 2474int snd_hda_codec_reset(struct hda_codec *codec)
2420{ 2475{
2421 struct hda_bus *bus = codec->bus; 2476 struct hda_bus *bus = codec->bus;
2422 struct snd_card *card = codec->card;
2423 int i;
2424 2477
2425 if (snd_hda_lock_devices(bus) < 0) 2478 if (snd_hda_lock_devices(bus) < 0)
2426 return -EBUSY; 2479 return -EBUSY;
@@ -2429,14 +2482,7 @@ int snd_hda_codec_reset(struct hda_codec *codec)
2429 cancel_delayed_work_sync(&codec->jackpoll_work); 2482 cancel_delayed_work_sync(&codec->jackpoll_work);
2430 flush_workqueue(bus->workq); 2483 flush_workqueue(bus->workq);
2431 snd_hda_ctls_clear(codec); 2484 snd_hda_ctls_clear(codec);
2432 /* release PCMs */ 2485 codec_release_pcms(codec);
2433 for (i = 0; i < codec->num_pcms; i++) {
2434 if (codec->pcm_info[i].pcm) {
2435 snd_device_free(card, codec->pcm_info[i].pcm);
2436 clear_bit(codec->pcm_info[i].device,
2437 bus->pcm_dev_bits);
2438 }
2439 }
2440 snd_hda_detach_beep_device(codec); 2486 snd_hda_detach_beep_device(codec);
2441 if (device_is_registered(hda_codec_dev(codec))) 2487 if (device_is_registered(hda_codec_dev(codec)))
2442 device_del(hda_codec_dev(codec)); 2488 device_del(hda_codec_dev(codec));
@@ -2454,8 +2500,6 @@ int snd_hda_codec_reset(struct hda_codec *codec)
2454 snd_array_free(&codec->cvt_setups); 2500 snd_array_free(&codec->cvt_setups);
2455 snd_array_free(&codec->spdif_out); 2501 snd_array_free(&codec->spdif_out);
2456 snd_array_free(&codec->verbs); 2502 snd_array_free(&codec->verbs);
2457 codec->num_pcms = 0;
2458 codec->pcm_info = NULL;
2459 codec->preset = NULL; 2503 codec->preset = NULL;
2460 codec->slave_dig_outs = NULL; 2504 codec->slave_dig_outs = NULL;
2461 codec->spdif_status_reset = 0; 2505 codec->spdif_status_reset = 0;
@@ -3952,12 +3996,12 @@ static void hda_call_codec_resume(struct hda_codec *codec)
3952static int hda_codec_runtime_suspend(struct device *dev) 3996static int hda_codec_runtime_suspend(struct device *dev)
3953{ 3997{
3954 struct hda_codec *codec = dev_to_hda_codec(dev); 3998 struct hda_codec *codec = dev_to_hda_codec(dev);
3999 struct hda_pcm *pcm;
3955 unsigned int state; 4000 unsigned int state;
3956 int i;
3957 4001
3958 cancel_delayed_work_sync(&codec->jackpoll_work); 4002 cancel_delayed_work_sync(&codec->jackpoll_work);
3959 for (i = 0; i < codec->num_pcms; i++) 4003 list_for_each_entry(pcm, &codec->pcm_list_head, list)
3960 snd_pcm_suspend_all(codec->pcm_info[i].pcm); 4004 snd_pcm_suspend_all(pcm->pcm);
3961 state = hda_call_codec_suspend(codec); 4005 state = hda_call_codec_suspend(codec);
3962 if (codec->d3_stop_clk && codec->epss && (state & AC_PWRST_CLK_STOP_OK)) 4006 if (codec->d3_stop_clk && codec->epss && (state & AC_PWRST_CLK_STOP_OK))
3963 clear_bit(codec->addr, &codec->bus->codec_powered); 4007 clear_bit(codec->addr, &codec->bus->codec_powered);
@@ -4018,22 +4062,21 @@ EXPORT_SYMBOL_GPL(snd_hda_build_controls);
4018 */ 4062 */
4019static int add_std_chmaps(struct hda_codec *codec) 4063static int add_std_chmaps(struct hda_codec *codec)
4020{ 4064{
4021 int i, str, err; 4065 struct hda_pcm *pcm;
4066 int str, err;
4022 4067
4023 for (i = 0; i < codec->num_pcms; i++) { 4068 list_for_each_entry(pcm, &codec->pcm_list_head, list) {
4024 for (str = 0; str < 2; str++) { 4069 for (str = 0; str < 2; str++) {
4025 struct snd_pcm *pcm = codec->pcm_info[i].pcm; 4070 struct hda_pcm_stream *hinfo = &pcm->stream[str];
4026 struct hda_pcm_stream *hinfo =
4027 &codec->pcm_info[i].stream[str];
4028 struct snd_pcm_chmap *chmap; 4071 struct snd_pcm_chmap *chmap;
4029 const struct snd_pcm_chmap_elem *elem; 4072 const struct snd_pcm_chmap_elem *elem;
4030 4073
4031 if (codec->pcm_info[i].own_chmap) 4074 if (pcm->own_chmap)
4032 continue; 4075 continue;
4033 if (!pcm || !hinfo->substreams) 4076 if (!pcm || !hinfo->substreams)
4034 continue; 4077 continue;
4035 elem = hinfo->chmap ? hinfo->chmap : snd_pcm_std_chmaps; 4078 elem = hinfo->chmap ? hinfo->chmap : snd_pcm_std_chmaps;
4036 err = snd_pcm_add_chmap_ctls(pcm, str, elem, 4079 err = snd_pcm_add_chmap_ctls(pcm->pcm, str, elem,
4037 hinfo->channels_max, 4080 hinfo->channels_max,
4038 0, &chmap); 4081 0, &chmap);
4039 if (err < 0) 4082 if (err < 0)
@@ -4564,10 +4607,10 @@ static int get_empty_pcm_device(struct hda_bus *bus, unsigned int type)
4564/* call build_pcms ops of the given codec and set up the default parameters */ 4607/* call build_pcms ops of the given codec and set up the default parameters */
4565int snd_hda_codec_parse_pcms(struct hda_codec *codec) 4608int snd_hda_codec_parse_pcms(struct hda_codec *codec)
4566{ 4609{
4567 unsigned int pcm; 4610 struct hda_pcm *cpcm;
4568 int err; 4611 int err;
4569 4612
4570 if (codec->num_pcms) 4613 if (!list_empty(&codec->pcm_list_head))
4571 return 0; /* already parsed */ 4614 return 0; /* already parsed */
4572 4615
4573 if (!codec->patch_ops.build_pcms) 4616 if (!codec->patch_ops.build_pcms)
@@ -4580,8 +4623,7 @@ int snd_hda_codec_parse_pcms(struct hda_codec *codec)
4580 return err; 4623 return err;
4581 } 4624 }
4582 4625
4583 for (pcm = 0; pcm < codec->num_pcms; pcm++) { 4626 list_for_each_entry(cpcm, &codec->pcm_list_head, list) {
4584 struct hda_pcm *cpcm = &codec->pcm_info[pcm];
4585 int stream; 4627 int stream;
4586 4628
4587 for (stream = 0; stream < 2; stream++) { 4629 for (stream = 0; stream < 2; stream++) {
@@ -4589,8 +4631,6 @@ int snd_hda_codec_parse_pcms(struct hda_codec *codec)
4589 4631
4590 if (!info->substreams) 4632 if (!info->substreams)
4591 continue; 4633 continue;
4592 if (snd_BUG_ON(!cpcm->name))
4593 return -EINVAL;
4594 err = set_pcm_default_values(codec, info); 4634 err = set_pcm_default_values(codec, info);
4595 if (err < 0) { 4635 if (err < 0) {
4596 codec_warn(codec, 4636 codec_warn(codec,
@@ -4608,7 +4648,7 @@ int snd_hda_codec_parse_pcms(struct hda_codec *codec)
4608int snd_hda_codec_build_pcms(struct hda_codec *codec) 4648int snd_hda_codec_build_pcms(struct hda_codec *codec)
4609{ 4649{
4610 struct hda_bus *bus = codec->bus; 4650 struct hda_bus *bus = codec->bus;
4611 unsigned int pcm; 4651 struct hda_pcm *cpcm;
4612 int dev, err; 4652 int dev, err;
4613 4653
4614 if (snd_BUG_ON(!bus->ops.attach_pcm)) 4654 if (snd_BUG_ON(!bus->ops.attach_pcm))
@@ -4621,9 +4661,7 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec)
4621 } 4661 }
4622 4662
4623 /* attach a new PCM streams */ 4663 /* attach a new PCM streams */
4624 for (pcm = 0; pcm < codec->num_pcms; pcm++) { 4664 list_for_each_entry(cpcm, &codec->pcm_list_head, list) {
4625 struct hda_pcm *cpcm = &codec->pcm_info[pcm];
4626
4627 if (cpcm->pcm) 4665 if (cpcm->pcm)
4628 continue; /* already attached */ 4666 continue; /* already attached */
4629 if (!cpcm->stream[0].substreams && !cpcm->stream[1].substreams) 4667 if (!cpcm->stream[0].substreams && !cpcm->stream[1].substreams)
@@ -4651,11 +4689,9 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec)
4651 * 4689 *
4652 * Create PCM information for each codec included in the bus. 4690 * Create PCM information for each codec included in the bus.
4653 * 4691 *
4654 * The build_pcms codec patch is requested to set up codec->num_pcms and 4692 * The build_pcms codec patch is requested to create and assign new
4655 * codec->pcm_info properly. The array is referred by the top-level driver 4693 * hda_pcm objects. The codec is responsible to call snd_hda_codec_pcm_new()
4656 * to create its PCM instances. 4694 * and fills the fields. Later they are instantiated by this function.
4657 * The allocated codec->pcm_info should be released in codec->patch_ops.free
4658 * callback.
4659 * 4695 *
4660 * At least, substreams, channels_min and channels_max must be filled for 4696 * At least, substreams, channels_min and channels_max must be filled for
4661 * each stream. substreams = 0 indicates that the stream doesn't exist. 4697 * each stream. substreams = 0 indicates that the stream doesn't exist.
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 8908a0768736..2ccd6f9a91fe 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -21,6 +21,7 @@
21#ifndef __SOUND_HDA_CODEC_H 21#ifndef __SOUND_HDA_CODEC_H
22#define __SOUND_HDA_CODEC_H 22#define __SOUND_HDA_CODEC_H
23 23
24#include <linux/kref.h>
24#include <sound/info.h> 25#include <sound/info.h>
25#include <sound/control.h> 26#include <sound/control.h>
26#include <sound/pcm.h> 27#include <sound/pcm.h>
@@ -268,6 +269,10 @@ struct hda_pcm {
268 int device; /* device number to assign */ 269 int device; /* device number to assign */
269 struct snd_pcm *pcm; /* assigned PCM instance */ 270 struct snd_pcm *pcm; /* assigned PCM instance */
270 bool own_chmap; /* codec driver provides own channel maps */ 271 bool own_chmap; /* codec driver provides own channel maps */
272 /* private: */
273 struct hda_codec *codec;
274 struct kref kref;
275 struct list_head list;
271}; 276};
272 277
273/* codec information */ 278/* codec information */
@@ -301,8 +306,7 @@ struct hda_codec {
301 struct hda_codec_ops patch_ops; 306 struct hda_codec_ops patch_ops;
302 307
303 /* PCM to create, set by patch_ops.build_pcms callback */ 308 /* PCM to create, set by patch_ops.build_pcms callback */
304 unsigned int num_pcms; 309 struct list_head pcm_list_head;
305 struct hda_pcm *pcm_info;
306 310
307 /* codec specific info */ 311 /* codec specific info */
308 void *spec; 312 void *spec;
@@ -521,6 +525,16 @@ int snd_hda_build_pcms(struct hda_bus *bus);
521int snd_hda_codec_parse_pcms(struct hda_codec *codec); 525int snd_hda_codec_parse_pcms(struct hda_codec *codec);
522int snd_hda_codec_build_pcms(struct hda_codec *codec); 526int snd_hda_codec_build_pcms(struct hda_codec *codec);
523 527
528__printf(2, 3)
529struct hda_pcm *snd_hda_codec_pcm_new(struct hda_codec *codec,
530 const char *fmt, ...);
531
532static inline void snd_hda_codec_pcm_get(struct hda_pcm *pcm)
533{
534 kref_get(&pcm->kref);
535}
536void snd_hda_codec_pcm_put(struct hda_pcm *pcm);
537
524int snd_hda_codec_prepare(struct hda_codec *codec, 538int snd_hda_codec_prepare(struct hda_codec *codec,
525 struct hda_pcm_stream *hinfo, 539 struct hda_pcm_stream *hinfo,
526 unsigned int stream, 540 unsigned int stream,
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 947d1a50f384..092f06fd21bd 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -4644,7 +4644,7 @@ int snd_hda_gen_build_controls(struct hda_codec *codec)
4644 err = snd_hda_create_dig_out_ctls(codec, 4644 err = snd_hda_create_dig_out_ctls(codec,
4645 spec->multiout.dig_out_nid, 4645 spec->multiout.dig_out_nid,
4646 spec->multiout.dig_out_nid, 4646 spec->multiout.dig_out_nid,
4647 spec->pcm_rec[1].pcm_type); 4647 spec->pcm_rec[1]->pcm_type);
4648 if (err < 0) 4648 if (err < 0)
4649 return err; 4649 return err;
4650 if (!spec->no_analog) { 4650 if (!spec->no_analog) {
@@ -5115,20 +5115,20 @@ static void fill_pcm_stream_name(char *str, size_t len, const char *sfx,
5115int snd_hda_gen_build_pcms(struct hda_codec *codec) 5115int snd_hda_gen_build_pcms(struct hda_codec *codec)
5116{ 5116{
5117 struct hda_gen_spec *spec = codec->spec; 5117 struct hda_gen_spec *spec = codec->spec;
5118 struct hda_pcm *info = spec->pcm_rec; 5118 struct hda_pcm *info;
5119 const struct hda_pcm_stream *p; 5119 const struct hda_pcm_stream *p;
5120 bool have_multi_adcs; 5120 bool have_multi_adcs;
5121 5121
5122 codec->num_pcms = 1;
5123 codec->pcm_info = info;
5124
5125 if (spec->no_analog) 5122 if (spec->no_analog)
5126 goto skip_analog; 5123 goto skip_analog;
5127 5124
5128 fill_pcm_stream_name(spec->stream_name_analog, 5125 fill_pcm_stream_name(spec->stream_name_analog,
5129 sizeof(spec->stream_name_analog), 5126 sizeof(spec->stream_name_analog),
5130 " Analog", codec->chip_name); 5127 " Analog", codec->chip_name);
5131 info->name = spec->stream_name_analog; 5128 info = snd_hda_codec_pcm_new(codec, "%s", spec->stream_name_analog);
5129 if (!info)
5130 return -ENOMEM;
5131 spec->pcm_rec[0] = info;
5132 5132
5133 if (spec->multiout.num_dacs > 0) { 5133 if (spec->multiout.num_dacs > 0) {
5134 p = spec->stream_analog_playback; 5134 p = spec->stream_analog_playback;
@@ -5161,10 +5161,12 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec)
5161 fill_pcm_stream_name(spec->stream_name_digital, 5161 fill_pcm_stream_name(spec->stream_name_digital,
5162 sizeof(spec->stream_name_digital), 5162 sizeof(spec->stream_name_digital),
5163 " Digital", codec->chip_name); 5163 " Digital", codec->chip_name);
5164 codec->num_pcms = 2; 5164 info = snd_hda_codec_pcm_new(codec, "%s",
5165 spec->stream_name_digital);
5166 if (!info)
5167 return -ENOMEM;
5165 codec->slave_dig_outs = spec->multiout.slave_dig_outs; 5168 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
5166 info = spec->pcm_rec + 1; 5169 spec->pcm_rec[1] = info;
5167 info->name = spec->stream_name_digital;
5168 if (spec->dig_out_type) 5170 if (spec->dig_out_type)
5169 info->pcm_type = spec->dig_out_type; 5171 info->pcm_type = spec->dig_out_type;
5170 else 5172 else
@@ -5198,9 +5200,11 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec)
5198 fill_pcm_stream_name(spec->stream_name_alt_analog, 5200 fill_pcm_stream_name(spec->stream_name_alt_analog,
5199 sizeof(spec->stream_name_alt_analog), 5201 sizeof(spec->stream_name_alt_analog),
5200 " Alt Analog", codec->chip_name); 5202 " Alt Analog", codec->chip_name);
5201 codec->num_pcms = 3; 5203 info = snd_hda_codec_pcm_new(codec, "%s",
5202 info = spec->pcm_rec + 2; 5204 spec->stream_name_alt_analog);
5203 info->name = spec->stream_name_alt_analog; 5205 if (!info)
5206 return -ENOMEM;
5207 spec->pcm_rec[2] = info;
5204 if (spec->alt_dac_nid) { 5208 if (spec->alt_dac_nid) {
5205 p = spec->stream_analog_alt_playback; 5209 p = spec->stream_analog_alt_playback;
5206 if (!p) 5210 if (!p)
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index 3d852660443a..b211f889b335 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -144,7 +144,7 @@ struct hda_gen_spec {
144 int const_channel_count; /* channel count for all */ 144 int const_channel_count; /* channel count for all */
145 145
146 /* PCM information */ 146 /* PCM information */
147 struct hda_pcm pcm_rec[3]; /* used in build_pcms() */ 147 struct hda_pcm *pcm_rec[3]; /* used in build_pcms() */
148 148
149 /* dynamic controls, init_verbs and input_mux */ 149 /* dynamic controls, init_verbs and input_mux */
150 struct auto_pin_cfg autocfg; 150 struct auto_pin_cfg autocfg;
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index cc32b878ae2e..aeb983e7506d 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -99,10 +99,10 @@ static void print_nid_array(struct snd_info_buffer *buffer,
99static void print_nid_pcms(struct snd_info_buffer *buffer, 99static void print_nid_pcms(struct snd_info_buffer *buffer,
100 struct hda_codec *codec, hda_nid_t nid) 100 struct hda_codec *codec, hda_nid_t nid)
101{ 101{
102 int pcm, type; 102 int type;
103 struct hda_pcm *cpcm; 103 struct hda_pcm *cpcm;
104 for (pcm = 0; pcm < codec->num_pcms; pcm++) { 104
105 cpcm = &codec->pcm_info[pcm]; 105 list_for_each_entry(cpcm, &codec->pcm_list_head, list) {
106 for (type = 0; type < 2; type++) { 106 for (type = 0; type < 2; type++) {
107 if (cpcm->stream[type].nid != nid || cpcm->pcm == NULL) 107 if (cpcm->stream[type].nid != nid || cpcm->pcm == NULL)
108 continue; 108 continue;
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index ced3e82d9e23..555781fad26f 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -719,7 +719,6 @@ struct ca0132_spec {
719 unsigned int num_inputs; 719 unsigned int num_inputs;
720 hda_nid_t shared_mic_nid; 720 hda_nid_t shared_mic_nid;
721 hda_nid_t shared_out_nid; 721 hda_nid_t shared_out_nid;
722 struct hda_pcm pcm_rec[5]; /* PCM information */
723 722
724 /* chip access */ 723 /* chip access */
725 struct mutex chipio_mutex; /* chip access mutex */ 724 struct mutex chipio_mutex; /* chip access mutex */
@@ -4036,12 +4035,11 @@ static struct hda_pcm_stream ca0132_pcm_digital_capture = {
4036static int ca0132_build_pcms(struct hda_codec *codec) 4035static int ca0132_build_pcms(struct hda_codec *codec)
4037{ 4036{
4038 struct ca0132_spec *spec = codec->spec; 4037 struct ca0132_spec *spec = codec->spec;
4039 struct hda_pcm *info = spec->pcm_rec; 4038 struct hda_pcm *info;
4040 4039
4041 codec->pcm_info = info; 4040 info = snd_hda_codec_pcm_new(codec, "CA0132 Analog");
4042 codec->num_pcms = 0; 4041 if (!info)
4043 4042 return -ENOMEM;
4044 info->name = "CA0132 Analog";
4045 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ca0132_pcm_analog_playback; 4043 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ca0132_pcm_analog_playback;
4046 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dacs[0]; 4044 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dacs[0];
4047 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 4045 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
@@ -4049,27 +4047,27 @@ static int ca0132_build_pcms(struct hda_codec *codec)
4049 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture; 4047 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture;
4050 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1; 4048 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1;
4051 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0]; 4049 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0];
4052 codec->num_pcms++;
4053 4050
4054 info++; 4051 info = snd_hda_codec_pcm_new(codec, "CA0132 Analog Mic-In2");
4055 info->name = "CA0132 Analog Mic-In2"; 4052 if (!info)
4053 return -ENOMEM;
4056 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture; 4054 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture;
4057 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1; 4055 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1;
4058 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[1]; 4056 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[1];
4059 codec->num_pcms++;
4060 4057
4061 info++; 4058 info = snd_hda_codec_pcm_new(codec, "CA0132 What U Hear");
4062 info->name = "CA0132 What U Hear"; 4059 if (!info)
4060 return -ENOMEM;
4063 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture; 4061 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture;
4064 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1; 4062 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1;
4065 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[2]; 4063 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[2];
4066 codec->num_pcms++;
4067 4064
4068 if (!spec->dig_out && !spec->dig_in) 4065 if (!spec->dig_out && !spec->dig_in)
4069 return 0; 4066 return 0;
4070 4067
4071 info++; 4068 info = snd_hda_codec_pcm_new(codec, "CA0132 Digital");
4072 info->name = "CA0132 Digital"; 4069 if (!info)
4070 return -ENOMEM;
4073 info->pcm_type = HDA_PCM_TYPE_SPDIF; 4071 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4074 if (spec->dig_out) { 4072 if (spec->dig_out) {
4075 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 4073 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
@@ -4081,7 +4079,6 @@ static int ca0132_build_pcms(struct hda_codec *codec)
4081 ca0132_pcm_digital_capture; 4079 ca0132_pcm_digital_capture;
4082 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in; 4080 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in;
4083 } 4081 }
4084 codec->num_pcms++;
4085 4082
4086 return 0; 4083 return 0;
4087} 4084}
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 0f8354cbc7a7..708bbed15ea3 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -86,7 +86,6 @@ struct hdmi_spec_per_pin {
86 bool non_pcm; 86 bool non_pcm;
87 bool chmap_set; /* channel-map override by ALSA API? */ 87 bool chmap_set; /* channel-map override by ALSA API? */
88 unsigned char chmap[8]; /* ALSA API channel-map */ 88 unsigned char chmap[8]; /* ALSA API channel-map */
89 char pcm_name[8]; /* filled in build_pcm callbacks */
90#ifdef CONFIG_PROC_FS 89#ifdef CONFIG_PROC_FS
91 struct snd_info_entry *proc_entry; 90 struct snd_info_entry *proc_entry;
92#endif 91#endif
@@ -132,7 +131,7 @@ struct hdmi_spec {
132 131
133 int num_pins; 132 int num_pins;
134 struct snd_array pins; /* struct hdmi_spec_per_pin */ 133 struct snd_array pins; /* struct hdmi_spec_per_pin */
135 struct snd_array pcm_rec; /* struct hda_pcm */ 134 struct hda_pcm *pcm_rec[16];
136 unsigned int channels_max; /* max over all cvts */ 135 unsigned int channels_max; /* max over all cvts */
137 136
138 struct hdmi_eld temp_eld; 137 struct hdmi_eld temp_eld;
@@ -355,8 +354,7 @@ static struct cea_channel_speaker_allocation channel_allocations[] = {
355 ((struct hdmi_spec_per_pin *)snd_array_elem(&spec->pins, idx)) 354 ((struct hdmi_spec_per_pin *)snd_array_elem(&spec->pins, idx))
356#define get_cvt(spec, idx) \ 355#define get_cvt(spec, idx) \
357 ((struct hdmi_spec_per_cvt *)snd_array_elem(&spec->cvts, idx)) 356 ((struct hdmi_spec_per_cvt *)snd_array_elem(&spec->cvts, idx))
358#define get_pcm_rec(spec, idx) \ 357#define get_pcm_rec(spec, idx) ((spec)->pcm_rec[idx])
359 ((struct hda_pcm *)snd_array_elem(&spec->pcm_rec, idx))
360 358
361static int pin_nid_to_pin_index(struct hda_codec *codec, hda_nid_t pin_nid) 359static int pin_nid_to_pin_index(struct hda_codec *codec, hda_nid_t pin_nid)
362{ 360{
@@ -2056,11 +2054,10 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
2056 struct hdmi_spec_per_pin *per_pin; 2054 struct hdmi_spec_per_pin *per_pin;
2057 2055
2058 per_pin = get_pin(spec, pin_idx); 2056 per_pin = get_pin(spec, pin_idx);
2059 sprintf(per_pin->pcm_name, "HDMI %d", pin_idx); 2057 info = snd_hda_codec_pcm_new(codec, "HDMI %d", pin_idx);
2060 info = snd_array_new(&spec->pcm_rec);
2061 if (!info) 2058 if (!info)
2062 return -ENOMEM; 2059 return -ENOMEM;
2063 info->name = per_pin->pcm_name; 2060 spec->pcm_rec[pin_idx] = info;
2064 info->pcm_type = HDA_PCM_TYPE_HDMI; 2061 info->pcm_type = HDA_PCM_TYPE_HDMI;
2065 info->own_chmap = true; 2062 info->own_chmap = true;
2066 2063
@@ -2070,9 +2067,6 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
2070 /* other pstr fields are set in open */ 2067 /* other pstr fields are set in open */
2071 } 2068 }
2072 2069
2073 codec->num_pcms = spec->num_pins;
2074 codec->pcm_info = spec->pcm_rec.list;
2075
2076 return 0; 2070 return 0;
2077} 2071}
2078 2072
@@ -2125,13 +2119,15 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
2125 2119
2126 /* add channel maps */ 2120 /* add channel maps */
2127 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { 2121 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
2122 struct hda_pcm *pcm;
2128 struct snd_pcm_chmap *chmap; 2123 struct snd_pcm_chmap *chmap;
2129 struct snd_kcontrol *kctl; 2124 struct snd_kcontrol *kctl;
2130 int i; 2125 int i;
2131 2126
2132 if (!codec->pcm_info[pin_idx].pcm) 2127 pcm = spec->pcm_rec[pin_idx];
2128 if (!pcm || !pcm->pcm)
2133 break; 2129 break;
2134 err = snd_pcm_add_chmap_ctls(codec->pcm_info[pin_idx].pcm, 2130 err = snd_pcm_add_chmap_ctls(pcm->pcm,
2135 SNDRV_PCM_STREAM_PLAYBACK, 2131 SNDRV_PCM_STREAM_PLAYBACK,
2136 NULL, 0, pin_idx, &chmap); 2132 NULL, 0, pin_idx, &chmap);
2137 if (err < 0) 2133 if (err < 0)
@@ -2186,14 +2182,12 @@ static void hdmi_array_init(struct hdmi_spec *spec, int nums)
2186{ 2182{
2187 snd_array_init(&spec->pins, sizeof(struct hdmi_spec_per_pin), nums); 2183 snd_array_init(&spec->pins, sizeof(struct hdmi_spec_per_pin), nums);
2188 snd_array_init(&spec->cvts, sizeof(struct hdmi_spec_per_cvt), nums); 2184 snd_array_init(&spec->cvts, sizeof(struct hdmi_spec_per_cvt), nums);
2189 snd_array_init(&spec->pcm_rec, sizeof(struct hda_pcm), nums);
2190} 2185}
2191 2186
2192static void hdmi_array_free(struct hdmi_spec *spec) 2187static void hdmi_array_free(struct hdmi_spec *spec)
2193{ 2188{
2194 snd_array_free(&spec->pins); 2189 snd_array_free(&spec->pins);
2195 snd_array_free(&spec->cvts); 2190 snd_array_free(&spec->cvts);
2196 snd_array_free(&spec->pcm_rec);
2197} 2191}
2198 2192
2199static void generic_hdmi_free(struct hda_codec *codec) 2193static void generic_hdmi_free(struct hda_codec *codec)
@@ -2381,11 +2375,10 @@ static int simple_playback_build_pcms(struct hda_codec *codec)
2381 chans = get_wcaps(codec, per_cvt->cvt_nid); 2375 chans = get_wcaps(codec, per_cvt->cvt_nid);
2382 chans = get_wcaps_channels(chans); 2376 chans = get_wcaps_channels(chans);
2383 2377
2384 info = snd_array_new(&spec->pcm_rec); 2378 info = snd_hda_codec_pcm_new(codec, "HDMI 0");
2385 if (!info) 2379 if (!info)
2386 return -ENOMEM; 2380 return -ENOMEM;
2387 info->name = get_pin(spec, 0)->pcm_name; 2381 spec->pcm_rec[0] = info;
2388 sprintf(info->name, "HDMI 0");
2389 info->pcm_type = HDA_PCM_TYPE_HDMI; 2382 info->pcm_type = HDA_PCM_TYPE_HDMI;
2390 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; 2383 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
2391 *pstr = spec->pcm_playback; 2384 *pstr = spec->pcm_playback;
@@ -2393,9 +2386,6 @@ static int simple_playback_build_pcms(struct hda_codec *codec)
2393 if (pstr->channels_max <= 2 && chans && chans <= 16) 2386 if (pstr->channels_max <= 2 && chans && chans <= 16)
2394 pstr->channels_max = chans; 2387 pstr->channels_max = chans;
2395 2388
2396 codec->num_pcms = 1;
2397 codec->pcm_info = info;
2398
2399 return 0; 2389 return 0;
2400} 2390}
2401 2391
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 70808f92276a..0a5a2246e57a 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -5843,7 +5843,7 @@ static void alc_fixup_bass_chmap(struct hda_codec *codec,
5843{ 5843{
5844 if (action == HDA_FIXUP_ACT_BUILD) { 5844 if (action == HDA_FIXUP_ACT_BUILD) {
5845 struct alc_spec *spec = codec->spec; 5845 struct alc_spec *spec = codec->spec;
5846 spec->gen.pcm_rec[0].stream[0].chmap = asus_pcm_2_1_chmaps; 5846 spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps;
5847 } 5847 }
5848} 5848}
5849 5849
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index 38a477333321..df243134baa8 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -83,7 +83,6 @@
83 83
84struct si3054_spec { 84struct si3054_spec {
85 unsigned international; 85 unsigned international;
86 struct hda_pcm pcm;
87}; 86};
88 87
89 88
@@ -199,11 +198,11 @@ static const struct hda_pcm_stream si3054_pcm = {
199 198
200static int si3054_build_pcms(struct hda_codec *codec) 199static int si3054_build_pcms(struct hda_codec *codec)
201{ 200{
202 struct si3054_spec *spec = codec->spec; 201 struct hda_pcm *info;
203 struct hda_pcm *info = &spec->pcm; 202
204 codec->num_pcms = 1; 203 info = snd_hda_codec_pcm_new(codec, "Si3054 Modem");
205 codec->pcm_info = info; 204 if (!info)
206 info->name = "Si3054 Modem"; 205 return -ENOMEM;
207 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = si3054_pcm; 206 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = si3054_pcm;
208 info->stream[SNDRV_PCM_STREAM_CAPTURE] = si3054_pcm; 207 info->stream[SNDRV_PCM_STREAM_CAPTURE] = si3054_pcm;
209 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = codec->mfg; 208 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = codec->mfg;
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 57ad503ff940..11a05638e03b 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -683,8 +683,10 @@ static int vt1708_build_pcms(struct hda_codec *codec)
683 * 24bit samples are used. Until any workaround is found, 683 * 24bit samples are used. Until any workaround is found,
684 * disable the 24bit format, so far. 684 * disable the 24bit format, so far.
685 */ 685 */
686 for (i = 0; i < codec->num_pcms; i++) { 686 for (i = 0; i < ARRAY_SIZE(spec->gen.pcm_rec); i++) {
687 struct hda_pcm *info = &spec->gen.pcm_rec[i]; 687 struct hda_pcm *info = spec->gen.pcm_rec[i];
688 if (!info)
689 continue;
688 if (!info->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams || 690 if (!info->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams ||
689 info->pcm_type != HDA_PCM_TYPE_AUDIO) 691 info->pcm_type != HDA_PCM_TYPE_AUDIO)
690 continue; 692 continue;