diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-04-26 06:11:44 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-05-14 08:54:56 -0400 |
commit | d3d020bd11d6f1c45444b208e77268b43d3782ef (patch) | |
tree | 11643f0f7c1bba1b0554ccf5ef986bbd5533b1ac | |
parent | 9121947d696df7ea259c0102e449da9621b9cf92 (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.c | 66 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 3 |
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 | */ |
2250 | static int hda_lock_devices(struct snd_card *card) | 2250 | int 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 | } |
2282 | EXPORT_SYMBOL_HDA(snd_hda_lock_devices); | ||
2261 | 2283 | ||
2262 | static void hda_unlock_devices(struct snd_card *card) | 2284 | void 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 | } |
2293 | EXPORT_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 | */ |
2279 | int snd_hda_codec_reset(struct hda_codec *codec) | 2305 | int 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 | ||
1023 | int snd_hda_lock_devices(struct hda_bus *bus); | ||
1024 | void snd_hda_unlock_devices(struct hda_bus *bus); | ||
1025 | |||
1023 | /* | 1026 | /* |
1024 | * power management | 1027 | * power management |
1025 | */ | 1028 | */ |