msm: bam_dmux: change write_lock acquire mode

Change writelock() to write_trylock_irqsave().  The irqsave prevents
deadlock when an interrupt is handled while the write_lock is held, and
the irq attempts to grab the read_lock.  The trylock prevents deadlock
when ul_timeout() is scheduled while the read_lock is held thus the
write_lock cannot be grabbed and irqsave prevents scheduling.

Change-Id: I19e7c995e645d447e93559a6fbb10ff08ee80815
CRs-Fixed: 319109
Signed-off-by: Jeffrey Hugo <jhugo@codeaurora.org>
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index c70e1b5..8ebac5b 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -877,9 +877,17 @@
 
 static void ul_timeout(struct work_struct *work)
 {
+	unsigned long flags;
+	int ret;
+
 	if (in_global_reset)
 		return;
-	write_lock(&ul_wakeup_lock);
+	ret = write_trylock_irqsave(&ul_wakeup_lock, flags);
+	if (!ret) { /* failed to grab lock, reschedule and bail */
+		schedule_delayed_work(&ul_timeout_work,
+				msecs_to_jiffies(UL_TIMEOUT_DELAY));
+		return;
+	}
 	if (ul_packet_written) {
 		ul_packet_written = 0;
 		schedule_delayed_work(&ul_timeout_work,
@@ -889,7 +897,7 @@
 		bam_is_connected = 0;
 		notify_all(BAM_DMUX_UL_DISCONNECTED, (unsigned long)(NULL));
 	}
-	write_unlock(&ul_wakeup_lock);
+	write_unlock_irqrestore(&ul_wakeup_lock, flags);
 }
 static void ul_wakeup(void)
 {