Merge "msm: sps: Fix BAM ISR race with pipe disconnect"
diff --git a/drivers/platform/msm/sps/sps_bam.c b/drivers/platform/msm/sps/sps_bam.c
index 7716ccb..5ad281d 100644
--- a/drivers/platform/msm/sps/sps_bam.c
+++ b/drivers/platform/msm/sps/sps_bam.c
@@ -165,7 +165,8 @@
 
 	list_for_each_entry(pipe, &dev->pipes_q, list) {
 		/* Check this pipe's bit in the source mask */
-		if ((source & pipe->pipe_index_mask)) {
+		if (BAM_PIPE_IS_ASSIGNED(pipe)
+				&& (source & pipe->pipe_index_mask)) {
 			/* This pipe has an interrupt pending */
 			pipe_handler(dev, pipe);
 			source &= ~pipe->pipe_index_mask;
diff --git a/drivers/platform/msm/sps/sps_rm.c b/drivers/platform/msm/sps/sps_rm.c
index ccdeaf7..2b46203 100644
--- a/drivers/platform/msm/sps/sps_rm.c
+++ b/drivers/platform/msm/sps/sps_rm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -18,6 +18,7 @@
 #include <linux/list.h>		/* list_head */
 #include <linux/slab.h>		/* kzalloc() */
 #include <linux/memory.h>	/* memset */
+#include <linux/interrupt.h>
 
 #include "spsi.h"
 #include "sps_core.h"
@@ -555,8 +556,11 @@
 {
 	struct sps_connection *map = (void *)pipe->map;
 	struct sps_connect *cfg = &pipe->connect;
+	struct sps_bam *bam = pipe->bam;
+	unsigned long flags;
 
 	mutex_lock(&sps_rm->lock);
+	spin_lock_irqsave(&bam->isr_lock, flags);
 
 	/* Free this connection */
 	if (cfg->mode == SPS_MODE_SRC)
@@ -570,6 +574,7 @@
 
 	sps_rm_remove_ref(map);
 
+	spin_unlock_irqrestore(&bam->isr_lock, flags);
 	mutex_unlock(&sps_rm->lock);
 
 	return 0;
@@ -782,6 +787,8 @@
 	if (pipe->client_state == SPS_STATE_CONNECT &&
 	    state == SPS_STATE_DISCONNECT) {
 		struct sps_connection *map;
+		struct sps_bam *bam = pipe->bam;
+		unsigned long flags;
 		u32 pipe_index;
 
 		if (pipe->connect.mode == SPS_MODE_SRC)
@@ -789,8 +796,12 @@
 		else
 			pipe_index = pipe->map->dest.pipe_index;
 
+		if (bam->props.irq > 0)
+			synchronize_irq(bam->props.irq);
 
+		spin_lock_irqsave(&bam->isr_lock, flags);
 		result = sps_bam_pipe_disconnect(pipe->bam, pipe_index);
+		spin_unlock_irqrestore(&bam->isr_lock, flags);
 		if (result) {
 			SPS_ERR("sps:Failed to disconnect BAM 0x%x pipe %d",
 				pipe->bam->props.phys_addr,