tspp: Add synchronization between API call and tasklet

The TSPP driver uses a tasklet which is scheduled on BAM transfer
completion to process the data. The tasklet verifies that the
channel had not already been closed. Therefore, it is necessary
to have a synchronization mechanism between the channel_close API
function and the tasklet function. Added acquisition of spinlock
in the channel_close function.

Change-Id: I274298cbc9c83b4b6c1d50ffb709b8c5d8d43231
CRs-Fixed: 477556
Signed-off-by: Liron Kuch <lkuch@codeaurora.org>
diff --git a/drivers/misc/tspp.c b/drivers/misc/tspp.c
index 3b226ad..eaf795b 100644
--- a/drivers/misc/tspp.c
+++ b/drivers/misc/tspp.c
@@ -1571,6 +1571,7 @@
 	int id;
 	int table_idx;
 	u32 val;
+	unsigned long flags;
 
 	struct sps_connect *config;
 	struct tspp_device *pdev;
@@ -1591,6 +1592,15 @@
 	if (!channel->used)
 		return 0;
 
+	/*
+	 * Need to protect access to used and waiting fields, as they are
+	 * used by the tasklet which is invoked from interrupt context
+	 */
+	spin_lock_irqsave(&pdev->spinlock, flags);
+	channel->used = 0;
+	channel->waiting = NULL;
+	spin_unlock_irqrestore(&pdev->spinlock, flags);
+
 	if (channel->expiration_period_ms)
 		del_timer(&channel->expiration_timer);
 
@@ -1644,9 +1654,7 @@
 	channel->buffer_count = 0;
 	channel->data = NULL;
 	channel->read = NULL;
-	channel->waiting = NULL;
 	channel->locked = NULL;
-	channel->used = 0;
 
 	if (tspp_channels_in_use(pdev) == 0) {
 		wake_unlock(&pdev->wake_lock);