diff options
author | Takashi Iwai <tiwai@suse.de> | 2017-10-24 08:15:10 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2017-10-24 08:15:49 +0200 |
commit | 1a0190157521704c11f8650756388b62f3887eb3 (patch) | |
tree | 25bb473c628872f05a1a1a97161d2dae9ce1c1d4 /sound/core/pcm.c | |
parent | b676da70c495acb2515de76300596e9147806ead (diff) | |
parent | 6ca73de7ebc5dac358551633e0c69ab6b5007baa (diff) | |
download | linux-1a0190157521704c11f8650756388b62f3887eb3.tar.bz2 |
Merge branch 'topic/card-disconnect' into for-next
Pull snd_card_disconnect_sync() extension for ASoC hot-unplug support.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/core/pcm.c')
-rw-r--r-- | sound/core/pcm.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 7eadb7fd8074..9070f277f8db 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -775,6 +775,9 @@ static int _snd_pcm_new(struct snd_card *card, const char *id, int device, .dev_register = snd_pcm_dev_register, .dev_disconnect = snd_pcm_dev_disconnect, }; + static struct snd_device_ops internal_ops = { + .dev_free = snd_pcm_dev_free, + }; if (snd_BUG_ON(!card)) return -ENXIO; @@ -801,7 +804,8 @@ static int _snd_pcm_new(struct snd_card *card, const char *id, int device, if (err < 0) goto free_pcm; - err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops); + err = snd_device_new(card, SNDRV_DEV_PCM, pcm, + internal ? &internal_ops : &ops); if (err < 0) goto free_pcm; @@ -1099,8 +1103,6 @@ static int snd_pcm_dev_register(struct snd_device *device) if (snd_BUG_ON(!device || !device->device_data)) return -ENXIO; pcm = device->device_data; - if (pcm->internal) - return 0; mutex_lock(®ister_mutex); err = snd_pcm_add(pcm); @@ -1152,6 +1154,10 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) { snd_pcm_stream_lock_irq(substream); if (substream->runtime) { + if (snd_pcm_running(substream)) + snd_pcm_stop(substream, + SNDRV_PCM_STATE_DISCONNECTED); + /* to be sure, set the state unconditionally */ substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED; wake_up(&substream->runtime->sleep); wake_up(&substream->runtime->tsleep); @@ -1159,12 +1165,10 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) snd_pcm_stream_unlock_irq(substream); } } - if (!pcm->internal) { - pcm_call_notify(pcm, n_disconnect); - } + + pcm_call_notify(pcm, n_disconnect); for (cidx = 0; cidx < 2; cidx++) { - if (!pcm->internal) - snd_unregister_device(&pcm->streams[cidx].dev); + snd_unregister_device(&pcm->streams[cidx].dev); free_chmap(&pcm->streams[cidx]); } mutex_unlock(&pcm->open_mutex); |