diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-25 08:38:26 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-25 08:38:26 -0700 |
commit | 58823de9d2f1265030d0d06cb03cc2a551994398 (patch) | |
tree | 6b4f3e681f467e99758de61d6dd0c45a39e7d133 /sound/pci/hda/hda_codec.c | |
parent | 4b7eba49c5912cbd7c70bbebec38d8cd54c2ef85 (diff) | |
parent | 6091106297933c5cf0e4470df9a5f4e703674391 (diff) |
Merge tag 'hda-switcheroo' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull VGA-switcheroo audio client support for HD-audio from Takashi Iwai.
This depended on the recent drm pull.
* tag 'hda-switcheroo' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
ALSA: hda - unlock on error in azx_interrupt()
ALSA: hda - Support VGA-switcheroo
ALSA: hda - Export snd_hda_lock_devices()
ALSA: hda - Check the dead HDMI audio controller by vga-switcheroo
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 66 |
1 files changed, 39 insertions, 27 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index eb09a334832..41ca803a1ff 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2239,24 +2239,50 @@ void snd_hda_ctls_clear(struct hda_codec *codec) /* pseudo device locking * toggle card->shutdown to allow/disallow the device access (as a hack) */ -static int hda_lock_devices(struct snd_card *card) +int snd_hda_lock_devices(struct hda_bus *bus) { + struct snd_card *card = bus->card; + struct hda_codec *codec; + spin_lock(&card->files_lock); - if (card->shutdown) { - spin_unlock(&card->files_lock); - return -EINVAL; - } + if (card->shutdown) + goto err_unlock; card->shutdown = 1; + if (!list_empty(&card->ctl_files)) + goto err_clear; + + list_for_each_entry(codec, &bus->codec_list, list) { + int pcm; + for (pcm = 0; pcm < codec->num_pcms; pcm++) { + struct hda_pcm *cpcm = &codec->pcm_info[pcm]; + if (!cpcm->pcm) + continue; + if (cpcm->pcm->streams[0].substream_opened || + cpcm->pcm->streams[1].substream_opened) + goto err_clear; + } + } spin_unlock(&card->files_lock); return 0; + + err_clear: + card->shutdown = 0; + err_unlock: + spin_unlock(&card->files_lock); + return -EINVAL; } +EXPORT_SYMBOL_HDA(snd_hda_lock_devices); -static void hda_unlock_devices(struct snd_card *card) +void snd_hda_unlock_devices(struct hda_bus *bus) { + struct snd_card *card = bus->card; + + card = bus->card; spin_lock(&card->files_lock); card->shutdown = 0; spin_unlock(&card->files_lock); } +EXPORT_SYMBOL_HDA(snd_hda_unlock_devices); /** * snd_hda_codec_reset - Clear all objects assigned to the codec @@ -2270,26 +2296,12 @@ static void hda_unlock_devices(struct snd_card *card) */ int snd_hda_codec_reset(struct hda_codec *codec) { - struct snd_card *card = codec->bus->card; - int i, pcm; + struct hda_bus *bus = codec->bus; + struct snd_card *card = bus->card; + int i; - if (hda_lock_devices(card) < 0) - return -EBUSY; - /* check whether the codec isn't used by any mixer or PCM streams */ - if (!list_empty(&card->ctl_files)) { - hda_unlock_devices(card); + if (snd_hda_lock_devices(bus) < 0) return -EBUSY; - } - for (pcm = 0; pcm < codec->num_pcms; pcm++) { - struct hda_pcm *cpcm = &codec->pcm_info[pcm]; - if (!cpcm->pcm) - continue; - if (cpcm->pcm->streams[0].substream_opened || - cpcm->pcm->streams[1].substream_opened) { - hda_unlock_devices(card); - return -EBUSY; - } - } /* OK, let it free */ @@ -2298,7 +2310,7 @@ int snd_hda_codec_reset(struct hda_codec *codec) codec->power_on = 0; codec->power_transition = 0; codec->power_jiffies = jiffies; - flush_workqueue(codec->bus->workq); + flush_workqueue(bus->workq); #endif snd_hda_ctls_clear(codec); /* relase PCMs */ @@ -2306,7 +2318,7 @@ int snd_hda_codec_reset(struct hda_codec *codec) if (codec->pcm_info[i].pcm) { snd_device_free(card, codec->pcm_info[i].pcm); clear_bit(codec->pcm_info[i].device, - codec->bus->pcm_dev_bits); + bus->pcm_dev_bits); } } if (codec->patch_ops.free) @@ -2331,7 +2343,7 @@ int snd_hda_codec_reset(struct hda_codec *codec) codec->owner = NULL; /* allow device access again */ - hda_unlock_devices(card); + snd_hda_unlock_devices(bus); return 0; } |