summaryrefslogtreecommitdiff
path: root/drivers/mxc/asrc/mxc_asrc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mxc/asrc/mxc_asrc.c')
-rw-r--r--drivers/mxc/asrc/mxc_asrc.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/drivers/mxc/asrc/mxc_asrc.c b/drivers/mxc/asrc/mxc_asrc.c
index 228f733b43fb..d7edf78cc87d 100644
--- a/drivers/mxc/asrc/mxc_asrc.c
+++ b/drivers/mxc/asrc/mxc_asrc.c
@@ -49,6 +49,7 @@
#define ASRC_RATIO_DECIMAL_DEPTH 26
DEFINE_SPINLOCK(data_lock);
+DEFINE_SPINLOCK(pair_lock);
DEFINE_SPINLOCK(input_int_lock);
DEFINE_SPINLOCK(output_int_lock);
@@ -992,6 +993,11 @@ static void asrc_output_task_worker(struct work_struct *w)
unsigned long lock_flags;
/* asrc output work struct */
+ spin_lock_irqsave(&pair_lock, lock_flags);
+ if (!params->pair_hold) {
+ spin_unlock_irqrestore(&pair_lock, lock_flags);
+ return;
+ }
switch (params->output_word_width) {
case ASRC_WIDTH_24_BIT:
asrc_read_output_FIFO_S24(params);
@@ -1003,6 +1009,7 @@ static void asrc_output_task_worker(struct work_struct *w)
default:
pr_err("%s: error word width\n", __func__);
}
+ spin_unlock_irqrestore(&pair_lock, lock_flags);
/* finish receiving all output data */
spin_lock_irqsave(&output_int_lock, lock_flags);
@@ -1542,13 +1549,18 @@ static long asrc_ioctl(struct file *file,
case ASRC_RELEASE_PAIR:
{
enum asrc_pair_index index;
+ unsigned long lock_flags;
if (copy_from_user
(&index, (void __user *)arg,
sizeof(enum asrc_pair_index))) {
err = -EFAULT;
break;
}
+ params->asrc_active = 0;
+ spin_lock_irqsave(&pair_lock, lock_flags);
+ params->pair_hold = 0;
+ spin_unlock_irqrestore(&pair_lock, lock_flags);
if (params->input_dma_channel)
dma_release_channel(params->input_dma_channel);
if (params->output_dma_channel)
@@ -1557,8 +1569,6 @@ static long asrc_ioctl(struct file *file,
mxc_free_dma_buf(params);
asrc_release_pair(index);
asrc_finish_conv(index);
- params->asrc_active = 0;
- params->pair_hold = 0;
break;
}
case ASRC_CONVERT:
@@ -1733,9 +1743,11 @@ static int mxc_asrc_open(struct inode *inode, struct file *file)
static int mxc_asrc_close(struct inode *inode, struct file *file)
{
struct asrc_pair_params *pair_params;
+ unsigned long lock_flags;
pair_params = file->private_data;
if (pair_params) {
if (pair_params->asrc_active) {
+ pair_params->asrc_active = 0;
dmaengine_terminate_all(
pair_params->input_dma_channel);
dmaengine_terminate_all(
@@ -1745,6 +1757,9 @@ static int mxc_asrc_close(struct inode *inode, struct file *file)
wake_up_interruptible(&pair_params->output_wait_queue);
}
if (pair_params->pair_hold) {
+ spin_lock_irqsave(&pair_lock, lock_flags);
+ pair_params->pair_hold = 0;
+ spin_unlock_irqrestore(&pair_lock, lock_flags);
if (pair_params->input_dma_channel)
dma_release_channel(
pair_params->input_dma_channel);