aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_ca0132.c
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 /sound/pci/hda/patch_ca0132.c
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>
Diffstat (limited to 'sound/pci/hda/patch_ca0132.c')
-rw-r--r--sound/pci/hda/patch_ca0132.c29
1 files changed, 13 insertions, 16 deletions
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}