msm: smd: provide atomic channel writes

Some smd clients may write from multiple threads, in which case it's
not safe to call smd_write without holding a lock.  smd_write_atomic()
provides the same functionality as smd_write() but obtains the smd
lock first.

Signed-off-by: Brian Swetland <swetland@google.com>
Signed-off-by: Daniel Walker <dwalker@codeaurora.org>
diff --git a/arch/arm/mach-msm/include/mach/msm_smd.h b/arch/arm/mach-msm/include/mach/msm_smd.h
index bdf7731..aa076e4 100644
--- a/arch/arm/mach-msm/include/mach/msm_smd.h
+++ b/arch/arm/mach-msm/include/mach/msm_smd.h
@@ -38,6 +38,7 @@
 ** it will return the requested length written or an error.
 */
 int smd_write(smd_channel_t *ch, const void *data, int len);
+int smd_write_atomic(smd_channel_t *ch, const void *data, int len);
 
 int smd_write_avail(smd_channel_t *ch);
 int smd_read_avail(smd_channel_t *ch);
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index 655fe42..086fd77 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -804,6 +804,16 @@
 	return ch->write(ch, data, len);
 }
 
+int smd_write_atomic(smd_channel_t *ch, const void *data, int len)
+{
+	unsigned long flags;
+	int res;
+	spin_lock_irqsave(&smd_lock, flags);
+	res = ch->write(ch, data, len);
+	spin_unlock_irqrestore(&smd_lock, flags);
+	return res;
+}
+
 int smd_read_avail(smd_channel_t *ch)
 {
 	return ch->read_avail(ch);