Merge remote-tracking branches 'asoc/topic/adau', 'asoc/topic/adau7002', 'asoc/topic/adsp', 'asoc/topic/ak4613' and 'asoc/topic/ak4642' into asoc-next
This commit is contained in:
@@ -67,6 +67,8 @@ struct snd_compr_file {
|
||||
struct snd_compr_stream stream;
|
||||
};
|
||||
|
||||
static void error_delayed_work(struct work_struct *work);
|
||||
|
||||
/*
|
||||
* a note on stream states used:
|
||||
* we use following states in the compressed core
|
||||
@@ -123,6 +125,9 @@ static int snd_compr_open(struct inode *inode, struct file *f)
|
||||
snd_card_unref(compr->card);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
INIT_DELAYED_WORK(&data->stream.error_work, error_delayed_work);
|
||||
|
||||
data->stream.ops = compr->ops;
|
||||
data->stream.direction = dirn;
|
||||
data->stream.private_data = compr->private_data;
|
||||
@@ -153,6 +158,8 @@ static int snd_compr_free(struct inode *inode, struct file *f)
|
||||
struct snd_compr_file *data = f->private_data;
|
||||
struct snd_compr_runtime *runtime = data->stream.runtime;
|
||||
|
||||
cancel_delayed_work_sync(&data->stream.error_work);
|
||||
|
||||
switch (runtime->state) {
|
||||
case SNDRV_PCM_STATE_RUNNING:
|
||||
case SNDRV_PCM_STATE_DRAINING:
|
||||
@@ -237,6 +244,15 @@ snd_compr_ioctl_avail(struct snd_compr_stream *stream, unsigned long arg)
|
||||
avail = snd_compr_calc_avail(stream, &ioctl_avail);
|
||||
ioctl_avail.avail = avail;
|
||||
|
||||
switch (stream->runtime->state) {
|
||||
case SNDRV_PCM_STATE_OPEN:
|
||||
return -EBADFD;
|
||||
case SNDRV_PCM_STATE_XRUN:
|
||||
return -EPIPE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (copy_to_user((__u64 __user *)arg,
|
||||
&ioctl_avail, sizeof(ioctl_avail)))
|
||||
return -EFAULT;
|
||||
@@ -346,11 +362,13 @@ static ssize_t snd_compr_read(struct file *f, char __user *buf,
|
||||
switch (stream->runtime->state) {
|
||||
case SNDRV_PCM_STATE_OPEN:
|
||||
case SNDRV_PCM_STATE_PREPARED:
|
||||
case SNDRV_PCM_STATE_XRUN:
|
||||
case SNDRV_PCM_STATE_SUSPENDED:
|
||||
case SNDRV_PCM_STATE_DISCONNECTED:
|
||||
retval = -EBADFD;
|
||||
goto out;
|
||||
case SNDRV_PCM_STATE_XRUN:
|
||||
retval = -EPIPE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
avail = snd_compr_get_avail(stream);
|
||||
@@ -399,10 +417,16 @@ static unsigned int snd_compr_poll(struct file *f, poll_table *wait)
|
||||
stream = &data->stream;
|
||||
|
||||
mutex_lock(&stream->device->lock);
|
||||
if (stream->runtime->state == SNDRV_PCM_STATE_OPEN) {
|
||||
|
||||
switch (stream->runtime->state) {
|
||||
case SNDRV_PCM_STATE_OPEN:
|
||||
case SNDRV_PCM_STATE_XRUN:
|
||||
retval = snd_compr_get_poll(stream) | POLLERR;
|
||||
goto out;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
poll_wait(f, &stream->runtime->sleep, wait);
|
||||
|
||||
avail = snd_compr_get_avail(stream);
|
||||
@@ -697,6 +721,45 @@ static int snd_compr_stop(struct snd_compr_stream *stream)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void error_delayed_work(struct work_struct *work)
|
||||
{
|
||||
struct snd_compr_stream *stream;
|
||||
|
||||
stream = container_of(work, struct snd_compr_stream, error_work.work);
|
||||
|
||||
mutex_lock(&stream->device->lock);
|
||||
|
||||
stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_STOP);
|
||||
wake_up(&stream->runtime->sleep);
|
||||
|
||||
mutex_unlock(&stream->device->lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* snd_compr_stop_error: Report a fatal error on a stream
|
||||
* @stream: pointer to stream
|
||||
* @state: state to transition the stream to
|
||||
*
|
||||
* Stop the stream and set its state.
|
||||
*
|
||||
* Should be called with compressed device lock held.
|
||||
*/
|
||||
int snd_compr_stop_error(struct snd_compr_stream *stream,
|
||||
snd_pcm_state_t state)
|
||||
{
|
||||
if (stream->runtime->state == state)
|
||||
return 0;
|
||||
|
||||
stream->runtime->state = state;
|
||||
|
||||
pr_debug("Changing state to: %d\n", state);
|
||||
|
||||
queue_delayed_work(system_power_efficient_wq, &stream->error_work, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_compr_stop_error);
|
||||
|
||||
static int snd_compress_wait_for_drain(struct snd_compr_stream *stream)
|
||||
{
|
||||
int ret;
|
||||
|
Reference in New Issue
Block a user