diff options
author | Christian Gromm <christian.gromm@microchip.com> | 2015-09-28 17:18:58 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-09-29 03:18:53 +0200 |
commit | 5e8aa94e97790b4092f6694ab7f381e6791d3245 (patch) | |
tree | 9e0e62b98c4a5f2549fc96a84d095f5e33d4eff0 | |
parent | aac997dfdd58eec1add02dae09030caeddc1abe6 (diff) | |
download | op-kernel-dev-5e8aa94e97790b4092f6694ab7f381e6791d3245.zip op-kernel-dev-5e8aa94e97790b4092f6694ab7f381e6791d3245.tar.gz |
staging: most: fix pcm_write input/output error
This patch keeps the process from sleeping after the PCM middle layer has
stopped playback by calling the pcm trigger callback. The patch is needed
to prevent aplay from causing a pcm_write Input/Output error.
Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/staging/most/aim-sound/sound.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/drivers/staging/most/aim-sound/sound.c b/drivers/staging/most/aim-sound/sound.c index df14ce5..f08545c 100644 --- a/drivers/staging/most/aim-sound/sound.c +++ b/drivers/staging/most/aim-sound/sound.c @@ -239,9 +239,9 @@ static int playback_thread(void *data) wait_event_interruptible( channel->playback_waitq, kthread_should_stop() || - (mbo = most_get_mbo(channel->iface, channel->id, - &audio_aim))); - + (channel->is_stream_running && + (mbo = most_get_mbo(channel->iface, channel->id, + &audio_aim)))); if (!mbo) continue; @@ -279,11 +279,12 @@ static int pcm_open(struct snd_pcm_substream *substream) channel->substream = substream; if (cfg->direction == MOST_CH_TX) { - init_waitqueue_head(&channel->playback_waitq); channel->playback_task = kthread_run(&playback_thread, channel, "most_audio_playback"); - if (IS_ERR(channel->playback_task)) + if (IS_ERR(channel->playback_task)) { + pr_err("Couldn't start thread\n"); return PTR_ERR(channel->playback_task); + } } if (most_start_channel(channel->iface, channel->id, &audio_aim)) { @@ -336,8 +337,10 @@ static int pcm_hw_params(struct snd_pcm_substream *substream, struct channel *channel = substream->private_data; if ((params_channels(hw_params) > channel->pcm_hardware.channels_max) || - (params_channels(hw_params) < channel->pcm_hardware.channels_min)) + (params_channels(hw_params) < channel->pcm_hardware.channels_min)) { + pr_err("Requested number of channels not supported.\n"); return -EINVAL; + } return snd_pcm_lib_alloc_vmalloc_buffer(substream, params_buffer_bytes(hw_params)); } @@ -422,6 +425,7 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd) switch (cmd) { case SNDRV_PCM_TRIGGER_START: channel->is_stream_running = true; + wake_up_interruptible(&channel->playback_waitq); return 0; case SNDRV_PCM_TRIGGER_STOP: @@ -606,6 +610,7 @@ static int audio_probe_channel(struct most_interface *iface, int channel_id, channel->cfg = cfg; channel->iface = iface; channel->id = channel_id; + init_waitqueue_head(&channel->playback_waitq); if (audio_set_hw_params(&channel->pcm_hardware, pcm_format, cfg)) goto err_free_card; |