aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-04-26 06:11:44 -0400
committerTakashi Iwai <tiwai@suse.de>2012-05-14 08:54:56 -0400
commitd3d020bd11d6f1c45444b208e77268b43d3782ef (patch)
tree11643f0f7c1bba1b0554ccf5ef986bbd5533b1ac
parent9121947d696df7ea259c0102e449da9621b9cf92 (diff)
ALSA: hda - Export snd_hda_lock_devices()
It's a preliminary work for the vga-switcher support. Export the function to do pseudo-lock for the sound card to be used in other places. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/hda_codec.c66
-rw-r--r--sound/pci/hda/hda_codec.h3
2 files changed, 42 insertions, 27 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index c556fe1c25eb..2fb935d9dccc 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -2247,24 +2247,50 @@ void snd_hda_ctls_clear(struct hda_codec *codec)
2247/* pseudo device locking 2247/* pseudo device locking
2248 * toggle card->shutdown to allow/disallow the device access (as a hack) 2248 * toggle card->shutdown to allow/disallow the device access (as a hack)
2249 */ 2249 */
2250static int hda_lock_devices(struct snd_card *card) 2250int snd_hda_lock_devices(struct hda_bus *bus)
2251{ 2251{
2252 struct snd_card *card = bus->card;
2253 struct hda_codec *codec;
2254
2252 spin_lock(&card->files_lock); 2255 spin_lock(&card->files_lock);
2253 if (card->shutdown) { 2256 if (card->shutdown)
2254 spin_unlock(&card->files_lock); 2257 goto err_unlock;
2255 return -EINVAL;
2256 }
2257 card->shutdown = 1; 2258 card->shutdown = 1;
2259 if (!list_empty(&card->ctl_files))
2260 goto err_clear;
2261
2262 list_for_each_entry(codec, &bus->codec_list, list) {
2263 int pcm;
2264 for (pcm = 0; pcm < codec->num_pcms; pcm++) {
2265 struct hda_pcm *cpcm = &codec->pcm_info[pcm];
2266 if (!cpcm->pcm)
2267 continue;
2268 if (cpcm->pcm->streams[0].substream_opened ||
2269 cpcm->pcm->streams[1].substream_opened)
2270 goto err_clear;
2271 }
2272 }
2258 spin_unlock(&card->files_lock); 2273 spin_unlock(&card->files_lock);
2259 return 0; 2274 return 0;
2275
2276 err_clear:
2277 card->shutdown = 0;
2278 err_unlock:
2279 spin_unlock(&card->files_lock);
2280 return -EINVAL;
2260} 2281}
2282EXPORT_SYMBOL_HDA(snd_hda_lock_devices);
2261 2283
2262static void hda_unlock_devices(struct snd_card *card) 2284void snd_hda_unlock_devices(struct hda_bus *bus)
2263{ 2285{
2286 struct snd_card *card = bus->card;
2287
2288 card = bus->card;
2264 spin_lock(&card->files_lock); 2289 spin_lock(&card->files_lock);
2265 card->shutdown = 0; 2290 card->shutdown = 0;
2266 spin_unlock(&card->files_lock); 2291 spin_unlock(&card->files_lock);
2267} 2292}
2293EXPORT_SYMBOL_HDA(snd_hda_unlock_devices);
2268 2294
2269/** 2295/**
2270 * snd_hda_codec_reset - Clear all objects assigned to the codec 2296 * snd_hda_codec_reset - Clear all objects assigned to the codec
@@ -2278,26 +2304,12 @@ static void hda_unlock_devices(struct snd_card *card)
2278 */ 2304 */
2279int snd_hda_codec_reset(struct hda_codec *codec) 2305int snd_hda_codec_reset(struct hda_codec *codec)
2280{ 2306{
2281 struct snd_card *card = codec->bus->card; 2307 struct hda_bus *bus = codec->bus;
2282 int i, pcm; 2308 struct snd_card *card = bus->card;
2309 int i;
2283 2310
2284 if (hda_lock_devices(card) < 0) 2311 if (snd_hda_lock_devices(bus) < 0)
2285 return -EBUSY;
2286 /* check whether the codec isn't used by any mixer or PCM streams */
2287 if (!list_empty(&card->ctl_files)) {
2288 hda_unlock_devices(card);
2289 return -EBUSY; 2312 return -EBUSY;
2290 }
2291 for (pcm = 0; pcm < codec->num_pcms; pcm++) {
2292 struct hda_pcm *cpcm = &codec->pcm_info[pcm];
2293 if (!cpcm->pcm)
2294 continue;
2295 if (cpcm->pcm->streams[0].substream_opened ||
2296 cpcm->pcm->streams[1].substream_opened) {
2297 hda_unlock_devices(card);
2298 return -EBUSY;
2299 }
2300 }
2301 2313
2302 /* OK, let it free */ 2314 /* OK, let it free */
2303 2315
@@ -2306,7 +2318,7 @@ int snd_hda_codec_reset(struct hda_codec *codec)
2306 codec->power_on = 0; 2318 codec->power_on = 0;
2307 codec->power_transition = 0; 2319 codec->power_transition = 0;
2308 codec->power_jiffies = jiffies; 2320 codec->power_jiffies = jiffies;
2309 flush_workqueue(codec->bus->workq); 2321 flush_workqueue(bus->workq);
2310#endif 2322#endif
2311 snd_hda_ctls_clear(codec); 2323 snd_hda_ctls_clear(codec);
2312 /* relase PCMs */ 2324 /* relase PCMs */
@@ -2314,7 +2326,7 @@ int snd_hda_codec_reset(struct hda_codec *codec)
2314 if (codec->pcm_info[i].pcm) { 2326 if (codec->pcm_info[i].pcm) {
2315 snd_device_free(card, codec->pcm_info[i].pcm); 2327 snd_device_free(card, codec->pcm_info[i].pcm);
2316 clear_bit(codec->pcm_info[i].device, 2328 clear_bit(codec->pcm_info[i].device,
2317 codec->bus->pcm_dev_bits); 2329 bus->pcm_dev_bits);
2318 } 2330 }
2319 } 2331 }
2320 if (codec->patch_ops.free) 2332 if (codec->patch_ops.free)
@@ -2339,7 +2351,7 @@ int snd_hda_codec_reset(struct hda_codec *codec)
2339 codec->owner = NULL; 2351 codec->owner = NULL;
2340 2352
2341 /* allow device access again */ 2353 /* allow device access again */
2342 hda_unlock_devices(card); 2354 snd_hda_unlock_devices(bus);
2343 return 0; 2355 return 0;
2344} 2356}
2345 2357
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 29a311b05f2d..be91cdbb1621 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -1020,6 +1020,9 @@ void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
1020 unsigned int power_state, 1020 unsigned int power_state,
1021 bool eapd_workaround); 1021 bool eapd_workaround);
1022 1022
1023int snd_hda_lock_devices(struct hda_bus *bus);
1024void snd_hda_unlock_devices(struct hda_bus *bus);
1025
1023/* 1026/*
1024 * power management 1027 * power management
1025 */ 1028 */