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);