Merge "msm: camera: add check for csid_cid to prevent of overwrite memory"
diff --git a/Documentation/devicetree/bindings/wcnss/wcnss-wlan.txt b/Documentation/devicetree/bindings/wcnss/wcnss-wlan.txt
index 2cb528c..6ef897a 100644
--- a/Documentation/devicetree/bindings/wcnss/wcnss-wlan.txt
+++ b/Documentation/devicetree/bindings/wcnss/wcnss-wlan.txt
@@ -39,7 +39,7 @@
         1200   -  WCN XO settling time (usec)
         1      -  WCN RPM power collapse enabled
         1      -  WCN standalone power collapse enabled
-
+        6      -  GPIO strength value
 
 Example:
 
@@ -64,5 +64,5 @@
         qcom,has-48mhz-xo;
         qcom,has-pronto-hw;
         qcom,wcnss-adc_tm = <&pm8226_adc_tm>;
-	qcom,wcnss-pm = <11 21 1200 1 1>;
+	qcom,wcnss-pm = <11 21 1200 1 1 6>;
     };
diff --git a/arch/arm/configs/msm8610-perf_defconfig b/arch/arm/configs/msm8610-perf_defconfig
index 55bc185..a521cbc 100644
--- a/arch/arm/configs/msm8610-perf_defconfig
+++ b/arch/arm/configs/msm8610-perf_defconfig
@@ -74,6 +74,7 @@
 CONFIG_ARM_ARCH_TIMER=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
 CONFIG_COMPACTION=y
 CONFIG_KSM=y
 CONFIG_CC_STACKPROTECTOR=y
diff --git a/arch/arm/configs/msm8610_defconfig b/arch/arm/configs/msm8610_defconfig
index b239bcb..1f7fcbd 100644
--- a/arch/arm/configs/msm8610_defconfig
+++ b/arch/arm/configs/msm8610_defconfig
@@ -75,6 +75,7 @@
 CONFIG_ARM_ARCH_TIMER=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
 CONFIG_COMPACTION=y
 CONFIG_KSM=y
 CONFIG_CC_STACKPROTECTOR=y
diff --git a/arch/arm/mach-msm/msm_rtb.c b/arch/arm/mach-msm/msm_rtb.c
index 28b2195..6a71e36 100644
--- a/arch/arm/mach-msm/msm_rtb.c
+++ b/arch/arm/mach-msm/msm_rtb.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, 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
@@ -23,7 +23,7 @@
 #include <linux/string.h>
 #include <linux/atomic.h>
 #include <linux/of.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm-generic/sizes.h>
 #include <mach/memory.h>
 #include <mach/msm_rtb.h>
@@ -38,18 +38,20 @@
 /* Write
  * 1) 3 bytes sentinel
  * 2) 1 bytes of log type
- * 3) 4 bytes of where the caller came from
+ * 3) 8 bytes of where the caller came from
  * 4) 4 bytes index
- * 4) 4 bytes extra data from the caller
+ * 4) 8 bytes extra data from the caller
+ * 5) 8 bytes for timestamp
  *
- * Total = 16 bytes.
+ * Total = 32 bytes.
  */
 struct msm_rtb_layout {
 	unsigned char sentinel[3];
 	unsigned char log_type;
-	void *caller;
-	unsigned long idx;
-	void *data;
+	uint32_t idx;
+	uint64_t caller;
+	uint64_t data;
+	uint64_t timestamp;
 } __attribute__ ((__packed__));
 
 
@@ -70,7 +72,7 @@
 static atomic_t msm_rtb_idx;
 #endif
 
-struct msm_rtb_state msm_rtb = {
+static struct msm_rtb_state msm_rtb = {
 	.filter = 1 << LOGK_LOGBUF,
 	.enabled = 1,
 };
@@ -109,24 +111,29 @@
 	start->log_type = (char)log_type;
 }
 
-static void msm_rtb_write_caller(void *caller, struct msm_rtb_layout *start)
+static void msm_rtb_write_caller(uint64_t caller, struct msm_rtb_layout *start)
 {
 	start->caller = caller;
 }
 
-static void msm_rtb_write_idx(unsigned long idx,
+static void msm_rtb_write_idx(uint32_t idx,
 				struct msm_rtb_layout *start)
 {
 	start->idx = idx;
 }
 
-static void msm_rtb_write_data(void *data, struct msm_rtb_layout *start)
+static void msm_rtb_write_data(uint64_t data, struct msm_rtb_layout *start)
 {
 	start->data = data;
 }
 
-static void uncached_logk_pc_idx(enum logk_event_type log_type, void *caller,
-				 void *data, int idx)
+static void msm_rtb_write_timestamp(struct msm_rtb_layout *start)
+{
+	start->timestamp = sched_clock();
+}
+
+static void uncached_logk_pc_idx(enum logk_event_type log_type, uint64_t caller,
+				 uint64_t data, int idx)
 {
 	struct msm_rtb_layout *start;
 
@@ -137,6 +144,7 @@
 	msm_rtb_write_caller(caller, start);
 	msm_rtb_write_idx(idx, start);
 	msm_rtb_write_data(data, start);
+	msm_rtb_write_timestamp(start);
 	mb();
 
 	return;
@@ -145,13 +153,10 @@
 static void uncached_logk_timestamp(int idx)
 {
 	unsigned long long timestamp;
-	void *timestamp_upper, *timestamp_lower;
 	timestamp = sched_clock();
-	timestamp_lower = (void *)lower_32_bits(timestamp);
-	timestamp_upper = (void *)upper_32_bits(timestamp);
-
-	uncached_logk_pc_idx(LOGK_TIMESTAMP|LOGTYPE_NOPC, timestamp_lower,
-			     timestamp_upper, idx);
+	uncached_logk_pc_idx(LOGK_TIMESTAMP|LOGTYPE_NOPC,
+			(uint64_t)lower_32_bits(timestamp),
+			(uint64_t)upper_32_bits(timestamp), idx);
 }
 
 #if defined(CONFIG_MSM_RTB_SEPARATE_CPUS)
@@ -213,7 +218,8 @@
 
 	i = msm_rtb_get_idx();
 
-	uncached_logk_pc_idx(log_type, caller, data, i);
+	uncached_logk_pc_idx(log_type, (uint64_t)((unsigned long) caller),
+				(uint64_t)((unsigned long) data), i);
 
 	return 1;
 }
@@ -225,7 +231,7 @@
 }
 EXPORT_SYMBOL(uncached_logk);
 
-int msm_rtb_probe(struct platform_device *pdev)
+static int msm_rtb_probe(struct platform_device *pdev)
 {
 	struct msm_rtb_platform_data *d = pdev->dev.platform_data;
 #if defined(CONFIG_MSM_RTB_SEPARATE_CPUS)
@@ -297,7 +303,6 @@
 	{.compatible = RTB_COMPAT_STR},
 	{},
 };
-EXPORT_COMPAT(RTB_COMPAT_STR);
 
 static struct platform_driver msm_rtb_driver = {
 	.driver         = {
diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c
index bcab791..d79a169 100644
--- a/drivers/gpu/msm/adreno_dispatch.c
+++ b/drivers/gpu/msm/adreno_dispatch.c
@@ -221,13 +221,17 @@
 		struct adreno_context *drawctxt, struct kgsl_cmdbatch *cmdbatch)
 {
 	unsigned int prev;
+	struct kgsl_device *device;
 	spin_lock(&drawctxt->lock);
 
 	if (kgsl_context_detached(&drawctxt->base) ||
 		drawctxt->state == ADRENO_CONTEXT_STATE_INVALID) {
 		spin_unlock(&drawctxt->lock);
+		device = cmdbatch->device;
 		/* get rid of this cmdbatch since the context is bad */
+		kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
 		kgsl_cmdbatch_destroy(cmdbatch);
+		kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
 		return -EINVAL;
 	}
 
@@ -414,7 +418,10 @@
 		 */
 
 		if (cmdbatch->flags & KGSL_CONTEXT_SYNC) {
+			struct kgsl_device *device = cmdbatch->device;
+			kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
 			kgsl_cmdbatch_destroy(cmdbatch);
+			kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
 			continue;
 		}
 
@@ -931,11 +938,8 @@
 			drawctxt->state == ADRENO_CONTEXT_STATE_INVALID) {
 			replay[i] = NULL;
 
-			kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
 			kgsl_cancel_events_timestamp(device, cmd->context,
 				cmd->timestamp);
-			kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
-
 			kgsl_cmdbatch_destroy(cmd);
 		}
 	}
@@ -1084,7 +1088,8 @@
 		kgsl_device_snapshot(device, 1);
 	}
 
-	kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+    kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+
 
 	/* Allocate memory to store the inflight commands */
 	replay = kzalloc(sizeof(*replay) * dispatcher->inflight, GFP_KERNEL);
@@ -1092,6 +1097,7 @@
 	if (replay == NULL) {
 		unsigned int ptr = dispatcher->head;
 
+		kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
 		/* Recovery failed - mark everybody guilty */
 		mark_guilty_context(device, 0);
 
@@ -1111,6 +1117,7 @@
 		 */
 
 		count = 0;
+		kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
 		goto replay;
 	}
 
@@ -1168,7 +1175,9 @@
 			cmdbatch->context->id, cmdbatch->timestamp);
 
 		mark_guilty_context(device, cmdbatch->context->id);
+		kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
 		adreno_drawctxt_invalidate(device, cmdbatch->context);
+		kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
 	}
 
 	/*
@@ -1277,7 +1286,9 @@
 	mark_guilty_context(device, cmdbatch->context->id);
 
 	/* Invalidate the context */
+	kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
 	adreno_drawctxt_invalidate(device, cmdbatch->context);
+	kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
 
 
 replay:
@@ -1296,8 +1307,10 @@
 	/* If adreno_reset() fails then what hope do we have for the future? */
 	BUG_ON(ret);
 
+	kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
 	/* Remove any pending command batches that have been invalidated */
 	remove_invalidated_cmdbatches(device, replay, count);
+	kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
 
 	/* Replay the pending command buffers */
 	for (i = 0; i < count; i++) {
@@ -1339,9 +1352,11 @@
 			/* Mark this context as guilty (failed recovery) */
 			mark_guilty_context(device, replay[i]->context->id);
 
+			kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
 			adreno_drawctxt_invalidate(device, replay[i]->context);
 			remove_invalidated_cmdbatches(device, &replay[i],
 				count - i);
+			kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
 		}
 	}
 
@@ -1449,8 +1464,10 @@
 			dispatcher->head = CMDQUEUE_NEXT(dispatcher->head,
 				ADRENO_DISPATCH_CMDQUEUE_SIZE);
 
+			kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
 			/* Destroy the retired command batch */
 			kgsl_cmdbatch_destroy(cmdbatch);
+			kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
 
 			/* Update the expire time for the next command batch */
 
@@ -1695,16 +1712,19 @@
 void adreno_dispatcher_close(struct adreno_device *adreno_dev)
 {
 	struct adreno_dispatcher *dispatcher = &adreno_dev->dispatcher;
+	struct kgsl_device *device = &adreno_dev->dev;
 
 	mutex_lock(&dispatcher->mutex);
 	del_timer_sync(&dispatcher->timer);
 	del_timer_sync(&dispatcher->fault_timer);
 
+	kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
 	while (dispatcher->head != dispatcher->tail) {
 		kgsl_cmdbatch_destroy(dispatcher->cmdqueue[dispatcher->head]);
 		dispatcher->head = (dispatcher->head + 1)
 			% ADRENO_DISPATCH_CMDQUEUE_SIZE;
 	}
+	kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
 
 	mutex_unlock(&dispatcher->mutex);
 
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 9adede8..a5b25a0 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -1807,16 +1807,13 @@
 	list_for_each_entry_safe(event, tmp, &cancel_synclist, node) {
 
 		if (event->type == KGSL_CMD_SYNCPOINT_TYPE_TIMESTAMP) {
-			struct kgsl_device *device = cmdbatch->device;
 			/*
 			 * Timestamp events are guaranteed to signal
 			 * when canceled
 			 */
-			kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
-			kgsl_cancel_event(device, event->context,
+			kgsl_cancel_event(cmdbatch->device, event->context,
 				event->timestamp, kgsl_cmdbatch_sync_func,
 				event);
-			kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
 		} else if (event->type == KGSL_CMD_SYNCPOINT_TYPE_FENCE) {
 			/* Put events that are successfully canceled */
 			if (kgsl_sync_fence_async_cancel(event->handle))
@@ -2314,8 +2311,11 @@
 	 * -EPROTO is a "success" error - it just tells the user that the
 	 * context had previously faulted
 	 */
-	if (result && result != -EPROTO)
+	if (result && result != -EPROTO) {
+		kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
 		kgsl_cmdbatch_destroy(cmdbatch);
+		kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+	}
 
 done:
 	kgsl_context_put(context);
@@ -2366,8 +2366,11 @@
 	 * -EPROTO is a "success" error - it just tells the user that the
 	 * context had previously faulted
 	 */
-	if (result && result != -EPROTO)
+	if (result && result != -EPROTO) {
+		kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
 		kgsl_cmdbatch_destroy(cmdbatch);
+		kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
+	}
 
 done:
 	kgsl_context_put(context);
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index 4a4a88c..887bb72 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -1948,13 +1948,13 @@
 		return;
 	}
 
-	pr_debug("%s:size=%d: <%d, %d, %d, %d, %d>\n", __func__,
+	pr_debug("%s:size=%d: <%d, %d, %d, %d, %d %d>\n", __func__,
 			prop_len, *payload, *(payload+1), *(payload+2),
-			*(payload+3), *(payload+4));
+			*(payload+3), *(payload+4), *(payload+5));
 
 	hdr = (struct smd_msg_hdr *)msg;
 	hdr->msg_type = WCNSS_PM_CONFIG_REQ;
-	hdr->msg_len = sizeof(struct smd_msg_hdr) + prop_len;
+	hdr->msg_len = sizeof(struct smd_msg_hdr) + (prop_len * sizeof(int));
 
 	rc = wcnss_smd_tx(msg, hdr->msg_len);
 	if (rc < 0)
diff --git a/drivers/nfc/nfc-nci.c b/drivers/nfc/nfc-nci.c
index e51da7f..b1681f1 100644
--- a/drivers/nfc/nfc-nci.c
+++ b/drivers/nfc/nfc-nci.c
@@ -61,7 +61,7 @@
 #define	CORE_RESET_RSP_GID		(0x60)
 #define	CORE_RESET_OID			(0x00)
 #define CORE_RST_NTF_LENGTH		(0x02)
-#define WAKE_TIMEOUT			(10)
+#define WAKE_TIMEOUT			(1000)
 #define WAKE_REG			(0x10)
 #define EFUSE_REG			(0xA0)
 #define WAKEUP_SRC_TIMEOUT		(2000)
@@ -101,6 +101,8 @@
 	struct workqueue_struct *my_wq;
 };
 
+static int nfcc_reboot(struct notifier_block *notifier, unsigned long val,
+			void *v);
 static int nfc_i2c_write(struct i2c_client *client, u8 *buf, int len);
 static int nfcc_hw_check(struct i2c_client *client, unsigned short curr_addr);
 static int nfcc_initialise(struct i2c_client *client, unsigned short curr_addr,
@@ -124,7 +126,7 @@
 
 
 unsigned int	disable_ctrl;
-bool		region2_sent;
+bool			region2_sent;
 
 static void qca199x_init_stat(struct qca199x_dev *qca199x_dev)
 {
@@ -163,15 +165,16 @@
 	if (device_may_wakeup(&qca199x_dev->client->dev) &&
 		(qca199x_dev->client->dev.power.is_suspended == true)) {
 		dev_dbg(&qca199x_dev->client->dev,
-			"NFC:Processor in suspend state device_may_wakeup\n");
+			"%s: NFC:Processor in suspend state device_may_wakeup\n",
+			__func__);
 		/*
-		* Keep system awake long enough to allow userspace
-		* to process the packet.
-		*/
+		 * Keep system awake long enough to allow userspace
+		 * to process the packet.
+		 */
 		pm_wakeup_event(&qca199x_dev->client->dev, WAKEUP_SRC_TIMEOUT);
 	} else {
 		dev_dbg(&qca199x_dev->client->dev,
-			"NFC:Processor not in suspend state\n");
+			"%s: NFC:Processor not in suspend state\n", __func__);
 	}
 
 	spin_lock_irqsave(&qca199x_dev->irq_enabled_lock, flags);
@@ -329,7 +332,12 @@
 		/* READ */
 		if ((ftm_raw_write_mode == 0) && (ftm_werr_code == 0)) {
 			ftm_rerr_code = i2c_master_recv(qca199x_dev->client,
-						&rd_byte, 1);
+						&rd_byte, sizeof(rd_byte));
+
+			if (ftm_rerr_code != sizeof(rd_byte)) {
+				total = -EMSGSIZE;
+				goto err;
+			}
 			if (ftm_rerr_code == 0x1)
 				ftm_rerr_code = 0;
 			tmp[0] = (unsigned char)ftm_rerr_code;
@@ -388,8 +396,8 @@
 	if (total > 0) {
 		if ((total > count) || copy_to_user(buf, tmp, total)) {
 			dev_err(&qca199x_dev->client->dev,
-				"failed to copy to user space, total = %d\n",
-					total);
+				"%s: failed to copy to user space, total = %d\n",
+					__func__, total);
 			total = -EFAULT;
 		}
 	}
@@ -438,6 +446,9 @@
 		ret = i2c_master_recv(qca199x_dev->client, tmp, (length +
 			PAYLOAD_HEADER_LENGTH));
 		total = ret;
+		if (ret != (length + PAYLOAD_HEADER_LENGTH))
+			goto leave;
+
 	}
 	dev_dbg(&qca199x_dev->client->dev, "%s : NfcNciRx %x %x %x\n",
 			__func__, tmp[0], tmp[1], tmp[2]);
@@ -456,12 +467,13 @@
 	int nfcc_buffer = 0;
 
 	if (count > MAX_BUFFER_SIZE) {
-		dev_err(&qca199x_dev->client->dev, "out of memory\n");
+		dev_err(&qca199x_dev->client->dev, "%s: out of memory\n",
+			__func__);
 		return -ENOMEM;
 	}
 	if (copy_from_user(tmp, buf, count)) {
 		dev_err(&qca199x_dev->client->dev,
-			"nfc-nci write: failed to copy from user space\n");
+			"%s: failed to copy from user space\n", __func__);
 		return -EFAULT;
 	}
 	/*
@@ -477,7 +489,8 @@
 		/* There has been an error while reading from nfcc */
 		if (nfcc_buffer < 0) {
 			dev_err(&qca199x_dev->client->dev,
-				"nfc-nci write: error while servicing nfcc read buffer\n");
+				"%s: error while servicing nfcc read buffer\n"
+				, __func__);
 		}
 		qca199x_dev->sent_first_nci_write = true;
 		qca199x_enable_irq(qca199x_dev);
@@ -492,7 +505,7 @@
 		if (count == 1) {
 			ftm_raw_write_mode = 0;
 			ret = i2c_master_send(qca199x_dev->client, tmp, count);
-			if (ret == 1)
+			if (ret == count)
 				ftm_werr_code = 0;
 			else
 				ftm_werr_code = ret;
@@ -502,7 +515,7 @@
 		if (count == 2) {
 			ftm_raw_write_mode = 1;
 			ret = i2c_master_send(qca199x_dev->client, tmp, count);
-			if (ret == 2)
+			if (ret == count)
 				ftm_werr_code = 0;
 			else
 				ftm_werr_code = ret;
@@ -515,7 +528,7 @@
 	}
 	if (ret != count) {
 		dev_err(&qca199x_dev->client->dev,
-		"NFC: failed to write %d\n", ret);
+		"%s: failed to write %d\n", __func__, ret);
 		ret = -EIO;
 	}
 	mutex_unlock(&qca199x_dev->read_mutex);
@@ -549,7 +562,7 @@
 		qca199x_enable_irq_clk_req(qca199x_dev);
 	}
 	dev_dbg(&qca199x_dev->client->dev,
-			"%d,%d\n", imajor(inode), iminor(inode));
+			"%s: %d,%d\n", __func__, imajor(inode), iminor(inode));
 	return ret;
 }
 
@@ -561,17 +574,21 @@
 	int r = 0;
 	int time_taken = 0;
 	unsigned char raw_nci_sleep[] = {0x2F, 0x03, 0x00};
-	/* Change slave address to 0xE */
 	unsigned char raw_nci_wake[]  = {0x10, 0x0F};
-	unsigned short	slave_addr	=	0xE;
+	/* Change slave address to 0xE */
+	unsigned short	slave_addr = 0xE;
 	unsigned short	curr_addr;
-	unsigned char wake_status	= WAKE_REG;
+	unsigned char wake_status = WAKE_REG;
 	struct qca199x_dev *qca199x_dev = filp->private_data;
 
-	dev_dbg(&qca199x_dev->client->dev, "nfcc_wake: %s: info: %p\n",
+	dev_dbg(&qca199x_dev->client->dev, "%s: info: %p\n",
 			__func__, qca199x_dev);
 
+	curr_addr = qca199x_dev->client->addr;
 	if (level == NFCC_SLEEP) {
+		/*
+		 * Normal NCI write
+		 */
 		r = i2c_master_send(qca199x_dev->client, &raw_nci_sleep[0],
 						sizeof(raw_nci_sleep));
 
@@ -579,57 +596,79 @@
 			return -EMSGSIZE;
 		qca199x_dev->state = NFCC_STATE_NORMAL_SLEEP;
 	} else {
-		curr_addr = qca199x_dev->client->addr;
 		qca199x_dev->client->addr = slave_addr;
 		r = nfc_i2c_write(qca199x_dev->client, &raw_nci_wake[0],
 						sizeof(raw_nci_wake));
+		if (r != sizeof(raw_nci_wake)) {
+			r = -EMSGSIZE;
+			dev_err(&qca199x_dev->client->dev,
+				"%s: nci wake write failed. Check hardware\n",
+				__func__);
+			goto leave;
+		}
 		do {
 			wake_status = WAKE_REG;
-			r = nfc_i2c_write(qca199x_dev->client, &wake_status, 1);
+			r = nfc_i2c_write(qca199x_dev->client, &wake_status,
+						 sizeof(wake_status));
+			if (r != sizeof(wake_status)) {
+				r = -EMSGSIZE;
+				dev_err(&qca199x_dev->client->dev,
+				"%s: wake status write fail.Check hardware\n",
+				 __func__);
+				goto leave;
+			}
 			/*
-			 * NFCC chip needs to be at least
-			 * 10usec high before make it low
+			 * I2C line is low after ~10 usec
 			 */
 			usleep_range(10, 15);
 			r = i2c_master_recv(qca199x_dev->client, &wake_status,
 						sizeof(wake_status));
+			if (r != sizeof(wake_status)) {
+				r = -EMSGSIZE;
+				dev_err(&qca199x_dev->client->dev,
+				"%s: wake status read fail.Check hardware\n",
+				 __func__);
+				goto leave;
+			}
 
 			time_taken++;
+			/*
+			 * Each NFCC wakeup cycle
+			 * takes about 0.5 ms
+			 */
 			if ((wake_status & NCI_WAKE) != 0)
 				/* NFCC wakeup time is between 0.5 and .52 ms */
-				usleep_range(500, 520);
+				usleep_range(500, 550);
 
 		} while ((wake_status & NCI_WAKE)
 				&& (time_taken < WAKE_TIMEOUT));
-		/* Restore original NFCC slave I2C address */
-
-		qca199x_dev->client->addr = curr_addr;
-		if (r != sizeof(wake_status))
-			return -EMSGSIZE;
-
 		if (time_taken >= WAKE_TIMEOUT) {
 			dev_err(&qca199x_dev->client->dev,
-			" %s : TIMED OUT to get WAKEUP bit\n", __func__);
+			"%s: timed out to get wakeup bit\n", __func__);
 			r = -EIO;
+			goto leave;
 		}
+		r = 0;
 		qca199x_dev->state = NFCC_STATE_NORMAL_WAKE;
 	}
-
+leave:
+	/* Restore original NFCC slave I2C address */
+	qca199x_dev->client->addr = curr_addr;
 	return r;
 }
 
 /*
  * Inside nfc_ioctl_power_states
  *
- * @brief   ioctl functions
+ * @brief	ioctl functions
  *
  *
  * Device control
  * remove control via ioctl
- * (arg = 0): NFC_DISABLE   GPIO = 0
- * (arg = 1): NFC_DISABLE   GPIO = 1
- *  NOT USED   (arg = 2): FW_DL GPIO = 0
- *  NOT USED   (arg = 3): FW_DL GPIO = 1
+ * (arg = 0): NFC_DISABLE	GPIO = 0
+ * (arg = 1): NFC_DISABLE	GPIO = 1
+ *	NOT USED   (arg = 2): FW_DL GPIO = 0
+ *	NOT USED   (arg = 3): FW_DL GPIO = 1
  * (arg = 4): NFCC_WAKE  = 1
  * (arg = 5): NFCC_WAKE  = 0
  *
@@ -648,7 +687,7 @@
 		dev_dbg(&qca199x_dev->client->dev, "gpio_set_value disable: %s: info: %p\n",
 			__func__, qca199x_dev);
 		gpio_set_value(qca199x_dev->dis_gpio, 0);
-		usleep(1000);
+		usleep_range(1000, 1100);
 	} else if (arg == 1) {
 		/*
 		 * We are attempting a hardware reset so let us disable
@@ -670,7 +709,7 @@
 		dev_dbg(&qca199x_dev->client->dev, "gpio_set_value enable: %s: info: %p\n",
 			__func__, qca199x_dev);
 		gpio_set_value(qca199x_dev->dis_gpio, 1);
-		/*nfcc needs atleast 100ms for the chip to power cycle*/
+		/* NFCC needs at least 100 ms to power cycle*/
 		msleep(100);
 	} else if (arg == 2) {
 		mutex_lock(&qca199x_dev->read_mutex);
@@ -708,14 +747,14 @@
 /*
  * Inside nfc_ioctl_nfcc_mode
  *
- * @brief   nfc_ioctl_nfcc_mode
+ * @brief	nfc_ioctl_nfcc_mode
  *
  * (arg = 0) ; NORMAL_MODE - Standard mode, unsolicited read behaviour
  * (arg = 1) ; SOLICITED_MODE - As above but reads are solicited from User Land
  * (arg = 2) ; UNSOLICITED_FTM_RAW MODE - NORMAL_MODE but messages from FTM and
- *             not NCI Host.
+ *			   not NCI Host.
  * (arg = 2) ; SOLICITED_FTM_RAW_MODE - As SOLICITED_MODE but messages from FTM
- *             and not NCI Host.
+ *			   and not NCI Host.
  *
  *
  *
@@ -766,6 +805,7 @@
  *
  * @brief   nfc_ioctl_nfcc_efuse
  *
+ *
  */
 int nfc_ioctl_nfcc_efuse(struct file *filp, unsigned int cmd,
 				unsigned long arg)
@@ -826,11 +866,8 @@
 				unsigned long arg)
 {
 	int r = 0;
-	int	time_taken	= 0;
-	unsigned short	slave_addr	=	0xE;
+	unsigned short	slave_addr = 0xE;
 	unsigned short	curr_addr;
-	unsigned char	raw_nci_wake[]			= {0x10, 0x0F};
-	unsigned char	raw_nci_read;
 	unsigned char raw_chip_version_addr		= 0x00;
 	unsigned char raw_chip_rev_id_addr		= 0x9C;
 	unsigned char raw_chip_version			= 0xFF;
@@ -844,88 +881,56 @@
 	 * Always wake up chip when reading 0x9C, otherwise this
 	 * register is not updated
 	 */
+	r = nfcc_wake(NFCC_WAKE, filp);
 	curr_addr = qca199x_dev->client->addr;
 	qca199x_dev->client->addr = slave_addr;
-	r = nfc_i2c_write(qca199x_dev->client, &raw_nci_wake[0],
-						sizeof(raw_nci_wake));
 
-	if (r != sizeof(raw_nci_wake))
+
+	if (r) {
 		dev_err(&qca199x_dev->client->dev,
-		"nfc_ioctl_nfcc_version : failed to send wake command\n");
-
-	/*
-	 * After placing the NFCC to sleep by a PROP
-	 * SLEEP NCI msg (2F 03) and we need to wake
-	 * it back up to obtain some information (by
-	 * setting the wake bit).We need to determine
-	 * when it has in actual fact woken before we
-	 * can read the required data. We do that by
-	 * reading back & testing if that wake bit has
-	 * been cleared.
-	 */
-	do {
-		raw_nci_read = 0x10;
-		r = nfc_i2c_write(qca199x_dev->client, &raw_nci_read, 1);
-		/*
-		 * NFCC chip needs to be at least
-		 * 10usec high before make it low
-		 */
-		usleep_range(10, 15);
-
-		r = i2c_master_recv(qca199x_dev->client, &raw_nci_read,
-						sizeof(raw_nci_read));
-
-		if ((raw_nci_read & NCI_WAKE) != 0)
-			/* NFCC wakeup time is between 0.5 and .52 ms */
-			usleep_range(500, 520);
-
-		time_taken++;
-
-	} while ((raw_nci_read & NCI_WAKE)
-			&& (time_taken < WAKE_TIMEOUT));
-
-	if (time_taken < WAKE_TIMEOUT)
-		qca199x_dev->state = NFCC_STATE_NORMAL_WAKE;
-	else
-		dev_err(&qca199x_dev->client->dev,
-		"nfc_ioctl_nfcc_version : TIMED OUT to get WAKEUP bit\n");
-
-
-	if (r != 1) {
-		/*
-		 * r < 0 indicates an error, maybe chip isn't
-		 * up yet.What should we do??? r = 0 indicates
-		 * nothing read, maybe chip isn't up yet. (should
-		 * not happen) r > 1 indicates too many bytes read,
-		 * maybe ?(should not happen)
-		 */
-		dev_err(&qca199x_dev->client->dev,
-		"nfc_ioctl_nfcc_version : i2c error %d\n", r);
+		"%s: nfcc wake failed: %d\n", __func__, r);
+		r = -EIO;
+		goto leave;
 	}
 
 	if (arg == 0) {
 		r = nfc_i2c_write(qca199x_dev->client,
-				&raw_chip_version_addr, 1);
+			&raw_chip_version_addr, sizeof(raw_chip_version_addr));
+		if (r != sizeof(raw_chip_version_addr)) {
+			r = -EMSGSIZE;
+			goto err;
+		}
 	} else if (arg == 1) {
 		r = nfc_i2c_write(qca199x_dev->client,
-				&raw_chip_rev_id_addr, 1);
+			&raw_chip_rev_id_addr, sizeof(raw_chip_rev_id_addr));
+		if (r != sizeof(raw_chip_version_addr)) {
+			r = -EMSGSIZE;
+			goto err;
+		}
 	} else {
-		/* Restore original NFCC slave I2C address */
-		qca199x_dev->client->addr = curr_addr;
-		return -EINVAL;
+		r = -EINVAL;
+		goto err;
 	}
 
 	if (r < 0) {
-		/* Restore original NFCC slave I2C address */
-		qca199x_dev->client->addr = curr_addr;
-		dev_err(&qca199x_dev->client->dev,
-			"NFCC_INVALID_CHIP_VERSION : i2c write fail\n");
-		return -EIO;
+		r = -EIO;
+		goto err;
 	}
-
-	usleep(10);
-	r = i2c_master_recv(qca199x_dev->client, &raw_chip_version, 1);
-
+	/*
+	* I2C line is low after ~10 usec
+	*/
+	usleep_range(10, 15);
+	r = i2c_master_recv(qca199x_dev->client, &raw_chip_version,
+		sizeof(raw_chip_version));
+	if (r != sizeof(raw_chip_version)) {
+		r = -EMSGSIZE;
+		goto err;
+	}
+	goto leave;
+err:
+	dev_err(&qca199x_dev->client->dev,
+		"%s: i2c access failed\n", __func__);
+leave:
 	/* Restore original NFCC slave I2C address */
 	qca199x_dev->client->addr = curr_addr;
 	return raw_chip_version;
@@ -934,12 +939,12 @@
 /*
  * Inside nfc_ioctl_kernel_logging
  *
- * @brief   nfc_ioctl_kernel_logging
+ * @brief	nfc_ioctl_kernel_logging
  *
  * (arg = 0) ; NO_LOGGING
  * (arg = 1) ; COMMS_LOGGING - BASIC LOGGING - Mainly just comms over I2C
  * (arg = 2) ; FULL_LOGGING - ENABLE ALL  - DBG messages for handlers etc.
- *           ; ! Be aware as amount of logging could impact behaviour !
+ *		; ! Be aware as amount of logging could impact behaviour !
  *
  *
  */
@@ -947,19 +952,19 @@
 {
 	int retval = 0;
 	struct qca199x_dev *qca199x_dev = container_of(filp->private_data,
-							   struct qca199x_dev,
-							   qca199x_device);
+							struct qca199x_dev,
+							qca199x_device);
 	if (arg == 0) {
 		dev_dbg(&qca199x_dev->client->dev,
-		"nfc_ioctl_kernel_logging : level = NO_LOGGING\n");
+		"%s : level = NO_LOGGING\n", __func__);
 		logging_level = 0;
 	} else if (arg == 1) {
 		dev_dbg(&qca199x_dev->client->dev,
-		"nfc_ioctl_kernel_logging: level = COMMS_LOGGING only\n");
+		"%s: level = COMMS_LOGGING only\n", __func__);
 		logging_level = 1;
 	} else if (arg == 2) {
 		dev_dbg(&qca199x_dev->client->dev,
-		"nfc_ioctl_kernel_logging: level = FULL_LOGGING\n");
+		"%s: level = FULL_LOGGING\n", __func__);
 		logging_level = 2;
 	}
 	return retval;
@@ -968,7 +973,7 @@
 /*
  * Inside nfc_ioctl_core_reset_ntf
  *
- * @brief   nfc_ioctl_core_reset_ntf
+ * @brief	nfc_ioctl_core_reset_ntf
  *
  * Allows callers to determine if a CORE_RESET_NTF has arrived
  *
@@ -980,22 +985,23 @@
 {
 	struct qca199x_dev *qca199x_dev = filp->private_data;
 	dev_dbg(&qca199x_dev->client->dev,
-		"nfc_ioctl_core_reset_ntf: returning = %d\n",
+		"%s: returning = %d\n",
+		__func__,
 		qca199x_dev->core_reset_ntf);
 	return qca199x_dev->core_reset_ntf;
 }
 
-static long nfc_ioctl(struct file *pfile, unsigned int cmd, unsigned long arg)
+static long nfc_ioctl(struct file *pfile, unsigned int cmd,
+			unsigned long arg)
 {
 	int r = 0;
 	struct qca199x_dev *qca199x_dev = pfile->private_data;
 	switch (cmd) {
-
 	case NFC_SET_PWR:
 		r = nfc_ioctl_power_states(pfile, cmd, arg);
 		break;
 	case NFCC_MODE:
-		nfc_ioctl_nfcc_mode(pfile, cmd, arg);
+		r = nfc_ioctl_nfcc_mode(pfile, cmd, arg);
 		break;
 	case NFCC_VERSION:
 		r = nfc_ioctl_nfcc_version(pfile, cmd, arg);
@@ -1050,9 +1056,15 @@
 		((i > 0xF) && (i < 0x12)) || ((i > 0x39) && (i < 0x4d)) ||
 		((i > 0x69) && (i < 0x74)) || (i == 0x18) || (i == 0x30) ||
 		(i == 0x58)) {
-			r = nfc_i2c_write(client, &raw_reg_rd, 1);
+			r = nfc_i2c_write(client, &raw_reg_rd,
+				sizeof(raw_reg_rd));
+			if (r != sizeof(raw_reg_rd))
+				break;
 			msleep(20);
-			r = i2c_master_recv(client, &raw_reg_rd, 1);
+			r = i2c_master_recv(client, &raw_reg_rd,
+				sizeof(raw_reg_rd));
+			if (r != sizeof(raw_reg_rd))
+				break;
 		}
 	}
 	client->addr = temp_addr;
@@ -1063,11 +1075,11 @@
 	int r;
 
 	r = i2c_master_send(client, buf, len);
-	dev_dbg(&client->dev, "send: %d\n", r);
+	dev_dbg(&client->dev, "%s: send: %d\n", __func__, r);
 	if (r == -EREMOTEIO) { /* Retry, chip was in standby */
 		usleep_range(6000, 10000);
 		r = i2c_master_send(client, buf, len);
-		dev_dbg(&client->dev, "send2: %d\n", r);
+		dev_dbg(&client->dev, "%s: send attempt 2: %d\n", __func__, r);
 	}
 	if (r != len)
 		return -EREMOTEIO;
@@ -1083,22 +1095,23 @@
 
 	client->addr = curr_addr;
 	/* Set-up Addr 0. No data written */
-	r = i2c_master_send(client, &buf, 1);
+	r = i2c_master_send(client, &buf, sizeof(buf));
 	if (r < 0)
 		goto err_presence_check;
 	buf = 0;
 	/* Read back from Addr 0 */
-	r = i2c_master_recv(client, &buf, 1);
+	r = i2c_master_recv(client, &buf, sizeof(buf));
 	if (r < 0)
 		goto err_presence_check;
 
 	r = 0;
-	return r;
+	goto leave;
 
 err_presence_check:
 	r = -ENXIO;
 	dev_err(&client->dev,
-		"nfc-nci nfcc_presence check - no NFCC available\n");
+		"%s: - no NFCC available\n", __func__);
+leave:
 	return r;
 }
 /* Initialise qca199x_ NFC controller hardware */
@@ -1106,7 +1119,7 @@
 				struct qca199x_dev *qca199x_dev)
 {
 	int r = 0;
-	unsigned char raw_1p8_CONTROL_011[]	= {0x11, XTAL_CLOCK};
+	unsigned char raw_1P8_CONTROL_011[]	= {0x11, XTAL_CLOCK};
 	unsigned char raw_1P8_CONTROL_010[]	= {0x10, PWR_EN};
 	unsigned char raw_1P8_X0_0B0[]		= {0xB0, (FREQ_SEL)};
 	unsigned char raw_slave1[]		= {0x09, NCI_I2C_SLAVE};
@@ -1123,12 +1136,17 @@
 
 	client->addr = curr_addr;
 	qca199x_dev->core_reset_ntf = DEFAULT_INITIAL_CORE_RESET_NTF;
-	r = i2c_master_send(client, &buf, 1);
+	r = i2c_master_send(client, &buf, sizeof(buf));
 	if (r < 0)
 		goto err_init;
 
+	/*
+	 * I2C line is low after ~10 usec
+	 */
+	usleep_range(10, 15);
+
 	buf = 0;
-	r = i2c_master_recv(client, &buf, 1);
+	r = i2c_master_recv(client, &buf, sizeof(buf));
 	if (r < 0)
 		goto err_init;
 
@@ -1138,36 +1156,37 @@
 	if (r < 0)
 		goto err_init;
 
-	usleep(1000);
-	RAW(1p8_CONTROL_011, XTAL_CLOCK | 0x01);
+	usleep_range(1000, 1100);
 
-	r = nfc_i2c_write(client, &raw_1p8_CONTROL_011[0],
-					sizeof(raw_1p8_CONTROL_011));
+	RAW(1P8_CONTROL_011, XTAL_CLOCK | 0x01);
+
+	r = nfc_i2c_write(client, &raw_1P8_CONTROL_011[0],
+					sizeof(raw_1P8_CONTROL_011));
 	if (r < 0)
 		goto err_init;
 
-	usleep(1000);
+	usleep_range(1000, 1100); /* 1 ms wait */
 	RAW(1P8_CONTROL_010, (0x8));
 	r = nfc_i2c_write(client, &raw_1P8_CONTROL_010[0],
 					sizeof(raw_1P8_CONTROL_010));
 	if (r < 0)
 		goto err_init;
 
-	usleep(10000);  /* 10ms wait */
+	usleep_range(10000, 11000);  /* 10 ms wait */
 	RAW(1P8_CONTROL_010, (0xC));
 	r = nfc_i2c_write(client, &raw_1P8_CONTROL_010[0],
 				sizeof(raw_1P8_CONTROL_010));
 	if (r < 0)
 		goto err_init;
 
-	usleep(100);  /* 100uS wait */
+	usleep_range(100, 110);  /* 100 us wait */
 	RAW(1P8_X0_0B0, (FREQ_SEL_19));
 	r = nfc_i2c_write(client, &raw_1P8_X0_0B0[0],
 					sizeof(raw_1P8_X0_0B0));
 	if (r < 0)
 		goto err_init;
 
-	usleep(1000);
+	usleep_range(1000, 1100); /* 1 ms wait */
 
 	/* PWR_EN = 1 */
 	RAW(1P8_CONTROL_010, (0xd));
@@ -1177,7 +1196,7 @@
 		goto err_init;
 
 
-	usleep(20000);  /* 20ms wait */
+	msleep(20);  /* 20ms wait */
 	/* LS_EN = 1 */
 	RAW(1P8_CONTROL_010, 0xF);
 	r = nfc_i2c_write(client, &raw_1P8_CONTROL_010[0],
@@ -1185,41 +1204,43 @@
 	if (r < 0)
 		goto err_init;
 
-	usleep(20000);  /* 20ms wait */
+	msleep(20);  /* 20ms wait */
 
 	/* Enable the PMIC clock */
 	RAW(1P8_PAD_CFG_CLK_REQ, (0x1));
 	r = nfc_i2c_write(client, &raw_1P8_PAD_CFG_CLK_REQ[0],
-				  sizeof(raw_1P8_PAD_CFG_CLK_REQ));
+				sizeof(raw_1P8_PAD_CFG_CLK_REQ));
 	if (r < 0)
 		goto err_init;
 
-	usleep(1000);
+	usleep_range(1000, 1100); /* 1 ms wait */
 
 	RAW(1P8_PAD_CFG_PWR_REQ, (0x1));
 	r = nfc_i2c_write(client, &raw_1P8_PAD_CFG_PWR_REQ[0],
-				  sizeof(raw_1P8_PAD_CFG_PWR_REQ));
+				sizeof(raw_1P8_PAD_CFG_PWR_REQ));
 	if (r < 0)
 		goto err_init;
 
-	usleep(1000);
+	usleep_range(1000, 1100); /* 1 ms wait */
 
 	RAW(slave2, 0x10);
 	r = nfc_i2c_write(client, &raw_slave2[0], sizeof(raw_slave2));
 	if (r < 0)
 		goto err_init;
 
-	usleep(1000);
+	usleep_range(1000, 1100); /* 1 ms wait */
 
 	RAW(slave1, NCI_I2C_SLAVE);
 	r = nfc_i2c_write(client, &raw_slave1[0], sizeof(raw_slave1));
 	if (r < 0)
 		goto err_init;
 
-	usleep(1000);
+	usleep_range(1000, 1100); /* 1 ms wait */
 
 	/* QCA199x NFCC CPU should now boot... */
-	r = i2c_master_recv(client, &raw_slave1_rd, 1);
+	r = i2c_master_recv(client, &raw_slave1_rd, sizeof(raw_slave1_rd));
+	if (r < 0)
+		goto err_init;
 	/* Talk on NCI slave address NCI_I2C_SLAVE 0x2C*/
 	client->addr = NCI_I2C_SLAVE;
 
@@ -1228,35 +1249,37 @@
 	 * get a core reset notification - This is time for chip
 	 * & NFCC controller to come-up.
 	 */
-	usleep(15000); /* 15 ms */
+	usleep_range(15000, 16500); /* 15 ms */
 
 	do {
-		ret = i2c_master_recv(client, rsp, 5);
+		ret = i2c_master_recv(client, rsp, sizeof(rsp));
+		if (ret < 0)
+			goto err_init;
 		/* Found core reset notification */
-		if (((rsp[0] == CORE_RESET_RSP_GID) &&
+		if ((rsp[0] == CORE_RESET_RSP_GID) &&
 			(rsp[1] == CORE_RESET_OID) &&
-			(rsp[2] == CORE_RST_NTF_LENGTH))
-				|| time_taken == NTF_TIMEOUT) {
+			(rsp[2] == CORE_RST_NTF_LENGTH)) {
 			dev_dbg(&client->dev,
-				"NFC core reset recevd: %s: info: %p\n",
+				"NFC core reset recvd: %s: info: %p\n",
 				__func__, client);
 			core_reset_completed = true;
 		} else {
-		  usleep(2000);  /* 2ms sleep before retry */
+		  usleep_range(2000, 2200);  /* 2 ms wait before retry */
 		}
 		time_taken++;
-	} while (!core_reset_completed);
-	if (time_taken == NTF_TIMEOUT)
+	} while (!core_reset_completed && (time_taken < NTF_TIMEOUT));
+	if (time_taken >= NTF_TIMEOUT) {
 		qca199x_dev->core_reset_ntf = TIMEDOUT_INITIAL_CORE_RESET_NTF;
-	else
-		qca199x_dev->core_reset_ntf = ARRIVED_INITIAL_CORE_RESET_NTF;
+		goto err_init;
+	}
+	qca199x_dev->core_reset_ntf = ARRIVED_INITIAL_CORE_RESET_NTF;
 
 	r = 0;
 	return r;
 err_init:
 	r = 1;
 	dev_err(&client->dev,
-		"nfc-nci nfcc_initialise: failed. Check Hardware\n");
+		"%s: failed. Check Hardware\n", __func__);
 	return r;
 }
 /*
@@ -1267,19 +1290,20 @@
 	int r = 0;
 
 	if (!strcmp(qca199x_dev->clk_src_name, "BBCLK2")) {
-		qca199x_dev->s_clk  =
+		qca199x_dev->s_clk =
 			clk_get(&qca199x_dev->client->dev, "ref_clk");
 		if (qca199x_dev->s_clk == NULL)
 			goto err_invalid_dis_gpio;
 	} else if (!strcmp(qca199x_dev->clk_src_name, "RFCLK3")) {
-		qca199x_dev->s_clk  =
+		qca199x_dev->s_clk =
 			clk_get(&qca199x_dev->client->dev, "ref_clk_rf");
 		if (qca199x_dev->s_clk == NULL)
 			goto err_invalid_dis_gpio;
 	} else if (!strcmp(qca199x_dev->clk_src_name, "GPCLK")) {
 		if (gpio_is_valid(qca199x_dev->clk_src_gpio)) {
-			qca199x_dev->s_clk  =
-				clk_get(&qca199x_dev->client->dev, "core_clk");
+			qca199x_dev->s_clk =
+				clk_get(&qca199x_dev->client->dev,
+				  "core_clk");
 			if (qca199x_dev->s_clk == NULL)
 				goto err_invalid_dis_gpio;
 		} else {
@@ -1287,8 +1311,9 @@
 		}
 	} else if (!strcmp(qca199x_dev->clk_src_name, "GPCLK2")) {
 		if (gpio_is_valid(qca199x_dev->clk_src_gpio)) {
-			qca199x_dev->s_clk  =
-				clk_get(&qca199x_dev->client->dev, "core_clk_pvt");
+			qca199x_dev->s_clk =
+				clk_get(&qca199x_dev->client->dev,
+				  "core_clk_pvt");
 			if (qca199x_dev->s_clk == NULL)
 				goto err_invalid_dis_gpio;
 		} else {
@@ -1364,7 +1389,7 @@
 	}
 
 	if ((!strcmp(pdata->clk_src_name, "GPCLK")) ||
-	    (!strcmp(pdata->clk_src_name, "GPCLK2"))) {
+		(!strcmp(pdata->clk_src_name, "GPCLK2"))) {
 			pdata->clk_src_gpio = of_get_named_gpio(np,
 					"qcom,clk-src-gpio", 0);
 			if ((!gpio_is_valid(pdata->clk_src_gpio)))
@@ -1393,7 +1418,7 @@
 			sizeof(struct qca199x_platform_data), GFP_KERNEL);
 		if (!platform_data) {
 			dev_err(&client->dev,
-			"nfc-nci probe: Failed to allocate memory\n");
+			"%s: Failed to allocate memory\n", __func__);
 			return -ENOMEM;
 		}
 		r = nfc_parse_dt(&client->dev, platform_data);
@@ -1405,20 +1430,20 @@
 	if (!platform_data)
 		return -EINVAL;
 	dev_dbg(&client->dev,
-		"nfc-nci probe: %s, inside nfc-nci flags = %x\n",
+		"%s, inside nfc-nci flags = %x\n",
 		__func__, client->flags);
 	if (platform_data == NULL) {
-		dev_err(&client->dev, "nfc-nci probe: failed\n");
+		dev_err(&client->dev, "%s: failed\n", __func__);
 		return -ENODEV;
 	}
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		dev_err(&client->dev, "nfc-nci probe: need I2C_FUNC_I2C\n");
+		dev_err(&client->dev, "%s: need I2C_FUNC_I2C\n", __func__);
 		return -ENODEV;
 	}
 	qca199x_dev = kzalloc(sizeof(*qca199x_dev), GFP_KERNEL);
 	if (qca199x_dev == NULL) {
 		dev_err(&client->dev,
-		"nfc-nci probe: failed to allocate memory for module data\n");
+		"%s: failed to allocate memory for module data\n", __func__);
 		return -ENOMEM;
 	}
 	qca199x_dev->client = client;
@@ -1436,27 +1461,29 @@
 		r = gpio_request(platform_data->dis_gpio, "nfc_reset_gpio");
 		if (r) {
 			dev_err(&client->dev,
-			"NFC: unable to request gpio [%d]\n",
+			"%s: unable to request gpio [%d]\n",
+				__func__,
 				platform_data->dis_gpio);
 			goto err_free_dev;
 		}
 		r = gpio_direction_output(platform_data->dis_gpio, 1);
 		if (r) {
 			dev_err(&client->dev,
-				"NFC: unable to set direction for gpio [%d]\n",
+				"%s: unable to set direction for gpio [%d]\n",
+					__func__,
 					platform_data->dis_gpio);
 			goto err_dis_gpio;
 		}
 	} else {
-		dev_err(&client->dev, "dis gpio not provided\n");
+		dev_err(&client->dev, "%s: dis gpio not provided\n", __func__);
 		goto err_free_dev;
 	}
 
 	/* Guarantee that the NFCC starts in a clean state. */
 	gpio_set_value(platform_data->dis_gpio, 1);/* HPD */
-	usleep(200);
+	usleep_range(200, 220);
 	gpio_set_value(platform_data->dis_gpio, 0);/* ULPM */
-	usleep(200);
+	usleep_range(200, 220);
 
 	r = nfcc_hw_check(client, platform_data->reg);
 	if (r) {
@@ -1468,7 +1495,8 @@
 	if (gpio_is_valid(platform_data->irq_gpio)) {
 		r = gpio_request(platform_data->irq_gpio, "nfc_irq_gpio");
 		if (r) {
-			dev_err(&client->dev, "unable to request gpio [%d]\n",
+			dev_err(&client->dev, "%s: unable to request gpio [%d]\n",
+				__func__,
 				platform_data->irq_gpio);
 			goto err_dis_gpio;
 		}
@@ -1476,7 +1504,8 @@
 		if (r) {
 
 			dev_err(&client->dev,
-			"unable to set direction for gpio [%d]\n",
+			"%s: unable to set direction for gpio [%d]\n",
+				__func__,
 				platform_data->irq_gpio);
 			goto err_irq;
 		}
@@ -1488,7 +1517,7 @@
 		client->irq = irqn;
 
 	} else {
-		dev_err(&client->dev, "irq gpio not provided\n");
+		dev_err(&client->dev, "%s: irq gpio not provided\n", __func__);
 		goto err_dis_gpio;
 	}
 	/* Interrupt from NFCC CLK_REQ to handle REF_CLK
@@ -1499,7 +1528,9 @@
 			r = gpio_request(platform_data->irq_gpio_clk_req,
 				"nfc_irq_gpio_clk_en");
 			if (r) {
-				dev_err(&client->dev, "unable to request CLK_EN gpio [%d]\n",
+				dev_err(&client->dev,
+				"%s: unable to request CLK_EN gpio [%d]\n",
+				__func__,
 					platform_data->irq_gpio_clk_req);
 				goto err_irq;
 			}
@@ -1507,8 +1538,8 @@
 					platform_data->irq_gpio_clk_req);
 			if (r) {
 				dev_err(&client->dev,
-					"unable to set direction for CLK_EN gpio [%d]\n",
-					platform_data->irq_gpio_clk_req);
+				"%s: cannot set direction CLK_EN gpio [%d]\n",
+				__func__, platform_data->irq_gpio_clk_req);
 				goto err_irq_clk;
 			}
 			gpio_to_irq(0);
@@ -1519,7 +1550,8 @@
 			}
 			platform_data->clk_req_irq_num = irqn;
 		} else {
-			dev_err(&client->dev, "irq CLK_EN gpio not provided\n");
+			dev_err(&client->dev,
+			"%s: irq CLK_EN gpio not provided\n", __func__);
 			goto err_irq;
 		}
 	}
@@ -1540,19 +1572,21 @@
 			r = gpio_request(platform_data->clkreq_gpio,
 				"nfc_clkreq_gpio");
 			if (r) {
-				dev_err(&client->dev, "unable to request gpio [%d]\n",
-						platform_data->clkreq_gpio);
+				dev_err(&client->dev,
+					"%s: unable to request gpio [%d]\n",
+					__func__, platform_data->clkreq_gpio);
 				goto err_clkreq_gpio;
 			}
 			r = gpio_direction_input(platform_data->clkreq_gpio);
 			if (r) {
 				dev_err(&client->dev,
-						"unable to set direction for gpio [%d]\n",
-						platform_data->clkreq_gpio);
+				"%s: cannot set direction for gpio [%d]\n",
+				__func__, platform_data->clkreq_gpio);
 				goto err_clkreq_gpio;
 			}
 		} else {
-			dev_err(&client->dev, "clkreq gpio not provided\n");
+			dev_err(&client->dev,
+				"%s: clkreq gpio not provided\n", __func__);
 			goto err_clk;
 		}
 		qca199x_dev->clkreq_gpio = platform_data->clkreq_gpio;
@@ -1579,7 +1613,7 @@
 
 	r = misc_register(&qca199x_dev->qca199x_device);
 	if (r) {
-		dev_err(&client->dev, "misc_register failed\n");
+		dev_err(&client->dev, "%s: misc_register failed\n", __func__);
 		goto err_misc_register;
 	}
 
@@ -1616,7 +1650,7 @@
 	r = request_irq(client->irq, qca199x_dev_irq_handler,
 			  IRQF_TRIGGER_RISING, client->name, qca199x_dev);
 	if (r) {
-		dev_err(&client->dev, "nfc-nci probe: request_irq failed\n");
+		dev_err(&client->dev, "%s: request_irq failed\n", __func__);
 		goto err_request_irq_failed;
 	}
 	qca199x_disable_irq(qca199x_dev);
@@ -1629,7 +1663,8 @@
 						client->name, qca199x_dev);
 		if (r) {
 			dev_err(&client->dev,
-			"nfc-nci probe: request_irq failed. irq no = %d\n, main irq =  %d",
+			"%s: request_irq failed. irq no = %d\n, main irq = %d",
+				__func__,
 				qca199x_dev->clk_req_irq_num, client->irq);
 			goto err_request_irq_failed;
 		}
@@ -1654,13 +1689,13 @@
 	region2_sent = false;
 
 	dev_dbg(&client->dev,
-	"nfc-nci probe: %s, probing qca1990 exited successfully\n",
+	"%s: probing qca1990 exited successfully\n",
 		 __func__);
 	return 0;
 
 err_create_workq:
 	dev_err(&client->dev,
-	"nfc-nci probe: %s, work_queue creation failure\n",
+	"%s: work_queue creation failure\n",
 		 __func__);
 	free_irq(client->irq, qca199x_dev);
 err_nfcc_not_present:
@@ -1678,7 +1713,8 @@
 		(!strcmp(platform_data->clk_src_name, "GPCLK2"))) {
 		r = gpio_direction_input(platform_data->irq_gpio_clk_req);
 		if (r)
-			dev_err(&client->dev, "nfc-nci probe: Unable to set direction\n");
+			dev_err(&client->dev,
+				"%s: Unable to set direction\n", __func__);
 		gpio_free(platform_data->irq_gpio_clk_req);
 	}
 err_irq:
@@ -1752,7 +1788,7 @@
 
 
 static int nfcc_reboot(struct notifier_block *notifier, unsigned long val,
-		      void *v)
+			  void *v)
 {
 	/*
 	 * Set DISABLE=1 *ONLY* if the NFC service has been disabled.
diff --git a/drivers/slimbus/slim-msm-ctrl.c b/drivers/slimbus/slim-msm-ctrl.c
index c662a2b..924a028 100644
--- a/drivers/slimbus/slim-msm-ctrl.c
+++ b/drivers/slimbus/slim-msm-ctrl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 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
@@ -207,8 +207,7 @@
 		 * signalling completion/exiting ISR
 		 */
 		mb();
-		if (dev->wr_comp)
-			complete(dev->wr_comp);
+		msm_slim_manage_tx_msgq(dev, false, NULL);
 	}
 	if (stat & MGR_INT_RX_MSG_RCVD) {
 		u32 rx_buf[10];
@@ -372,8 +371,7 @@
 		}
 	}
 	txn->rl--;
-	pbuf = msm_get_msg_buf(dev, txn->rl);
-	dev->wr_comp = NULL;
+	pbuf = msm_get_msg_buf(dev, txn->rl, &done);
 	dev->err = 0;
 
 	if (txn->dt == SLIM_MSG_DEST_ENUMADDR) {
@@ -438,11 +436,8 @@
 	if (txn->mt == SLIM_MSG_MT_CORE &&
 		mc == SLIM_MSG_MC_BEGIN_RECONFIGURATION)
 		dev->reconf_busy = true;
-	dev->wr_comp = &done;
 	msm_send_msg_buf(dev, pbuf, txn->rl, MGR_TX_MSG);
 	timeout = wait_for_completion_timeout(&done, HZ);
-	if (!timeout)
-		dev->wr_comp = NULL;
 	if (mc == SLIM_MSG_MC_RECONFIGURE_NOW) {
 		if ((txn->mc == (SLIM_MSG_MC_RECONFIGURE_NOW |
 					SLIM_MSG_CLK_PAUSE_SEQ_FLG)) &&
@@ -505,7 +500,9 @@
 retry_laddr:
 	init_completion(&done);
 	mutex_lock(&dev->tx_lock);
-	buf = msm_get_msg_buf(dev, 9);
+	buf = msm_get_msg_buf(dev, 9, &done);
+	if (buf == NULL)
+		return -ENOMEM;
 	buf[0] = SLIM_MSG_ASM_FIRST_WORD(9, SLIM_MSG_MT_CORE,
 					SLIM_MSG_MC_ASSIGN_LOGICAL_ADDRESS,
 					SLIM_MSG_DEST_LOGICALADDR,
@@ -513,7 +510,6 @@
 	buf[1] = ea[3] | (ea[2] << 8) | (ea[1] << 16) | (ea[0] << 24);
 	buf[2] = laddr;
 
-	dev->wr_comp = &done;
 	ret = msm_send_msg_buf(dev, buf, 9, MGR_TX_MSG);
 	timeout = wait_for_completion_timeout(&done, HZ);
 	if (!timeout)
@@ -521,7 +517,6 @@
 	if (dev->err) {
 		ret = dev->err;
 		dev->err = 0;
-		dev->wr_comp = NULL;
 	}
 	mutex_unlock(&dev->tx_lock);
 	if (ret) {
@@ -1183,6 +1178,10 @@
 		ret = -ENOMEM;
 		goto err_get_res_failed;
 	}
+	dev->wr_comp = kzalloc(sizeof(struct completion *) * MSM_TX_BUFS,
+				GFP_KERNEL);
+	if (!dev->wr_comp)
+		return -ENOMEM;
 	dev->dev = &pdev->dev;
 	platform_set_drvdata(pdev, dev);
 	slim_set_ctrldata(&dev->ctrl, dev);
@@ -1271,7 +1270,8 @@
 	dev->ctrl.dev.parent = &pdev->dev;
 	dev->ctrl.dev.of_node = pdev->dev.of_node;
 
-	ret = request_irq(dev->irq, msm_slim_interrupt, IRQF_TRIGGER_HIGH,
+	ret = request_threaded_irq(dev->irq, NULL, msm_slim_interrupt,
+				IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
 				"msm_slim_irq", dev);
 	if (ret) {
 		dev_err(&pdev->dev, "request IRQ failed\n");
@@ -1400,6 +1400,7 @@
 err_ioremap_bam_failed:
 	iounmap(dev->base);
 err_ioremap_failed:
+	kfree(dev->wr_comp);
 	kfree(dev);
 err_get_res_failed:
 	release_mem_region(bam_mem->start, resource_size(bam_mem));
@@ -1437,6 +1438,7 @@
 	kthread_stop(dev->rx_msgq_thread);
 	iounmap(dev->bam.base);
 	iounmap(dev->base);
+	kfree(dev->wr_comp);
 	kfree(dev);
 	bam_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 						"slimbus_bam_physical");
diff --git a/drivers/slimbus/slim-msm-ngd.c b/drivers/slimbus/slim-msm-ngd.c
index 299d3ee..f3a886b 100644
--- a/drivers/slimbus/slim-msm-ngd.c
+++ b/drivers/slimbus/slim-msm-ngd.c
@@ -101,15 +101,13 @@
 								dev->err);
 		/* Guarantee that error interrupts are cleared */
 		mb();
-		if (dev->wr_comp)
-			complete(dev->wr_comp);
+		msm_slim_manage_tx_msgq(dev, false, NULL);
 
 	} else if (stat & NGD_INT_TX_MSG_SENT) {
 		writel_relaxed(NGD_INT_TX_MSG_SENT, ngd + NGD_INT_CLR);
 		/* Make sure interrupt is cleared */
 		mb();
-		if (dev->wr_comp)
-			complete(dev->wr_comp);
+		msm_slim_manage_tx_msgq(dev, false, NULL);
 	}
 	if (stat & NGD_INT_RX_MSG_RCVD) {
 		u32 rx_buf[10];
@@ -165,27 +163,51 @@
 	case QMI_SERVER_ARRIVE:
 		schedule_work(&qmi->ssr_up);
 		break;
-	case QMI_SERVER_EXIT:
-		dev->state = MSM_CTRL_DOWN;
-		/* make sure autosuspend is not called until ADSP comes up*/
-		pm_runtime_get_noresume(dev->dev);
-		/* Reset ctrl_up completion */
-		init_completion(&dev->ctrl_up);
-		schedule_work(&qmi->ssr_down);
-		break;
 	default:
 		break;
 	}
 	return 0;
 }
 
+static int dsp_ssr_notify_cb(struct notifier_block *n, unsigned long code,
+				void *_cmd)
+{
+	struct msm_slim_ss *dsp = container_of(n, struct msm_slim_ss, nb);
+	struct msm_slim_ctrl *dev = container_of(dsp, struct msm_slim_ctrl,
+						dsp);
+
+	switch (code) {
+	case SUBSYS_BEFORE_SHUTDOWN:
+		SLIM_INFO(dev, "SLIM DSP SSR notify cb:%lu\n", code);
+		/* wait for current transaction */
+		mutex_lock(&dev->tx_lock);
+		/* make sure autosuspend is not called until ADSP comes up*/
+		pm_runtime_get_noresume(dev->dev);
+		dev->state = MSM_CTRL_DOWN;
+		/* Reset ctrl_up completion */
+		init_completion(&dev->ctrl_up);
+		/* disconnect BAM pipes */
+		if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED)
+			dev->use_rx_msgqs = MSM_MSGQ_DOWN;
+		if (dev->use_tx_msgqs == MSM_MSGQ_ENABLED)
+			dev->use_tx_msgqs = MSM_MSGQ_DOWN;
+		msm_slim_sps_exit(dev, false);
+		schedule_work(&dev->qmi.ssr_down);
+		mutex_unlock(&dev->tx_lock);
+		break;
+	default:
+		break;
+	}
+	return NOTIFY_DONE;
+}
+
 static int mdm_ssr_notify_cb(struct notifier_block *n, unsigned long code,
 				void *_cmd)
 {
 	void __iomem *ngd;
-	struct msm_slim_mdm *mdm = container_of(n, struct msm_slim_mdm, nb);
-	struct msm_slim_ctrl *dev = container_of(mdm, struct msm_slim_ctrl,
-						mdm);
+	struct msm_slim_ss *ext_mdm = container_of(n, struct msm_slim_ss, nb);
+	struct msm_slim_ctrl *dev = container_of(ext_mdm, struct msm_slim_ctrl,
+						ext_mdm);
 	struct slim_controller *ctrl = &dev->ctrl;
 	u32 laddr;
 	struct slim_device *sbdev;
@@ -200,11 +222,11 @@
 		 * handover later
 		 */
 		msm_slim_qmi_check_framer_request(dev);
-		dev->mdm.state = MSM_CTRL_DOWN;
+		dev->ext_mdm.state = MSM_CTRL_DOWN;
 		msm_slim_put_ctrl(dev);
 		break;
 	case SUBSYS_AFTER_POWERUP:
-		if (dev->mdm.state != MSM_CTRL_DOWN)
+		if (dev->ext_mdm.state != MSM_CTRL_DOWN)
 			return NOTIFY_DONE;
 		SLIM_INFO(dev,
 			"SLIM %lu external_modem SSR notify cb\n", code);
@@ -215,19 +237,21 @@
 		ngd = dev->base + NGD_BASE(dev->ctrl.nr, dev->ver);
 		laddr = readl_relaxed(ngd + NGD_STATUS);
 		if (!(laddr & NGD_LADDR)) {
+			mutex_lock(&dev->tx_lock);
 			/* runtime-pm state should be consistent with HW */
 			pm_runtime_disable(dev->dev);
 			pm_runtime_set_suspended(dev->dev);
 			dev->state = MSM_CTRL_DOWN;
+			mutex_unlock(&dev->tx_lock);
 			SLIM_INFO(dev,
 				"SLIM MDM SSR (active framer on MDM) dev-down\n");
 			list_for_each_entry(sbdev, &ctrl->devs, dev_list)
 				slim_report_absent(sbdev);
-			ngd_slim_power_up(dev, true);
+			ngd_slim_runtime_resume(dev->dev);
 			pm_runtime_set_active(dev->dev);
 			pm_runtime_enable(dev->dev);
 		}
-		dev->mdm.state = MSM_CTRL_AWAKE;
+		dev->ext_mdm.state = MSM_CTRL_AWAKE;
 		msm_slim_put_ctrl(dev);
 		break;
 	default:
@@ -286,12 +310,24 @@
 	u16 txn_mc = txn->mc;
 	u8 wbuf[SLIM_MSGQ_BUF_LEN];
 	bool report_sat = false;
+	bool sync_wr = true;
+
+	if (txn->mc & SLIM_MSG_CLK_PAUSE_SEQ_FLG)
+		return -EPROTONOSUPPORT;
+
+	if (txn->mt == SLIM_MSG_MT_CORE &&
+		(txn->mc >= SLIM_MSG_MC_BEGIN_RECONFIGURATION &&
+		 txn->mc <= SLIM_MSG_MC_RECONFIGURE_NOW))
+		return 0;
 
 	if (txn->mc == SLIM_USR_MC_REPORT_SATELLITE &&
 		txn->mt == SLIM_MSG_MT_SRC_REFERRED_USER)
 		report_sat = true;
-	if (!pm_runtime_enabled(dev->dev) && dev->state == MSM_CTRL_ASLEEP &&
-			report_sat == false) {
+	else
+		mutex_lock(&dev->tx_lock);
+
+	if (!report_sat && !pm_runtime_enabled(dev->dev) &&
+			dev->state == MSM_CTRL_ASLEEP) {
 		/*
 		 * Counter-part of system-suspend when runtime-pm is not enabled
 		 * This way, resume can be left empty and device will be put in
@@ -299,22 +335,24 @@
 		 * If the state was DOWN, SSR UP notification will take
 		 * care of putting the device in active state.
 		 */
-		ngd_slim_runtime_resume(dev->dev);
+		mutex_unlock(&dev->tx_lock);
+		ret = ngd_slim_runtime_resume(dev->dev);
+
+		if (ret) {
+			SLIM_ERR(dev, "slim resume failed ret:%d, state:%d",
+					ret, dev->state);
+			return -EREMOTEIO;
+		}
+		mutex_lock(&dev->tx_lock);
 	}
 
-	else if (txn->mc & SLIM_MSG_CLK_PAUSE_SEQ_FLG)
-		return -EPROTONOSUPPORT;
-
-	if (txn->mt == SLIM_MSG_MT_CORE &&
-		(txn->mc >= SLIM_MSG_MC_BEGIN_RECONFIGURATION &&
-		 txn->mc <= SLIM_MSG_MC_RECONFIGURE_NOW)) {
-		return 0;
-	}
 	/* If txn is tried when controller is down, wait for ADSP to boot */
 	if (!report_sat) {
+
 		if (dev->state == MSM_CTRL_DOWN) {
 			u8 mc = (u8)txn->mc;
 			int timeout;
+			mutex_unlock(&dev->tx_lock);
 			SLIM_INFO(dev, "ADSP slimbus not up yet\n");
 			/*
 			 * Messages related to data channel management can't
@@ -354,33 +392,31 @@
 				return -EREMOTEIO;
 			timeout = wait_for_completion_timeout(&dev->ctrl_up,
 							HZ);
-			if (!timeout && dev->state == MSM_CTRL_DOWN)
+			if (!timeout)
 				return -ETIMEDOUT;
+			mutex_lock(&dev->tx_lock);
 		}
+
+		mutex_unlock(&dev->tx_lock);
 		ret = msm_slim_get_ctrl(dev);
+		mutex_lock(&dev->tx_lock);
 		/*
 		 * Runtime-pm's callbacks are not called until runtime-pm's
 		 * error status is cleared
 		 * Setting runtime status to suspended clears the error
 		 * It also makes HW status cosistent with what SW has it here
 		 */
-		if (ret == -ENETRESET && dev->state == MSM_CTRL_DOWN) {
+		if ((pm_runtime_enabled(dev->dev) && ret < 0) ||
+				dev->state == MSM_CTRL_DOWN) {
+			SLIM_ERR(dev, "slim ctrl vote failed ret:%d, state:%d",
+					ret, dev->state);
 			pm_runtime_set_suspended(dev->dev);
+			mutex_unlock(&dev->tx_lock);
 			msm_slim_put_ctrl(dev);
 			return -EREMOTEIO;
-		} else if (ret >= 0) {
-			dev->state = MSM_CTRL_AWAKE;
 		}
 	}
-	mutex_lock(&dev->tx_lock);
 
-	if (report_sat == false && dev->state != MSM_CTRL_AWAKE) {
-		SLIM_ERR(dev, "controller not ready\n");
-		mutex_unlock(&dev->tx_lock);
-		pm_runtime_set_suspended(dev->dev);
-		msm_slim_put_ctrl(dev);
-		return -EREMOTEIO;
-	}
 	if (txn->mt == SLIM_MSG_MT_CORE &&
 		(txn->mc == SLIM_MSG_MC_CONNECT_SOURCE ||
 		txn->mc == SLIM_MSG_MC_CONNECT_SINK ||
@@ -438,7 +474,25 @@
 		txn->rl = txn->len + 4;
 	}
 	txn->rl--;
-	pbuf = msm_get_msg_buf(dev, txn->rl);
+
+	if (txn->mt == SLIM_MSG_MT_CORE && txn->comp &&
+		dev->use_tx_msgqs == MSM_MSGQ_ENABLED &&
+		(txn_mc != SLIM_MSG_MC_REQUEST_INFORMATION &&
+		 txn_mc != SLIM_MSG_MC_REQUEST_VALUE &&
+		 txn_mc != SLIM_MSG_MC_REQUEST_CHANGE_VALUE &&
+		 txn_mc != SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION)) {
+		sync_wr = false;
+		pbuf = msm_get_msg_buf(dev, txn->rl, txn->comp);
+	} else if (txn->mt == SLIM_MSG_MT_DEST_REFERRED_USER &&
+			dev->use_tx_msgqs == MSM_MSGQ_ENABLED &&
+			txn->mc == SLIM_USR_MC_REPEAT_CHANGE_VALUE &&
+			txn->comp) {
+		sync_wr = false;
+		pbuf = msm_get_msg_buf(dev, txn->rl, txn->comp);
+	} else {
+		pbuf = msm_get_msg_buf(dev, txn->rl, &tx_sent);
+	}
+
 	if (!pbuf) {
 		SLIM_ERR(dev, "Message buffer unavailable\n");
 		ret = -ENOMEM;
@@ -509,10 +563,9 @@
 	 */
 	txn_mc = txn->mc;
 	txn_mt = txn->mt;
-	dev->wr_comp = &tx_sent;
 	ret = msm_send_msg_buf(dev, pbuf, txn->rl,
 			NGD_BASE(dev->ctrl.nr, dev->ver) + NGD_TX_MSG);
-	if (!ret) {
+	if (!ret && sync_wr) {
 		int timeout = wait_for_completion_timeout(&tx_sent, HZ);
 		if (!timeout) {
 			ret = -ETIMEDOUT;
@@ -521,14 +574,15 @@
 			 * transactions don't timeout due to unavailable
 			 * descriptors
 			 */
-			msm_slim_disconnect_endp(dev, &dev->tx_msgq,
-						&dev->use_tx_msgqs);
-			msm_slim_connect_endp(dev, &dev->tx_msgq, NULL);
+			if (dev->state != MSM_CTRL_DOWN) {
+				msm_slim_disconnect_endp(dev, &dev->tx_msgq,
+							&dev->use_tx_msgqs);
+				msm_slim_connect_endp(dev, &dev->tx_msgq, NULL);
+			}
 		} else {
 			ret = dev->err;
 		}
 	}
-	dev->wr_comp = NULL;
 	if (ret) {
 		u32 conf, stat, rx_msgq, int_stat, int_en, int_clr;
 		void __iomem *ngd = dev->base + NGD_BASE(dev->ctrl.nr,
@@ -569,9 +623,10 @@
 		return ret ? ret : dev->err;
 	}
 ngd_xfer_err:
-	mutex_unlock(&dev->tx_lock);
-	if (!report_sat)
+	if (!report_sat) {
+		mutex_unlock(&dev->tx_lock);
 		msm_slim_put_ctrl(dev);
+	}
 	return ret ? ret : dev->err;
 }
 
@@ -880,7 +935,6 @@
 			enum msm_ctrl_state prev_state = dev->state;
 			SLIM_INFO(dev,
 				"SLIM SAT: capability exchange successful\n");
-			dev->state = MSM_CTRL_AWAKE;
 			if (prev_state >= MSM_CTRL_ASLEEP)
 				complete(&dev->reconf);
 			else
@@ -964,8 +1018,10 @@
 	if (!mdm_restart && cur_state == MSM_CTRL_DOWN) {
 		int timeout = wait_for_completion_timeout(&dev->qmi.qmi_comp,
 						HZ);
-		if (!timeout)
+		if (!timeout) {
 			SLIM_ERR(dev, "slimbus QMI init timed out\n");
+			return -EREMOTEIO;
+		}
 	}
 
 	/* No need to vote if contorller is not in low power mode */
@@ -1052,11 +1108,11 @@
 		SLIM_ERR(dev, "Failed to receive master capability\n");
 		return -ETIMEDOUT;
 	}
-	if (cur_state == MSM_CTRL_DOWN) {
-		complete(&dev->ctrl_up);
-		/* Resetting the log level */
-		SLIM_RST_LOGLVL(dev);
-	}
+	/* mutliple transactions waiting on slimbus to power up? */
+	if (cur_state == MSM_CTRL_DOWN)
+		complete_all(&dev->ctrl_up);
+	/* Resetting the log level */
+	SLIM_RST_LOGLVL(dev);
 	return 0;
 }
 
@@ -1211,12 +1267,6 @@
 	struct slim_device *sbdev;
 
 	ngd_slim_enable(dev, false);
-	/* disconnect BAM pipes */
-	if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED)
-		dev->use_rx_msgqs = MSM_MSGQ_DOWN;
-	if (dev->use_tx_msgqs == MSM_MSGQ_ENABLED)
-		dev->use_tx_msgqs = MSM_MSGQ_DOWN;
-	msm_slim_sps_exit(dev, false);
 	/* device up should be called again after SSR */
 	list_for_each_entry(sbdev, &ctrl->devs, dev_list)
 		slim_report_absent(sbdev);
@@ -1295,6 +1345,10 @@
 		dev_err(&pdev->dev, "no memory for MSM slimbus controller\n");
 		return PTR_ERR(dev);
 	}
+	dev->wr_comp = kzalloc(sizeof(struct completion *) * MSM_TX_BUFS,
+				GFP_KERNEL);
+	if (!dev->wr_comp)
+		return -ENOMEM;
 	dev->dev = &pdev->dev;
 	platform_set_drvdata(pdev, dev);
 	slim_set_ctrldata(&dev->ctrl, dev);
@@ -1378,6 +1432,7 @@
 	init_completion(&dev->reconf);
 	init_completion(&dev->ctrl_up);
 	mutex_init(&dev->tx_lock);
+	mutex_init(&dev->tx_buf_lock);
 	spin_lock_init(&dev->rx_lock);
 	dev->ee = 1;
 	dev->irq = irq->start;
@@ -1405,8 +1460,9 @@
 	dev->ctrl.dev.of_node = pdev->dev.of_node;
 	dev->state = MSM_CTRL_DOWN;
 
-	ret = request_irq(dev->irq, ngd_slim_interrupt,
-			IRQF_TRIGGER_HIGH, "ngd_slim_irq", dev);
+	ret = request_threaded_irq(dev->irq, NULL,
+			ngd_slim_interrupt,
+			IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "ngd_slim_irq", dev);
 
 	if (ret) {
 		dev_err(&pdev->dev, "request IRQ failed\n");
@@ -1420,14 +1476,21 @@
 	pm_runtime_set_suspended(dev->dev);
 	pm_runtime_enable(dev->dev);
 
+	dev->dsp.nb.notifier_call = dsp_ssr_notify_cb;
+	dev->dsp.ssr = subsys_notif_register_notifier("adsp",
+						&dev->dsp.nb);
+	if (IS_ERR_OR_NULL(dev->dsp.ssr))
+		dev_err(dev->dev,
+			"subsys_notif_register_notifier failed %p",
+			dev->dsp.ssr);
 	if (slim_mdm) {
-		dev->mdm.nb.notifier_call = mdm_ssr_notify_cb;
-		dev->mdm.ssr = subsys_notif_register_notifier(ext_modem_id,
-							&dev->mdm.nb);
-		if (IS_ERR_OR_NULL(dev->mdm.ssr))
+		dev->ext_mdm.nb.notifier_call = mdm_ssr_notify_cb;
+		dev->ext_mdm.ssr = subsys_notif_register_notifier(ext_modem_id,
+							&dev->ext_mdm.nb);
+		if (IS_ERR_OR_NULL(dev->ext_mdm.ssr))
 			dev_err(dev->dev,
 				"subsys_notif_register_notifier failed %p",
-				dev->mdm.ssr);
+				dev->ext_mdm.ssr);
 	}
 
 	INIT_WORK(&dev->qmi.ssr_down, ngd_adsp_down);
@@ -1469,6 +1532,7 @@
 	if (dev->sysfs_created)
 		sysfs_remove_file(&dev->dev->kobj,
 				&dev_attr_debug_mask.attr);
+	kfree(dev->wr_comp);
 	kfree(dev);
 	return ret;
 }
@@ -1484,13 +1548,18 @@
 				SLIMBUS_QMI_SVC_V1,
 				SLIMBUS_QMI_INS_ID, &dev->qmi.nb);
 	pm_runtime_disable(&pdev->dev);
-	if (!IS_ERR_OR_NULL(dev->mdm.ssr))
-		subsys_notif_unregister_notifier(dev->mdm.ssr, &dev->mdm.nb);
+	if (!IS_ERR_OR_NULL(dev->dsp.ssr))
+		subsys_notif_unregister_notifier(dev->dsp.ssr,
+						&dev->dsp.nb);
+	if (!IS_ERR_OR_NULL(dev->ext_mdm.ssr))
+		subsys_notif_unregister_notifier(dev->ext_mdm.ssr,
+						&dev->ext_mdm.nb);
 	free_irq(dev->irq, dev);
 	slim_del_controller(&dev->ctrl);
 	kthread_stop(dev->rx_msgq_thread);
 	iounmap(dev->bam.base);
 	iounmap(dev->base);
+	kfree(dev->wr_comp);
 	kfree(dev);
 	return 0;
 }
@@ -1500,8 +1569,10 @@
 {
 	struct platform_device *pdev = to_platform_device(device);
 	struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
+	mutex_lock(&dev->tx_lock);
 	if (dev->state == MSM_CTRL_AWAKE)
 		dev->state = MSM_CTRL_IDLE;
+	mutex_unlock(&dev->tx_lock);
 	dev_dbg(device, "pm_runtime: idle...\n");
 	pm_request_autosuspend(device);
 	return -EAGAIN;
@@ -1518,6 +1589,7 @@
 	struct platform_device *pdev = to_platform_device(device);
 	struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
 	int ret = 0;
+	mutex_lock(&dev->tx_lock);
 	if (dev->state >= MSM_CTRL_ASLEEP)
 		ret = ngd_slim_power_up(dev, false);
 	if (ret) {
@@ -1529,6 +1601,7 @@
 	} else {
 		dev->state = MSM_CTRL_AWAKE;
 	}
+	mutex_unlock(&dev->tx_lock);
 	SLIM_INFO(dev, "Slim runtime resume: ret %d\n", ret);
 	return ret;
 }
@@ -1539,6 +1612,7 @@
 	struct platform_device *pdev = to_platform_device(device);
 	struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
 	int ret = 0;
+	mutex_lock(&dev->tx_lock);
 	ret = ngd_slim_power_down(dev);
 	if (ret) {
 		if (ret != -EBUSY)
@@ -1547,6 +1621,7 @@
 	} else {
 		dev->state = MSM_CTRL_ASLEEP;
 	}
+	mutex_unlock(&dev->tx_lock);
 	SLIM_INFO(dev, "Slim runtime suspend: ret %d\n", ret);
 	return ret;
 }
diff --git a/drivers/slimbus/slim-msm.c b/drivers/slimbus/slim-msm.c
index 915bf88..c3f371c 100644
--- a/drivers/slimbus/slim-msm.c
+++ b/drivers/slimbus/slim-msm.c
@@ -11,6 +11,7 @@
  */
 #include <linux/pm_runtime.h>
 #include <linux/dma-mapping.h>
+#include <linux/delay.h>
 #include <linux/slimbus/slimbus.h>
 #include <mach/sps.h>
 #include "slim-msm.h"
@@ -390,9 +391,9 @@
 	struct msm_slim_endp *endpoint = &dev->tx_msgq;
 	struct sps_mem_buffer *mem = &endpoint->buf;
 	struct sps_pipe *pipe = endpoint->sps;
-	int ix = (buf - (u8 *)mem->base) / SLIM_MSGQ_BUF_LEN;
+	int ix = (buf - (u8 *)mem->base);
 
-	phys_addr_t phys_addr = mem->phys_base + (SLIM_MSGQ_BUF_LEN * ix);
+	phys_addr_t phys_addr = mem->phys_base + ix;
 
 	for (ret = 0; ret < ((len + 3) >> 2); ret++)
 		pr_debug("BAM TX buf[%d]:0x%x", ret, ((u32 *)buf)[ret]);
@@ -405,29 +406,110 @@
 	return ret;
 }
 
-static u32 *msm_slim_tx_msgq_return(struct msm_slim_ctrl *dev)
+void msm_slim_tx_msg_return(struct msm_slim_ctrl *dev)
 {
 	struct msm_slim_endp *endpoint = &dev->tx_msgq;
 	struct sps_mem_buffer *mem = &endpoint->buf;
 	struct sps_pipe *pipe = endpoint->sps;
 	struct sps_iovec iovec;
-	int ret;
-
-	/* first transaction after establishing connection */
-	if (dev->tx_idx == -1) {
-		dev->tx_idx = 0;
-		return mem->base;
+	int idx, ret = 0;
+	if (dev->use_tx_msgqs != MSM_MSGQ_ENABLED) {
+		/* use 1 buffer, non-blocking writes are not possible */
+		if (dev->wr_comp[0]) {
+			struct completion *comp = dev->wr_comp[0];
+			dev->wr_comp[0] = NULL;
+			complete(comp);
+		}
+		return;
 	}
-	ret = sps_get_iovec(pipe, &iovec);
-	if (ret || iovec.addr == 0) {
-		dev_err(dev->dev, "sps_get_iovec() failed 0x%x\n", ret);
+	while (!ret) {
+		ret = sps_get_iovec(pipe, &iovec);
+		if (ret || iovec.addr == 0) {
+			if (ret)
+				pr_err("SLIM TX get IOVEC failed:%d", ret);
+			return;
+		}
+		idx = (int) ((iovec.addr - mem->phys_base) / SLIM_MSGQ_BUF_LEN);
+		if (idx < MSM_TX_BUFS && dev->wr_comp[idx]) {
+			struct completion *comp = dev->wr_comp[idx];
+			dev->wr_comp[idx] = NULL;
+			complete(comp);
+		}
+		/* reclaim all packets that were delivered out of order */
+		if (idx != dev->tx_head)
+			pr_err("SLIM OUT OF ORDER TX:idx:%d, head:%d", idx,
+								dev->tx_head);
+		while (idx == dev->tx_head) {
+			dev->tx_head = (dev->tx_head + 1) % MSM_TX_BUFS;
+			idx++;
+			if (dev->tx_head == dev->tx_tail ||
+					dev->wr_comp[idx] != NULL)
+				break;
+		}
+	}
+}
+
+static u32 *msm_slim_modify_tx_buf(struct msm_slim_ctrl *dev,
+					struct completion *comp)
+{
+	struct msm_slim_endp *endpoint = &dev->tx_msgq;
+	struct sps_mem_buffer *mem = &endpoint->buf;
+	u32 *retbuf = NULL;
+	if ((dev->tx_tail + 1) % MSM_TX_BUFS == dev->tx_head)
+		return NULL;
+
+	retbuf = (u32 *)((u8 *)mem->base +
+				(dev->tx_tail * SLIM_MSGQ_BUF_LEN));
+	dev->wr_comp[dev->tx_tail] = comp;
+	dev->tx_tail = (dev->tx_tail + 1) % MSM_TX_BUFS;
+	return retbuf;
+}
+u32 *msm_slim_manage_tx_msgq(struct msm_slim_ctrl *dev, bool getbuf,
+					struct completion *comp)
+{
+	int ret = 0;
+	int retries = 0;
+	u32 *retbuf = NULL;
+
+	mutex_lock(&dev->tx_buf_lock);
+	if (!getbuf) {
+		msm_slim_tx_msg_return(dev);
+		mutex_unlock(&dev->tx_buf_lock);
 		return NULL;
 	}
 
-	/* Calculate buffer index */
-	dev->tx_idx = ((int)(iovec.addr - mem->phys_base)) / SLIM_MSGQ_BUF_LEN;
+	retbuf = msm_slim_modify_tx_buf(dev, comp);
+	if (retbuf) {
+		mutex_unlock(&dev->tx_buf_lock);
+		return retbuf;
+	}
 
-	return (u32 *)((u8 *)mem->base + (dev->tx_idx * SLIM_MSGQ_BUF_LEN));
+	do {
+		msm_slim_tx_msg_return(dev);
+		retbuf = msm_slim_modify_tx_buf(dev, comp);
+		if (!retbuf)
+			ret = -EAGAIN;
+		else {
+			if (retries > 0)
+				SLIM_INFO(dev, "SLIM TX retrieved:%d retries",
+							retries);
+			mutex_unlock(&dev->tx_buf_lock);
+			return retbuf;
+		}
+
+		/*
+		 * superframe size will vary based on clock gear
+		 * 1 superframe will consume at least 1 message
+		 * if HW is in good condition. With MX_RETRIES,
+		 * make sure we wait for a [3, 10] superframes
+		 * before deciding HW couldn't process descriptors
+		 */
+		usleep_range(100, 250);
+		retries++;
+	} while (ret && (retries < INIT_MX_RETRIES));
+
+	mutex_unlock(&dev->tx_buf_lock);
+	return NULL;
 }
 
 int msm_send_msg_buf(struct msm_slim_ctrl *dev, u32 *buf, u8 len, u32 tx_reg)
@@ -445,16 +527,19 @@
 	return msm_slim_post_tx_msgq(dev, (u8 *)buf, len);
 }
 
-u32 *msm_get_msg_buf(struct msm_slim_ctrl *dev, int len)
+u32 *msm_get_msg_buf(struct msm_slim_ctrl *dev, int len,
+			struct completion *comp)
 {
 	/*
 	 * Currently we block a transaction until the current one completes.
 	 * In case we need multiple transactions, use message Q
 	 */
-	if (dev->use_tx_msgqs != MSM_MSGQ_ENABLED)
+	if (dev->use_tx_msgqs != MSM_MSGQ_ENABLED) {
+		dev->wr_comp[0] = comp;
 		return dev->tx_buf;
+	}
 
-	return msm_slim_tx_msgq_return(dev);
+	return msm_slim_manage_tx_msgq(dev, true, comp);
 }
 
 static void
@@ -604,7 +689,8 @@
 		}
 		dev->use_rx_msgqs = MSM_MSGQ_ENABLED;
 	} else {
-		dev->tx_idx = -1;
+		dev->tx_tail = 0;
+		dev->tx_head = 0;
 		dev->use_tx_msgqs = MSM_MSGQ_ENABLED;
 	}
 
@@ -711,16 +797,18 @@
 	config->options = SPS_O_ERROR | SPS_O_NO_Q |
 				SPS_O_ACK_TRANSFERS | SPS_O_AUTO_ENABLE;
 
+	/* Desc and TX buf are circular queues */
 	/* Allocate memory for the FIFO descriptors */
 	ret = msm_slim_sps_mem_alloc(dev, descr,
-				MSM_TX_BUFS * sizeof(struct sps_iovec));
+				(MSM_TX_BUFS + 1) * sizeof(struct sps_iovec));
 	if (ret) {
 		dev_err(dev->dev, "unable to allocate SPS descriptors\n");
 		goto alloc_descr_failed;
 	}
 
-	/* Allocate memory for the message buffer(s), N descrs, 40-byte mesg */
-	ret = msm_slim_sps_mem_alloc(dev, mem, MSM_TX_BUFS * SLIM_MSGQ_BUF_LEN);
+	/* Allocate TX buffer from which descriptors are created */
+	ret = msm_slim_sps_mem_alloc(dev, mem, ((MSM_TX_BUFS + 1) *
+					SLIM_MSGQ_BUF_LEN));
 	if (ret) {
 		dev_err(dev->dev, "dma_alloc_coherent failed\n");
 		goto alloc_buffer_failed;
@@ -863,10 +951,16 @@
 
 void msm_slim_sps_exit(struct msm_slim_ctrl *dev, bool dereg)
 {
+	int i;
+
 	if (dev->use_rx_msgqs >= MSM_MSGQ_ENABLED)
 		msm_slim_remove_ep(dev, &dev->rx_msgq, &dev->use_rx_msgqs);
 	if (dev->use_tx_msgqs >= MSM_MSGQ_ENABLED)
 		msm_slim_remove_ep(dev, &dev->tx_msgq, &dev->use_tx_msgqs);
+	for (i = dev->port_b; i < MSM_SLIM_NPORTS; i++) {
+		if (dev->pipes[i - dev->port_b].connected)
+			msm_slim_disconn_pipe_port(dev, i - dev->port_b);
+	}
 	if (dereg) {
 		int i;
 		for (i = dev->port_b; i < MSM_SLIM_NPORTS; i++) {
diff --git a/drivers/slimbus/slim-msm.h b/drivers/slimbus/slim-msm.h
index 9673208..99297a9 100644
--- a/drivers/slimbus/slim-msm.h
+++ b/drivers/slimbus/slim-msm.h
@@ -22,7 +22,7 @@
 /* Per spec.max 40 bytes per received message */
 #define SLIM_MSGQ_BUF_LEN	40
 
-#define MSM_TX_BUFS	2
+#define MSM_TX_BUFS		32
 
 #define SLIM_USR_MC_GENERIC_ACK		0x25
 #define SLIM_USR_MC_MASTER_CAPABILITY	0x0
@@ -214,7 +214,7 @@
 	struct work_struct		ssr_up;
 };
 
-struct msm_slim_mdm {
+struct msm_slim_ss {
 	struct notifier_block nb;
 	void *ssr;
 	enum msm_ctrl_state state;
@@ -236,14 +236,15 @@
 	u8			msg_cnt;
 	u32			tx_buf[10];
 	u8			rx_msgs[MSM_CONCUR_MSG][SLIM_MSGQ_BUF_LEN];
-	int			tx_idx;
+	int			tx_tail;
+	int			tx_head;
 	spinlock_t		rx_lock;
 	int			head;
 	int			tail;
 	int			irq;
 	int			err;
 	int			ee;
-	struct completion	*wr_comp;
+	struct completion	**wr_comp;
 	struct msm_slim_sat	*satd[MSM_MAX_NSATS];
 	struct msm_slim_endp	pipes[7];
 	struct msm_slim_sps_bam	bam;
@@ -254,6 +255,7 @@
 	struct clk		*rclk;
 	struct clk		*hclk;
 	struct mutex		tx_lock;
+	struct mutex		tx_buf_lock;
 	u8			pgdla;
 	enum msm_slim_msgq	use_rx_msgqs;
 	enum msm_slim_msgq	use_tx_msgqs;
@@ -267,7 +269,8 @@
 	u32			ver;
 	struct msm_slim_qmi	qmi;
 	struct msm_slim_pdata	pdata;
-	struct msm_slim_mdm	mdm;
+	struct msm_slim_ss	ext_mdm;
+	struct msm_slim_ss	dsp;
 	int			default_ipc_log_mask;
 	int			ipc_log_mask;
 	bool			sysfs_created;
@@ -372,7 +375,10 @@
 int msm_slim_port_xfer(struct slim_controller *ctrl, u8 pn, phys_addr_t iobuf,
 			u32 len, struct completion *comp);
 int msm_send_msg_buf(struct msm_slim_ctrl *dev, u32 *buf, u8 len, u32 tx_reg);
-u32 *msm_get_msg_buf(struct msm_slim_ctrl *dev, int len);
+u32 *msm_get_msg_buf(struct msm_slim_ctrl *dev, int len,
+			struct completion *comp);
+u32 *msm_slim_manage_tx_msgq(struct msm_slim_ctrl *dev, bool getbuf,
+			struct completion *comp);
 int msm_slim_rx_msgq_get(struct msm_slim_ctrl *dev, u32 *data, int offset);
 int msm_slim_sps_init(struct msm_slim_ctrl *dev, struct resource *bam_mem,
 			u32 pipe_reg, bool remote);
diff --git a/drivers/slimbus/slimbus.c b/drivers/slimbus/slimbus.c
index fecf5ec..27b92ba 100644
--- a/drivers/slimbus/slimbus.c
+++ b/drivers/slimbus/slimbus.c
@@ -1100,7 +1100,7 @@
 	} else
 		ret = slim_processtxn(ctrl, SLIM_MSG_DEST_LOGICALADDR, mc, ec,
 				SLIM_MSG_MT_CORE, rbuf, wbuf, len, mlen,
-				NULL, sbdev->laddr, NULL);
+				msg->comp, sbdev->laddr, NULL);
 xfer_err:
 	return ret;
 }
diff --git a/drivers/video/msm/mdss/dsi_host_v2.c b/drivers/video/msm/mdss/dsi_host_v2.c
index 592f70e..68c991c 100644
--- a/drivers/video/msm/mdss/dsi_host_v2.c
+++ b/drivers/video/msm/mdss/dsi_host_v2.c
@@ -653,14 +653,25 @@
 	return rc;
 }
 
+/* MIPI_DSI_MRPS, Maximum Return Packet Size */
+static char max_pktsize[2] = {0x00, 0x00}; /* LSB tx first, 10 bytes */
+
+static struct dsi_cmd_desc pkt_size_cmd = {
+	{DTYPE_MAX_PKTSIZE, 1, 0, 0, 0, sizeof(max_pktsize)},
+	max_pktsize,
+};
+
 int msm_dsi_cmd_dma_rx(struct mdss_dsi_ctrl_pdata *ctrl,
 			struct dsi_buf *rp, int rlen)
 {
-	u32 *lp, data;
-	int i, off, cnt;
+	u32 *lp, data, *temp;
+	int i, j = 0, off, cnt;
 	unsigned char *ctrl_base = dsi_host_private->dsi_base;
+	char reg[16];
+	int repeated_bytes = 0;
 
 	lp = (u32 *)rp->data;
+	temp = (u32 *)reg;
 	cnt = rlen;
 	cnt += 3;
 	cnt >>= 2;
@@ -668,16 +679,52 @@
 	if (cnt > 4)
 		cnt = 4; /* 4 x 32 bits registers only */
 
+	if (rlen == 4)
+		rp->read_cnt = 4;
+	else
+		rp->read_cnt = (max_pktsize[0] + 6);
+
+	if (rp->read_cnt > 16) {
+		int bytes_shifted, data_lost = 0, rem_header_bytes = 0;
+		/* Any data more than 16 bytes will be shifted out */
+		bytes_shifted = rp->read_cnt - rlen;
+		if (bytes_shifted >= 4)
+			data_lost = bytes_shifted - 4; /* remove dcs header */
+		else
+			rem_header_bytes = 4 - bytes_shifted; /* rem header */
+		/*
+		 * (rp->len - 4) -> current rx buffer data length.
+		 * If data_lost > 0, then ((rp->len - 4) - data_lost) will be
+		 * the number of repeating bytes.
+		 * If data_lost == 0, then ((rp->len - 4) + rem_header_bytes)
+		 * will be the number of bytes repeating in between rx buffer
+		 * and the current RDBK_DATA registers. We need to skip the
+		 * repeating bytes.
+		 */
+		repeated_bytes = (rp->len - 4) - data_lost + rem_header_bytes;
+	}
+
 	off = DSI_RDBK_DATA0;
 	off += ((cnt - 1) * 4);
 
 	for (i = 0; i < cnt; i++) {
 		data = (u32)MIPI_INP(ctrl_base + off);
-		*lp++ = ntohl(data); /* to network byte order */
+		/* to network byte order */
+		if (!repeated_bytes)
+			*lp++ = ntohl(data);
+		else
+			*temp++ = ntohl(data);
 		pr_debug("%s: data = 0x%x and ntohl(data) = 0x%x\n",
 					 __func__, data, ntohl(data));
 		off -= 4;
-		rp->len += sizeof(*lp);
+		if (rlen == 4)
+			rp->len += sizeof(*lp);
+	}
+
+	/* Skip duplicates and append other data to the rx buffer */
+	if (repeated_bytes) {
+		for (i = repeated_bytes; i < 16; i++)
+			rp->data[j++] = reg[i];
 	}
 
 	return rlen;
@@ -769,14 +816,6 @@
 	return rc;
 }
 
-/* MIPI_DSI_MRPS, Maximum Return Packet Size */
-static char max_pktsize[2] = {0x00, 0x00}; /* LSB tx first, 10 bytes */
-
-static struct dsi_cmd_desc pkt_size_cmd = {
-	{DTYPE_MAX_PKTSIZE, 1, 0, 0, 0, sizeof(max_pktsize)},
-	max_pktsize,
-};
-
 static int msm_dsi_set_max_packet_size(struct mdss_dsi_ctrl_pdata *ctrl,
 						int size)
 {
@@ -814,10 +853,23 @@
 {
 	int rc;
 	struct dsi_buf *tp, *rp;
+	int rx_byte = 0;
+
+	if (rlen <= 2)
+		rx_byte = 4;
+	else
+		rx_byte = DSI_MAX_BYTES_TO_READ;
 
 	tp = &ctrl->tx_buf;
 	rp = &ctrl->rx_buf;
 	mdss_dsi_buf_init(rp);
+	rc = msm_dsi_set_max_packet_size(ctrl, rlen);
+	if (rc) {
+		pr_err("%s: dsi_set_max_pkt failed\n", __func__);
+		rc = -EINVAL;
+		goto dsi_cmds_rx_1_error;
+	}
+
 	mdss_dsi_buf_init(tp);
 
 	rc = mdss_dsi_cmd_dma_add(tp, cmds);
@@ -840,10 +892,12 @@
 	}
 
 	if (rlen <= DSI_SHORT_PKT_DATA_SIZE) {
-		msm_dsi_cmd_dma_rx(ctrl, rp, rlen);
+		msm_dsi_cmd_dma_rx(ctrl, rp, rx_byte);
 	} else {
-		msm_dsi_cmd_dma_rx(ctrl, rp, rlen + DSI_HOST_HDR_SIZE);
-		rp->len = rlen + DSI_HOST_HDR_SIZE;
+		msm_dsi_cmd_dma_rx(ctrl, rp, rx_byte);
+		rp->len = rx_byte - 2;	/*2 bytes for CRC*/
+		rp->len = rp->len - (DSI_MAX_PKT_SIZE - rlen);
+		rp->data = rp->start + (16 - (rlen + 2 + DSI_HOST_HDR_SIZE));
 	}
 	rc = msm_dsi_parse_rx_response(rp);
 
@@ -860,16 +914,15 @@
 {
 	int rc;
 	struct dsi_buf *tp, *rp;
-	int pkt_size, data_bytes, total;
+	int pkt_size, data_bytes, dlen, end = 0, diff;
 
 	tp = &ctrl->tx_buf;
 	rp = &ctrl->rx_buf;
 	mdss_dsi_buf_init(rp);
 	pkt_size = DSI_MAX_PKT_SIZE;
 	data_bytes = MDSS_DSI_LEN;
-	total = 0;
 
-	while (true) {
+	while (!end) {
 		rc = msm_dsi_set_max_packet_size(ctrl, pkt_size);
 		if (rc)
 			break;
@@ -880,7 +933,7 @@
 			pr_err("%s: dsi_cmd_dma_add failed\n", __func__);
 			rc = -EINVAL;
 			break;
-	}
+		}
 		rc = msm_dsi_wait4video_eng_busy(ctrl);
 		if (rc) {
 			pr_err("%s: wait4video_eng failed\n", __func__);
@@ -894,19 +947,32 @@
 		}
 
 		msm_dsi_cmd_dma_rx(ctrl, rp, DSI_MAX_BYTES_TO_READ);
+		if (rlen <= data_bytes) {
+			diff = data_bytes - rlen;
+			end = 1;
+		} else {
+			diff = 0;
+			rlen -= data_bytes;
+		}
+		dlen = DSI_MAX_BYTES_TO_READ - 2;
+		dlen -= diff;
+		rp->data += dlen;
+		rp->len += dlen;
 
-		rp->data += DSI_MAX_BYTES_TO_READ - DSI_HOST_HDR_SIZE;
-		total += data_bytes;
-		if (total >= rlen)
-			break;
-
-		data_bytes = DSI_MAX_BYTES_TO_READ - DSI_HOST_HDR_SIZE;
-		pkt_size += data_bytes;
+		if (!end) {
+			data_bytes = 14;
+			if (rlen < data_bytes)
+				pkt_size += rlen;
+			else
+				pkt_size += data_bytes;
+		}
+		pr_debug("%s: rp data=%x len=%d dlen=%d diff=%d\n",
+			 __func__, (int) (unsigned long) rp->data,
+			 rp->len, dlen, diff);
 	}
 
 	if (!rc) {
 		rp->data = rp->start;
-		rp->len = rlen + DSI_HOST_HDR_SIZE;
 		rc = msm_dsi_parse_rx_response(rp);
 	}
 
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
index cd0af6d..27524af 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.c
+++ b/drivers/video/msm/mdss/mdp3_ctrl.c
@@ -1589,8 +1589,9 @@
 	lut_config.lut_sel = mdp3_session->lut_sel;
 	lut_config.lut_position = 0;
 	lut_config.lut_dirty = true;
-	lut.color0_lut = r;
-	lut.color1_lut = g;
+	/* In HW the order is color0 = g, color1 = r and color2 = b*/
+	lut.color0_lut = g;
+	lut.color1_lut = r;
 	lut.color2_lut = b;
 
 	mutex_lock(&mdp3_session->lock);
diff --git a/drivers/video/msm/mdss/mdss_dsi_cmd.c b/drivers/video/msm/mdss/mdss_dsi_cmd.c
index 8fc1115c0..6d8f9e9 100644
--- a/drivers/video/msm/mdss/mdss_dsi_cmd.c
+++ b/drivers/video/msm/mdss/mdss_dsi_cmd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -66,6 +66,7 @@
 		off = 8 - off;
 	dp->data += off;
 	dp->len = 0;
+	dp->read_cnt = 0;
 	return dp->data;
 }
 
@@ -86,6 +87,7 @@
 
 	dp->data = dp->start;
 	dp->len = 0;
+	dp->read_cnt = 0;
 	return size;
 }
 
@@ -574,6 +576,7 @@
 	/* strip out dcs type */
 	rp->data++;
 	rp->len = 1;
+	rp->read_cnt -= 3;
 	return rp->len;
 }
 
@@ -585,6 +588,7 @@
 	/* strip out dcs type */
 	rp->data++;
 	rp->len = 2;
+	rp->read_cnt -= 2;
 	return rp->len;
 }
 
@@ -593,6 +597,7 @@
 	/* strip out dcs header */
 	rp->data += 4;
 	rp->len -= 4;
+	rp->read_cnt -= 6;
 	return rp->len;
 }
 
diff --git a/drivers/video/msm/mdss/mdss_dsi_cmd.h b/drivers/video/msm/mdss/mdss_dsi_cmd.h
index f806e78..3abe4fc 100644
--- a/drivers/video/msm/mdss/mdss_dsi_cmd.h
+++ b/drivers/video/msm/mdss/mdss_dsi_cmd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -30,7 +30,7 @@
 
 #define MDSS_DSI_MRPS	0x04  /* Maximum Return Packet Size */
 
-#define MDSS_DSI_LEN 8 /* 4 x 4 - 6 - 2, bytes dcs header+crc-align  */
+#define MDSS_DSI_LEN 10 /* 4 x 4 - 4 - 2, bytes dcs header+crc-align  */
 
 struct dsi_buf {
 	u32 *hdr;	/* dsi host header */
@@ -40,6 +40,7 @@
 	char *data;	/* buffer */
 	int len;	/* data length */
 	dma_addr_t dmap; /* mapped dma addr */
+	int read_cnt;
 };
 
 /* dcs read/write */
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
old mode 100644
new mode 100755
index 4c72d28..70e2972
--- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
@@ -32,11 +32,11 @@
 	struct mdss_mdp_ctl *ctl;
 	u32 pp_num;
 	u8 ref_cnt;
-	struct completion pp_comp;
 	struct completion stop_comp;
+	wait_queue_head_t pp_waitq;
 	struct list_head vsync_handlers;
 	int panel_on;
-	int koff_cnt;
+	atomic_t koff_cnt;
 	int clk_enabled;
 	int vsync_enabled;
 	int rdptr_enabled;
@@ -55,10 +55,14 @@
 	u32 vclk_line;	/* vsync clock per line */
 	struct mdss_panel_recovery recovery;
 	bool ulps;
+	struct mdss_mdp_cmd_ctx *sync_ctx; /* for partial update */
+	u32 pp_timeout_report_cnt;
 };
 
 struct mdss_mdp_cmd_ctx mdss_mdp_cmd_ctx_list[MAX_SESSIONS];
 
+static int mdss_mdp_cmd_do_notifier(struct mdss_mdp_cmd_ctx *ctx);
+
 static inline u32 mdss_mdp_cmd_line_count(struct mdss_mdp_ctl *ctl)
 {
 	struct mdss_mdp_mixer *mixer;
@@ -287,7 +291,7 @@
 			ctx->rdptr_enabled--;
 
 		/* keep clk on during kickoff */
-		if (ctx->rdptr_enabled == 0 && ctx->koff_cnt)
+		if (ctx->rdptr_enabled == 0 && atomic_read(&ctx->koff_cnt))
 			ctx->rdptr_enabled++;
 	}
 
@@ -314,14 +318,13 @@
 	if (!ctx->ctl)
 		return;
 	spin_lock_irqsave(&ctx->clk_lock, flags);
-	if (ctx->koff_cnt) {
+	if (atomic_read(&ctx->koff_cnt)) {
 		mdss_mdp_ctl_reset(ctx->ctl);
 		pr_debug("%s: intf_num=%d\n", __func__,
 					ctx->ctl->intf_num);
-		ctx->koff_cnt--;
+		atomic_dec(&ctx->koff_cnt);
 		mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_PING_PONG_COMP,
 						ctx->pp_num);
-		complete_all(&ctx->pp_comp);
 	}
 	spin_unlock_irqrestore(&ctx->clk_lock, flags);
 }
@@ -348,25 +351,27 @@
 	}
 	mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num);
 
-	complete_all(&ctx->pp_comp);
 	MDSS_XLOG(ctl->num, ctx->koff_cnt, ctx->clk_enabled,
 					ctx->rdptr_enabled);
 
-	if (ctx->koff_cnt) {
-		atomic_inc(&ctx->pp_done_cnt);
-		schedule_work(&ctx->pp_done_work);
-		ctx->koff_cnt--;
-		if (ctx->koff_cnt) {
+	if (atomic_add_unless(&ctx->koff_cnt, -1, 0)) {
+		if (atomic_read(&ctx->koff_cnt))
 			pr_err("%s: too many kickoffs=%d!\n", __func__,
-			       ctx->koff_cnt);
-			ctx->koff_cnt = 0;
+			       atomic_read(&ctx->koff_cnt));
+		if (mdss_mdp_cmd_do_notifier(ctx)) {
+			atomic_inc(&ctx->pp_done_cnt);
+			schedule_work(&ctx->pp_done_work);
 		}
-	} else
+		wake_up_all(&ctx->pp_waitq);
+	} else {
 		pr_err("%s: should not have pingpong interrupt!\n", __func__);
+	}
 
-	trace_mdp_cmd_pingpong_done(ctl, ctx->pp_num, ctx->koff_cnt);
+	trace_mdp_cmd_pingpong_done(ctl, ctx->pp_num,
+			atomic_read(&ctx->koff_cnt));
 	pr_debug("%s: ctl_num=%d intf_num=%d ctx=%d kcnt=%d\n", __func__,
-		ctl->num, ctl->intf_num, ctx->pp_num, ctx->koff_cnt);
+		ctl->num, ctl->intf_num, ctx->pp_num,
+			atomic_read(&ctx->koff_cnt));
 
 	spin_unlock(&ctx->clk_lock);
 }
@@ -504,7 +509,6 @@
 	struct mdss_mdp_cmd_ctx *ctx;
 	struct mdss_panel_data *pdata;
 	unsigned long flags;
-	int need_wait = 0;
 	int rc = 0;
 
 	ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data;
@@ -515,11 +519,6 @@
 
 	pdata = ctl->panel_data;
 
-	spin_lock_irqsave(&ctx->clk_lock, flags);
-	if (ctx->koff_cnt > 0)
-		need_wait = 1;
-	spin_unlock_irqrestore(&ctx->clk_lock, flags);
-
 	ctl->roi_bkup.w = ctl->width;
 	ctl->roi_bkup.h = ctl->height;
 
@@ -527,33 +526,95 @@
 			ctx->rdptr_enabled, ctl->roi_bkup.w,
 			ctl->roi_bkup.h);
 
-	pr_debug("%s: need_wait=%d  intf_num=%d ctx=%p\n",
-			__func__, need_wait, ctl->intf_num, ctx);
+	pr_debug("%s: intf_num=%d ctx=%p koff_cnt=%d\n", __func__,
+			ctl->intf_num, ctx, atomic_read(&ctx->koff_cnt));
 
-	if (need_wait) {
-		rc = wait_for_completion_timeout(
-				&ctx->pp_comp, KOFF_TIMEOUT);
+	rc = wait_event_timeout(ctx->pp_waitq,
+			atomic_read(&ctx->koff_cnt) == 0,
+			KOFF_TIMEOUT);
 
-		trace_mdp_cmd_wait_pingpong(ctl->num, ctx->koff_cnt);
+	if (rc <= 0) {
+		u32 status, mask;
 
-		if (rc <= 0) {
-			WARN(1, "cmd kickoff timed out (%d) ctl=%d\n",
-						rc, ctl->num);
-			mdss_dsi_debug_check_te(pdata);
-			MDSS_XLOG_TOUT_HANDLER("mdp", "dsi0", "dsi1",
-						"edp", "hdmi", "panic");
-			rc = -EPERM;
-			mdss_mdp_ctl_notify(ctl, MDP_NOTIFY_FRAME_TIMEOUT);
-		} else {
-			rc = 0;
+		mask = BIT(MDSS_MDP_IRQ_PING_PONG_COMP + ctx->pp_num);
+		status = mask & readl_relaxed(ctl->mdata->mdp_base +
+				MDSS_MDP_REG_INTR_STATUS);
+		if (status) {
+			WARN(1, "pp done but irq not triggered\n");
+			mdss_mdp_irq_clear(ctl->mdata,
+					MDSS_MDP_IRQ_PING_PONG_COMP,
+					ctx->pp_num);
+			local_irq_save(flags);
+			mdss_mdp_cmd_pingpong_done(ctl);
+			local_irq_restore(flags);
+			rc = 1;
 		}
+
+		rc = atomic_read(&ctx->koff_cnt) == 0;
 	}
 
-	MDSS_XLOG(ctl->num, ctx->koff_cnt, ctx->clk_enabled,
-					ctx->rdptr_enabled, rc);
+	if (rc <= 0) {
+		if (!ctx->pp_timeout_report_cnt) {
+			WARN(1, "cmd kickoff timed out (%d) ctl=%d\n",
+					rc, ctl->num);
+			mdss_dsi_debug_check_te(pdata);
+			MDSS_XLOG_TOUT_HANDLER("mdp", "dsi0", "dsi1",
+					"edp", "hdmi", "panic");
+		}
+		ctx->pp_timeout_report_cnt++;
+		rc = -EPERM;
+		mdss_mdp_ctl_notify(ctl, MDP_NOTIFY_FRAME_TIMEOUT);
+		atomic_add_unless(&ctx->koff_cnt, -1, 0);
+	} else {
+		rc = 0;
+		ctx->pp_timeout_report_cnt = 0;
+	}
+
+	/* signal any pending ping pong done events */
+	while (atomic_add_unless(&ctx->pp_done_cnt, -1, 0))
+		mdss_mdp_ctl_notify(ctx->ctl, MDP_NOTIFY_FRAME_DONE);
+
+	MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt), ctx->clk_enabled,
+			ctx->rdptr_enabled, rc);
+
 	return rc;
 }
 
+static int mdss_mdp_cmd_do_notifier(struct mdss_mdp_cmd_ctx *ctx)
+{
+	struct mdss_mdp_cmd_ctx *sctx;
+	sctx = ctx->sync_ctx;
+
+	if (!sctx || atomic_read(&sctx->koff_cnt) == 0)
+		return 1;
+
+	return 0;
+}
+
+static void mdss_mdp_cmd_set_sync_ctx(
+		struct mdss_mdp_ctl *ctl, struct mdss_mdp_ctl *sctl)
+{
+	struct mdss_mdp_cmd_ctx *ctx, *sctx;
+
+	ctx = (struct mdss_mdp_cmd_ctx *)ctl->priv_data;
+	if (!sctl) {
+		ctx->sync_ctx = NULL;
+		return;
+	}
+
+	sctx = (struct mdss_mdp_cmd_ctx *)sctl->priv_data;
+
+	if (!sctl->roi.w && !sctl->roi.h) {
+		/* left only */
+		ctx->sync_ctx = NULL;
+		sctx->sync_ctx = NULL;
+	} else {
+		 /* left + right */
+		ctx->sync_ctx = sctx;
+		sctx->sync_ctx = ctx;
+	}
+}
+
 static int mdss_mdp_cmd_set_partial_roi(struct mdss_mdp_ctl *ctl)
 {
 	int rc = 0;
@@ -572,8 +633,7 @@
 
 int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg)
 {
-	struct mdss_mdp_cmd_ctx *ctx;
-	unsigned long flags;
+	struct mdss_mdp_cmd_ctx *ctx, *sctx = NULL;
 	int rc;
 
 	ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data;
@@ -602,10 +662,11 @@
 	MDSS_XLOG(ctl->num, ctl->roi.x, ctl->roi.y, ctl->roi.w,
 						ctl->roi.h);
 
-	spin_lock_irqsave(&ctx->clk_lock, flags);
-	ctx->koff_cnt++;
-	spin_unlock_irqrestore(&ctx->clk_lock, flags);
-	trace_mdp_cmd_kickoff(ctl->num, ctx->koff_cnt);
+	atomic_inc(&ctx->koff_cnt);
+	if (sctx)
+		atomic_inc(&sctx->koff_cnt);
+
+	trace_mdp_cmd_kickoff(ctl->num, atomic_read(&ctx->koff_cnt));
 
 	mdss_mdp_cmd_clk_on(ctx);
 
@@ -615,7 +676,9 @@
 	 * tx dcs command if had any
 	 */
 	mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_DSI_CMDLIST_KOFF, NULL);
-	INIT_COMPLETION(ctx->pp_comp);
+
+	mdss_mdp_cmd_set_sync_ctx(ctl, NULL);
+
 	mdss_mdp_irq_enable(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num);
 	mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_START, 1);
 	mdss_mdp_ctl_perf_set_transaction_status(ctl,
@@ -667,13 +730,10 @@
 				pr_err("no panel data\n");
 			} else {
 				pinfo = &ctl->panel_data->panel_info;
-
-				if (pinfo->panel_dead) {
-					mdss_mdp_irq_disable
-						(MDSS_MDP_IRQ_PING_PONG_RD_PTR,
-								ctx->pp_num);
-					ctx->rdptr_enabled = 0;
-				}
+				mdss_mdp_irq_disable
+					(MDSS_MDP_IRQ_PING_PONG_RD_PTR,
+							ctx->pp_num);
+				ctx->rdptr_enabled = 0;
 			}
 		}
 
@@ -754,7 +814,8 @@
 
 	ctx->ctl = ctl;
 	ctx->pp_num = mixer->num;
-	init_completion(&ctx->pp_comp);
+	ctx->pp_timeout_report_cnt = 0;
+	init_waitqueue_head(&ctx->pp_waitq);
 	init_completion(&ctx->stop_comp);
 	spin_lock_init(&ctx->clk_lock);
 	mutex_init(&ctx->clk_mtx);
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index b165664..27fe7bc 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -29,7 +29,7 @@
 #include "q6voice.h"
 
 
-#define TIMEOUT_MS 300
+#define TIMEOUT_MS 500
 
 
 #define CMD_STATUS_SUCCESS 0