qdsp5: audio: Protect common data between ADSP ISR and flush operation

During NEEDS_DATA or BUFFER_UPDATE event processing in ISR
context, if flush command is issued by application then
there is chance of concurrent access of some of the variables
shared between ISR and Process context. This may result in race
condition causing values of these shared variables to be
inconsistent.

Fix this by protecting these variables using spin lock. Also corrected
locking sequence order in encode drivers.

Change-Id: I06b4d08053ad13d1b118ab6f29e69e95b49d133f
Signed-off-by: Manish Dewangan <manish@codeaurora.org>
diff --git a/arch/arm/mach-msm/qdsp5/audio_aac.c b/arch/arm/mach-msm/qdsp5/audio_aac.c
index 5e1e655..57ea4f3 100644
--- a/arch/arm/mach-msm/qdsp5/audio_aac.c
+++ b/arch/arm/mach-msm/qdsp5/audio_aac.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2008-2009, 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2011-2012 Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -672,24 +672,31 @@
 
 static void audio_flush(struct audio *audio)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&audio->dsp_lock, flags);
 	audio->out[0].used = 0;
 	audio->out[1].used = 0;
 	audio->out_head = 0;
 	audio->out_tail = 0;
 	audio->reserved = 0;
 	audio->out_needed = 0;
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 	atomic_set(&audio->out_bytes, 0);
 }
 
 static void audio_flush_pcm_buf(struct audio *audio)
 {
 	uint8_t index;
+	unsigned long flags;
 
+	spin_lock_irqsave(&audio->dsp_lock, flags);
 	for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
 		audio->in[index].used = 0;
 	audio->buf_refresh = 0;
 	audio->read_next = 0;
 	audio->fill_next = 0;
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 }
 
 static int audaac_validate_usr_config(struct msm_audio_aac_config *config)
diff --git a/arch/arm/mach-msm/qdsp5/audio_aac_in.c b/arch/arm/mach-msm/qdsp5/audio_aac_in.c
index c9e60d8..bfe48ee 100644
--- a/arch/arm/mach-msm/qdsp5/audio_aac_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_aac_in.c
@@ -2,7 +2,7 @@
  *
  * aac audio input device
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This code is based in part on arch/arm/mach-msm/qdsp5v2/audio_aac_in.c,
  * Copyright (C) 2008 Google, Inc.
@@ -697,21 +697,23 @@
 	 * sleep and knowing that system is not able
 	 * to process io request at the moment
 	 */
-	wake_up(&audio->write_wait);
-	mutex_lock(&audio->write_lock);
-	audaac_in_flush(audio);
-	mutex_unlock(&audio->write_lock);
 	wake_up(&audio->wait);
 	mutex_lock(&audio->read_lock);
-	audaac_out_flush(audio);
+	audaac_in_flush(audio);
 	mutex_unlock(&audio->read_lock);
+	wake_up(&audio->write_wait);
+	mutex_lock(&audio->write_lock);
+	audaac_out_flush(audio);
+	mutex_unlock(&audio->write_lock);
 }
 
 static void audaac_in_flush(struct audio_aac_in *audio)
 {
 	int i;
+	unsigned long flags;
 
 	audio->dsp_cnt = 0;
+	spin_lock_irqsave(&audio->dsp_lock, flags);
 	audio->in_head = 0;
 	audio->in_tail = 0;
 	audio->in_count = 0;
@@ -720,6 +722,7 @@
 		audio->in[i].size = 0;
 		audio->in[i].read = 0;
 	}
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 	MM_DBG("in_bytes %d\n", atomic_read(&audio->in_bytes));
 	MM_DBG("in_samples %d\n", atomic_read(&audio->in_samples));
 	atomic_set(&audio->in_bytes, 0);
@@ -729,15 +732,18 @@
 static void audaac_out_flush(struct audio_aac_in *audio)
 {
 	int i;
+	unsigned long flags;
 
 	audio->out_head = 0;
-	audio->out_tail = 0;
 	audio->out_count = 0;
+	spin_lock_irqsave(&audio->dsp_lock, flags);
+	audio->out_tail = 0;
 	for (i = OUT_FRAME_NUM-1; i >= 0; i--) {
 		audio->out[i].size = 0;
 		audio->out[i].read = 0;
 		audio->out[i].used = 0;
 	}
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 }
 
 /* ------------------- device --------------------- */
diff --git a/arch/arm/mach-msm/qdsp5/audio_amrnb.c b/arch/arm/mach-msm/qdsp5/audio_amrnb.c
index 476a63d..6e936f8 100644
--- a/arch/arm/mach-msm/qdsp5/audio_amrnb.c
+++ b/arch/arm/mach-msm/qdsp5/audio_amrnb.c
@@ -2,7 +2,7 @@
  *
  * amrnb audio decoder device
  *
- * Copyright (c) 2008-2009, 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2011-2012 Code Aurora Forum. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5/audio_mp3.c
  *
@@ -628,24 +628,31 @@
 
 static void audamrnb_flush(struct audio *audio)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&audio->dsp_lock, flags);
 	audio->out[0].used = 0;
 	audio->out[1].used = 0;
 	audio->out_head = 0;
 	audio->out_tail = 0;
 	audio->out_needed = 0;
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 	atomic_set(&audio->out_bytes, 0);
 }
 
 static void audamrnb_flush_pcm_buf(struct audio *audio)
 {
 	uint8_t index;
+	unsigned long flags;
 
+	spin_lock_irqsave(&audio->dsp_lock, flags);
 	for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
 		audio->in[index].used = 0;
 
 	audio->buf_refresh = 0;
 	audio->read_next = 0;
 	audio->fill_next = 0;
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 }
 
 static void audamrnb_ioport_reset(struct audio *audio)
diff --git a/arch/arm/mach-msm/qdsp5/audio_amrwb.c b/arch/arm/mach-msm/qdsp5/audio_amrwb.c
index e811731..10150b9 100644
--- a/arch/arm/mach-msm/qdsp5/audio_amrwb.c
+++ b/arch/arm/mach-msm/qdsp5/audio_amrwb.c
@@ -6,7 +6,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009, 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, 2011-2012 Code Aurora Forum. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
@@ -616,25 +616,32 @@
 
 static void audamrwb_flush(struct audio *audio)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&audio->dsp_lock, flags);
 	audio->out[0].used = 0;
 	audio->out[1].used = 0;
 	audio->out_head = 0;
 	audio->out_tail = 0;
 	audio->reserved = 0;
 	audio->out_needed = 0;
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 	atomic_set(&audio->out_bytes, 0);
 }
 
 static void audamrwb_flush_pcm_buf(struct audio *audio)
 {
 	uint8_t index;
+	unsigned long flags;
 
+	spin_lock_irqsave(&audio->dsp_lock, flags);
 	for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
 		audio->in[index].used = 0;
 
 	audio->buf_refresh = 0;
 	audio->read_next = 0;
 	audio->fill_next = 0;
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 }
 
 static void audamrwb_ioport_reset(struct audio *audio)
diff --git a/arch/arm/mach-msm/qdsp5/audio_evrc.c b/arch/arm/mach-msm/qdsp5/audio_evrc.c
index 3c39b6d..a21cc99 100644
--- a/arch/arm/mach-msm/qdsp5/audio_evrc.c
+++ b/arch/arm/mach-msm/qdsp5/audio_evrc.c
@@ -1,6 +1,6 @@
 /* arch/arm/mach-msm/audio_evrc.c
  *
- * Copyright (c) 2008-2009, 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2011-2012 Code Aurora Forum. All rights reserved.
  *
  * This code also borrows from audio_aac.c, which is
  * Copyright (C) 2008 Google, Inc.
@@ -615,24 +615,30 @@
 
 static void audevrc_flush(struct audio *audio)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&audio->dsp_lock, flags);
 	audio->out[0].used = 0;
 	audio->out[1].used = 0;
 	audio->out_head = 0;
 	audio->out_tail = 0;
 	audio->out_needed = 0;
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 	atomic_set(&audio->out_bytes, 0);
 }
 
 static void audevrc_flush_pcm_buf(struct audio *audio)
 {
 	uint8_t index;
+	unsigned long flags;
 
+	spin_lock_irqsave(&audio->dsp_lock, flags);
 	for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
 		audio->in[index].used = 0;
-
 	audio->buf_refresh = 0;
 	audio->read_next = 0;
 	audio->fill_next = 0;
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 }
 
 static void audevrc_ioport_reset(struct audio *audio)
diff --git a/arch/arm/mach-msm/qdsp5/audio_evrc_in.c b/arch/arm/mach-msm/qdsp5/audio_evrc_in.c
index 7a5536a..7b17fa1 100644
--- a/arch/arm/mach-msm/qdsp5/audio_evrc_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_evrc_in.c
@@ -2,7 +2,7 @@
  *
  * evrc audio input device
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This code is based in part on arch/arm/mach-msm/qdsp5v2/audio_evrc_in.c,
  * Copyright (C) 2008 Google, Inc.
@@ -655,21 +655,23 @@
 	 * sleep and knowing that system is not able
 	 * to process io request at the moment
 	 */
-	wake_up(&audio->write_wait);
-	mutex_lock(&audio->write_lock);
-	audevrc_in_flush(audio);
-	mutex_unlock(&audio->write_lock);
 	wake_up(&audio->wait);
 	mutex_lock(&audio->read_lock);
-	audevrc_out_flush(audio);
+	audevrc_in_flush(audio);
 	mutex_unlock(&audio->read_lock);
+	wake_up(&audio->write_wait);
+	mutex_lock(&audio->write_lock);
+	audevrc_out_flush(audio);
+	mutex_unlock(&audio->write_lock);
 }
 
 static void audevrc_in_flush(struct audio_evrc_in *audio)
 {
 	int i;
+	unsigned long flags;
 
 	audio->dsp_cnt = 0;
+	spin_lock_irqsave(&audio->dsp_lock, flags);
 	audio->in_head = 0;
 	audio->in_tail = 0;
 	audio->in_count = 0;
@@ -678,6 +680,7 @@
 		audio->in[i].size = 0;
 		audio->in[i].read = 0;
 	}
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 	MM_DBG("in_bytes %d\n", atomic_read(&audio->in_bytes));
 	MM_DBG("in_samples %d\n", atomic_read(&audio->in_samples));
 	atomic_set(&audio->in_bytes, 0);
@@ -687,15 +690,18 @@
 static void audevrc_out_flush(struct audio_evrc_in *audio)
 {
 	int i;
+	unsigned long flags;
 
 	audio->out_head = 0;
-	audio->out_tail = 0;
 	audio->out_count = 0;
+	spin_lock_irqsave(&audio->dsp_lock, flags);
+	audio->out_tail = 0;
 	for (i = OUT_FRAME_NUM-1; i >= 0; i--) {
 		audio->out[i].size = 0;
 		audio->out[i].read = 0;
 		audio->out[i].used = 0;
 	}
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 }
 
 /* ------------------- device --------------------- */
diff --git a/arch/arm/mach-msm/qdsp5/audio_mp3.c b/arch/arm/mach-msm/qdsp5/audio_mp3.c
index c4b464a..dfd8528 100644
--- a/arch/arm/mach-msm/qdsp5/audio_mp3.c
+++ b/arch/arm/mach-msm/qdsp5/audio_mp3.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -853,12 +853,16 @@
 
 static void audio_flush(struct audio *audio)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&audio->dsp_lock, flags);
 	audio->out[0].used = 0;
 	audio->out[1].used = 0;
 	audio->out_head = 0;
 	audio->out_tail = 0;
 	audio->reserved = 0;
 	audio->out_needed = 0;
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 	atomic_set(&audio->out_bytes, 0);
 }
 
@@ -885,13 +889,15 @@
 static void audio_flush_pcm_buf(struct audio *audio)
 {
 	uint8_t index;
+	unsigned long flags;
 
+	spin_lock_irqsave(&audio->dsp_lock, flags);
 	for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
 		audio->in[index].used = 0;
-
 	audio->buf_refresh = 0;
 	audio->read_next = 0;
 	audio->fill_next = 0;
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 }
 
 static void audio_ioport_reset(struct audio *audio)
diff --git a/arch/arm/mach-msm/qdsp5/audio_pcm.c b/arch/arm/mach-msm/qdsp5/audio_pcm.c
index 02103fc..bd6e4a2 100644
--- a/arch/arm/mach-msm/qdsp5/audio_pcm.c
+++ b/arch/arm/mach-msm/qdsp5/audio_pcm.c
@@ -1,7 +1,7 @@
 
 /* audio_pcm.c - pcm audio decoder driver
  *
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * Based on the mp3 decoder driver in arch/arm/mach-msm/qdsp5/audio_mp3.c
  *
@@ -639,12 +639,16 @@
 
 static void audio_flush(struct audio *audio)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&audio->dsp_lock, flags);
 	audio->out[0].used = 0;
 	audio->out[1].used = 0;
 	audio->out_head = 0;
 	audio->out_tail = 0;
 	audio->reserved = 0;
 	audio->out_needed = 0;
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 	atomic_set(&audio->out_bytes, 0);
 }
 
diff --git a/arch/arm/mach-msm/qdsp5/audio_qcelp.c b/arch/arm/mach-msm/qdsp5/audio_qcelp.c
index b12e713..1ac67341 100644
--- a/arch/arm/mach-msm/qdsp5/audio_qcelp.c
+++ b/arch/arm/mach-msm/qdsp5/audio_qcelp.c
@@ -2,7 +2,7 @@
  *
  * qcelp 13k audio decoder device
  *
- * Copyright (c) 2008-2009, 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2011-2012 Code Aurora Forum. All rights reserved.
  *
  * This code is based in part on audio_mp3.c, which is
  * Copyright (C) 2008 Google, Inc.
@@ -612,23 +612,30 @@
 
 static void audqcelp_flush(struct audio *audio)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&audio->dsp_lock, flags);
 	audio->out[0].used = 0;
 	audio->out[1].used = 0;
 	audio->out_head = 0;
 	audio->out_tail = 0;
 	audio->out_needed = 0;
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 }
 
 static void audqcelp_flush_pcm_buf(struct audio *audio)
 {
 	uint8_t index;
+	unsigned long flags;
 
+	spin_lock_irqsave(&audio->dsp_lock, flags);
 	for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
 		audio->in[index].used = 0;
 
 	audio->buf_refresh = 0;
 	audio->read_next = 0;
 	audio->fill_next = 0;
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 }
 
 static void audqcelp_ioport_reset(struct audio *audio)
diff --git a/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c b/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c
index a339825..dfd40be 100644
--- a/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_qcelp_in.c
@@ -2,7 +2,7 @@
  *
  * qcelp audio input device
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This code is based in part on arch/arm/mach-msm/qdsp5v2/audio_qcelp_in.c,
  * Copyright (C) 2008 Google, Inc.
@@ -657,29 +657,32 @@
 	 * sleep and knowing that system is not able
 	 * to process io request at the moment
 	 */
-	wake_up(&audio->write_wait);
-	mutex_lock(&audio->write_lock);
-	audqcelp_in_flush(audio);
-	mutex_unlock(&audio->write_lock);
 	wake_up(&audio->wait);
 	mutex_lock(&audio->read_lock);
-	audqcelp_out_flush(audio);
+	audqcelp_in_flush(audio);
 	mutex_unlock(&audio->read_lock);
+	wake_up(&audio->write_wait);
+	mutex_lock(&audio->write_lock);
+	audqcelp_out_flush(audio);
+	mutex_unlock(&audio->write_lock);
 }
 
 static void audqcelp_in_flush(struct audio_qcelp_in *audio)
 {
 	int i;
+	unsigned long flags;
 
+	audio->eos_ack = 0;
+	spin_lock_irqsave(&audio->dsp_lock, flags);
 	audio->dsp_cnt = 0;
 	audio->in_head = 0;
 	audio->in_tail = 0;
 	audio->in_count = 0;
-	audio->eos_ack = 0;
 	for (i = FRAME_NUM-1; i >= 0; i--) {
 		audio->in[i].size = 0;
 		audio->in[i].read = 0;
 	}
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 	MM_DBG("in_bytes %d\n", atomic_read(&audio->in_bytes));
 	MM_DBG("in_samples %d\n", atomic_read(&audio->in_samples));
 	atomic_set(&audio->in_bytes, 0);
@@ -689,15 +692,18 @@
 static void audqcelp_out_flush(struct audio_qcelp_in *audio)
 {
 	int i;
+	unsigned long flags;
 
 	audio->out_head = 0;
-	audio->out_tail = 0;
 	audio->out_count = 0;
+	spin_lock_irqsave(&audio->dsp_lock, flags);
+	audio->out_tail = 0;
 	for (i = OUT_FRAME_NUM-1; i >= 0; i--) {
 		audio->out[i].size = 0;
 		audio->out[i].read = 0;
 		audio->out[i].used = 0;
 	}
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 }
 
 /* ------------------- device --------------------- */
diff --git a/arch/arm/mach-msm/qdsp5/audio_wma.c b/arch/arm/mach-msm/qdsp5/audio_wma.c
index cf2ade4..a9e82df 100644
--- a/arch/arm/mach-msm/qdsp5/audio_wma.c
+++ b/arch/arm/mach-msm/qdsp5/audio_wma.c
@@ -1,6 +1,6 @@
 /* audio_wma.c - wma audio decoder driver
  *
- * Copyright (c) 2009, 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009, 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5/audio_mp3.c
  *
@@ -659,11 +659,15 @@
 
 static void audio_flush(struct audio *audio)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&audio->dsp_lock, flags);
 	audio->out[0].used = 0;
 	audio->out[1].used = 0;
 	audio->out_head = 0;
 	audio->out_tail = 0;
 	audio->reserved = 0;
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 	atomic_set(&audio->out_bytes, 0);
 }
 
@@ -671,11 +675,15 @@
 {
 	uint8_t index;
 
+	unsigned long flags;
+
+	spin_lock_irqsave(&audio->dsp_lock, flags);
 	for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
 		audio->in[index].used = 0;
 	audio->buf_refresh = 0;
 	audio->read_next = 0;
 	audio->fill_next = 0;
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 }
 
 static void audio_ioport_reset(struct audio *audio)
diff --git a/arch/arm/mach-msm/qdsp5/audio_wmapro.c b/arch/arm/mach-msm/qdsp5/audio_wmapro.c
index d9b384a..6d6cc27 100644
--- a/arch/arm/mach-msm/qdsp5/audio_wmapro.c
+++ b/arch/arm/mach-msm/qdsp5/audio_wmapro.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * All source code in this file is licensed under the following license except
  * where indicated.
@@ -648,23 +648,30 @@
 
 static void audio_flush(struct audio *audio)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&audio->dsp_lock, flags);
 	audio->out[0].used = 0;
 	audio->out[1].used = 0;
 	audio->out_head = 0;
 	audio->out_tail = 0;
 	audio->reserved = 0;
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 	atomic_set(&audio->out_bytes, 0);
 }
 
 static void audio_flush_pcm_buf(struct audio *audio)
 {
 	uint8_t index;
+	unsigned long flags;
 
+	spin_lock_irqsave(&audio->dsp_lock, flags);
 	for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
 		audio->in[index].used = 0;
 	audio->buf_refresh = 0;
 	audio->read_next = 0;
 	audio->fill_next = 0;
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 }
 
 static void audio_ioport_reset(struct audio *audio)