aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-02-20 06:50:46 -0500
committerTakashi Iwai <tiwai@suse.de>2015-02-26 09:52:45 -0500
commit820cc6cf2c552155ea919e596a85e1f4e5dfa2b5 (patch)
treee6b75fc3f36ef14fd64d6f311c2f8e8c5391c8c5
parent7e40b80da452770878943edfe7da80f10f8d25da (diff)
ALSA: hda - Clear pcm pointer assigned to hda_pcm at device removal
We leave the pcm field of struct hda_pcm at removal of each device, so far. This hasn't been a problem since unbinding the codec driver isn't supposed to happen and another route via snd_hda_codec_reset() clears all the once. However, for a proper unbind implementation, we need to care about it. This patch does the thing above properly: - Include struct hda_pcm pointer instead of struct hda_pcm_stream pointers in struct azx_dev. This allows us to point the hda_pcm object at dev_free callback. - Introduce to_hda_pcm_stream() macro for better readability. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/hda_controller.c22
-rw-r--r--sound/pci/hda/hda_controller.h2
2 files changed, 16 insertions, 8 deletions
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index 789ca66c3094..1695f0e2bd9d 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -258,11 +258,18 @@ static void azx_timecounter_init(struct snd_pcm_substream *substream,
258 tc->cycle_last = last; 258 tc->cycle_last = last;
259} 259}
260 260
261static inline struct hda_pcm_stream *
262to_hda_pcm_stream(struct snd_pcm_substream *substream)
263{
264 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
265 return &apcm->info->stream[substream->stream];
266}
267
261static u64 azx_adjust_codec_delay(struct snd_pcm_substream *substream, 268static u64 azx_adjust_codec_delay(struct snd_pcm_substream *substream,
262 u64 nsec) 269 u64 nsec)
263{ 270{
264 struct azx_pcm *apcm = snd_pcm_substream_chip(substream); 271 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
265 struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; 272 struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream);
266 u64 codec_frames, codec_nsecs; 273 u64 codec_frames, codec_nsecs;
267 274
268 if (!hinfo->ops.get_delay) 275 if (!hinfo->ops.get_delay)
@@ -398,7 +405,7 @@ static int azx_setup_periods(struct azx *chip,
398static int azx_pcm_close(struct snd_pcm_substream *substream) 405static int azx_pcm_close(struct snd_pcm_substream *substream)
399{ 406{
400 struct azx_pcm *apcm = snd_pcm_substream_chip(substream); 407 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
401 struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; 408 struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream);
402 struct azx *chip = apcm->chip; 409 struct azx *chip = apcm->chip;
403 struct azx_dev *azx_dev = get_azx_dev(substream); 410 struct azx_dev *azx_dev = get_azx_dev(substream);
404 unsigned long flags; 411 unsigned long flags;
@@ -440,7 +447,7 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream)
440 struct azx_pcm *apcm = snd_pcm_substream_chip(substream); 447 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
441 struct azx_dev *azx_dev = get_azx_dev(substream); 448 struct azx_dev *azx_dev = get_azx_dev(substream);
442 struct azx *chip = apcm->chip; 449 struct azx *chip = apcm->chip;
443 struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; 450 struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream);
444 int err; 451 int err;
445 452
446 /* reset BDL address */ 453 /* reset BDL address */
@@ -467,7 +474,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
467 struct azx_pcm *apcm = snd_pcm_substream_chip(substream); 474 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
468 struct azx *chip = apcm->chip; 475 struct azx *chip = apcm->chip;
469 struct azx_dev *azx_dev = get_azx_dev(substream); 476 struct azx_dev *azx_dev = get_azx_dev(substream);
470 struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; 477 struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream);
471 struct snd_pcm_runtime *runtime = substream->runtime; 478 struct snd_pcm_runtime *runtime = substream->runtime;
472 unsigned int bufsize, period_bytes, format_val, stream_tag; 479 unsigned int bufsize, period_bytes, format_val, stream_tag;
473 int err; 480 int err;
@@ -707,7 +714,7 @@ unsigned int azx_get_position(struct azx *chip,
707 714
708 if (substream->runtime) { 715 if (substream->runtime) {
709 struct azx_pcm *apcm = snd_pcm_substream_chip(substream); 716 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
710 struct hda_pcm_stream *hinfo = apcm->hinfo[stream]; 717 struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream);
711 718
712 if (chip->get_delay[stream]) 719 if (chip->get_delay[stream])
713 delay += chip->get_delay[stream](chip, azx_dev, pos); 720 delay += chip->get_delay[stream](chip, azx_dev, pos);
@@ -790,7 +797,7 @@ static struct snd_pcm_hardware azx_pcm_hw = {
790static int azx_pcm_open(struct snd_pcm_substream *substream) 797static int azx_pcm_open(struct snd_pcm_substream *substream)
791{ 798{
792 struct azx_pcm *apcm = snd_pcm_substream_chip(substream); 799 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
793 struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; 800 struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream);
794 struct azx *chip = apcm->chip; 801 struct azx *chip = apcm->chip;
795 struct azx_dev *azx_dev; 802 struct azx_dev *azx_dev;
796 struct snd_pcm_runtime *runtime = substream->runtime; 803 struct snd_pcm_runtime *runtime = substream->runtime;
@@ -904,6 +911,7 @@ static void azx_pcm_free(struct snd_pcm *pcm)
904 struct azx_pcm *apcm = pcm->private_data; 911 struct azx_pcm *apcm = pcm->private_data;
905 if (apcm) { 912 if (apcm) {
906 list_del(&apcm->list); 913 list_del(&apcm->list);
914 apcm->info->pcm = NULL;
907 kfree(apcm); 915 kfree(apcm);
908 } 916 }
909} 917}
@@ -940,6 +948,7 @@ static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
940 apcm->chip = chip; 948 apcm->chip = chip;
941 apcm->pcm = pcm; 949 apcm->pcm = pcm;
942 apcm->codec = codec; 950 apcm->codec = codec;
951 apcm->info = cpcm;
943 pcm->private_data = apcm; 952 pcm->private_data = apcm;
944 pcm->private_free = azx_pcm_free; 953 pcm->private_free = azx_pcm_free;
945 if (cpcm->pcm_type == HDA_PCM_TYPE_MODEM) 954 if (cpcm->pcm_type == HDA_PCM_TYPE_MODEM)
@@ -947,7 +956,6 @@ static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
947 list_add_tail(&apcm->list, &chip->pcm_list); 956 list_add_tail(&apcm->list, &chip->pcm_list);
948 cpcm->pcm = pcm; 957 cpcm->pcm = pcm;
949 for (s = 0; s < 2; s++) { 958 for (s = 0; s < 2; s++) {
950 apcm->hinfo[s] = &cpcm->stream[s];
951 if (cpcm->stream[s].substreams) 959 if (cpcm->stream[s].substreams)
952 snd_pcm_set_ops(pcm, s, &azx_pcm_ops); 960 snd_pcm_set_ops(pcm, s, &azx_pcm_ops);
953 } 961 }
diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h
index e4f46a21698a..94c1a4719f7f 100644
--- a/sound/pci/hda/hda_controller.h
+++ b/sound/pci/hda/hda_controller.h
@@ -283,7 +283,7 @@ struct azx_pcm {
283 struct azx *chip; 283 struct azx *chip;
284 struct snd_pcm *pcm; 284 struct snd_pcm *pcm;
285 struct hda_codec *codec; 285 struct hda_codec *codec;
286 struct hda_pcm_stream *hinfo[2]; 286 struct hda_pcm *info;
287 struct list_head list; 287 struct list_head list;
288}; 288};
289 289