Merge "ASoC: wcd9320: use hwdep nodes to get calibration"
diff --git a/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt b/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
index bbc9f08..541b50a 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
@@ -100,6 +100,12 @@
 - qcom,efuse-temperature-map: Truth table of efuse value temperature value pair for
 			different parts. if qcom,default temp is defined, then it can
 			specify only pairs which deviate from default temperature.
+- qcom,therm-reset-temp: Degree above which the KTM will initiate a secure watchdog reset.
+			When this property is defined, KTM will monitor all the tsens from
+			boot time and will initiate a secure watchdog reset if any of the
+			tsens temperature reaches this threshold. This reset helps in
+			generating more informative crash dumps opposed to the crash dump
+			generated by the hardware reset.
 
 Optional child nodes
 - qti,pmic-opt-curr-temp: Threshold temperature for requesting optimum current (request
@@ -139,6 +145,7 @@
 		qcom,temp-hysteresis = <10>;
 		qcom,freq-step = <2>;
 		qcom,freq-control-mask = <0xf>
+		qcom,therm-reset-temp = <115>;
 		qcom,core-limit-temp = <90>;
 		qcom,core-temp-hysteresis = <10>;
 		qcom,core-control-mask = <7>;
diff --git a/Documentation/devicetree/bindings/platform/msm/avtimer.txt b/Documentation/devicetree/bindings/platform/msm/avtimer.txt
index 86c9b67..2d89262 100644
--- a/Documentation/devicetree/bindings/platform/msm/avtimer.txt
+++ b/Documentation/devicetree/bindings/platform/msm/avtimer.txt
@@ -12,10 +12,15 @@
   "avtimer_msb_addr" : AVtimer msb physical address
 - compatible : Must be "qcom,avtimer"
 
+Optional properties:
+- clk_div : For 8916 the clk is at 27MHz and hence ticks are to be
+ divided by 27 to achive the msec value.
+
 Example:
 	qcom,avtimer {
 		compatible = "qcom,avtimer";
 		reg = <0xfe053008 0x4>,
 			<0xfe05300c 0x4>;
 		reg-names = "avtimer_lsb_addr", "avtimer_msb_addr";
+		qcom,clk_div = <27>;
 	};
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index b7413cb..87fb3e9 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -360,6 +360,8 @@
  [stack:1001]             = the stack of the thread with tid 1001
  [vdso]                   = the "virtual dynamic shared object",
                             the kernel system call handler
+ [anon:<name>]            = an anonymous mapping that has been
+                            named by userspace
 
  or if empty, the mapping is anonymous.
 
@@ -409,6 +411,7 @@
 KernelPageSize:        4 kB
 MMUPageSize:           4 kB
 Locked:              374 kB
+Name:           name from userspace
 
 The first of these lines shows the same information as is displayed for the
 mapping in /proc/PID/maps.  The remaining lines show the size of the mapping
@@ -424,6 +427,9 @@
 "Swap" shows how much would-be-anonymous memory is also used, but out on
 swap.
 
+The "Name" field will only be present on a mapping that has been named by
+userspace, and will show the name passed in by userspace.
+
 This file is only present if the CONFIG_MMU kernel configuration option is
 enabled.
 
diff --git a/arch/arm/boot/compressed/libfdt_env.h b/arch/arm/boot/compressed/libfdt_env.h
index 1f4e718..799b575 100644
--- a/arch/arm/boot/compressed/libfdt_env.h
+++ b/arch/arm/boot/compressed/libfdt_env.h
@@ -1,6 +1,7 @@
 #ifndef _ARM_LIBFDT_ENV_H
 #define _ARM_LIBFDT_ENV_H
 
+#include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <asm/byteorder.h>
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 495117f..f8c9b46 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -1987,6 +1987,7 @@
 		gpios = <&msmgpio 36 0>, <&msmgpio 37 0>, <&msmgpio 38 0>, <&msmgpio 39 0>, <&msmgpio 40 0>;
 		qcom,has-48mhz-xo;
 		qcom,has-pronto-hw;
+		qcom,wcnss-pm = <11 21 1200 1 1>;
 	};
 
 	qcom,ocmem@fdd00000 {
@@ -2263,6 +2264,7 @@
 		qcom,poll-ms = <250>;
 		qcom,limit-temp = <60>;
 		qcom,temp-hysteresis = <10>;
+		qcom,therm-reset-temp = <115>;
 		qcom,freq-step = <2>;
 		qcom,freq-control-mask = <0xf>;
 		qcom,core-limit-temp = <80>;
diff --git a/arch/arm/configs/msm8226_defconfig b/arch/arm/configs/msm8226_defconfig
index 525def5..ae3e19d 100644
--- a/arch/arm/configs/msm8226_defconfig
+++ b/arch/arm/configs/msm8226_defconfig
@@ -527,3 +527,4 @@
 CONFIG_MOBICORE_API=m
 CONFIG_MSM_RPM_RBCPR_STATS_V2_LOG=y
 CONFIG_MSM_RDBG=m
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
diff --git a/arch/arm/configs/msm8610_defconfig b/arch/arm/configs/msm8610_defconfig
index 6874b28..b239bcb 100644
--- a/arch/arm/configs/msm8610_defconfig
+++ b/arch/arm/configs/msm8610_defconfig
@@ -504,3 +504,4 @@
 CONFIG_MSM_RDBG=m
 CONFIG_MOBICORE_SUPPORT=m
 CONFIG_MOBICORE_API=m
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index 7c299d7..2711278 100755
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -459,6 +459,7 @@
 CONFIG_QPNP_CLKDIV=y
 CONFIG_QPNP_REVID=y
 CONFIG_QPNP_COINCELL=y
+CONFIG_MSM_AVTIMER=y
 CONFIG_MSM_IOMMU_V1=y
 CONFIG_IOMMU_PGTABLES_L2=y
 CONFIG_MSM_IOMMU_VBIF_CHECK=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index e8a1cde..52f3598 100755
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -483,6 +483,7 @@
 CONFIG_QPNP_CLKDIV=y
 CONFIG_QPNP_REVID=y
 CONFIG_QPNP_COINCELL=y
+CONFIG_MSM_AVTIMER=y
 CONFIG_MSM_IOMMU_V1=y
 CONFIG_MSM_IOMMU_PMON=y
 CONFIG_IOMMU_PGTABLES_L2=y
@@ -568,3 +569,4 @@
 CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y
 CONFIG_MSM_RDBG=m
 CONFIG_MSM_AVTIMER=y
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/apr.h b/arch/arm/mach-msm/include/mach/qdsp6v2/apr.h
index 9f4acca..04eb5ee 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/apr.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/apr.h
@@ -168,4 +168,5 @@
 int apr_set_q6_state(enum apr_subsys_state state);
 void apr_set_subsys_state(void);
 const char *apr_get_lpass_subsys_name(void);
+extern int is_modem_up;
 #endif
diff --git a/arch/arm/mach-msm/qdsp6v2/apr.c b/arch/arm/mach-msm/qdsp6v2/apr.c
index 937eeda..d3119bc 100644
--- a/arch/arm/mach-msm/qdsp6v2/apr.c
+++ b/arch/arm/mach-msm/qdsp6v2/apr.c
@@ -41,6 +41,7 @@
 
 static wait_queue_head_t dsp_wait;
 static wait_queue_head_t modem_wait;
+int is_modem_up = 0;
 /* Subsystem restart: QDSP6 data, functions */
 static struct workqueue_struct *apr_reset_workqueue;
 static void apr_reset_deregister(struct work_struct *work);
@@ -646,6 +647,7 @@
 		if (apr_cmpxchg_modem_state(APR_SUBSYS_DOWN, APR_SUBSYS_UP) ==
 						APR_SUBSYS_DOWN)
 			wake_up(&modem_wait);
+                is_modem_up = 1;
 		pr_debug("M-Notify: Bootup Completed\n");
 		break;
 	default:
diff --git a/arch/arm/mach-msm/qdsp6v2/apr_v2.c b/arch/arm/mach-msm/qdsp6v2/apr_v2.c
index fbb8713..c4d934e 100644
--- a/arch/arm/mach-msm/qdsp6v2/apr_v2.c
+++ b/arch/arm/mach-msm/qdsp6v2/apr_v2.c
@@ -53,7 +53,12 @@
 		pr_debug("%s: adsp Up\n", __func__);
 	} else if ((dest_id == APR_DEST_MODEM) &&
 		   (apr_get_modem_state() == APR_SUBSYS_DOWN)) {
-		pr_debug("%s: Wait for modem to bootup\n", __func__);
+                if (is_modem_up) {
+                    pr_err("%s: modem shutdown \
+                            due to SSR, return", __func__);
+                    return NULL;
+                }
+                pr_debug("%s: Wait for modem to bootup\n", __func__);
 		rc = apr_wait_for_device_up(dest_id);
 		if (rc == 0) {
 			pr_err("%s: Modem is not Up\n", __func__);
diff --git a/drivers/base/sync.c b/drivers/base/sync.c
index 645a698..7e1ecf3 100644
--- a/drivers/base/sync.c
+++ b/drivers/base/sync.c
@@ -34,7 +34,6 @@
 static void sync_fence_signal_pt(struct sync_pt *pt);
 static int _sync_pt_has_signaled(struct sync_pt *pt);
 static void sync_fence_free(struct kref *kref);
-static void sync_dump(struct sync_fence *fence);
 
 static LIST_HEAD(sync_timeline_list_head);
 static DEFINE_SPINLOCK(sync_timeline_list_lock);
@@ -586,6 +585,74 @@
 	return fence->status != 0;
 }
 
+static const char *sync_status_str(int status)
+{
+	if (status > 0)
+		return "signaled";
+	else if (status == 0)
+		return "active";
+	else
+		return "error";
+}
+
+static void sync_pt_log(struct sync_pt *pt)
+{
+	int status = pt->status;
+	pr_cont("  %s_pt %s",
+		   pt->parent->name,
+		   sync_status_str(status));
+
+	if (pt->status) {
+		struct timeval tv = ktime_to_timeval(pt->timestamp);
+		pr_cont("@%ld.%06ld", tv.tv_sec, tv.tv_usec);
+	}
+
+	if (pt->parent->ops->timeline_value_str &&
+	    pt->parent->ops->pt_value_str) {
+		char value[64];
+		pt->parent->ops->pt_value_str(pt, value, sizeof(value));
+		pr_cont(": %s", value);
+		pt->parent->ops->timeline_value_str(pt->parent, value,
+					    sizeof(value));
+		pr_cont(" / %s", value);
+	}
+
+	pr_cont("\n");
+
+	/* Show additional details for active fences */
+	if (pt->status == 0 && pt->parent->ops->pt_log)
+		pt->parent->ops->pt_log(pt);
+}
+
+void sync_fence_log(struct sync_fence *fence)
+{
+	struct list_head *pos;
+	unsigned long flags;
+
+	pr_info("[%p] %s: %s\n", fence, fence->name,
+		sync_status_str(fence->status));
+
+	pr_info("waiters:\n");
+
+	spin_lock_irqsave(&fence->waiter_list_lock, flags);
+	list_for_each(pos, &fence->waiter_list_head) {
+		struct sync_fence_waiter *waiter =
+			container_of(pos, struct sync_fence_waiter,
+				     waiter_list);
+
+		pr_info(" %pF\n", waiter->callback);
+	}
+	spin_unlock_irqrestore(&fence->waiter_list_lock, flags);
+
+	pr_info("syncpoints:\n");
+	list_for_each(pos, &fence->pt_list_head) {
+		struct sync_pt *pt =
+			container_of(pos, struct sync_pt, pt_list);
+		sync_pt_log(pt);
+	}
+}
+EXPORT_SYMBOL(sync_fence_log);
+
 int sync_fence_wait(struct sync_fence *fence, long timeout)
 {
 	int err = 0;
@@ -611,7 +678,7 @@
 
 	if (fence->status < 0) {
 		pr_info("fence error %d on [%p]\n", fence->status, fence);
-		sync_dump(fence);
+		sync_fence_log(fence);
 		return fence->status;
 	}
 
@@ -619,7 +686,7 @@
 		if (timeout > 0) {
 			pr_info("fence timeout on [%p] after %dms\n", fence,
 				jiffies_to_msecs(timeout));
-			sync_dump(fence);
+			sync_fence_log(fence);
 		}
 		return -ETIME;
 	}
@@ -841,16 +908,6 @@
 }
 
 #ifdef CONFIG_DEBUG_FS
-static const char *sync_status_str(int status)
-{
-	if (status > 0)
-		return "signaled";
-	else if (status == 0)
-		return "active";
-	else
-		return "error";
-}
-
 static void sync_print_pt(struct seq_file *s, struct sync_pt *pt, bool fence)
 {
 	int status = pt->status;
@@ -983,35 +1040,4 @@
 	return 0;
 }
 late_initcall(sync_debugfs_init);
-
-#define DUMP_CHUNK 256
-static char sync_dump_buf[64 * 1024];
-static void sync_dump(struct sync_fence *fence)
-{
-       struct seq_file s = {
-               .buf = sync_dump_buf,
-               .size = sizeof(sync_dump_buf) - 1,
-       };
-       int i;
-
-       seq_printf(&s, "fence:\n--------------\n");
-       sync_print_fence(&s, fence);
-       seq_printf(&s, "\n");
-
-       for (i = 0; i < s.count; i += DUMP_CHUNK) {
-               if ((s.count - i) > DUMP_CHUNK) {
-                       char c = s.buf[i + DUMP_CHUNK];
-                       s.buf[i + DUMP_CHUNK] = 0;
-                       pr_cont("%s", s.buf + i);
-                       s.buf[i + DUMP_CHUNK] = c;
-               } else {
-                       s.buf[s.count] = 0;
-                       pr_cont("%s", s.buf + i);
-               }
-       }
-}
-#else
-static void sync_dump(struct sync_fence *fence)
-{
-}
 #endif
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 009ab57..871864f 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -466,11 +466,15 @@
 	spin_unlock(&clst->hlock);
 }
 
-static int get_page_list(uint32_t kernel, uint32_t sc, remote_arg_t *pra,
-			struct fastrpc_buf *ibuf, struct fastrpc_buf *obuf)
+static int get_page_list(uint32_t kernel, struct smq_invoke_ctx *ctx)
 {
+	struct fastrpc_apps *me = &gfa;
 	struct smq_phy_page *pgstart, *pages;
 	struct smq_invoke_buf *list;
+	struct fastrpc_buf *ibuf = &ctx->dev->buf;
+	struct fastrpc_buf *obuf = &ctx->obuf;
+	remote_arg_t *pra = ctx->pra;
+	uint32_t sc = ctx->sc;
 	int i, rlen, err = 0;
 	int inbufs = REMOTE_SCALARS_INBUFS(sc);
 	int outbufs = REMOTE_SCALARS_OUTBUFS(sc);
@@ -506,11 +510,21 @@
 			continue;
 		buf = pra[i].buf.pv;
 		num = buf_num_pages(buf, len);
-		if (!kernel)
-			list[i].num = buf_get_pages(buf, len, num,
-				i >= inbufs, pages, rlen / sizeof(*pages));
-		else
-			list[i].num = 0;
+		if (!kernel) {
+			if (me->smmu.enabled) {
+				VERIFY(err, 0 != access_ok(i >= inbufs ?
+					VERIFY_WRITE : VERIFY_READ,
+					(void __user *)buf, len));
+				if (err)
+					goto bail;
+				if (ctx->fds && (ctx->fds[i] >= 0))
+					list[i].num = 1;
+			} else {
+				list[i].num = buf_get_pages(buf, len, num,
+						i >= inbufs, pages,
+						rlen / sizeof(*pages));
+			}
+		}
 		VERIFY(err, list[i].num >= 0);
 		if (err)
 			goto bail;
@@ -539,20 +553,25 @@
 	return err;
 }
 
-static int get_args(uint32_t kernel, uint32_t sc, remote_arg_t *pra,
-			remote_arg_t *rpra, remote_arg_t *upra,
-			struct fastrpc_buf *ibuf, struct fastrpc_buf **abufs,
-			int *nbufs, int *fds, struct ion_handle **handles)
+static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx,
+			remote_arg_t *upra)
 {
 	struct fastrpc_apps *me = &gfa;
 	struct smq_invoke_buf *list;
-	struct fastrpc_buf *pbuf = ibuf, *obufs = 0;
+	struct fastrpc_buf *pbuf = &ctx->obuf, *obufs = 0;
 	struct smq_phy_page *pages;
+	struct vm_area_struct *vma;
+	struct ion_handle **handles = ctx->handles;
 	void *args;
+	remote_arg_t *pra = ctx->pra;
+	remote_arg_t *rpra = ctx->rpra;
+	uint32_t sc = ctx->sc, start;
 	int i, rlen, size, used, inh, bufs = 0, err = 0;
 	int inbufs = REMOTE_SCALARS_INBUFS(sc);
 	int outbufs = REMOTE_SCALARS_OUTBUFS(sc);
-	unsigned long iova, len;
+	int *fds = ctx->fds, idx, num;
+	unsigned long len;
+	ion_phys_addr_t iova;
 
 	list = smq_invoke_buf_start(rpra, sc);
 	pages = smq_phy_page_start(sc, list);
@@ -565,7 +584,10 @@
 		if (!rpra[i].buf.len)
 			continue;
 		if (me->smmu.enabled && fds && (fds[i] >= 0)) {
+			start = buf_page_start(pra[i].buf.pv);
 			len = buf_page_size(pra[i].buf.len);
+			num = buf_num_pages(pra[i].buf.pv, pra[i].buf.len);
+			idx = list[i].pgidx;
 			handles[i] = ion_import_dma_buf(me->iclient, fds[i]);
 			VERIFY(err, 0 == IS_ERR_OR_NULL(handles[i]));
 			if (err)
@@ -575,10 +597,15 @@
 						&iova, &len, 0, 0));
 			if (err)
 				goto bail;
+			VERIFY(err, (num << PAGE_SHIFT) <= len);
+			if (err)
+				goto bail;
+			VERIFY(err, 0 != (vma = find_vma(current->mm, start)));
+			if (err)
+				goto bail;
 			rpra[i].buf.pv = pra[i].buf.pv;
-			list[i].num = 1;
-			pages[list[i].pgidx].addr = iova;
-			pages[list[i].pgidx].size = len;
+			pages[idx].addr = iova + (start - vma->vm_start);
+			pages[idx].size = num << PAGE_SHIFT;
 			continue;
 		} else if (list[i].num) {
 			rpra[i].buf.pv = pra[i].buf.pv;
@@ -642,8 +669,8 @@
 	}
 	dmac_flush_range(rpra, (char *)rpra + used);
  bail:
-	*abufs = obufs;
-	*nbufs = bufs;
+	ctx->abufs = obufs;
+	ctx->nbufs = bufs;
 	return err;
 }
 
@@ -950,14 +977,11 @@
 		VERIFY(err, 0 == get_dev(me, &ctx->dev));
 		if (err)
 			goto bail;
-		VERIFY(err, 0 == get_page_list(kernel, ctx->sc, ctx->pra,
-					&ctx->dev->buf, &ctx->obuf));
+		VERIFY(err, 0 == get_page_list(kernel, ctx));
 		if (err)
 			goto bail;
 		ctx->rpra = (remote_arg_t *)ctx->obuf.virt;
-		VERIFY(err, 0 == get_args(kernel, ctx->sc, ctx->pra, ctx->rpra,
-				invoke->pra, &ctx->obuf, &ctx->abufs,
-				&ctx->nbufs, ctx->fds, ctx->handles));
+		VERIFY(err, 0 == get_args(kernel, ctx, invoke->pra));
 		if (err)
 			goto bail;
 	}
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 9c767c6..edf0216 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -473,12 +473,12 @@
 			*in_busy_ptr = 1;
 			err = diag_device_write(buf, smd_info->peripheral,
 						write_ptr_modem);
+			spin_unlock_irqrestore(&smd_info->in_busy_lock, flags);
 			if (err) {
 				pr_err_ratelimited("diag: In %s, diag_device_write error: %d\n",
 					__func__, err);
 				goto err;
 			}
-			spin_unlock_irqrestore(&smd_info->in_busy_lock, flags);
 		}
 	} else {
 		/* The data is raw and needs to be hdlc encoded */
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index a4bd163..5600c11 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -3547,6 +3547,7 @@
 	.drawctxt_create = adreno_drawctxt_create,
 	.drawctxt_detach = adreno_drawctxt_detach,
 	.drawctxt_destroy = adreno_drawctxt_destroy,
+	.drawctxt_dump = adreno_drawctxt_dump,
 	.setproperty = adreno_setproperty,
 	.postmortem_dump = adreno_dump,
 	.drawctxt_sched = adreno_drawctxt_sched,
diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c
index 5f80fcf..bcab791 100644
--- a/drivers/gpu/msm/adreno_dispatch.c
+++ b/drivers/gpu/msm/adreno_dispatch.c
@@ -157,7 +157,7 @@
 	struct kgsl_cmdbatch *cmdbatch = NULL;
 	int pending;
 
-	mutex_lock(&drawctxt->mutex);
+	spin_lock(&drawctxt->lock);
 	if (drawctxt->cmdqueue_head != drawctxt->cmdqueue_tail) {
 		cmdbatch = drawctxt->cmdqueue[drawctxt->cmdqueue_head];
 
@@ -202,7 +202,7 @@
 	}
 
 done:
-	mutex_unlock(&drawctxt->mutex);
+	spin_unlock(&drawctxt->lock);
 
 	return cmdbatch;
 }
@@ -221,11 +221,11 @@
 		struct adreno_context *drawctxt, struct kgsl_cmdbatch *cmdbatch)
 {
 	unsigned int prev;
-	mutex_lock(&drawctxt->mutex);
+	spin_lock(&drawctxt->lock);
 
 	if (kgsl_context_detached(&drawctxt->base) ||
 		drawctxt->state == ADRENO_CONTEXT_STATE_INVALID) {
-		mutex_unlock(&drawctxt->mutex);
+		spin_unlock(&drawctxt->lock);
 		/* get rid of this cmdbatch since the context is bad */
 		kgsl_cmdbatch_destroy(cmdbatch);
 		return -EINVAL;
@@ -247,7 +247,7 @@
 
 	/* Reset the command queue head to reflect the newly requeued change */
 	drawctxt->cmdqueue_head = prev;
-	mutex_unlock(&drawctxt->mutex);
+	spin_unlock(&drawctxt->lock);
 	return 0;
 }
 
@@ -378,6 +378,7 @@
 	struct adreno_dispatcher *dispatcher = &adreno_dev->dispatcher;
 	int count = 0;
 	int requeued = 0;
+	unsigned int timestamp;
 
 	/*
 	 * Each context can send a specific number of command batches per cycle
@@ -417,6 +418,8 @@
 			continue;
 		}
 
+		timestamp = cmdbatch->timestamp;
+
 		ret = sendcmd(adreno_dev, cmdbatch);
 
 		/*
@@ -432,6 +435,8 @@
 			break;
 		}
 
+		drawctxt->submitted_timestamp = timestamp;
+
 		count++;
 	}
 
@@ -568,7 +573,7 @@
 {
 	int ret;
 
-	mutex_lock(&drawctxt->mutex);
+	spin_lock(&drawctxt->lock);
 
 	/*
 	 * Wake up if there is room in the context or if the whole thing got
@@ -580,7 +585,7 @@
 	else
 		ret = drawctxt->queued < _context_cmdqueue_size ? 1 : 0;
 
-	mutex_unlock(&drawctxt->mutex);
+	spin_unlock(&drawctxt->lock);
 
 	return ret;
 }
@@ -635,10 +640,10 @@
 {
 	int ret;
 
-	mutex_lock(&drawctxt->mutex);
+	spin_lock(&drawctxt->lock);
 
 	if (kgsl_context_detached(&drawctxt->base)) {
-		mutex_unlock(&drawctxt->mutex);
+		spin_unlock(&drawctxt->lock);
 		return -EINVAL;
 	}
 
@@ -679,17 +684,17 @@
 
 	while (drawctxt->queued >= _context_cmdqueue_size) {
 		trace_adreno_drawctxt_sleep(drawctxt);
-		mutex_unlock(&drawctxt->mutex);
+		spin_unlock(&drawctxt->lock);
 
 		ret = wait_event_interruptible_timeout(drawctxt->wq,
 			_check_context_queue(drawctxt),
 			msecs_to_jiffies(_context_queue_wait));
 
-		mutex_lock(&drawctxt->mutex);
+		spin_lock(&drawctxt->lock);
 		trace_adreno_drawctxt_wake(drawctxt);
 
 		if (ret <= 0) {
-			mutex_unlock(&drawctxt->mutex);
+			spin_unlock(&drawctxt->lock);
 			return (ret == 0) ? -ETIMEDOUT : (int) ret;
 		}
 	}
@@ -699,22 +704,26 @@
 	 */
 
 	if (drawctxt->state == ADRENO_CONTEXT_STATE_INVALID) {
-		mutex_unlock(&drawctxt->mutex);
+		spin_unlock(&drawctxt->lock);
 		return -EDEADLK;
 	}
 	if (kgsl_context_detached(&drawctxt->base)) {
-		mutex_unlock(&drawctxt->mutex);
+		spin_unlock(&drawctxt->lock);
 		return -EINVAL;
 	}
 
 	ret = get_timestamp(drawctxt, cmdbatch, timestamp);
 	if (ret) {
-		mutex_unlock(&drawctxt->mutex);
+		spin_unlock(&drawctxt->lock);
 		return ret;
 	}
 
 	cmdbatch->timestamp = *timestamp;
 
+	/* SYNC commands have timestamp 0 and will get optimized out anyway */
+	if (!(cmdbatch->flags & KGSL_CONTEXT_SYNC))
+		drawctxt->queued_timestamp = *timestamp;
+
 	/*
 	 * Set the fault tolerance policy for the command batch - assuming the
 	 * context hasn't disabled FT use the current device policy
@@ -734,7 +743,7 @@
 	trace_adreno_cmdbatch_queued(cmdbatch, drawctxt->queued);
 
 
-	mutex_unlock(&drawctxt->mutex);
+	spin_unlock(&drawctxt->lock);
 
 	/* Add the context to the dispatcher pending list */
 	dispatcher_queue_context(adreno_dev, drawctxt);
diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
index 0778cac..df9d6ec 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -179,6 +179,56 @@
 }
 
 /**
+ * adreno_drawctxt_dump() - dump information about a draw context
+ * @device: KGSL device that owns the context
+ * @context: KGSL context to dump information about
+ *
+ * Dump specific information about the context to the kernel log.  Used for
+ * fence timeout callbacks
+ */
+void adreno_drawctxt_dump(struct kgsl_device *device,
+		struct kgsl_context *context)
+{
+	unsigned int queue, start, retire;
+	struct adreno_context *drawctxt = ADRENO_CONTEXT(context);
+
+	queue = kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_QUEUED);
+	start = kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_CONSUMED);
+	retire = kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_RETIRED);
+
+	spin_lock(&drawctxt->lock);
+	dev_err(device->dev,
+		"  context[%d]: queue=%d, submit=%d, start=%d, retire=%d\n",
+		context->id, queue, drawctxt->submitted_timestamp,
+		start, retire);
+
+	if (drawctxt->cmdqueue_head != drawctxt->cmdqueue_tail) {
+		struct kgsl_cmdbatch *cmdbatch =
+			drawctxt->cmdqueue[drawctxt->cmdqueue_head];
+
+		if (test_bit(CMDBATCH_FLAG_FENCE_LOG, &cmdbatch->priv)) {
+			dev_err(device->dev,
+				"  possible deadlock. Context %d might be blocked for itself\n",
+				context->id);
+			goto done;
+		}
+
+		spin_lock(&cmdbatch->lock);
+
+		if (!list_empty(&cmdbatch->synclist)) {
+			dev_err(device->dev,
+				"  context[%d] (ts=%d) Active sync points:\n",
+				context->id, cmdbatch->timestamp);
+
+			kgsl_dump_syncpoints(device, cmdbatch);
+		}
+		spin_unlock(&cmdbatch->lock);
+	}
+done:
+	spin_unlock(&drawctxt->lock);
+}
+
+/**
  * adreno_drawctxt_wait() - sleep until a timestamp expires
  * @adreno_dev: pointer to the adreno_device struct
  * @drawctxt: Pointer to the draw context to sleep for
@@ -317,14 +367,10 @@
 	kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
 
 	if (timeout) {
-		ret = (int) wait_event_timeout(drawctxt->waiting,
+		if (0 == (int) wait_event_timeout(drawctxt->waiting,
 			_check_global_timestamp(device, drawctxt, timestamp),
-			msecs_to_jiffies(timeout));
-
-		if (ret == 0)
+			msecs_to_jiffies(timeout)))
 			ret = -ETIMEDOUT;
-		else if (ret > 0)
-			ret = 0;
 	} else {
 		wait_event(drawctxt->waiting,
 			_check_global_timestamp(device, drawctxt, timestamp));
@@ -355,11 +401,9 @@
 
 	trace_adreno_drawctxt_invalidate(drawctxt);
 
+	spin_lock(&drawctxt->lock);
 	drawctxt->state = ADRENO_CONTEXT_STATE_INVALID;
 
-	/* Clear the pending queue */
-	mutex_lock(&drawctxt->mutex);
-
 	/*
 	 * set the timestamp to the last value since the context is invalidated
 	 * and we want the pending events for this context to go away
@@ -379,18 +423,13 @@
 		drawctxt->cmdqueue_head = (drawctxt->cmdqueue_head + 1) %
 			ADRENO_CONTEXT_CMDQUEUE_SIZE;
 
-		mutex_unlock(&drawctxt->mutex);
-
-		kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
 		kgsl_cancel_events_timestamp(device, context,
 			cmdbatch->timestamp);
-		kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
 
 		kgsl_cmdbatch_destroy(cmdbatch);
-		mutex_lock(&drawctxt->mutex);
 	}
 
-	mutex_unlock(&drawctxt->mutex);
+	spin_unlock(&drawctxt->lock);
 
 	/* Give the bad news to everybody waiting around */
 	wake_up_all(&drawctxt->waiting);
@@ -439,7 +478,7 @@
 	drawctxt->base.flags |= KGSL_CONTEXT_PER_CONTEXT_TS;
 	drawctxt->type = (drawctxt->base.flags & KGSL_CONTEXT_TYPE_MASK)
 	>> KGSL_CONTEXT_TYPE_SHIFT;
-	mutex_init(&drawctxt->mutex);
+	spin_lock_init(&drawctxt->lock);
 	init_waitqueue_head(&drawctxt->wq);
 	init_waitqueue_head(&drawctxt->waiting);
 
@@ -518,7 +557,7 @@
 	if (adreno_dev->drawctxt_active == drawctxt)
 		adreno_drawctxt_switch(adreno_dev, NULL, 0);
 
-	mutex_lock(&drawctxt->mutex);
+	spin_lock(&drawctxt->lock);
 
 	while (drawctxt->cmdqueue_head != drawctxt->cmdqueue_tail) {
 		struct kgsl_cmdbatch *cmdbatch =
@@ -527,7 +566,7 @@
 		drawctxt->cmdqueue_head = (drawctxt->cmdqueue_head + 1) %
 			ADRENO_CONTEXT_CMDQUEUE_SIZE;
 
-		mutex_unlock(&drawctxt->mutex);
+		spin_unlock(&drawctxt->lock);
 
 		/*
 		 * If the context is deteached while we are waiting for
@@ -543,10 +582,10 @@
 		 */
 
 		kgsl_cmdbatch_destroy(cmdbatch);
-		mutex_lock(&drawctxt->mutex);
+		spin_lock(&drawctxt->lock);
 	}
 
-	mutex_unlock(&drawctxt->mutex);
+	spin_unlock(&drawctxt->lock);
 	/*
 	 * internal_timestamp is set in adreno_ringbuffer_addcmds,
 	 * which holds the device mutex. The entire context destroy
@@ -555,9 +594,14 @@
 	 */
 	BUG_ON(!mutex_is_locked(&device->mutex));
 
-	/* Wait for the last global timestamp to pass before continuing */
+	/* Wait for the last global timestamp to pass before continuing.
+	 * The maxumum wait time is 30s, some large IB's can take longer
+	 * than 10s and if hang happens then the time for the context's
+	 * commands to retire will be greater than 10s. 30s should be sufficient
+	 * time to wait for the commands even if a hang happens.
+	 */
 	ret = adreno_drawctxt_wait_global(adreno_dev, context,
-		drawctxt->internal_timestamp, 10 * 1000);
+		drawctxt->internal_timestamp, 30 * 1000);
 
 	/*
 	 * If the wait for global fails then nothing after this point is likely
diff --git a/drivers/gpu/msm/adreno_drawctxt.h b/drivers/gpu/msm/adreno_drawctxt.h
index 8543f39..e4de042 100644
--- a/drivers/gpu/msm/adreno_drawctxt.h
+++ b/drivers/gpu/msm/adreno_drawctxt.h
@@ -131,6 +131,8 @@
  * @queued: Number of commands queued in the cmdqueue
  * @ops: Context switch functions for this context.
  * @fault_policy: GFT fault policy set in cmdbatch_skip_cmd();
+ * @queued_timestamp: The last timestamp that was queued on this context
+ * @submitted_timestamp: The last timestamp that was submitted for this context
  */
 struct adreno_context {
 	struct kgsl_context base;
@@ -139,7 +141,7 @@
 	int state;
 	unsigned long priv;
 	unsigned int type;
-	struct mutex mutex;
+	spinlock_t lock;
 	struct kgsl_memdesc gpustate;
 	unsigned int reg_restore[3];
 	unsigned int shader_save[3];
@@ -179,6 +181,8 @@
 
 	const struct adreno_context_ops *ops;
 	unsigned int fault_policy;
+	unsigned int queued_timestamp;
+	unsigned int submitted_timestamp;
 };
 
 /**
@@ -288,4 +292,7 @@
 	shadow->size = shadow->pitch * shadow->height * 4;
 }
 
+void adreno_drawctxt_dump(struct kgsl_device *device,
+		struct kgsl_context *context);
+
 #endif  /* __ADRENO_DRAWCTXT_H */
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 5a33d9d..9adede8 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -471,6 +471,33 @@
 }
 
 /**
+ * kgsl_context_dump() - dump information about a draw context
+ * @device: KGSL device that owns the context
+ * @context: KGSL context to dump information about
+ *
+ * Dump specific information about the context to the kernel log.  Used for
+ * fence timeout callbacks
+ */
+void kgsl_context_dump(struct kgsl_context *context)
+{
+	struct kgsl_device *device;
+
+	if (_kgsl_context_get(context) == 0)
+		return;
+
+	device = context->device;
+
+	if (kgsl_context_detached(context)) {
+		dev_err(device->dev, "  context[%d]: context detached\n",
+			context->id);
+	} else if (device->ftbl->drawctxt_dump != NULL)
+		device->ftbl->drawctxt_dump(device, context);
+
+	kgsl_context_put(context);
+}
+EXPORT_SYMBOL(kgsl_context_dump);
+
+/**
  * kgsl_context_init() - helper to initialize kgsl_context members
  * @dev_priv: the owner of the context
  * @context: the newly created context struct, should be allocated by
@@ -1554,22 +1581,11 @@
 	struct kref refcount;
 };
 
-static void _kgsl_cmdbatch_timer(unsigned long data)
+void kgsl_dump_syncpoints(struct kgsl_device *device,
+	struct kgsl_cmdbatch *cmdbatch)
 {
-	struct kgsl_cmdbatch *cmdbatch = (struct kgsl_cmdbatch *) data;
 	struct kgsl_cmdbatch_sync_event *event;
 
-	if (cmdbatch == NULL || cmdbatch->context == NULL)
-		return;
-
-	spin_lock(&cmdbatch->lock);
-	if (list_empty(&cmdbatch->synclist))
-		goto done;
-
-	pr_err("kgsl: possible gpu syncpoint deadlock for context %d timestamp %d\n",
-		cmdbatch->context->id, cmdbatch->timestamp);
-	pr_err(" Active sync points:\n");
-
 	/* Print all the pending sync objects */
 	list_for_each_entry(event, &cmdbatch->synclist, node) {
 
@@ -1580,15 +1596,67 @@
 			 retired = kgsl_readtimestamp(event->device,
 				event->context, KGSL_TIMESTAMP_RETIRED);
 
-			pr_err("  [timestamp] context %d timestamp %d (retired %d)\n",
+			dev_err(device->dev,
+				"  [timestamp] context %d timestamp %d (retired %d)\n",
 				event->context->id, event->timestamp,
 				retired);
 			break;
 		}
 		case KGSL_CMD_SYNCPOINT_TYPE_FENCE:
-			pr_err("  fence: [%p] %s\n", event->handle,
-				(event->handle && event->handle->fence)
-					? event->handle->fence->name : "NULL");
+			if (event->handle)
+				dev_err(device->dev, "  fence: [%p] %s\n",
+					event->handle->fence,
+					event->handle->name);
+			else
+				dev_err(device->dev, "  fence: invalid\n");
+			break;
+		}
+	}
+}
+
+static void _kgsl_cmdbatch_timer(unsigned long data)
+{
+	struct kgsl_device *device;
+	struct kgsl_cmdbatch *cmdbatch = (struct kgsl_cmdbatch *) data;
+	struct kgsl_cmdbatch_sync_event *event;
+
+	if (cmdbatch == NULL || cmdbatch->context == NULL)
+		return;
+
+	spin_lock(&cmdbatch->lock);
+	if (list_empty(&cmdbatch->synclist))
+		goto done;
+
+	device = cmdbatch->context->device;
+
+	dev_err(device->dev,
+		"kgsl: possible gpu syncpoint deadlock for context %d timestamp %d\n",
+		cmdbatch->context->id, cmdbatch->timestamp);
+	dev_err(device->dev, " Active sync points:\n");
+
+	/* Print all the pending sync objects */
+	list_for_each_entry(event, &cmdbatch->synclist, node) {
+		switch (event->type) {
+		case KGSL_CMD_SYNCPOINT_TYPE_TIMESTAMP: {
+			unsigned int retired;
+
+			retired = kgsl_readtimestamp(event->device,
+				event->context, KGSL_TIMESTAMP_RETIRED);
+
+			dev_err(device->dev,
+				"  [timestamp] context %d timestamp %d (retired %d)\n",
+				event->context->id, event->timestamp, retired);
+			break;
+		}
+		case KGSL_CMD_SYNCPOINT_TYPE_FENCE:
+			if (event->handle && event->handle->fence) {
+				set_bit(CMDBATCH_FLAG_FENCE_LOG,
+					&cmdbatch->priv);
+				kgsl_sync_fence_log(event->handle->fence);
+				clear_bit(CMDBATCH_FLAG_FENCE_LOG,
+					&cmdbatch->priv);
+			} else
+				dev_err(device->dev, "  fence: invalid\n");
 			break;
 		}
 	}
@@ -1698,6 +1766,9 @@
 {
 	struct kgsl_cmdbatch_sync_event *event = priv;
 
+	trace_syncpoint_timestamp_expire(event->cmdbatch,
+		event->context, event->timestamp);
+
 	kgsl_cmdbatch_sync_expire(device, event);
 	kgsl_context_put(event->context);
 	/* Put events that have signaled */
@@ -1736,13 +1807,16 @@
 	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_cancel_event(cmdbatch->device, event->context,
+			kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
+			kgsl_cancel_event(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))
@@ -1765,6 +1839,9 @@
 {
 	struct kgsl_cmdbatch_sync_event *event = priv;
 
+	trace_syncpoint_fence_expire(event->cmdbatch,
+		event->handle ? event->handle->name : "unknown");
+
 	kgsl_cmdbatch_sync_expire(event->device, event);
 	/* Put events that have signaled */
 	kgsl_cmdbatch_sync_event_put(event);
@@ -1823,10 +1900,11 @@
 	event->handle = kgsl_sync_fence_async_wait(sync->fd,
 		kgsl_cmdbatch_sync_fence_func, event);
 
-
 	if (IS_ERR_OR_NULL(event->handle)) {
 		int ret = PTR_ERR(event->handle);
 
+		event->handle = NULL;
+
 		/* Failed to add the event to the async callback */
 		kgsl_cmdbatch_sync_event_put(event);
 
@@ -1839,9 +1917,18 @@
 		/* Event no longer needed by this function */
 		kgsl_cmdbatch_sync_event_put(event);
 
+		/*
+		 * If ret == 0 the fence was already signaled - print a trace
+		 * message so we can track that
+		 */
+		if (ret == 0)
+			trace_syncpoint_fence_expire(cmdbatch, "signaled");
+
 		return ret;
 	}
 
+	trace_syncpoint_fence(cmdbatch, event->handle->name);
+
 	/*
 	 * Event was successfully added to the synclist, the async
 	 * callback and handle to cancel event has been set.
@@ -1930,6 +2017,8 @@
 
 		kgsl_cmdbatch_put(cmdbatch);
 		kfree(event);
+	} else {
+		trace_syncpoint_timestamp(cmdbatch, context, sync->timestamp);
 	}
 
 done:
@@ -3200,6 +3289,9 @@
 	return ret;
 }
 
+/* The largest allowable alignment for a GPU object is 32MB */
+#define KGSL_MAX_ALIGN (32 * SZ_1M)
+
 /*
  * The common parts of kgsl_ioctl_gpumem_alloc and kgsl_ioctl_gpumem_alloc_id.
  */
@@ -3226,11 +3318,13 @@
 	/* Cap the alignment bits to the highest number we can handle */
 
 	align = (flags & KGSL_MEMALIGN_MASK) >> KGSL_MEMALIGN_SHIFT;
-	if (align >= 32) {
-		KGSL_CORE_ERR("Alignment too big, restricting to 2^31\n");
+	if (align >= ilog2(KGSL_MAX_ALIGN)) {
+		KGSL_CORE_ERR("Alignment too large; restricting to %dK\n",
+			KGSL_MAX_ALIGN >> 10);
 
 		flags &= ~KGSL_MEMALIGN_MASK;
-		flags |= (31 << KGSL_MEMALIGN_SHIFT) & KGSL_MEMALIGN_MASK;
+		flags |= (ilog2(KGSL_MAX_ALIGN) << KGSL_MEMALIGN_SHIFT) &
+			KGSL_MEMALIGN_MASK;
 	}
 
 	entry = kgsl_mem_entry_create();
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 6f17d56c..582af93 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -126,6 +126,8 @@
 						uint32_t *flags);
 	int (*drawctxt_detach) (struct kgsl_context *context);
 	void (*drawctxt_destroy) (struct kgsl_context *context);
+	void (*drawctxt_dump) (struct kgsl_device *device,
+		struct kgsl_context *context);
 	long (*ioctl) (struct kgsl_device_private *dev_priv,
 		unsigned int cmd, void *data);
 	int (*setproperty) (struct kgsl_device_private *dev_priv,
@@ -202,12 +204,15 @@
  * @CMDBATCH_FLAG_SKIP - skip the entire command batch
  * @CMDBATCH_FLAG_FORCE_PREAMBLE - Force the preamble on for the cmdbatch
  * @CMDBATCH_FLAG_WFI - Force wait-for-idle for the submission
+ * @CMDBATCH_FLAG_FENCE_LOG - Set if the cmdbatch is dumping fence logs via the
+ * cmdbatch timer - this is used to avoid recursion
  */
 
 enum kgsl_cmdbatch_priv {
 	CMDBATCH_FLAG_SKIP = 0,
 	CMDBATCH_FLAG_FORCE_PREAMBLE,
 	CMDBATCH_FLAG_WFI,
+	CMDBATCH_FLAG_FENCE_LOG,
 };
 
 struct kgsl_device {
@@ -547,6 +552,8 @@
 		*context);
 int kgsl_context_detach(struct kgsl_context *context);
 
+void kgsl_context_dump(struct kgsl_context *context);
+
 int kgsl_memfree_find_entry(pid_t pid, unsigned long *gpuaddr,
 	unsigned long *size, unsigned int *flags);
 
@@ -693,6 +700,8 @@
 {
 	kgsl_signal_event(device, context, timestamp, KGSL_EVENT_CANCELLED);
 }
+void kgsl_dump_syncpoints(struct kgsl_device *device,
+	struct kgsl_cmdbatch *cmdbatch);
 
 void kgsl_cmdbatch_destroy(struct kgsl_cmdbatch *cmdbatch);
 
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index e931a24..e26c09c 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -1715,16 +1715,21 @@
 int kgsl_active_count_wait(struct kgsl_device *device, int count)
 {
 	int result = 0;
+	long wait_jiffies = HZ;
 
 	BUG_ON(!mutex_is_locked(&device->mutex));
 
-	if (atomic_read(&device->active_cnt) > count) {
-		int ret;
+	while (atomic_read(&device->active_cnt) > count) {
+		long ret;
 		kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
 		ret = wait_event_timeout(device->active_cnt_wq,
-			_check_active_count(device, count), HZ);
+			_check_active_count(device, count), wait_jiffies);
 		kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
 		result = ret == 0 ? -ETIMEDOUT : 0;
+		if (!result)
+			wait_jiffies = ret;
+		else
+			break;
 	}
 
 	return result;
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index 896fb19..6b5a555 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -641,8 +641,12 @@
 
 	page_size = (align >= ilog2(SZ_64K) && size >= SZ_64K)
 			? SZ_64K : PAGE_SIZE;
-	/* update align flags for what we actually use */
-	if (page_size != PAGE_SIZE)
+	/*
+	 * The alignment cannot be less than the intended page size - it can be
+	 * larger however to accomodate hardware quirks
+	 */
+
+	if (ilog2(align) < page_size)
 		kgsl_memdesc_set_align(memdesc, ilog2(page_size));
 
 	/*
diff --git a/drivers/gpu/msm/kgsl_sync.c b/drivers/gpu/msm/kgsl_sync.c
index cef052d..9b27722 100644
--- a/drivers/gpu/msm/kgsl_sync.c
+++ b/drivers/gpu/msm/kgsl_sync.c
@@ -22,12 +22,13 @@
 #include "kgsl_sync.h"
 
 struct sync_pt *kgsl_sync_pt_create(struct sync_timeline *timeline,
-	unsigned int timestamp)
+	struct kgsl_context *context, unsigned int timestamp)
 {
 	struct sync_pt *pt;
 	pt = sync_pt_create(timeline, (int) sizeof(struct kgsl_sync_pt));
 	if (pt) {
 		struct kgsl_sync_pt *kpt = (struct kgsl_sync_pt *) pt;
+		kpt->context = context;
 		kpt->timestamp = timestamp;
 	}
 	return pt;
@@ -45,7 +46,7 @@
 static struct sync_pt *kgsl_sync_pt_dup(struct sync_pt *pt)
 {
 	struct kgsl_sync_pt *kpt = (struct kgsl_sync_pt *) pt;
-	return kgsl_sync_pt_create(pt->parent, kpt->timestamp);
+	return kgsl_sync_pt_create(pt->parent, kpt->context, kpt->timestamp);
 }
 
 static int kgsl_sync_pt_has_signaled(struct sync_pt *pt)
@@ -95,6 +96,38 @@
 	kfree(ev);
 }
 
+static int _add_fence_event(struct kgsl_device *device,
+	struct kgsl_context *context, unsigned int timestamp)
+{
+	struct kgsl_fence_event_priv *event;
+	int ret;
+
+	event = kmalloc(sizeof(*event), GFP_KERNEL);
+	if (event == NULL)
+		return -ENOMEM;
+
+	/*
+	 * Increase the refcount for the context to keep it through the
+	 * callback
+	 */
+
+	_kgsl_context_get(context);
+
+	event->context = context;
+	event->timestamp = timestamp;
+	event->context = context;
+
+	ret = kgsl_add_event(device, context->id, timestamp,
+		kgsl_fence_event_cb, event, context->dev_priv);
+
+	if (ret) {
+		kgsl_context_put(context);
+		kfree(event);
+	}
+
+	return ret;
+}
+
 /**
  * kgsl_add_fence_event - Create a new fence event
  * @device - KGSL device to create the event on
@@ -112,23 +145,19 @@
 	u32 context_id, u32 timestamp, void __user *data, int len,
 	struct kgsl_device_private *owner)
 {
-	struct kgsl_fence_event_priv *event;
 	struct kgsl_timestamp_event_fence priv;
 	struct kgsl_context *context;
 	struct sync_pt *pt;
 	struct sync_fence *fence = NULL;
 	int ret = -EINVAL;
 	char fence_name[sizeof(fence->name)] = {};
+	unsigned int cur;
 
 	priv.fence_fd = -1;
 
 	if (len != sizeof(priv))
 		return -EINVAL;
 
-	event = kzalloc(sizeof(*event), GFP_KERNEL);
-	if (event == NULL)
-		return -ENOMEM;
-
 	kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
 
 	context = kgsl_context_get_owner(owner, context_id);
@@ -136,10 +165,8 @@
 	if (context == NULL)
 		goto unlock;
 
-	event->context = context;
-	event->timestamp = timestamp;
+	pt = kgsl_sync_pt_create(context->timeline, context, timestamp);
 
-	pt = kgsl_sync_pt_create(context->timeline, timestamp);
 	if (pt == NULL) {
 		KGSL_DRV_ERR(device, "kgsl_sync_pt_create failed\n");
 		ret = -ENOMEM;
@@ -169,6 +196,24 @@
 	}
 	sync_fence_install(fence, priv.fence_fd);
 
+	/*
+	 * If the timestamp hasn't expired yet create an event to trigger it.
+	 * Otherwise, just signal the fence - there is no reason to go through
+	 * the effort of creating a fence we don't need.
+	 */
+
+	cur = kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_RETIRED);
+
+	if (timestamp_cmp(cur, timestamp) >= 0)
+		kgsl_sync_timeline_signal(context->timeline, cur);
+	else {
+		ret = _add_fence_event(device, context, timestamp);
+		if (ret)
+			goto unlock;
+	}
+
+	kgsl_context_put(context);
+
 	/* Unlock the mutex before copying to user */
 	kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
 
@@ -177,21 +222,6 @@
 		goto out;
 	}
 
-	/*
-	 * Hold the context ref-count for the event - it will get released in
-	 * the callback
-	 */
-
-	kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
-
-	ret = kgsl_add_event(device, context_id, timestamp,
-			kgsl_fence_event_cb, event, owner);
-
-	kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
-
-	if (ret)
-		goto out;
-
 	return 0;
 
 unlock:
@@ -205,7 +235,6 @@
 		sync_fence_put(fence);
 
 	kgsl_context_put(context);
-	kfree(event);
 	return ret;
 }
 
@@ -242,6 +271,14 @@
 	snprintf(str, size, "%u", kpt->timestamp);
 }
 
+static void kgsl_sync_pt_log(struct sync_pt *sync_pt)
+{
+	struct kgsl_sync_pt *kpt = (struct kgsl_sync_pt *) sync_pt;
+	pr_info("-----\n");
+	kgsl_context_dump(kpt->context);
+	pr_info("-----\n");
+}
+
 static void kgsl_sync_timeline_release_obj(struct sync_timeline *sync_timeline)
 {
 	/*
@@ -259,6 +296,7 @@
 	.timeline_value_str = kgsl_sync_timeline_value_str,
 	.pt_value_str = kgsl_sync_pt_value_str,
 	.release_obj = kgsl_sync_timeline_release_obj,
+	.pt_log = kgsl_sync_pt_log,
 };
 
 int kgsl_sync_timeline_create(struct kgsl_context *context)
@@ -331,9 +369,13 @@
 		sync_fence_put(fence);
 		return ERR_PTR(-ENOMEM);
 	}
+
 	kwaiter->fence = fence;
 	kwaiter->priv = priv;
 	kwaiter->func = func;
+
+	strlcpy(kwaiter->name, fence->name, sizeof(kwaiter->name));
+
 	sync_fence_waiter_init((struct sync_fence_waiter *) kwaiter,
 		kgsl_sync_callback);
 
diff --git a/drivers/gpu/msm/kgsl_sync.h b/drivers/gpu/msm/kgsl_sync.h
index 275eaf0..d9d26ff 100644
--- a/drivers/gpu/msm/kgsl_sync.h
+++ b/drivers/gpu/msm/kgsl_sync.h
@@ -25,19 +25,21 @@
 
 struct kgsl_sync_pt {
 	struct sync_pt pt;
+	struct kgsl_context *context;
 	unsigned int timestamp;
 };
 
 struct kgsl_sync_fence_waiter {
 	struct sync_fence_waiter waiter;
 	struct sync_fence *fence;
+	char name[32];
 	void (*func)(void *priv);
 	void *priv;
 };
 
 #if defined(CONFIG_SYNC)
 struct sync_pt *kgsl_sync_pt_create(struct sync_timeline *timeline,
-	unsigned int timestamp);
+	struct kgsl_context *context, unsigned int timestamp);
 void kgsl_sync_pt_destroy(struct sync_pt *pt);
 int kgsl_add_fence_event(struct kgsl_device *device,
 	u32 context_id, u32 timestamp, void __user *data, int len,
@@ -49,9 +51,14 @@
 struct kgsl_sync_fence_waiter *kgsl_sync_fence_async_wait(int fd,
 	void (*func)(void *priv), void *priv);
 int kgsl_sync_fence_async_cancel(struct kgsl_sync_fence_waiter *waiter);
+static inline void kgsl_sync_fence_log(struct sync_fence *fence)
+{
+	sync_fence_log(fence);
+}
 #else
 static inline struct sync_pt
-*kgsl_sync_pt_create(struct sync_timeline *timeline, unsigned int timestamp)
+*kgsl_sync_pt_create(struct sync_timeline *timeline,
+	struct kgsl_context *context, unsigned int timestamp)
 {
 	return NULL;
 }
@@ -96,6 +103,10 @@
 	return 1;
 }
 
+static inline void kgsl_sync_fence_log(struct sync_fence *fence)
+{
+}
+
 #endif
 
 #endif /* __KGSL_SYNC_H */
diff --git a/drivers/gpu/msm/kgsl_trace.h b/drivers/gpu/msm/kgsl_trace.h
index c737cc8..8830a9e 100644
--- a/drivers/gpu/msm/kgsl_trace.h
+++ b/drivers/gpu/msm/kgsl_trace.h
@@ -796,13 +796,11 @@
 	)
 );
 
-
 TRACE_EVENT(kgsl_pwrstats,
 	TP_PROTO(struct kgsl_device *device, s64 time,
 		struct kgsl_power_stats *pstats),
 
 	TP_ARGS(device, time, pstats),
-
 	TP_STRUCT__entry(
 		__string(device_name, device->name)
 		__field(s64, total_time)
@@ -826,6 +824,61 @@
 	)
 );
 
+DECLARE_EVENT_CLASS(syncpoint_timestamp_template,
+	TP_PROTO(struct kgsl_cmdbatch *cmdbatch, struct kgsl_context *context,
+		unsigned int timestamp),
+	TP_ARGS(cmdbatch, context, timestamp),
+	TP_STRUCT__entry(
+		__field(unsigned int, cmdbatch_context_id)
+		__field(unsigned int, context_id)
+		__field(unsigned int, timestamp)
+	),
+	TP_fast_assign(
+		__entry->cmdbatch_context_id = cmdbatch->context->id;
+		__entry->context_id = context->id;
+		__entry->timestamp = timestamp;
+	),
+	TP_printk("ctx=%d sync ctx=%d ts=%d",
+		__entry->cmdbatch_context_id, __entry->context_id,
+		__entry->timestamp)
+);
+
+DEFINE_EVENT(syncpoint_timestamp_template, syncpoint_timestamp,
+	TP_PROTO(struct kgsl_cmdbatch *cmdbatch, struct kgsl_context *context,
+		unsigned int timestamp),
+	TP_ARGS(cmdbatch, context, timestamp)
+);
+
+DEFINE_EVENT(syncpoint_timestamp_template, syncpoint_timestamp_expire,
+	TP_PROTO(struct kgsl_cmdbatch *cmdbatch, struct kgsl_context *context,
+		unsigned int timestamp),
+	TP_ARGS(cmdbatch, context, timestamp)
+);
+
+DECLARE_EVENT_CLASS(syncpoint_fence_template,
+	TP_PROTO(struct kgsl_cmdbatch *cmdbatch, char *name),
+	TP_ARGS(cmdbatch, name),
+	TP_STRUCT__entry(
+		__string(fence_name, name)
+		__field(unsigned int, cmdbatch_context_id)
+	),
+	TP_fast_assign(
+		__entry->cmdbatch_context_id = cmdbatch->context->id;
+		__assign_str(fence_name, name);
+	),
+	TP_printk("ctx=%d fence=%s",
+		__entry->cmdbatch_context_id, __get_str(fence_name))
+);
+
+DEFINE_EVENT(syncpoint_fence_template, syncpoint_fence,
+	TP_PROTO(struct kgsl_cmdbatch *cmdbatch, char *name),
+	TP_ARGS(cmdbatch, name)
+);
+
+DEFINE_EVENT(syncpoint_fence_template, syncpoint_fence_expire,
+	TP_PROTO(struct kgsl_cmdbatch *cmdbatch, char *name),
+	TP_ARGS(cmdbatch, name)
+);
 
 #endif /* _KGSL_TRACE_H */
 
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index 545e68f..f77a4f6 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -789,7 +789,7 @@
 					(uint32_t)dev->base +
 					QUP_OUT_FIFO_BASE + (*idx), 0);
 				*idx += 2;
-			} else if (next->flags == 0 && dev->pos == msg->len - 1
+			} else if ((dev->pos == msg->len - 1)
 					&& *idx < (dev->wr_sz*2) &&
 					(next->addr != msg->addr)) {
 				/* Last byte of an intermittent write */
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
index e8702e4..08cc00c 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
@@ -19,7 +19,7 @@
 #include <linux/io.h>
 #include <linux/list.h>
 #include <linux/delay.h>
-#include <linux/avtimer.h>
+#include <linux/avtimer_kernel.h>
 #include <media/v4l2-subdev.h>
 #include <media/msmb_isp.h>
 #include <mach/msm_bus.h>
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
index ba1e58c..263d54d 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
@@ -403,8 +403,8 @@
 		reset_type = ISP_RST_HARD;
 	}
 	rst_val = msm_vfe32_reset_values[reset_type];
-	init_completion(&vfe_dev->reset_complete);
 	if (blocking) {
+		init_completion(&vfe_dev->reset_complete);
 		msm_camera_io_w_mb(rst_val, vfe_dev->vfe_base + 0x4);
 		rc = wait_for_completion_timeout(
 		   &vfe_dev->reset_complete, msecs_to_jiffies(50));
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index 2567657..12fd081 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -642,11 +642,11 @@
 			vfe_dev->axi_data.src_info[VFE_PIX_0].last_updt_frm_id;
 		if (vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id != *cfg_data
 			|| update_id == *cfg_data) {
-			pr_err("hw update lock failed,acquire id %u\n",
+			ISP_DBG("hw update lock failed,acquire id %u\n",
 				*cfg_data);
-			pr_err("hw update lock failed,current id %lu\n",
+			ISP_DBG("hw update lock failed,current id %lu\n",
 				vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id);
-			pr_err("hw update lock failed,last id %u\n",
+			ISP_DBG("hw update lock failed,last id %u\n",
 				update_id);
 			return -EINVAL;
 		}
@@ -655,13 +655,13 @@
 	case VFE_HW_UPDATE_UNLOCK: {
 		if (vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id
 			!= *cfg_data) {
-			pr_err("hw update across frame boundary,begin id %u\n",
+			ISP_DBG("hw update across frame boundary,begin id %u\n",
 				*cfg_data);
-			pr_err("hw update across frame boundary,end id %lu\n",
+			ISP_DBG("hw update across frame boundary,end id %lu\n",
 				vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id);
-			vfe_dev->axi_data.src_info[VFE_PIX_0].last_updt_frm_id =
-			vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
 		}
+		vfe_dev->axi_data.src_info[VFE_PIX_0].last_updt_frm_id =
+			vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
 		break;
 	}
 	case VFE_READ: {
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
index aa0d88b..c9e5159 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -166,7 +166,8 @@
 	} \
 }
 
-static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev);
+static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev,
+	uint32_t buff_mgr_ops);
 static void cpp_load_fw(struct cpp_device *cpp_dev, char *fw_name_bin);
 static void cpp_timer_callback(unsigned long data);
 
@@ -638,13 +639,15 @@
 					/* delete CPP timer */
 					CPP_DBG("delete timer.\n");
 					msm_cpp_clear_timer(cpp_dev);
-					msm_cpp_notify_frame_done(cpp_dev);
+					msm_cpp_notify_frame_done(cpp_dev,
+						VIDIOC_MSM_BUF_MNGR_BUF_DONE);
 				} else if (msg_id ==
 					MSM_CPP_MSG_ID_FRAME_NACK) {
 					pr_err("NACK error from hw!!\n");
 					CPP_DBG("delete timer.\n");
 					msm_cpp_clear_timer(cpp_dev);
-					msm_cpp_notify_frame_done(cpp_dev);
+					msm_cpp_notify_frame_done(cpp_dev,
+						VIDIOC_MSM_BUF_MNGR_PUT_BUF);
 				}
 				i += cmd_len + 2;
 			}
@@ -1071,7 +1074,8 @@
 	return rc;
 }
 
-static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev)
+static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev,
+	uint32_t buff_mgr_ops)
 {
 	struct v4l2_event v4l2_evt;
 	struct msm_queue_cmd *frame_qcmd = NULL;
@@ -1107,7 +1111,7 @@
 			buff_mgr_info.index =
 				processed_frame->output_buffer_info[0].index;
 			rc = msm_cpp_buffer_ops(cpp_dev,
-				VIDIOC_MSM_BUF_MNGR_BUF_DONE,
+				buff_mgr_ops,
 				&buff_mgr_info);
 			if (rc < 0) {
 				pr_err("error putting buffer\n");
@@ -1129,8 +1133,8 @@
 			buff_mgr_info.index =
 				processed_frame->output_buffer_info[1].index;
 			rc = msm_cpp_buffer_ops(cpp_dev,
-				VIDIOC_MSM_BUF_MNGR_BUF_DONE,
-					&buff_mgr_info);
+				buff_mgr_ops,
+				&buff_mgr_info);
 			if (rc < 0) {
 				pr_err("error putting buffer\n");
 				rc = -EINVAL;
@@ -1197,7 +1201,8 @@
 	if (cpp_timer.data.cpp_dev->timeout_trial_cnt >=
 		MSM_CPP_MAX_TIMEOUT_TRIAL) {
 		pr_info("Max trial reached\n");
-		msm_cpp_notify_frame_done(cpp_timer.data.cpp_dev);
+		msm_cpp_notify_frame_done(cpp_timer.data.cpp_dev,
+			VIDIOC_MSM_BUF_MNGR_PUT_BUF);
 		cpp_timer.data.cpp_dev->timeout_trial_cnt = 0;
 		return;
 	}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
index 270fb38..e5d82fd 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
@@ -211,13 +211,23 @@
 		pr_err("%s failed line %d\n", __func__, __LINE__);
 		return -EINVAL;
 	}
-	/* assume total size within the max queue */
+
+	reg_addr = i2c_cmd->reg_addr;
 	while (cmd_size) {
-		CDBG("%s cmd_size %d addr 0x%x data 0x%x", __func__,
+		CDBG("%s cmd_size %d addr 0x%x data 0x%x\n", __func__,
 			cmd_size, i2c_cmd->reg_addr, i2c_cmd->reg_data);
 		delay = i2c_cmd->delay;
 		data[i++] = CCI_I2C_WRITE_CMD;
-		reg_addr = i2c_cmd->reg_addr;
+
+		/* in case of multiple command
+		* MSM_CCI_I2C_WRITE : address is not continuous, so update
+		*			address for a new packet.
+		* MSM_CCI_I2C_WRITE_SEQ : address is continuous, need to keep
+		*			the incremented address for a
+		*			new packet */
+		if (c_ctrl->cmd == MSM_CCI_I2C_WRITE)
+			reg_addr = i2c_cmd->reg_addr;
+
 		/* either byte or word addr */
 		if (i2c_msg->addr_type == MSM_CAMERA_I2C_BYTE_ADDR)
 			data[i++] = reg_addr;
@@ -226,21 +236,25 @@
 			data[i++] = reg_addr & 0x00FF;
 		}
 		/* max of 10 data bytes */
-		if (i2c_msg->data_type == MSM_CAMERA_I2C_BYTE_DATA) {
-			data[i++] = i2c_cmd->reg_data;
-			reg_addr++;
-		} else {
-			if ((i + 1) <= 10) {
-				data[i++] = (i2c_cmd->reg_data &
-					0xFF00) >> 8; /* MSB */
-				data[i++] = i2c_cmd->reg_data &
-					0x00FF; /* LSB */
-				reg_addr += 2;
-			} else
-				break;
-		}
-		i2c_cmd++;
-		--cmd_size;
+		do {
+			if (i2c_msg->data_type == MSM_CAMERA_I2C_BYTE_DATA) {
+				data[i++] = i2c_cmd->reg_data;
+				reg_addr++;
+			} else {
+				if ((i + 1) <= 10) {
+					data[i++] = (i2c_cmd->reg_data &
+						0xFF00) >> 8; /* MSB */
+					data[i++] = i2c_cmd->reg_data &
+						0x00FF; /* LSB */
+					reg_addr += 2;
+				} else
+					break;
+			}
+			i2c_cmd++;
+			--cmd_size;
+		} while ((c_ctrl->cmd == MSM_CCI_I2C_WRITE_SEQ) &&
+				(cmd_size > 0) && (i <= 10));
+
 		data[0] |= ((i-1) << 4);
 		len = ((i-1)/4) + 1;
 		rc = msm_cci_validate_queue(cci_dev, len, master, queue);
@@ -789,6 +803,7 @@
 		rc = msm_cci_i2c_read_bytes(sd, cci_ctrl);
 		break;
 	case MSM_CCI_I2C_WRITE:
+	case MSM_CCI_I2C_WRITE_SEQ:
 		rc = msm_cci_i2c_write(sd, cci_ctrl);
 		break;
 	case MSM_CCI_GPIO_WRITE:
diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h
index 44c134e..283bd28 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h
+++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h
@@ -53,6 +53,7 @@
 	MSM_CCI_SET_SYNC_CID,
 	MSM_CCI_I2C_READ,
 	MSM_CCI_I2C_WRITE,
+	MSM_CCI_I2C_WRITE_SEQ,
 	MSM_CCI_GPIO_WRITE,
 };
 
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c
index 8d9274b..6af0cea 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c
@@ -158,7 +158,7 @@
 		reg_conf_tbl[i].reg_data = data[i];
 		reg_conf_tbl[i].delay = 0;
 	}
-	cci_ctrl.cmd = MSM_CCI_I2C_WRITE;
+	cci_ctrl.cmd = MSM_CCI_I2C_WRITE_SEQ;
 	cci_ctrl.cci_info = client->cci_client;
 	cci_ctrl.cfg.cci_i2c_write_cfg.reg_setting = reg_conf_tbl;
 	cci_ctrl.cfg.cci_i2c_write_cfg.data_type = MSM_CAMERA_I2C_BYTE_DATA;
diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c
index 0eee530..032cca4 100644
--- a/drivers/media/platform/msm/vidc/hfi_response_handler.c
+++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c
@@ -215,6 +215,7 @@
 	cmd_done.device_id = device_id;
 	cmd_done.session_id = ((struct hal_session *) pkt->session_id)->
 		session_id;
+	cmd_done.status = hfi_map_err_status(pkt->event_data1);
 	dprintk(VIDC_INFO, "Received : SESSION_ERROR with event id : %d\n",
 		pkt->event_data1);
 	switch (pkt->event_data1) {
@@ -222,6 +223,7 @@
 	case HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE:
 	case HFI_ERR_SESSION_UNSUPPORTED_SETTING:
 	case HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED:
+		cmd_done.status = VIDC_ERR_NONE;
 		dprintk(VIDC_INFO, "Non Fatal : HFI_EVENT_SESSION_ERROR\n");
 		break;
 	default:
@@ -834,12 +836,9 @@
 	} else {
 		sess_close = (struct hal_session *)pkt->session_id;
 		if (sess_close) {
-			dprintk(VIDC_INFO,
-				"Sess init failed: Deleting session: 0x%x 0x%p",
+			dprintk(VIDC_WARN,
+				"Sess init failed: 0x%x, 0x%p",
 				sess_close->session_id, sess_close);
-			list_del(&sess_close->list);
-			kfree(sess_close);
-			sess_close = NULL;
 		}
 	}
 	cmd_done.size = sizeof(struct vidc_hal_session_init_done);
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index 30ca194..7830db7 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -1400,7 +1400,7 @@
 	case V4L2_DEC_QCOM_CMD_FLUSH:
 		if (core->state != VIDC_CORE_INVALID &&
 			inst->state ==  MSM_VIDC_CORE_INVALID) {
-			rc = msm_comm_recover_from_session_error(inst);
+			rc = msm_comm_kill_session(inst);
 			if (rc)
 				dprintk(VIDC_ERR,
 					"Failed to recover from session_error: %d\n",
@@ -1415,7 +1415,7 @@
 	case V4L2_DEC_CMD_STOP:
 		if (core->state != VIDC_CORE_INVALID &&
 			inst->state ==  MSM_VIDC_CORE_INVALID) {
-			rc = msm_comm_recover_from_session_error(inst);
+			rc = msm_comm_kill_session(inst);
 			if (rc)
 				dprintk(VIDC_ERR,
 					"Failed to recover from session_error: %d\n",
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index ba17820..794d116 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -46,6 +46,10 @@
 	u32 __mbs = (__h >> 4) * (__w >> 4);\
 	__mbs;\
 })
+static void msm_comm_generate_session_error(struct msm_vidc_inst *inst);
+static void msm_comm_generate_sys_error(struct msm_vidc_inst *inst);
+static void handle_session_error(enum command_response cmd, void *data);
+
 static bool is_turbo_requested(struct msm_vidc_core *core,
 		enum session_type type)
 {
@@ -398,7 +402,7 @@
 		dprintk(VIDC_ERR,
 			"%s: Wait interrupted or timeout[%u]: %d\n",
 			__func__, (u32)inst->session, SESSION_MSG_INDEX(cmd));
-		msm_comm_recover_from_session_error(inst);
+		msm_comm_kill_session(inst);
 		rc = -EIO;
 	} else {
 		rc = 0;
@@ -432,32 +436,19 @@
 	wake_up(&inst->kernel_event_queue);
 }
 
-static void msm_comm_generate_session_error(struct msm_vidc_inst *inst)
-{
-	if (!inst) {
-		dprintk(VIDC_ERR, "%s: invalid input parameters", __func__);
-		return;
-	}
-	mutex_lock(&inst->lock);
-	inst->session = NULL;
-	inst->state = MSM_VIDC_CORE_INVALID;
-	msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR);
-	mutex_unlock(&inst->lock);
-}
-
 static void msm_comm_generate_max_clients_error(struct msm_vidc_inst *inst)
 {
+	enum command_response cmd = SESSION_ERROR;
+	struct msm_vidc_cb_cmd_done response = {0};
+
 	if (!inst) {
 		dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__);
 		return;
 	}
-	mutex_lock(&inst->sync_lock);
-	inst->session = NULL;
-	inst->state = MSM_VIDC_CORE_INVALID;
-	msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_MAX_CLIENTS);
-	dprintk(VIDC_WARN,
-			"%s: Too many clients\n", __func__);
-	mutex_unlock(&inst->sync_lock);
+	dprintk(VIDC_ERR, "%s: Too many clients\n", __func__);
+	response.session_id = (u32) inst;
+	response.status = VIDC_ERR_MAX_CLIENTS;
+	handle_session_error(cmd, (void *)&response);
 }
 
 static void handle_session_init_done(enum command_response cmd, void *data)
@@ -834,21 +825,50 @@
 static void handle_session_error(enum command_response cmd, void *data)
 {
 	struct msm_vidc_cb_cmd_done *response = data;
+	int rc;
+	struct hfi_device *hdev = NULL;
 	struct msm_vidc_inst *inst = NULL;
-	if (response) {
-		inst = (struct msm_vidc_inst *)response->session_id;
-		if (inst) {
-			dprintk(VIDC_WARN,
-				"Session error receivd for session %p\n", inst);
-			mutex_lock(&inst->sync_lock);
-			inst->state = MSM_VIDC_CORE_INVALID;
-			mutex_unlock(&inst->sync_lock);
-			msm_vidc_queue_v4l2_event(inst,
-					V4L2_EVENT_MSM_VIDC_SYS_ERROR);
-		}
-	} else {
+
+	if (!response) {
 		dprintk(VIDC_ERR,
 			"Failed to get valid response for session error\n");
+		return;
+	}
+
+	inst = (struct msm_vidc_inst *)response->session_id;
+
+	if (!inst || !inst->session || !inst->core->device) {
+		dprintk(VIDC_ERR,
+				"Session (%p) not in a stable enough state to handle session error\n",
+				inst);
+		return;
+	}
+
+	hdev = inst->core->device;
+	dprintk(VIDC_WARN, "Session error received for session %p\n", inst);
+	change_inst_state(inst, MSM_VIDC_CORE_INVALID);
+
+	mutex_lock(&inst->lock);
+	dprintk(VIDC_DBG, "cleaning up inst: %p\n", inst);
+	rc = call_hfi_op(hdev, session_clean, inst->session);
+	if (rc)
+		dprintk(VIDC_ERR, "Session (%p) clean failed: %d\n", inst, rc);
+
+	inst->session = NULL;
+	mutex_unlock(&inst->lock);
+
+	if (response->status == VIDC_ERR_MAX_CLIENTS) {
+		dprintk(VIDC_WARN,
+			"send max clients reached error to client: %p\n",
+			inst);
+		msm_vidc_queue_v4l2_event(inst,
+			V4L2_EVENT_MSM_VIDC_MAX_CLIENTS);
+	} else {
+		dprintk(VIDC_ERR,
+			"send session error to client: %p\n",
+			inst);
+		msm_vidc_queue_v4l2_event(inst,
+			V4L2_EVENT_MSM_VIDC_SYS_ERROR);
 	}
 }
 
@@ -1249,10 +1269,10 @@
 	inst = (struct msm_vidc_inst *)response->session_id;
 	fill_buf_done = (struct vidc_hal_fbd *)&response->output_done;
 	buffer_type = msm_comm_get_hal_output_buffer(inst);
-	if (fill_buf_done->buffer_type == buffer_type)
+	if (fill_buf_done->buffer_type == buffer_type) {
 		vb = get_vb_from_device_addr(&inst->bufq[CAPTURE_PORT],
 			(u32)fill_buf_done->packet_buffer1);
-	else {
+	} else {
 		if (handle_multi_stream_buffers(inst,
 			(u32)fill_buf_done->packet_buffer1))
 			dprintk(VIDC_ERR,
@@ -1881,7 +1901,7 @@
 			num_mbs_per_sec, inst->core->resources.max_load);
 		msm_vidc_print_running_insts(inst->core);
 		inst->state = MSM_VIDC_CORE_INVALID;
-		msm_comm_recover_from_session_error(inst);
+		msm_comm_kill_session(inst);
 		return -EBUSY;
 	}
 
@@ -2672,7 +2692,7 @@
 			__func__, (u32)inst->session,
 			SESSION_MSG_INDEX(SESSION_PROPERTY_INFO));
 		inst->state = MSM_VIDC_CORE_INVALID;
-		msm_comm_recover_from_session_error(inst);
+		msm_comm_kill_session(inst);
 		rc = -EIO;
 		goto exit;
 	}
@@ -2790,11 +2810,9 @@
 				rc = wait_for_sess_signal_receipt(inst,
 					SESSION_RELEASE_BUFFER_DONE);
 				if (rc) {
-					mutex_lock(&inst->sync_lock);
-					inst->state = MSM_VIDC_CORE_INVALID;
-					mutex_unlock(&inst->sync_lock);
-					msm_comm_recover_from_session_error(
-						inst);
+					change_inst_state(inst,
+						MSM_VIDC_CORE_INVALID);
+					msm_comm_kill_session(inst);
 				}
 				mutex_lock(&inst->lock);
 			}
@@ -2861,11 +2879,9 @@
 				rc = wait_for_sess_signal_receipt(inst,
 					SESSION_RELEASE_BUFFER_DONE);
 				if (rc) {
-					mutex_lock(&inst->sync_lock);
-					inst->state = MSM_VIDC_CORE_INVALID;
-					mutex_unlock(&inst->sync_lock);
-					msm_comm_recover_from_session_error(
-						inst);
+					change_inst_state(inst,
+						MSM_VIDC_CORE_INVALID);
+					msm_comm_kill_session(inst);
 				}
 				mutex_lock(&inst->lock);
 			}
@@ -3472,9 +3488,7 @@
 		}
 	}
 	if (rc) {
-		mutex_lock(&inst->sync_lock);
-		inst->state = MSM_VIDC_CORE_INVALID;
-		mutex_unlock(&inst->sync_lock);
+		change_inst_state(inst, MSM_VIDC_CORE_INVALID);
 		msm_vidc_queue_v4l2_event(inst,
 					V4L2_EVENT_MSM_VIDC_HW_OVERLOAD);
 		dprintk(VIDC_WARN,
@@ -3484,6 +3498,22 @@
 	return rc;
 }
 
+static void msm_comm_generate_session_error(struct msm_vidc_inst *inst)
+{
+	enum command_response cmd = SESSION_ERROR;
+	struct msm_vidc_cb_cmd_done response = {0};
+
+	dprintk(VIDC_WARN, "msm_comm_generate_session_error\n");
+	if (!inst || !inst->core) {
+		dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__);
+		return;
+	}
+
+	response.session_id = (u32)inst;
+	response.status = VIDC_ERR_FAIL;
+	handle_session_error(cmd, (void *)&response);
+}
+
 static void msm_comm_generate_sys_error(struct msm_vidc_inst *inst)
 {
 	struct msm_vidc_core *core;
@@ -3498,43 +3528,55 @@
 	handle_sys_error(cmd, (void *) &response);
 
 }
-int msm_comm_recover_from_session_error(struct msm_vidc_inst *inst)
+
+int msm_comm_kill_session(struct msm_vidc_inst *inst)
 {
-	struct hfi_device *hdev;
 	int rc = 0;
 
 	if (!inst || !inst->core || !inst->core->device) {
 		dprintk(VIDC_ERR, "%s: invalid input parameters", __func__);
 		return -EINVAL;
+	} else if (!inst->session) {
+		/* There's no hfi session to kill */
+		return 0;
 	}
-	if (!inst->session || inst->state < MSM_VIDC_OPEN_DONE) {
-		dprintk(VIDC_WARN,
-			"No corresponding FW session. No need to send Abort");
-		return rc;
-	}
-	hdev = inst->core->device;
 
-	init_completion(&inst->completions[SESSION_MSG_INDEX
-		(SESSION_ABORT_DONE)]);
-
-	/* We have received session_error. Send session_abort to firmware
-	 *  to clean up and release the session
+	/*
+	 * We're internally forcibly killing the session, if fw is aware of
+	 * the session send session_abort to firmware to clean up and release
+	 * the session, else just kill the session inside the driver.
 	 */
-	rc = call_hfi_op(hdev, session_abort, (void *) inst->session);
-	if (rc) {
-		dprintk(VIDC_ERR, "session_abort failed rc: %d\n", rc);
-		return rc;
+	if (inst->state >= MSM_VIDC_OPEN_DONE &&
+			inst->state < MSM_VIDC_CLOSE_DONE) {
+		struct hfi_device *hdev = inst->core->device;
+		int abort_completion = SESSION_MSG_INDEX(SESSION_ABORT_DONE);
+
+		rc = call_hfi_op(hdev, session_abort, (void *) inst->session);
+		if (rc) {
+			dprintk(VIDC_ERR, "session_abort failed rc: %d\n", rc);
+			return rc;
+		}
+
+		init_completion(&inst->completions[abort_completion]);
+		rc = wait_for_completion_timeout(
+				&inst->completions[abort_completion],
+				msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
+		if (!rc) {
+			dprintk(VIDC_ERR,
+					"%s: Wait interrupted or timed out [%p]: %d\n",
+					__func__, inst, abort_completion);
+			msm_comm_generate_sys_error(inst);
+		} else {
+			change_inst_state(inst, MSM_VIDC_CLOSE_DONE);
+		}
+	} else {
+		dprintk(VIDC_WARN,
+				"Inactive session %p, triggering an internal session error\n",
+				inst);
+		msm_comm_generate_session_error(inst);
+
 	}
-	rc = wait_for_completion_timeout(
-		&inst->completions[SESSION_MSG_INDEX(SESSION_ABORT_DONE)],
-		msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
-	if (!rc) {
-		dprintk(VIDC_ERR, "%s: Wait interrupted or timeout[%u]: %d\n",
-			__func__, (u32)inst->session,
-			SESSION_MSG_INDEX(SESSION_ABORT_DONE));
-		msm_comm_generate_sys_error(inst);
-	} else
-		change_inst_state(inst, MSM_VIDC_CLOSE_DONE);
+
 	return rc;
 }
 
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.h b/drivers/media/platform/msm/vidc/msm_vidc_common.h
index f4e2cd5..1e86278 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.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
@@ -52,7 +52,7 @@
 		V4L2_CTRL_DRIVER_PRIV(idx))
 
 int msm_comm_check_scaling_supported(struct msm_vidc_inst *inst);
-int msm_comm_recover_from_session_error(struct msm_vidc_inst *inst);
+int msm_comm_kill_session(struct msm_vidc_inst *inst);
 enum multi_stream msm_comm_get_stream_output_mode(struct msm_vidc_inst *inst);
 enum hal_buffer msm_comm_get_hal_output_buffer(struct msm_vidc_inst *inst);
 struct msm_smem *msm_comm_smem_alloc(struct msm_vidc_inst *inst,
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index f5587fc..0de42ae 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -1501,6 +1501,7 @@
 					void *pkt)
 {
 	u32 rx_req_is_set = 0;
+	struct vidc_hal_cmd_pkt_hdr *cmd_packet;
 	struct vidc_iface_q_info *q_info;
 	int result = -EPERM;
 
@@ -1528,6 +1529,12 @@
 		goto err_q_null;
 	}
 
+	cmd_packet = (struct vidc_hal_cmd_pkt_hdr *)pkt;
+	if ((cmd_packet->packet_type != HFI_CMD_SYS_PC_PREP) &&
+		(cmd_packet->packet_type != HFI_CMD_SYS_RELEASE_RESOURCE)) {
+		device->pc_num_cmds++;
+	}
+
 	if (!venus_hfi_write_queue(q_info, (u8 *)pkt, &rx_req_is_set)) {
 		WARN(!mutex_is_locked(&device->clk_pwr_lock),
 					"Clock/power lock must be acquired");
@@ -2865,15 +2872,24 @@
 static void venus_hfi_pm_hndlr(struct work_struct *work)
 {
 	int rc = 0;
+	u32 ctrl_status = 0;
 	struct venus_hfi_device *device = list_first_entry(
 			&hal_ctxt.dev_head, struct venus_hfi_device, list);
+
+	if (!device) {
+		dprintk(VIDC_ERR, "%s: NULL device\n", __func__);
+		return;
+	}
+
 	mutex_lock(&device->clk_pwr_lock);
 	if (device->clk_state == ENABLED_PREPARED || !device->power_enabled) {
 		dprintk(VIDC_DBG,
 				"Clocks status: %d, Power status: %d, ignore power off\n",
 				device->clk_state, device->power_enabled);
-		goto clks_enabled;
+		mutex_unlock(&device->clk_pwr_lock);
+		return;
 	}
+	device->pc_num_cmds = 0;
 	mutex_unlock(&device->clk_pwr_lock);
 
 	rc = __unset_free_ocmem(device);
@@ -2894,17 +2910,51 @@
 	}
 
 	mutex_lock(&device->clk_pwr_lock);
+	if (device->pc_num_cmds) {
+		dprintk(VIDC_DBG,
+			"ignore power off due to client sent commands = %d\n",
+			device->pc_num_cmds);
+		goto skip_power_off;
+	}
 	if (device->clk_state == ENABLED_PREPARED) {
 		dprintk(VIDC_ERR,
 				"Clocks are still enabled after PC_PREP_DONE, ignore power off");
-		goto clks_enabled;
+		goto skip_power_off;
 	}
 
 	rc = venus_hfi_power_off(device);
-	if (rc)
+	if (rc) {
 		dprintk(VIDC_ERR, "Failed venus power off");
-clks_enabled:
+		goto err_power_off;
+	}
+
 	mutex_unlock(&device->clk_pwr_lock);
+	return;
+
+err_power_off:
+skip_power_off:
+
+	/* Reset PC_READY bit as power_off is skipped, if set by Venus */
+	ctrl_status = venus_hfi_read_register(device, VIDC_CPU_CS_SCIACMDARG0);
+	if (ctrl_status & VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY) {
+		ctrl_status &= ~(VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY);
+		venus_hfi_write_register(device, VIDC_CPU_CS_SCIACMDARG0,
+				ctrl_status, 0);
+	}
+
+	/* Cancel pending delayed works if any */
+	cancel_delayed_work(&venus_hfi_pm_work);
+	dprintk(VIDC_WARN, "Power off skipped (%d, %d)\n",
+		device->clk_state, device->pc_num_cmds);
+
+	mutex_unlock(&device->clk_pwr_lock);
+
+	rc = __alloc_set_ocmem(device, true);
+	if (rc) {
+		dprintk(VIDC_WARN,
+			"Failed to re-allocate OCMEM. Performance will be impacted\n");
+	}
+	return;
 }
 
 static int venus_hfi_try_clk_gating(struct venus_hfi_device *device)
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.h b/drivers/media/platform/msm/vidc/venus_hfi.h
index 05d7b6a..a1ed069 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.h
+++ b/drivers/media/platform/msm/vidc/venus_hfi.h
@@ -215,6 +215,7 @@
 	struct workqueue_struct *venus_pm_workq;
 	int spur_count;
 	int reg_count;
+	int pc_num_cmds;
 	u32 base_addr;
 	u32 register_base;
 	u32 register_size;
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
index b3c20b6..edd71f1 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
@@ -780,6 +780,11 @@
 #define HFI_TEST_SSR_SW_DIV_BY_ZERO	0x2
 #define HFI_TEST_SSR_HW_WDOG_IRQ	0x3
 
+struct vidc_hal_cmd_pkt_hdr {
+	u32 size;
+	u32 packet_type;
+};
+
 struct vidc_hal_msg_pkt_hdr {
 	u32 size;
 	u32 packet;
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 3a93469..399cea9 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -648,7 +648,7 @@
 	}
 	if (req_mode > HIGH) {
 		pr_err("Invalid bandwidth mode (%d)\n", req_mode);
-		return ret;
+		return -EINVAL;
 	}
 
 	/*
@@ -1115,8 +1115,8 @@
 	bool found_dead_app = false;
 
 	if (!memcmp(data->client.app_name, "keymaste", strlen("keymaste"))) {
-		pr_warn("Do not unload keymaster app from tz\n");
-		return 0;
+		pr_debug("Do not unload keymaster app from tz\n");
+		goto unload_exit;
 	}
 
 	if (data->client.app_id > 0) {
@@ -1211,6 +1211,7 @@
 		spin_unlock_irqrestore(&qseecom.registered_app_list_lock,
 								flags1);
 	}
+unload_exit:
 	qseecom_unmap_ion_allocated_memory(data);
 	data->released = true;
 	return ret;
@@ -1392,6 +1393,74 @@
 	return ret;
 }
 
+static int __validate_send_cmd_inputs(struct qseecom_dev_handle *data,
+				struct qseecom_send_cmd_req *req)
+{
+	if (!data || !data->client.ihandle) {
+		pr_err("Client or client handle is not initialized\n");
+		return -EINVAL;
+	}
+	if (((req->resp_buf == NULL) && (req->resp_len != 0)) ||
+						(req->cmd_req_buf == NULL)) {
+		pr_err("cmd buffer or response buffer is null\n");
+		return -EINVAL;
+	}
+	if (((uint32_t)req->cmd_req_buf < data->client.user_virt_sb_base) ||
+		((uint32_t)req->cmd_req_buf >= (data->client.user_virt_sb_base +
+					data->client.sb_length))) {
+		pr_err("cmd buffer address not within shared bufffer\n");
+		return -EINVAL;
+	}
+	if (((uintptr_t)req->resp_buf <
+				data->client.user_virt_sb_base)  ||
+		((uintptr_t)req->resp_buf >=
+		(data->client.user_virt_sb_base + data->client.sb_length))) {
+		pr_err("response buffer address not within shared bufffer\n");
+		return -EINVAL;
+	}
+	if ((req->cmd_req_len == 0) ||
+		(req->cmd_req_len > data->client.sb_length) ||
+		(req->resp_len > data->client.sb_length)) {
+		pr_err("cmd buf length or response buf length not valid\n");
+		return -EINVAL;
+	}
+	if (req->cmd_req_len > UINT_MAX - req->resp_len) {
+		pr_err("Integer overflow detected in req_len & rsp_len\n");
+		return -EINVAL;
+	}
+
+	if ((req->cmd_req_len + req->resp_len) > data->client.sb_length) {
+		pr_debug("Not enough memory to fit cmd_buf.\n");
+		pr_debug("resp_buf. Required: %u, Available: %zu\n",
+				(req->cmd_req_len + req->resp_len),
+					data->client.sb_length);
+		return -ENOMEM;
+	}
+	if ((uintptr_t)req->cmd_req_buf > (ULONG_MAX - req->cmd_req_len)) {
+		pr_err("Integer overflow in req_len & cmd_req_buf\n");
+		return -EINVAL;
+	}
+	if ((uintptr_t)req->resp_buf > (ULONG_MAX - req->resp_len)) {
+		pr_err("Integer overflow in resp_len & resp_buf\n");
+		return -EINVAL;
+	}
+	if (data->client.user_virt_sb_base >
+					(ULONG_MAX - data->client.sb_length)) {
+		pr_err("Integer overflow in user_virt_sb_base & sb_length\n");
+		return -EINVAL;
+	}
+	if ((((uintptr_t)req->cmd_req_buf + req->cmd_req_len) >
+		((uintptr_t)data->client.user_virt_sb_base +
+						data->client.sb_length)) ||
+		(((uintptr_t)req->resp_buf + req->resp_len) >
+		((uintptr_t)data->client.user_virt_sb_base +
+						data->client.sb_length))) {
+		pr_err("cmd buf or resp buf is out of shared buffer region\n");
+		return -EINVAL;
+	}
+	return 0;
+}
+
 static int __qseecom_send_cmd(struct qseecom_dev_handle *data,
 				struct qseecom_send_cmd_req *req)
 {
@@ -1404,46 +1473,7 @@
 	bool found_app = false;
 	int name_len = 0;
 
-	if (req->cmd_req_buf == NULL || req->resp_buf == NULL) {
-		pr_err("cmd buffer or response buffer is null\n");
-		return -EINVAL;
-	}
-	if (((uint32_t)req->cmd_req_buf < data->client.user_virt_sb_base) ||
-		((uint32_t)req->cmd_req_buf >= (data->client.user_virt_sb_base +
-					data->client.sb_length))) {
-		pr_err("cmd buffer address not within shared bufffer\n");
-		return -EINVAL;
-	}
-
-
-	if (((uint32_t)req->resp_buf < data->client.user_virt_sb_base)  ||
-		((uint32_t)req->resp_buf >= (data->client.user_virt_sb_base +
-					data->client.sb_length))){
-		pr_err("response buffer address not within shared bufffer\n");
-		return -EINVAL;
-	}
-
-	if ((req->cmd_req_len == 0) || (req->resp_len == 0) ||
-		req->cmd_req_len > data->client.sb_length ||
-		req->resp_len > data->client.sb_length) {
-		pr_err("cmd buffer length or "
-				"response buffer length not valid\n");
-		return -EINVAL;
-	}
-
-	if (req->cmd_req_len > UINT_MAX - req->resp_len) {
-		pr_err("Integer overflow detected in req_len & rsp_len, exiting now\n");
-		return -EINVAL;
-	}
-
 	reqd_len_sb_in = req->cmd_req_len + req->resp_len;
-	if (reqd_len_sb_in > data->client.sb_length) {
-		pr_debug("Not enough memory to fit cmd_buf and "
-			"resp_buf. Required: %u, Available: %u\n",
-				reqd_len_sb_in, data->client.sb_length);
-		return -ENOMEM;
-	}
-
 	/* find app_id & img_name from list */
 	spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
 	list_for_each_entry(ptr_app, &qseecom.registered_app_list_head,
@@ -1517,6 +1547,10 @@
 		pr_err("copy_from_user failed\n");
 		return ret;
 	}
+
+	if (__validate_send_cmd_inputs(data, &req))
+		return -EINVAL;
+
 	ret = __qseecom_send_cmd(data, &req);
 
 	if (ret)
@@ -1525,6 +1559,32 @@
 	return ret;
 }
 
+int __boundary_checks_offset(struct qseecom_send_modfd_cmd_req *cmd_req,
+			struct qseecom_send_modfd_listener_resp *lstnr_resp,
+			struct qseecom_dev_handle *data, bool listener_svc,
+			int i) {
+
+	if ((!listener_svc) && (cmd_req->ifd_data[i].fd > 0)) {
+		if ((cmd_req->cmd_req_len < sizeof(uint32_t)) ||
+				(cmd_req->ifd_data[i].cmd_buf_offset >
+				cmd_req->cmd_req_len - sizeof(uint32_t))) {
+			pr_err("Invalid offset 0x%x\n",
+					cmd_req->ifd_data[i].cmd_buf_offset);
+			return -EINVAL;
+		}
+	} else if ((listener_svc) && (lstnr_resp->ifd_data[i].fd > 0)) {
+		if ((lstnr_resp->resp_len < sizeof(uint32_t)) ||
+				(lstnr_resp->ifd_data[i].cmd_buf_offset >
+				lstnr_resp->resp_len - sizeof(uint32_t))) {
+			pr_err("Invalid offset 0x%x\n",
+					lstnr_resp->ifd_data[i].cmd_buf_offset);
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+#define SG_ENTRY_SZ   sizeof(struct qseecom_sg_entry)
 static int __qseecom_update_cmd_buf(void *msg, bool cleanup,
 					struct qseecom_dev_handle *data,
 					bool listener_svc)
@@ -1598,6 +1658,10 @@
 		if (sg_ptr->nents == 1) {
 			uint32_t *update;
 			update = (uint32_t *) field;
+
+			if (__boundary_checks_offset(cmd_req, lstnr_resp, data,
+							listener_svc, i))
+				goto err;
 			if (cleanup)
 				*update = 0;
 			else
@@ -1607,6 +1671,31 @@
 		} else {
 			struct qseecom_sg_entry *update;
 			int j = 0;
+
+			if ((!listener_svc) && (cmd_req->ifd_data[i].fd > 0)) {
+				if ((cmd_req->cmd_req_len <
+					SG_ENTRY_SZ * sg_ptr->nents) ||
+					(cmd_req->ifd_data[i].cmd_buf_offset >
+					(cmd_req->cmd_req_len -
+					SG_ENTRY_SZ * sg_ptr->nents))) {
+					pr_err("Invalid offset = 0x%x\n",
+						cmd_req->ifd_data[i].
+						cmd_buf_offset);
+					goto err;
+				}
+			} else if ((listener_svc) &&
+					(lstnr_resp->ifd_data[i].fd > 0)) {
+				if ((lstnr_resp->resp_len <
+					SG_ENTRY_SZ * sg_ptr->nents) ||
+					(lstnr_resp->ifd_data[i].cmd_buf_offset >
+					(lstnr_resp->resp_len -
+					SG_ENTRY_SZ * sg_ptr->nents))) {
+					pr_err("Invalid offset = 0x%x\n",
+						lstnr_resp->ifd_data[i].
+							cmd_buf_offset);
+					goto err;
+				}
+			}
 			update = (struct qseecom_sg_entry *) field;
 			for (j = 0; j < sg_ptr->nents; j++) {
 				if (cleanup) {
@@ -1655,35 +1744,14 @@
 		return ret;
 	}
 
-	if (req.cmd_req_buf == NULL || req.resp_buf == NULL) {
-		pr_err("cmd buffer or response buffer is null\n");
-		return -EINVAL;
-	}
-	if (((uint32_t)req.cmd_req_buf < data->client.user_virt_sb_base) ||
-		((uint32_t)req.cmd_req_buf >= (data->client.user_virt_sb_base +
-					data->client.sb_length))) {
-		pr_err("cmd buffer address not within shared bufffer\n");
-		return -EINVAL;
-	}
-
-	if (((uint32_t)req.resp_buf < data->client.user_virt_sb_base)  ||
-		((uint32_t)req.resp_buf >= (data->client.user_virt_sb_base +
-					data->client.sb_length))){
-		pr_err("response buffer address not within shared bufffer\n");
-		return -EINVAL;
-	}
-
-	if (req.cmd_req_len == 0 || req.cmd_req_len > data->client.sb_length ||
-		req.resp_len > data->client.sb_length) {
-		pr_err("cmd or response buffer length not valid\n");
-		return -EINVAL;
-	}
-
 	send_cmd_req.cmd_req_buf = req.cmd_req_buf;
 	send_cmd_req.cmd_req_len = req.cmd_req_len;
 	send_cmd_req.resp_buf = req.resp_buf;
 	send_cmd_req.resp_len = req.resp_len;
 
+	if (__validate_send_cmd_inputs(data, &send_cmd_req))
+		return -EINVAL;
+
 	/* validate offsets */
 	for (i = 0; i < MAX_ION_FD; i++) {
 		if (req.ifd_data[i].cmd_buf_offset >= req.cmd_req_len) {
@@ -2332,6 +2400,9 @@
 	req.cmd_req_buf = send_buf;
 	req.resp_buf = resp_buf;
 
+	if (__validate_send_cmd_inputs(data, &req))
+		return -EINVAL;
+
 	mutex_lock(&app_access_lock);
 	atomic_inc(&data->ioctl_count);
 	if (qseecom.support_bus_scaling) {
@@ -4525,8 +4596,7 @@
 	mutex_lock(&qsee_bw_mutex);
 	mutex_lock(&clk_access_lock);
 
-	if (qseecom.cumulative_mode != INACTIVE &&
-		qseecom.current_mode != INACTIVE) {
+	if (qseecom.current_mode != INACTIVE) {
 		ret = msm_bus_scale_client_update_request(
 			qseecom.qsee_perf_client, INACTIVE);
 		if (ret)
diff --git a/drivers/net/wireless/wcnss/wcnss_vreg.c b/drivers/net/wireless/wcnss/wcnss_vreg.c
index c066acd..9c65a63 100644
--- a/drivers/net/wireless/wcnss/wcnss_vreg.c
+++ b/drivers/net/wireless/wcnss/wcnss_vreg.c
@@ -236,6 +236,18 @@
 				cpu_relax();
 
 			iris_reg = readl_relaxed(iris_read_reg);
+			pr_info("wcnss: IRIS Reg: %08x\n", iris_reg);
+			if (iris_reg == PRONTO_IRIS_REG_CHIP_ID) {
+				pr_info("wcnss: IRIS Card not Preset\n");
+				auto_detect = WCNSS_XO_INVALID;
+				/* Reset iris read bit */
+				reg &= ~WCNSS_PMU_CFG_IRIS_XO_READ;
+				/* Clear XO_MODE[b2:b1] bits.
+				   Clear implies 19.2 MHz TCXO
+				 */
+				reg &= ~(WCNSS_PMU_CFG_IRIS_XO_MODE);
+				goto xo_configure;
+			}
 			auto_detect = xo_auto_detect(iris_reg);
 
 			/* Reset iris read bit */
@@ -258,6 +270,7 @@
 				*iris_xo_set = WCNSS_XO_48MHZ;
 		}
 
+xo_configure:
 		writel_relaxed(reg, pmu_conf_reg);
 
 		/* Reset IRIS */
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index ed6fa29..4a4a88c 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -215,7 +215,6 @@
 #define	WCNSS_BUILD_VER_REQ           (WCNSS_CTRL_MSG_START + 9)
 #define	WCNSS_BUILD_VER_RSP           (WCNSS_CTRL_MSG_START + 10)
 #define	WCNSS_PM_CONFIG_REQ           (WCNSS_CTRL_MSG_START + 11)
-#define WCNSS_CBC_COMPLETE_IND		(WCNSS_CTRL_MSG_START + 12)
 
 /* max 20mhz channel count */
 #define WCNSS_MAX_CH_NUM			45
@@ -408,7 +407,6 @@
 	void __iomem *alarms_tactl;
 	void __iomem *fiq_reg;
 	int	nv_downloaded;
-	int	is_cbc_done;
 	unsigned char *fw_cal_data;
 	unsigned char *user_cal_data;
 	int	fw_cal_rcvd;
@@ -1052,7 +1050,6 @@
 		pr_debug("wcnss: closing WCNSS SMD channel :%s",
 				WCNSS_CTRL_CHANNEL);
 		penv->nv_downloaded = 0;
-		penv->is_cbc_done = 0;
 		break;
 
 	default:
@@ -1261,15 +1258,6 @@
 }
 EXPORT_SYMBOL(wcnss_device_ready);
 
-int wcnss_cbc_complete(void)
-{
-	if (penv && penv->pdev && penv->is_cbc_done &&
-		!wcnss_device_is_shutdown())
-		return 1;
-	return 0;
-}
-EXPORT_SYMBOL(wcnss_cbc_complete);
-
 int wcnss_device_is_shutdown(void)
 {
 	if (penv && penv->is_shutdown)
@@ -1905,10 +1893,6 @@
 		pr_debug("wcnss: received WCNSS_CALDATA_DNLD_RSP from ccpu %u\n",
 			fw_status);
 		break;
-	case WCNSS_CBC_COMPLETE_IND:
-		penv->is_cbc_done = 1;
-		pr_info("wcnss: received WCNSS_CBC_COMPLETE_IND from FW\n");
-		break;
 
 	case WCNSS_CALDATA_UPLD_REQ:
 		extract_cal_data(len);
diff --git a/drivers/nfc/nfc-nci.c b/drivers/nfc/nfc-nci.c
index a9c093b..e51da7f 100644
--- a/drivers/nfc/nfc-nci.c
+++ b/drivers/nfc/nfc-nci.c
@@ -28,6 +28,7 @@
 #include <linux/regulator/consumer.h>
 #include "nfc-nci.h"
 #include <mach/gpiomux.h>
+#include <linux/pm_runtime.h>
 
 struct qca199x_platform_data {
 	unsigned int irq_gpio;
@@ -56,11 +57,14 @@
 #define MAX_QCA_REG				(116)
 /* will timeout in approx. 100ms as 10us steps */
 #define NFC_RF_CLK_FREQ			(19200000)
-#define NTF_TIMEOUT				(10)
+#define NTF_TIMEOUT				(25)
 #define	CORE_RESET_RSP_GID		(0x60)
 #define	CORE_RESET_OID			(0x00)
 #define CORE_RST_NTF_LENGTH		(0x02)
 #define WAKE_TIMEOUT			(10)
+#define WAKE_REG			(0x10)
+#define EFUSE_REG			(0xA0)
+#define WAKEUP_SRC_TIMEOUT		(2000)
 
 static void clk_req_update(struct work_struct *work);
 
@@ -91,6 +95,7 @@
 	unsigned int		clk_src_gpio;
 	const	char		*clk_src_name;
 	struct	clk		*s_clk;
+	unsigned int 		core_reset_ntf;
 	bool			clk_run;
 	struct work_struct	msm_clock_controll_work;
 	struct workqueue_struct *my_wq;
@@ -98,7 +103,8 @@
 
 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);
+static int nfcc_initialise(struct i2c_client *client, unsigned short curr_addr,
+				struct qca199x_dev *qca199x_dev);
 static int qca199x_clock_select(struct qca199x_dev *qca199x_dev);
 static int qca199x_clock_deselect(struct qca199x_dev *qca199x_dev);
 
@@ -154,6 +160,20 @@
 	struct qca199x_dev *qca199x_dev = dev_id;
 	unsigned long flags;
 
+	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");
+		/*
+		* 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");
+	}
+
 	spin_lock_irqsave(&qca199x_dev->irq_enabled_lock, flags);
 	qca199x_dev->count_irq++;
 	spin_unlock_irqrestore(&qca199x_dev->irq_enabled_lock, flags);
@@ -539,11 +559,13 @@
 int nfcc_wake(int level, struct file *filp)
 {
 	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;
 	unsigned short	curr_addr;
+	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",
@@ -553,7 +575,6 @@
 		r = i2c_master_send(qca199x_dev->client, &raw_nci_sleep[0],
 						sizeof(raw_nci_sleep));
 
-		r = sizeof(raw_nci_sleep);
 		if (r != sizeof(raw_nci_sleep))
 			return -EMSGSIZE;
 		qca199x_dev->state = NFCC_STATE_NORMAL_SLEEP;
@@ -562,11 +583,35 @@
 		qca199x_dev->client->addr = slave_addr;
 		r = nfc_i2c_write(qca199x_dev->client, &raw_nci_wake[0],
 						sizeof(raw_nci_wake));
+		do {
+			wake_status = WAKE_REG;
+			r = nfc_i2c_write(qca199x_dev->client, &wake_status, 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, &wake_status,
+						sizeof(wake_status));
+
+			time_taken++;
+			if ((wake_status & NCI_WAKE) != 0)
+				/* NFCC wakeup time is between 0.5 and .52 ms */
+				usleep_range(500, 520);
+
+		} while ((wake_status & NCI_WAKE)
+				&& (time_taken < WAKE_TIMEOUT));
 		/* Restore original NFCC slave I2C address */
+
 		qca199x_dev->client->addr = curr_addr;
-		r = sizeof(raw_nci_wake);
-		if (r != sizeof(raw_nci_wake))
+		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__);
+			r = -EIO;
+		}
 		qca199x_dev->state = NFCC_STATE_NORMAL_WAKE;
 	}
 
@@ -625,12 +670,13 @@
 		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);
-		usleep(1000);
+		/*nfcc needs atleast 100ms for the chip to power cycle*/
+		msleep(100);
 	} else if (arg == 2) {
 		mutex_lock(&qca199x_dev->read_mutex);
 		dev_dbg(&qca199x_dev->client->dev, "before nfcc_initialise: %s: info: %p\n",
 			__func__, qca199x_dev);
-		r = nfcc_initialise(qca199x_dev->client, 0xE);
+		r = nfcc_initialise(qca199x_dev->client, 0xE, qca199x_dev);
 		dev_dbg(&qca199x_dev->client->dev, "after nfcc_initialise: %s: info: %p\n",
 			__func__, qca199x_dev);
 		/* Also reset first NCI write */
@@ -645,12 +691,12 @@
 		msleep(20);
 	} else if (arg == 4) {
 		mutex_lock(&qca199x_dev->read_mutex);
-		nfcc_wake(NFCC_WAKE, filp);
+		r = nfcc_wake(NFCC_WAKE, filp);
 		dev_dbg(&qca199x_dev->client->dev, "nfcc wake: %s: info: %p\n",
 			__func__, qca199x_dev);
 		mutex_unlock(&qca199x_dev->read_mutex);
 	} else if (arg == 5) {
-		nfcc_wake(NFCC_SLEEP, filp);
+		r = nfcc_wake(NFCC_SLEEP, filp);
 	} else {
 		r = -ENOIOCTLCMD;
 	}
@@ -716,6 +762,60 @@
 }
 
 /*
+ * Inside nfc_ioctl_nfcc_efuse
+ *
+ * @brief   nfc_ioctl_nfcc_efuse
+ *
+ */
+int nfc_ioctl_nfcc_efuse(struct file *filp, unsigned int cmd,
+				unsigned long arg)
+{
+	int r = 0;
+	unsigned short slave_addr = 0xE;
+	unsigned short curr_addr;
+	unsigned char efuse_addr  = EFUSE_REG;
+	unsigned char efuse_value = 0xFF;
+
+	struct qca199x_dev *qca199x_dev = filp->private_data;
+
+	curr_addr = qca199x_dev->client->addr;
+	qca199x_dev->client->addr = slave_addr;
+
+	r = nfc_i2c_write(qca199x_dev->client,
+				&efuse_addr, 1);
+	if (r < 0) {
+		/* Restore original NFCC slave I2C address */
+		qca199x_dev->client->addr = curr_addr;
+		dev_err(&qca199x_dev->client->dev,
+		"ERROR_WRITE_FAIL : i2c write fail\n");
+		return -EIO;
+	}
+
+	/*
+	 * NFCC chip needs to be at least
+	 * 10usec high before make it low
+	 */
+	usleep_range(10, 15);
+
+	r = i2c_master_recv(qca199x_dev->client, &efuse_value,
+					sizeof(efuse_value));
+	if (r < 0) {
+		/* Restore original NFCC slave I2C address */
+		qca199x_dev->client->addr = curr_addr;
+		dev_err(&qca199x_dev->client->dev,
+		"ERROR_I2C_RCV_FAIL : i2c recv fail\n");
+		return -EIO;
+	}
+
+	dev_dbg(&qca199x_dev->client->dev, "%s : EFUSE_VALUE %02x\n",
+	__func__, efuse_value);
+
+	/* Restore original NFCC slave I2C address */
+	qca199x_dev->client->addr = curr_addr;
+	return efuse_value;
+}
+
+/*
  * Inside nfc_ioctl_nfcc_version
  *
  * @brief   nfc_ioctl_nfcc_version
@@ -764,13 +864,24 @@
 	 * 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)
-			usleep(1000);
+			/* NFCC wakeup time is between 0.5 and .52 ms */
+			usleep_range(500, 520);
 
 		time_taken++;
-	} while ((r == 1) && (raw_nci_read & NCI_WAKE)
+
+	} while ((raw_nci_read & NCI_WAKE)
 			&& (time_taken < WAKE_TIMEOUT));
 
 	if (time_taken < WAKE_TIMEOUT)
@@ -854,14 +965,34 @@
 	return retval;
 }
 
+/*
+ * Inside nfc_ioctl_core_reset_ntf
+ *
+ * @brief   nfc_ioctl_core_reset_ntf
+ *
+ * Allows callers to determine if a CORE_RESET_NTF has arrived
+ *
+ * Returns the value of variable core_reset_ntf
+ *
+ */
+int nfc_ioctl_core_reset_ntf(struct file *filp, unsigned int cmd,
+				unsigned long arg)
+{
+	struct qca199x_dev *qca199x_dev = filp->private_data;
+	dev_dbg(&qca199x_dev->client->dev,
+		"nfc_ioctl_core_reset_ntf: returning = %d\n",
+		qca199x_dev->core_reset_ntf);
+	return qca199x_dev->core_reset_ntf;
+}
+
 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:
-		nfc_ioctl_power_states(pfile, cmd, arg);
+		r = nfc_ioctl_power_states(pfile, cmd, arg);
 		break;
 	case NFCC_MODE:
 		nfc_ioctl_nfcc_mode(pfile, cmd, arg);
@@ -876,6 +1007,17 @@
 		break;
 	case SET_EMULATOR_TEST_POINT:
 		break;
+	case NFCC_INITIAL_CORE_RESET_NTF:
+		r = nfc_ioctl_core_reset_ntf(pfile, cmd, arg);
+		break;
+	case NFC_GET_EFUSE:
+		r = nfc_ioctl_nfcc_efuse(pfile, cmd, arg);
+		if (r < 0) {
+			r = 0xFF;
+			dev_err(&qca199x_dev->client->dev,
+			"nfc_ioctl : FAILED TO READ EFUSE TYPE\n");
+		}
+		break;
 	default:
 		r = -ENOIOCTLCMD;
 	}
@@ -960,7 +1102,8 @@
 	return r;
 }
 /* Initialise qca199x_ NFC controller hardware */
-static int nfcc_initialise(struct i2c_client *client, unsigned short curr_addr)
+static int nfcc_initialise(struct i2c_client *client, unsigned short curr_addr,
+				struct qca199x_dev *qca199x_dev)
 {
 	int r = 0;
 	unsigned char raw_1p8_CONTROL_011[]	= {0x11, XTAL_CLOCK};
@@ -979,6 +1122,7 @@
 	int ret = 0;
 
 	client->addr = curr_addr;
+	qca199x_dev->core_reset_ntf = DEFAULT_INITIAL_CORE_RESET_NTF;
 	r = i2c_master_send(client, &buf, 1);
 	if (r < 0)
 		goto err_init;
@@ -1102,6 +1246,11 @@
 		}
 		time_taken++;
 	} while (!core_reset_completed);
+	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;
+
 	r = 0;
 	return r;
 err_init:
@@ -1496,6 +1645,8 @@
 		INIT_WORK(&qca199x_dev->msm_clock_controll_work,
 			clk_req_update);
 	}
+	device_init_wakeup(&client->dev, true);
+	device_set_wakeup_capable(&client->dev, true);
 	i2c_set_clientdata(client, qca199x_dev);
 	gpio_set_value(platform_data->dis_gpio, 1);
 
@@ -1560,11 +1711,33 @@
 	return 0;
 }
 
+static int qca199x_suspend(struct device *device)
+{
+	struct i2c_client *client = to_i2c_client(device);
+
+	if (device_may_wakeup(&client->dev))
+		enable_irq_wake(client->irq);
+	return 0;
+}
+
+static int qca199x_resume(struct device *device)
+{
+	struct i2c_client *client = to_i2c_client(device);
+
+	if (device_may_wakeup(&client->dev))
+		disable_irq_wake(client->irq);
+	return 0;
+}
+
 static const struct i2c_device_id qca199x_id[] = {
 	{"qca199x-i2c", 0},
 	{}
 };
 
+static const struct dev_pm_ops nfc_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(qca199x_suspend, qca199x_resume)
+};
+
 static struct i2c_driver qca199x = {
 	.id_table = qca199x_id,
 	.probe = qca199x_probe,
@@ -1573,6 +1746,7 @@
 		.owner = THIS_MODULE,
 		.name = "nfc-nci",
 		.of_match_table = msm_match_table,
+		.pm = &nfc_pm_ops,
 	},
 };
 
diff --git a/drivers/nfc/nfc-nci.h b/drivers/nfc/nfc-nci.h
index 297c152..398fa3f 100644
--- a/drivers/nfc/nfc-nci.h
+++ b/drivers/nfc/nfc-nci.h
@@ -60,6 +60,8 @@
 #define SET_RX_BLOCK	_IOW(0xE9, 0x04, unsigned int)
 #define SET_EMULATOR_TEST_POINT		_IOW(0xE9, 0x05, unsigned int)
 #define NFCC_VERSION				_IOW(0xE9, 0x08, unsigned int)
+#define NFC_GET_EFUSE				_IOW(0xE9, 0x09, unsigned int)
+#define NFCC_INITIAL_CORE_RESET_NTF		_IOW(0xE9, 0x10, unsigned int)
 
 #define NFC_MAX_I2C_TRANSFER	(0x0400)
 #define NFC_MSG_MAX_SIZE	(0x21)
@@ -195,6 +197,11 @@
 	NFCC_INT,
 };
 
+enum nfcc_initial_core_reset_ntf {
+	TIMEDOUT_INITIAL_CORE_RESET_NTF = 0, /* 0*/
+	ARRIVED_INITIAL_CORE_RESET_NTF, /* 1 */
+	DEFAULT_INITIAL_CORE_RESET_NTF, /*2*/
+};
 
 struct nfc_info {
 	struct	miscdevice			miscdev;
diff --git a/drivers/platform/msm/avtimer.c b/drivers/platform/msm/avtimer.c
index d5fa885..bb9b2bf 100644
--- a/drivers/platform/msm/avtimer.c
+++ b/drivers/platform/msm/avtimer.c
@@ -25,11 +25,15 @@
 #include <linux/wait.h>
 #include <linux/sched.h>
 #include <mach/qdsp6v2/apr.h>
+#include <sound/q6core.h>
 
 #define DEVICE_NAME "avtimer"
 #define TIMEOUT_MS 1000
 #define CORE_CLIENT 1
 #define TEMP_PORT ((CORE_CLIENT << 8) | 0x0001)
+#define SSR_WAKETIME 1000
+#define Q6_READY_RETRY 250
+#define Q6_READY_MAX_RETRIES 40
 
 #define AVCS_CMD_REMOTE_AVTIMER_VOTE_REQUEST 0x00012914
 #define AVCS_CMD_RSP_REMOTE_AVTIMER_VOTE_REQUEST 0x00012915
@@ -53,11 +57,15 @@
 	struct mutex avtimer_lock;
 	int avtimer_open_cnt;
 	struct dev_avtimer_data avtimer_pdata;
+	struct delayed_work ssr_dwork;
 	wait_queue_head_t adsp_resp_wait;
 	int enable_timer_resp_recieved;
 	int timer_handle;
 	void __iomem *p_avtimer_msw;
 	void __iomem *p_avtimer_lsw;
+	uint32_t clk_div;
+	atomic_t adsp_ready;
+	int num_retries;
 };
 
 static struct avtimer_t avtimer;
@@ -102,6 +110,10 @@
 		pr_debug("%s: Reset event received in AV timer\n", __func__);
 		apr_reset(avtimer.core_handle_q);
 		avtimer.core_handle_q = NULL;
+		avtimer.avtimer_open_cnt = 0;
+		atomic_set(&avtimer.adsp_ready, 0);
+		schedule_delayed_work(&avtimer.ssr_dwork,
+				  msecs_to_jiffies(SSR_WAKETIME));
 		break;
 	}
 
@@ -239,8 +251,10 @@
 			goto done;
 		}
 		rc = avcs_core_enable_avtimer("timer");
-		if (!rc)
+		if (!rc) {
 			avtimer.avtimer_open_cnt++;
+			atomic_set(&avtimer.adsp_ready, 1);
+		}
 	} else {
 		if (avtimer.avtimer_open_cnt > 0) {
 			avtimer.avtimer_open_cnt--;
@@ -257,6 +271,48 @@
 }
 EXPORT_SYMBOL(avcs_core_disable_power_collapse);
 
+static void reset_work(struct work_struct *work)
+{
+	if (q6core_is_adsp_ready()) {
+		avcs_core_disable_power_collapse(1);
+		avtimer.num_retries = Q6_READY_MAX_RETRIES;
+		return;
+	}
+	pr_debug("%s:Q6 not ready-retry after sometime\n", __func__);
+	if (--avtimer.num_retries > 0) {
+		schedule_delayed_work(&avtimer.ssr_dwork,
+			  msecs_to_jiffies(Q6_READY_RETRY));
+	} else {
+		pr_err("%s: Q6 failed responding after multiple retries\n",
+							__func__);
+		avtimer.num_retries = Q6_READY_MAX_RETRIES;
+	}
+}
+
+int avcs_core_query_timer(uint64_t *avtimer_tick)
+{
+	uint32_t avtimer_msw = 0, avtimer_lsw = 0;
+	uint32_t res = 0;
+	uint64_t avtimer_tick_temp;
+
+	if (!atomic_read(&avtimer.adsp_ready)) {
+		pr_debug("%s:In SSR, return\n", __func__);
+		return -ENETRESET;
+	}
+	avtimer_lsw = ioread32(avtimer.p_avtimer_lsw);
+	avtimer_msw = ioread32(avtimer.p_avtimer_msw);
+
+	avtimer_tick_temp =
+		(uint64_t)((uint64_t)avtimer_msw << 32)
+			| avtimer_lsw;
+	res = do_div(avtimer_tick_temp, avtimer.clk_div);
+	*avtimer_tick = avtimer_tick_temp;
+	pr_debug("%s:Avtimer: msw: %u, lsw: %u, tick: %llu\n", __func__,
+			avtimer_msw, avtimer_lsw, *avtimer_tick);
+	return 0;
+}
+EXPORT_SYMBOL(avcs_core_query_timer);
+
 static int avtimer_open(struct inode *inode, struct file *file)
 {
 	return avcs_core_disable_power_collapse(1);
@@ -285,6 +341,7 @@
 			avtimer_msw_2nd = ioread32(avtimer.p_avtimer_msw);
 		} while (avtimer_msw_1st != avtimer_msw_2nd);
 
+		avtimer_lsw = avtimer_lsw/avtimer.clk_div;
 		avtimer_tick =
 		((uint64_t) avtimer_msw_1st << 32) | avtimer_lsw;
 
@@ -317,6 +374,7 @@
 	dev_t dev = MKDEV(major, 0);
 	struct device *device_handle;
 	struct resource *reg_lsb = NULL, *reg_msb = NULL;
+	uint32_t clk_div_val;
 
 	if (!pdev) {
 		pr_err("%s: Invalid params\n", __func__);
@@ -336,6 +394,8 @@
 			"avtimer_msb_addr", __func__);
 		return -EINVAL;
 	}
+	INIT_DELAYED_WORK(&avtimer.ssr_dwork, reset_work);
+
 	avtimer.p_avtimer_lsw = devm_ioremap_nocache(&pdev->dev,
 				reg_lsb->start, resource_size(reg_lsb));
 	if (!avtimer.p_avtimer_lsw) {
@@ -351,6 +411,7 @@
 			__func__);
 		goto unmap;
 	}
+	avtimer.num_retries = Q6_READY_MAX_RETRIES;
 	/* get the device number */
 	if (major)
 		result = register_chrdev_region(dev, 1, DEVICE_NAME);
@@ -360,14 +421,15 @@
 	}
 
 	if (result < 0) {
-		pr_err("%s: Registering avtimer device failed\n", __func__);
+		dev_err(&pdev->dev, "%s: Registering avtimer device failed\n",
+			__func__);
 		goto unmap;
 	}
 
 	avtimer.avtimer_class = class_create(THIS_MODULE, "avtimer");
 	if (IS_ERR(avtimer.avtimer_class)) {
 		result = PTR_ERR(avtimer.avtimer_class);
-		pr_err("%s: Error creating avtimer class: %d\n",
+		dev_err(&pdev->dev, "%s: Error creating avtimer class: %d\n",
 			__func__, result);
 		goto unregister_chrdev_region;
 	}
@@ -376,7 +438,8 @@
 	result = cdev_add(&avtimer.myc, dev, 1);
 
 	if (result < 0) {
-		pr_err("%s: Registering file operations failed\n", __func__);
+		dev_err(&pdev->dev, "%s: Registering file operations failed\n",
+			__func__);
 		goto class_destroy;
 	}
 
@@ -394,6 +457,13 @@
 	pr_debug("%s: Device create done for avtimer major=%d\n",
 			__func__, major);
 
+	if (of_property_read_u32(pdev->dev.of_node,
+			"qcom,clk_div", &clk_div_val))
+		avtimer.clk_div = 1;
+	else
+		avtimer.clk_div = clk_div_val;
+
+	pr_debug("avtimer.clk_div = %d\n", avtimer.clk_div);
 	return 0;
 
 class_destroy:
diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
index 537dc1d..6752828 100644
--- a/drivers/power/qpnp-bms.c
+++ b/drivers/power/qpnp-bms.c
@@ -2209,7 +2209,6 @@
 	rc_new_uah = (params->fcc_uah * pc_new) / 100;
 	soc_new = (rc_new_uah - params->cc_uah - params->uuc_uah)*100
 					/ (params->fcc_uah - params->uuc_uah);
-	soc_new = bound_soc(soc_new);
 
 	/*
 	 * if soc_new is ZERO force it higher so that phone doesnt report soc=0
@@ -2467,6 +2466,8 @@
 	/* always clamp soc due to BMS hw/sw immaturities */
 	new_calculated_soc = clamp_soc_based_on_voltage(chip,
 					new_calculated_soc);
+
+	new_calculated_soc = bound_soc(new_calculated_soc);
 	/*
 	 * If the battery is full, configure the cc threshold so the system
 	 * wakes up after SoC changes
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index a30b5bb..38bd666 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -1736,11 +1736,8 @@
 					power_supply_changed(chip->usb_psy);
 				}
 			}
-			if (!qpnp_chg_is_dc_chg_plugged_in(chip)) {
-				chip->delta_vddmax_mv = 0;
-				qpnp_chg_set_appropriate_vddmax(chip);
+			if (!qpnp_chg_is_dc_chg_plugged_in(chip))
 				chip->chg_done = false;
-			}
 
 			if (!qpnp_is_dc_higher_prio(chip))
 				qpnp_chg_idcmax_set(chip, chip->maxinput_dc_ma);
@@ -1771,10 +1768,6 @@
 				}
 			}
 
-			if (!qpnp_chg_is_dc_chg_plugged_in(chip)) {
-				chip->delta_vddmax_mv = 0;
-				qpnp_chg_set_appropriate_vddmax(chip);
-			}
 			schedule_delayed_work(&chip->eoc_work,
 				msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
 			schedule_work(&chip->soc_check_work);
@@ -1952,14 +1945,8 @@
 			qpnp_chg_force_run_on_batt(chip, !dc_present ? 1 : 0);
 		if (!dc_present && (!qpnp_chg_is_usb_chg_plugged_in(chip) ||
 					qpnp_chg_is_otg_en_set(chip))) {
-			chip->delta_vddmax_mv = 0;
-			qpnp_chg_set_appropriate_vddmax(chip);
 			chip->chg_done = false;
 		} else {
-			if (!qpnp_chg_is_usb_chg_plugged_in(chip)) {
-				chip->delta_vddmax_mv = 0;
-				qpnp_chg_set_appropriate_vddmax(chip);
-			}
 			schedule_delayed_work(&chip->eoc_work,
 				msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
 			schedule_work(&chip->soc_check_work);
@@ -3808,8 +3795,6 @@
 							? "cool" : "warm",
 						qpnp_chg_vddmax_get(chip));
 				}
-				chip->delta_vddmax_mv = 0;
-				qpnp_chg_set_appropriate_vddmax(chip);
 				qpnp_chg_charge_en(chip, 0);
 				/* sleep for a second before enabling */
 				msleep(2000);
diff --git a/drivers/slimbus/slim-msm-ngd.c b/drivers/slimbus/slim-msm-ngd.c
index 85e8842..299d3ee 100644
--- a/drivers/slimbus/slim-msm-ngd.c
+++ b/drivers/slimbus/slim-msm-ngd.c
@@ -1154,6 +1154,14 @@
 	struct slim_device *sbdev;
 	struct list_head *pos, *next;
 	int ret, i = 0;
+	ret = qmi_svc_event_notifier_register(SLIMBUS_QMI_SVC_ID,
+				SLIMBUS_QMI_SVC_V1,
+				SLIMBUS_QMI_INS_ID, &dev->qmi.nb);
+	if (ret) {
+		pr_err("Slimbus QMI service registration failed:%d", ret);
+		return ret;
+	}
+
 	while (!kthread_should_stop()) {
 		set_current_state(TASK_INTERRUPTIBLE);
 		wait_for_completion(&dev->qmi.slave_notify);
@@ -1426,14 +1434,6 @@
 	INIT_WORK(&dev->qmi.ssr_up, ngd_adsp_up);
 	dev->qmi.nb.notifier_call = ngd_qmi_available;
 	pm_runtime_get_noresume(dev->dev);
-	ret = qmi_svc_event_notifier_register(SLIMBUS_QMI_SVC_ID,
-				SLIMBUS_QMI_SVC_V1,
-				SLIMBUS_QMI_INS_ID, &dev->qmi.nb);
-	if (ret) {
-		pr_err("Slimbus QMI service registration failed:%d", ret);
-		goto qmi_register_failed;
-	}
-
 
 	/* Fire up the Rx message queue thread */
 	dev->rx_msgq_thread = kthread_run(ngd_slim_rx_msgq_thread, dev,
@@ -1458,10 +1458,6 @@
 err_notify_thread_create_failed:
 	kthread_stop(dev->rx_msgq_thread);
 err_rx_thread_create_failed:
-	qmi_svc_event_notifier_unregister(SLIMBUS_QMI_SVC_ID,
-				SLIMBUS_QMI_SVC_V1,
-				SLIMBUS_QMI_INS_ID, &dev->qmi.nb);
-qmi_register_failed:
 	free_irq(dev->irq, dev);
 err_request_irq_failed:
 	slim_del_controller(&dev->ctrl);
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index e5eb9b2..f2fb09d 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.c
@@ -39,6 +39,8 @@
 #include <mach/rpm-regulator-smd.h>
 #include <linux/regulator/consumer.h>
 #include <linux/msm_thermal_ioctl.h>
+#include <mach/rpm-smd.h>
+#include <mach/scm.h>
 
 #define MAX_CURRENT_UA 1000000
 #define MAX_RAILS 5
@@ -46,6 +48,7 @@
 #define MONITOR_ALL_TSENS -1
 #define BYTES_PER_FUSE_ROW  8
 #define MAX_EFUSE_VALUE  16
+#define THERM_SECURE_BITE_CMD 8
 
 static struct msm_thermal_data msm_thermal_info;
 static struct delayed_work check_temp_work;
@@ -89,6 +92,7 @@
 static bool ocr_probed;
 static bool interrupt_mode_enable;
 static bool msm_thermal_probed;
+static bool therm_reset_enabled;
 static int *tsens_id_map;
 static DEFINE_MUTEX(vdd_rstr_mutex);
 static DEFINE_MUTEX(psm_mutex);
@@ -169,6 +173,7 @@
 };
 
 enum msm_thresh_list {
+	MSM_THERM_RESET,
 	MSM_VDD_RESTRICTION,
 	MSM_LIST_MAX_NR,
 };
@@ -929,6 +934,73 @@
 	return ret;
 }
 
+static void msm_thermal_bite(int tsens_id, long temp)
+{
+	pr_err("TSENS:%d reached temperature:%ld. System reset\n",
+		tsens_id, temp);
+	scm_call_atomic1(SCM_SVC_BOOT, THERM_SECURE_BITE_CMD, 0);
+}
+
+static int do_therm_reset(void)
+{
+	int ret = 0, i;
+	long temp = 0;
+
+	if (!therm_reset_enabled)
+		return ret;
+
+	for (i = 0; i < thresh[MSM_THERM_RESET].thresh_ct; i++) {
+		ret = therm_get_temp(
+			thresh[MSM_THERM_RESET].thresh_list[i].sensor_id,
+			THERM_TSENS_ID,
+			&temp);
+		if (ret) {
+			pr_err("Unable to read TSENS sensor:%d. err:%d\n",
+			thresh[MSM_THERM_RESET].thresh_list[i].sensor_id,
+			ret);
+			continue;
+		}
+
+		if (temp >= msm_thermal_info.therm_reset_temp_degC)
+			msm_thermal_bite(
+			thresh[MSM_THERM_RESET].thresh_list[i].sensor_id, temp);
+	}
+
+	return ret;
+}
+
+static void therm_reset_notify(struct therm_threshold *thresh_data)
+{
+	long temp;
+	int ret = 0;
+
+	if (!therm_reset_enabled)
+		return;
+
+	if (!thresh_data) {
+		pr_err("Invalid input\n");
+		return;
+	}
+
+	switch (thresh_data->trip_triggered) {
+	case THERMAL_TRIP_CONFIGURABLE_HI:
+		ret = therm_get_temp(thresh_data->sensor_id,
+				THERM_TSENS_ID, &temp);
+		if (ret)
+			pr_err("Unable to read TSENS sensor:%d. err:%d\n",
+				thresh_data->sensor_id, ret);
+		msm_thermal_bite(tsens_id_map[thresh_data->sensor_id],
+					temp);
+		break;
+	case THERMAL_TRIP_CONFIGURABLE_LOW:
+		break;
+	default:
+		pr_err("Invalid trip type\n");
+		break;
+	}
+	set_threshold(thresh_data->sensor_id, thresh_data->threshold);
+}
+
 #ifdef CONFIG_SMP
 static void __ref do_core_control(long temp)
 {
@@ -1266,6 +1338,8 @@
 	long temp = 0;
 	int ret = 0;
 
+	do_therm_reset();
+
 	ret = therm_get_temp(msm_thermal_info.sensor_id, THERM_TSENS_ID, &temp);
 	if (ret) {
 		pr_err("Unable to read TSENS sensor:%d. err:%d\n",
@@ -1740,6 +1814,9 @@
 		goto init_exit;
 	}
 
+	if (therm_reset_enabled)
+		therm_set_threshold(&thresh[MSM_THERM_RESET]);
+
 	if (vdd_rstr_enabled)
 		therm_set_threshold(&thresh[MSM_VDD_RESTRICTION]);
 
@@ -3047,6 +3124,38 @@
 	return ret;
 }
 
+static int probe_therm_reset(struct device_node *node,
+		struct msm_thermal_data *data,
+		struct platform_device *pdev)
+{
+	char *key = NULL;
+	int ret = 0;
+
+	key = "qcom,therm-reset-temp";
+	ret = of_property_read_u32(node, key, &data->therm_reset_temp_degC);
+	if (ret)
+		goto PROBE_RESET_EXIT;
+
+	ret = init_threshold(MSM_THERM_RESET, MONITOR_ALL_TSENS,
+		data->therm_reset_temp_degC, data->therm_reset_temp_degC - 10,
+		therm_reset_notify);
+	if (ret) {
+		pr_err("Therm reset data structure init failed\n");
+		goto PROBE_RESET_EXIT;
+	}
+
+	therm_reset_enabled = true;
+
+PROBE_RESET_EXIT:
+	if (ret) {
+		dev_info(&pdev->dev,
+		"%s:Failed reading node=%s, key=%s err=%d. KTM continues\n",
+			__func__, node->full_name, key, ret);
+		therm_reset_enabled = false;
+	}
+	return ret;
+}
+
 static int probe_freq_mitigation(struct device_node *node,
 		struct msm_thermal_data *data,
 		struct platform_device *pdev)
@@ -3132,6 +3241,8 @@
 	ret = probe_cc(node, &data, pdev);
 
 	ret = probe_freq_mitigation(node, &data, pdev);
+	ret = probe_therm_reset(node, &data, pdev);
+
 	/*
 	 * Probe optional properties below. Call probe_psm before
 	 * probe_vdd_rstr because rpm_regulator_get has to be called
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index b13e8e5..fe0b20f 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1240,7 +1240,7 @@
 		 * upon set config#1. Call set_alt for non-zero
 		 * alternate setting.
 		 */
-		if (!w_value && cdev->config) {
+		if (!w_value && cdev->config && !f->get_alt) {
 			value = 0;
 			break;
 		}
diff --git a/drivers/video/msm/mdss/mdp3_dma.c b/drivers/video/msm/mdss/mdp3_dma.c
index 2dd66f8..4bf2ca7 100644
--- a/drivers/video/msm/mdss/mdp3_dma.c
+++ b/drivers/video/msm/mdss/mdp3_dma.c
@@ -763,7 +763,7 @@
 			MDP3_REG_READ(MDP3_REG_DMA_P_HIST_EXTRA_INFO_1);
 
 	spin_lock_irqsave(&dma->histo_lock, flag);
-	init_completion(&dma->histo_comp);
+	INIT_COMPLETION(dma->histo_comp);
 	MDP3_REG_WRITE(MDP3_REG_DMA_P_HIST_START, 1);
 	wmb();
 	dma->histo_state = MDP3_DMA_HISTO_STATE_START;
@@ -781,7 +781,7 @@
 
 	spin_lock_irqsave(&dma->histo_lock, flag);
 
-	init_completion(&dma->histo_comp);
+	INIT_COMPLETION(dma->histo_comp);
 	MDP3_REG_WRITE(MDP3_REG_DMA_P_HIST_START, 1);
 	wmb();
 	dma->histo_state = MDP3_DMA_HISTO_STATE_START;
@@ -800,7 +800,7 @@
 
 	spin_lock_irqsave(&dma->histo_lock, flag);
 
-	init_completion(&dma->histo_comp);
+	INIT_COMPLETION(dma->histo_comp);
 
 	mdp3_dma_clk_auto_gating(dma, 0);
 
diff --git a/drivers/video/msm/mdss/mdp3_ppp_hwio.c b/drivers/video/msm/mdss/mdp3_ppp_hwio.c
index a25c2c7..8c5d771 100644
--- a/drivers/video/msm/mdss/mdp3_ppp_hwio.c
+++ b/drivers/video/msm/mdss/mdp3_ppp_hwio.c
@@ -953,7 +953,7 @@
 			PPP_WRITEL(phase_step_y, MDP3_PPP_SCALE_PHASEY_STEP);
 
 
-			if (dstW > src->roi.width || dstW > src->roi.height)
+			if (dstW > src->roi.width || dstH > src->roi.height)
 				ppp_load_up_lut();
 
 			if (mdp_blur)
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index bf91a29..edde3e3 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -44,6 +44,7 @@
 #include <linux/file.h>
 #include <linux/memory_alloc.h>
 #include <linux/kthread.h>
+#include <linux/of_address.h>
 
 #include <mach/board.h>
 #include <mach/memory.h>
@@ -87,7 +88,10 @@
 static int mdss_fb_suspend_sub(struct msm_fb_data_type *mfd);
 static int mdss_fb_ioctl(struct fb_info *info, unsigned int cmd,
 			 unsigned long arg);
-static int mdss_fb_mmap(struct fb_info *info, struct vm_area_struct *vma);
+static int mdss_fb_fbmem_ion_mmap(struct fb_info *info,
+		struct vm_area_struct *vma);
+static int mdss_fb_alloc_fb_ion_memory(struct msm_fb_data_type *mfd,
+		size_t size);
 static void mdss_fb_release_fences(struct msm_fb_data_type *mfd);
 static int __mdss_fb_sync_buf_done_callback(struct notifier_block *p,
 		unsigned long val, void *data);
@@ -1070,31 +1074,258 @@
 	return mdss_fb_blank_sub(blank_mode, info, mfd->op_enable);
 }
 
-/*
- * Custom Framebuffer mmap() function for MSM driver.
- * Differs from standard mmap() function by allowing for customized
- * page-protection.
+/* Set VM page protection */
+static inline void __mdss_fb_set_page_protection(struct vm_area_struct *vma,
+		struct msm_fb_data_type *mfd)
+{
+	if (mfd->mdp_fb_page_protection == MDP_FB_PAGE_PROTECTION_WRITECOMBINE)
+		vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+	else if (mfd->mdp_fb_page_protection ==
+			MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE)
+		vma->vm_page_prot = pgprot_writethroughcache(vma->vm_page_prot);
+	else if (mfd->mdp_fb_page_protection ==
+			MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE)
+		vma->vm_page_prot = pgprot_writebackcache(vma->vm_page_prot);
+	else if (mfd->mdp_fb_page_protection ==
+			MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE)
+		vma->vm_page_prot = pgprot_writebackwacache(vma->vm_page_prot);
+	else
+		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+
+}
+
+static inline int mdss_fb_create_ion_client(struct msm_fb_data_type *mfd)
+{
+	mfd->fb_ion_client  = msm_ion_client_create(-1 , "mdss_fb_iclient");
+	if (IS_ERR_OR_NULL(mfd->fb_ion_client)) {
+		pr_err("Err:client not created, val %d\n",
+				PTR_RET(mfd->fb_ion_client));
+		mfd->fb_ion_client = NULL;
+		return PTR_RET(mfd->fb_ion_client);
+	}
+	return 0;
+}
+
+void mdss_fb_free_fb_ion_memory(struct msm_fb_data_type *mfd)
+{
+	if (!mfd) {
+		pr_err("no mfd\n");
+		return;
+	}
+
+	if (!mfd->fbi->screen_base)
+		return;
+
+	if (!mfd->fb_ion_client || !mfd->fb_ion_handle) {
+		pr_err("invalid input parameters for fb%d\n", mfd->index);
+		return;
+	}
+
+	mfd->fbi->screen_base = NULL;
+	mfd->fbi->fix.smem_start = 0;
+
+	ion_unmap_kernel(mfd->fb_ion_client, mfd->fb_ion_handle);
+
+	if (mfd->mdp.fb_mem_get_iommu_domain) {
+		ion_unmap_iommu(mfd->fb_ion_client, mfd->fb_ion_handle,
+				mfd->mdp.fb_mem_get_iommu_domain(), 0);
+	}
+
+	ion_free(mfd->fb_ion_client, mfd->fb_ion_handle);
+	mfd->fb_ion_handle = NULL;
+}
+
+int mdss_fb_alloc_fb_ion_memory(struct msm_fb_data_type *mfd, size_t fb_size)
+{
+	unsigned long buf_size;
+	int rc;
+	void *vaddr;
+
+	if (!mfd) {
+		pr_err("Invalid input param - no mfd");
+		return -EINVAL;
+	}
+
+	if (!mfd->fb_ion_client) {
+		rc = mdss_fb_create_ion_client(mfd);
+		if (rc < 0) {
+			pr_err("fb ion client couldn't be created - %d\n", rc);
+			return rc;
+		}
+	}
+
+	pr_debug("size for mmap = %zu", fb_size);
+	mfd->fb_ion_handle = ion_alloc(mfd->fb_ion_client, fb_size, SZ_4K,
+			ION_HEAP(ION_SYSTEM_HEAP_ID), 0);
+	if (IS_ERR_OR_NULL(mfd->fb_ion_handle)) {
+		pr_err("unable to alloc fbmem from ion - %ld\n",
+				PTR_ERR(mfd->fb_ion_handle));
+		return PTR_ERR(mfd->fb_ion_handle);
+	}
+
+	if (mfd->mdp.fb_mem_get_iommu_domain) {
+		rc = ion_map_iommu(mfd->fb_ion_client, mfd->fb_ion_handle,
+				mfd->mdp.fb_mem_get_iommu_domain(), 0, SZ_4K, 0,
+				&mfd->iova, &buf_size, 0, 0);
+		if (rc) {
+			pr_err("Cannot map fb_mem to IOMMU. rc=%d\n", rc);
+			goto fb_mmap_failed;
+		}
+	} else {
+		pr_err("No IOMMU Domain");
+		goto fb_mmap_failed;
+
+	}
+
+	vaddr  = ion_map_kernel(mfd->fb_ion_client, mfd->fb_ion_handle);
+	if (IS_ERR_OR_NULL(vaddr)) {
+		pr_err("ION memory mapping failed - %ld\n", PTR_ERR(vaddr));
+		rc = PTR_ERR(vaddr);
+		if (mfd->mdp.fb_mem_get_iommu_domain) {
+			ion_unmap_iommu(mfd->fb_ion_client, mfd->fb_ion_handle,
+					mfd->mdp.fb_mem_get_iommu_domain(), 0);
+		}
+		goto fb_mmap_failed;
+	}
+
+	pr_debug("alloc 0x%zuB vaddr = %p (%pa iova) for fb%d\n", fb_size,
+			vaddr, &mfd->iova, mfd->index);
+
+	mfd->fbi->screen_base = (char *) vaddr;
+	mfd->fbi->fix.smem_start = (unsigned int) mfd->iova;
+	mfd->fbi->fix.smem_len = fb_size;
+
+	return rc;
+
+fb_mmap_failed:
+	ion_free(mfd->fb_ion_client, mfd->fb_ion_handle);
+	return rc;
+}
+
+/**
+ * mdss_fb_fbmem_ion_mmap() -  Custom fb  mmap() function for MSM driver.
+ *
+ * @info -  Framebuffer info.
+ * @vma  -  VM area which is part of the process virtual memory.
+ *
+ * This framebuffer mmap function differs from standard mmap() function by
+ * allowing for customized page-protection and dynamically allocate framebuffer
+ * memory from system heap and map to iommu virtual address.
+ *
+ * Return: virtual address is returned through vma
  */
-static int mdss_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
+static int mdss_fb_fbmem_ion_mmap(struct fb_info *info,
+		struct vm_area_struct *vma)
+{
+	int rc = 0;
+	size_t req_size, fb_size;
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	struct sg_table *table;
+	unsigned long addr = vma->vm_start;
+	unsigned long offset = vma->vm_pgoff * PAGE_SIZE;
+	struct scatterlist *sg;
+	unsigned int i;
+	struct page *page;
+
+	if (!mfd || !mfd->pdev || !mfd->pdev->dev.of_node) {
+		pr_err("Invalid device node\n");
+		return -ENODEV;
+	}
+
+	req_size = vma->vm_end - vma->vm_start;
+	fb_size = mfd->fbi->fix.smem_len;
+	if (req_size > fb_size) {
+		pr_warn("requested map is greater than framebuffer");
+		return -EOVERFLOW;
+	}
+
+	if (!mfd->fbi->screen_base) {
+		rc = mdss_fb_alloc_fb_ion_memory(mfd, fb_size);
+		if (rc < 0) {
+			pr_err("fb mmap failed!!!!");
+			return rc;
+		}
+	}
+
+	table = ion_sg_table(mfd->fb_ion_client, mfd->fb_ion_handle);
+	if (IS_ERR(table)) {
+		pr_err("Unable to get sg_table from ion:%ld\n", PTR_ERR(table));
+		mfd->fbi->screen_base = NULL;
+		return PTR_ERR(table);
+	} else if (!table) {
+		pr_err("sg_list is NULL\n");
+		mfd->fbi->screen_base = NULL;
+		return -EINVAL;
+	}
+
+	page = sg_page(table->sgl);
+	if (page) {
+		for_each_sg(table->sgl, sg, table->nents, i) {
+			unsigned long remainder = vma->vm_end - addr;
+			unsigned long len = sg->length;
+
+			page = sg_page(sg);
+
+			if (offset >= sg->length) {
+				offset -= sg->length;
+				continue;
+			} else if (offset) {
+				page += offset / PAGE_SIZE;
+				len = sg->length - offset;
+				offset = 0;
+			}
+			len = min(len, remainder);
+
+			__mdss_fb_set_page_protection(vma, mfd);
+
+			pr_debug("vma=%p, addr=%x len=%ld",
+					vma, (unsigned int)addr, len);
+			pr_cont("vm_start=%x vm_end=%x vm_page_prot=%ld\n",
+					(unsigned int)vma->vm_start,
+					(unsigned int)vma->vm_end,
+					(unsigned long int)vma->vm_page_prot);
+
+			io_remap_pfn_range(vma, addr, page_to_pfn(page), len,
+					vma->vm_page_prot);
+			addr += len;
+			if (addr >= vma->vm_end)
+				break;
+		}
+	} else {
+		pr_err("PAGE is null\n");
+		mdss_fb_free_fb_ion_memory(mfd);
+		return -ENOMEM;
+	}
+
+	return rc;
+}
+
+/*
+ * mdss_fb_physical_mmap() - Custom fb mmap() function for MSM driver.
+ *
+ * @info -  Framebuffer info.
+ * @vma  -  VM area which is part of the process virtual memory.
+ *
+ * This framebuffer mmap function differs from standard mmap() function as
+ * map to framebuffer memory from the CMA memory which is allocated during
+ * bootup.
+ *
+ * Return: virtual address is returned through vma
+ */
+static int mdss_fb_physical_mmap(struct fb_info *info,
+		struct vm_area_struct *vma)
 {
 	/* Get frame buffer memory range. */
 	unsigned long start = info->fix.smem_start;
 	u32 len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len);
 	unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
-	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
-	int ret = 0;
 
 	if (!start) {
-		pr_warn("No framebuffer memory is allocated.\n");
+		pr_warn("No framebuffer memory is allocated\n");
 		return -ENOMEM;
 	}
 
-	ret = mdss_fb_pan_idle(mfd);
-	if (ret) {
-		pr_err("Shutdown pending. Aborting operation\n");
-		return ret;
-	}
-
 	/* Set VM flags. */
 	start &= PAGE_MASK;
 	if ((vma->vm_end <= vma->vm_start) ||
@@ -1106,22 +1337,7 @@
 		return -EINVAL;
 	vma->vm_pgoff = off >> PAGE_SHIFT;
 	/* This is an IO map - tell maydump to skip this VMA */
-	vma->vm_flags |= VM_IO | VM_RESERVED;
-
-	/* Set VM page protection */
-	if (mfd->mdp_fb_page_protection == MDP_FB_PAGE_PROTECTION_WRITECOMBINE)
-		vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
-	else if (mfd->mdp_fb_page_protection ==
-		 MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE)
-		vma->vm_page_prot = pgprot_writethroughcache(vma->vm_page_prot);
-	else if (mfd->mdp_fb_page_protection ==
-		 MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE)
-		vma->vm_page_prot = pgprot_writebackcache(vma->vm_page_prot);
-	else if (mfd->mdp_fb_page_protection ==
-		 MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE)
-		vma->vm_page_prot = pgprot_writebackwacache(vma->vm_page_prot);
-	else
-		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+	vma->vm_flags |= VM_IO;
 
 	/* Remap the frame buffer I/O range */
 	if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
@@ -1132,6 +1348,22 @@
 	return 0;
 }
 
+static int mdss_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	int rc = 0;
+
+	if (!info->fix.smem_start && !mfd->fb_ion_handle)
+		rc = mdss_fb_fbmem_ion_mmap(info, vma);
+	else
+		rc = mdss_fb_physical_mmap(info, vma);
+
+	if (rc < 0)
+		pr_err("fb mmap failed with rc = %d", rc);
+
+	return rc;
+}
+
 static struct fb_ops mdss_fb_ops = {
 	.owner = THIS_MODULE,
 	.fb_open = mdss_fb_open,
@@ -1141,48 +1373,66 @@
 	.fb_blank = mdss_fb_blank,	/* blank display */
 	.fb_pan_display = mdss_fb_pan_display,	/* pan display */
 	.fb_ioctl = mdss_fb_ioctl,	/* perform fb specific ioctl */
+#ifdef CONFIG_COMPAT
+	.fb_compat_ioctl = mdss_fb_compat_ioctl,
+#endif
 	.fb_mmap = mdss_fb_mmap,
 };
 
 static int mdss_fb_alloc_fbmem_iommu(struct msm_fb_data_type *mfd, int dom)
 {
 	void *virt = NULL;
-	unsigned long phys = 0;
+	phys_addr_t phys = 0;
 	size_t size = 0;
 	struct platform_device *pdev = mfd->pdev;
+	int rc = 0;
+	struct device_node *fbmem_pnode = NULL;
 
 	if (!pdev || !pdev->dev.of_node) {
 		pr_err("Invalid device node\n");
 		return -ENODEV;
 	}
 
-	if (of_property_read_u32(pdev->dev.of_node,
-				 "qcom,memory-reservation-size",
-				 &size) || !size) {
+	fbmem_pnode = of_parse_phandle(pdev->dev.of_node,
+		"linux,contiguous-region", 0);
+	if (!fbmem_pnode) {
+		pr_debug("fbmem is not reserved for %s\n", pdev->name);
 		mfd->fbi->screen_base = NULL;
 		mfd->fbi->fix.smem_start = 0;
-		mfd->fbi->fix.smem_len = 0;
 		return 0;
+	} else {
+		const u32 *addr;
+		u64 len;
+
+		addr = of_get_address(fbmem_pnode, 0, &len, NULL);
+		if (!addr) {
+			pr_err("fbmem size is not specified\n");
+			of_node_put(fbmem_pnode);
+			return -EINVAL;
+		}
+		size = (size_t)len;
+		of_node_put(fbmem_pnode);
 	}
 
-	pr_info("%s frame buffer reserve_size=0x%x\n", __func__, size);
+	pr_debug("%s frame buffer reserve_size=0x%zx\n", __func__, size);
 
 	if (size < PAGE_ALIGN(mfd->fbi->fix.line_length *
 			      mfd->fbi->var.yres_virtual))
 		pr_warn("reserve size is smaller than framebuffer size\n");
 
-	virt = allocate_contiguous_memory(size, MEMTYPE_EBI1, SZ_1M, 0);
+	virt = dma_alloc_coherent(&pdev->dev, size, &phys, GFP_KERNEL);
 	if (!virt) {
-		pr_err("unable to alloc fbmem size=%u\n", size);
+		pr_err("unable to alloc fbmem size=%zx\n", size);
 		return -ENOMEM;
 	}
 
-	phys = memory_pool_node_paddr(virt);
-
-	msm_iommu_map_contig_buffer(phys, dom, 0, size, SZ_4K, 0,
+	rc = msm_iommu_map_contig_buffer(phys, dom, 0, size, SZ_4K, 0,
 					    &mfd->iova);
-	pr_info("allocating %u bytes at %p (%lx phys) for fb %d\n",
-		 size, virt, phys, mfd->index);
+	if (rc)
+		pr_warn("Cannot map fb_mem %pa to IOMMU. rc=%d\n", &phys, rc);
+
+	pr_debug("alloc 0x%zxB @ (%pa phys) (0x%p virt) (%pa iova) for fb%d\n",
+		 size, &phys, virt, &mfd->iova, mfd->index);
 
 	mfd->fbi->screen_base = virt;
 	mfd->fbi->fix.smem_start = phys;
@@ -1194,9 +1444,9 @@
 static int mdss_fb_alloc_fbmem(struct msm_fb_data_type *mfd)
 {
 
-	if (mfd->mdp.fb_mem_alloc_fnc)
+	if (mfd->mdp.fb_mem_alloc_fnc) {
 		return mfd->mdp.fb_mem_alloc_fnc(mfd);
-	else if (mfd->mdp.fb_mem_get_iommu_domain) {
+	} else if (mfd->mdp.fb_mem_get_iommu_domain) {
 		int dom = mfd->mdp.fb_mem_get_iommu_domain();
 		if (dom >= 0)
 			return mdss_fb_alloc_fbmem_iommu(mfd, dom);
@@ -1374,8 +1624,14 @@
 	var->hsync_len = panel_info->lcdc.h_pulse_width;
 	var->pixclock = panel_info->clk_rate / 1000;
 
-	/* id field for fb app  */
+	/*
+	 * Populate smem length here for uspace to get the
+	 * Framebuffer size when FBIO_FSCREENINFO ioctl is
+	 * called.
+	 */
+	fix->smem_len = PAGE_ALIGN(fix->line_length * var->yres) * mfd->fb_page;
 
+	/* id field for fb app  */
 	id = (int *)&mfd->panel;
 
 	snprintf(fix->id, sizeof(fix->id), "mdssfb_%x", (u32) *id);
@@ -1390,10 +1646,8 @@
 
 	mdss_fb_parse_dt(mfd);
 
-	if (mdss_fb_alloc_fbmem(mfd)) {
-		pr_err("unable to allocate framebuffer memory\n");
-		return -ENOMEM;
-	}
+	if (mdss_fb_alloc_fbmem(mfd))
+		pr_warn("unable to allocate fb memory in fb register\n");
 
 	mfd->op_enable = true;
 
@@ -1430,9 +1684,8 @@
 		return -EPERM;
 	}
 
-	pr_info("FrameBuffer[%d] %dx%d size=%d registered successfully!\n",
-		     mfd->index, fbi->var.xres, fbi->var.yres,
-		     fbi->fix.smem_len);
+	pr_info("FrameBuffer[%d] %dx%d registered successfully!\n", mfd->index,
+					fbi->var.xres, fbi->var.yres);
 
 	return 0;
 }
@@ -1606,6 +1859,16 @@
 			mfd->disp_thread = NULL;
 		}
 
+		if (mfd->mdp.release_fnc) {
+			ret = mfd->mdp.release_fnc(mfd, true);
+			if (ret)
+				pr_err("error fb%d release process %s pid=%d\n",
+					mfd->index, task->comm, pid);
+		}
+
+		if (mfd->fb_ion_handle)
+			mdss_fb_free_fb_ion_memory(mfd);
+
 		ret = mdss_fb_blank_sub(FB_BLANK_POWERDOWN, info,
 			mfd->op_enable);
 		if (ret) {
@@ -2181,6 +2444,8 @@
 	else
 		mfd->fbi->fix.line_length = var->xres * var->bits_per_pixel / 8;
 
+	mfd->fbi->fix.smem_len = mfd->fbi->fix.line_length *
+					mfd->fbi->var.yres_virtual;
 
 	if (mfd->panel_reconfig || (mfd->fb_imgType != old_imgType)) {
 		mdss_fb_blank_sub(FB_BLANK_POWERDOWN, info, mfd->op_enable);
diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h
index 1ab0fb7..8e6be01 100644
--- a/drivers/video/msm/mdss/mdss_fb.h
+++ b/drivers/video/msm/mdss/mdss_fb.h
@@ -229,6 +229,8 @@
 	u32 dcm_state;
 	struct list_head proc_list;
 	u32 wait_for_kickoff;
+	struct ion_client *fb_ion_client;
+	struct ion_handle *fb_ion_handle;
 };
 
 static inline void mdss_fb_update_notify_update(struct msm_fb_data_type *mfd)
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index f7d02b2..08c0eac 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -615,6 +615,29 @@
 	return vbp_max;
 }
 
+static bool mdss_mdp_video_mode_intf_connected(struct mdss_mdp_ctl *ctl)
+{
+	int i;
+	struct mdss_data_type *mdata;
+
+	if (!ctl || !ctl->mdata)
+		return 0;
+
+	mdata = ctl->mdata;
+	for (i = 0; i < mdata->nctl; i++) {
+		struct mdss_mdp_ctl *ctl = mdata->ctl_off + i;
+
+		if (ctl->is_video_mode && ctl->power_on) {
+			pr_debug("video interface connected ctl:%d\n",
+			ctl->num);
+			return true;
+		}
+	}
+
+	return false;
+}
+
+
 static void __mdss_mdp_perf_calc_ctl_helper(struct mdss_mdp_ctl *ctl,
 		struct mdss_mdp_perf_params *perf,
 		struct mdss_mdp_pipe **left_plist, int left_cnt,
@@ -710,13 +733,12 @@
 			left_plist, (left_plist ? MDSS_MDP_MAX_STAGE : 0),
 			right_plist, (right_plist ? MDSS_MDP_MAX_STAGE : 0));
 
-	if (ctl->is_video_mode) {
-		if (perf->bw_overlap > perf->bw_prefill)
-			perf->bw_ctl = apply_fudge_factor(perf->bw_ctl,
-				&mdss_res->ib_factor_overlap);
-		else
-			perf->bw_ctl = apply_fudge_factor(perf->bw_ctl,
-				&mdss_res->ib_factor);
+	if (ctl->is_video_mode || mdss_mdp_video_mode_intf_connected(ctl)) {
+		perf->bw_ctl =
+			max(apply_fudge_factor(perf->bw_overlap,
+				&mdss_res->ib_factor_overlap),
+			apply_fudge_factor(perf->bw_prefill,
+				&mdss_res->ib_factor));
 	}
 	pr_debug("ctl=%d clk_rate=%u\n", ctl->num, perf->mdp_clk_rate);
 	pr_debug("bw_overlap=%llu bw_prefill=%llu prefill_bytes=%d\n",
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index f286de5..e5965e6 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -1731,7 +1731,7 @@
 		return;
 
 	if (!fbi->fix.smem_start || fbi->fix.smem_len == 0 ||
-	     mdp5_data->borderfill_enable) {
+			mdp5_data->borderfill_enable) {
 		mfd->mdp.kickoff_fnc(mfd, NULL);
 		return;
 	}
@@ -1747,11 +1747,6 @@
 
 	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
 
-	ret = mdss_iommu_ctrl(1);
-	if (IS_ERR_VALUE(ret)) {
-		pr_err("IOMMU attach failed\n");
-		goto pan_display_error;
-	}
 
 	bpp = fbi->var.bits_per_pixel / 8;
 	offset = fbi->var.xoffset * bpp +
@@ -1769,6 +1764,12 @@
 		goto pan_display_error;
 	}
 
+	ret = mdss_iommu_ctrl(1);
+	if (IS_ERR_VALUE(ret)) {
+		pr_err("IOMMU attach failed\n");
+		goto pan_display_error;
+	}
+
 	ret = mdss_mdp_overlay_get_fb_pipe(mfd, &pipe,
 					MDSS_MDP_MIXER_MUX_LEFT);
 	if (ret) {
diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c
index 4819456..b39c5a7 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pipe.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c
@@ -303,13 +303,7 @@
 	if (pipe->mixer->type == MDSS_MDP_MIXER_TYPE_WRITEBACK)
 		wb_mixer = 1;
 
-	/*
-	 * Don't want to allow SMP changes for backend composition pipes
-	 * inorder to preserve SMPs as much as possible.
-	 * On the contrary for non backend composition pipes we should
-	 * allow SMP allocations to prevent composition failures.
-	 */
-	force_alloc = !(pipe->flags & MDP_BACKEND_COMPOSITION);
+	force_alloc = pipe->flags & MDP_SMP_FORCE_ALLOC;
 
 	mutex_lock(&mdss_mdp_smp_lock);
 	for (i = (MAX_PLANES - 1); i >= ps.num_planes; i--) {
diff --git a/drivers/video/msm/mdss/mdss_mdp_wb.c b/drivers/video/msm/mdss/mdss_mdp_wb.c
index b50ba59..a87b0ab 100644
--- a/drivers/video/msm/mdss/mdss_mdp_wb.c
+++ b/drivers/video/msm/mdss/mdss_mdp_wb.c
@@ -406,11 +406,28 @@
 	int ret;
 
 	if (!list_empty(&wb->register_queue)) {
+		struct ion_client *iclient = mdss_get_ionclient();
+		struct ion_handle *ihdl;
+
+		if (!iclient) {
+			pr_err("iclient is NULL\n");
+			return NULL;
+		}
+
+		ihdl = ion_import_dma_buf(iclient, data->memory_id);
+		if (IS_ERR_OR_NULL(ihdl)) {
+			pr_err("unable to import fd %d\n", data->memory_id);
+			return NULL;
+		}
+		/* only interested in ptr address, so we can free handle */
+		ion_free(iclient, ihdl);
+
 		list_for_each_entry(node, &wb->register_queue, registered_entry)
-			if ((node->buf_info.memory_id == data->memory_id) &&
+			if ((node->buf_data.p[0].srcp_ihdl == ihdl) &&
 				    (node->buf_info.offset == data->offset)) {
-				pr_debug("found node fd=%x off=%x addr=%x\n",
-						data->memory_id, data->offset,
+				pr_debug("found fd=%d hdl=%p off=%x addr=%x\n",
+						data->memory_id, ihdl,
+						data->offset,
 						node->buf_data.p[0].addr);
 				return node;
 			}
@@ -465,8 +482,9 @@
 
 	if (node->user_alloc) {
 		buf = &node->buf_data.p[0];
-		pr_debug("free user node mem_id=%d offset=%u addr=0x%x\n",
+		pr_debug("free user mem_id=%d ihdl=%p, offset=%u addr=0x%x\n",
 				node->buf_info.memory_id,
+				buf->srcp_ihdl,
 				node->buf_info.offset,
 				buf->addr);
 
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 2fb663a..1874adb 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -82,6 +82,56 @@
 	return mm->total_vm;
 }
 
+static void seq_print_vma_name(struct seq_file *m, struct vm_area_struct *vma)
+{
+	const char __user *name = vma_get_anon_name(vma);
+	struct mm_struct *mm = vma->vm_mm;
+
+	unsigned long page_start_vaddr;
+	unsigned long page_offset;
+	unsigned long num_pages;
+	unsigned long max_len = NAME_MAX;
+	int i;
+
+	page_start_vaddr = (unsigned long)name & PAGE_MASK;
+	page_offset = (unsigned long)name - page_start_vaddr;
+	num_pages = DIV_ROUND_UP(page_offset + max_len, PAGE_SIZE);
+
+	seq_puts(m, "[anon:");
+
+	for (i = 0; i < num_pages; i++) {
+		int len;
+		int write_len;
+		const char *kaddr;
+		long pages_pinned;
+		struct page *page;
+
+		pages_pinned = get_user_pages(current, mm, page_start_vaddr,
+				1, 0, 0, &page, NULL);
+		if (pages_pinned < 1) {
+			seq_puts(m, "<fault>]");
+			return;
+		}
+
+		kaddr = (const char *)kmap(page);
+		len = min(max_len, PAGE_SIZE - page_offset);
+		write_len = strnlen(kaddr + page_offset, len);
+		seq_write(m, kaddr + page_offset, write_len);
+		kunmap(page);
+		put_page(page);
+
+		/* if strnlen hit a null terminator then we're done */
+		if (write_len != len)
+			break;
+
+		max_len -= len;
+		page_offset = 0;
+		page_start_vaddr += PAGE_SIZE;
+	}
+
+	seq_putc(m, ']');
+}
+
 static void vma_stop(struct proc_maps_private *priv, struct vm_area_struct *vma)
 {
 	if (vma && vma != priv->tail_vma) {
@@ -281,6 +331,12 @@
 				seq_pad(m, ' ');
 				seq_printf(m, "[stack:%d]", tid);
 			}
+			goto done;
+		}
+
+		if (vma_get_anon_name(vma)) {
+			seq_pad(m, ' ');
+			seq_print_vma_name(m, vma);
 		}
 	}
 
@@ -513,6 +569,12 @@
 		   (vma->vm_flags & VM_LOCKED) ?
 			(unsigned long)(mss.pss >> (10 + PSS_SHIFT)) : 0);
 
+	if (vma_get_anon_name(vma)) {
+		seq_puts(m, "Name:           ");
+		seq_print_vma_name(m, vma);
+		seq_putc(m, '\n');
+	}
+
 	if (m->count < m->size)  /* vma is copied successfully */
 		m->version = (vma != get_gate_vma(task->mm))
 			? vma->vm_start : 0;
diff --git a/include/linux/avtimer_kernel.h b/include/linux/avtimer_kernel.h
new file mode 100644
index 0000000..5eff8cc
--- /dev/null
+++ b/include/linux/avtimer_kernel.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _AVTIMER_H
+#define _AVTIMER_H
+
+#include <uapi/linux/avtimer.h>
+
+int avcs_core_open(void);
+int avcs_core_disable_power_collapse(int disable);/* true or flase */
+int avcs_core_query_timer(uint64_t *avtimer_tick);
+
+#endif
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 2218ac4..b574c60 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1394,7 +1394,7 @@
 extern struct vm_area_struct *vma_merge(struct mm_struct *,
 	struct vm_area_struct *prev, unsigned long addr, unsigned long end,
 	unsigned long vm_flags, struct anon_vma *, struct file *, pgoff_t,
-	struct mempolicy *);
+	struct mempolicy *, const char __user *);
 extern struct anon_vma *find_mergeable_anon_vma(struct vm_area_struct *);
 extern int split_vma(struct mm_struct *,
 	struct vm_area_struct *, unsigned long addr, int new_below);
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index b98b4b9..8535cc0 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -216,6 +216,10 @@
 	 * linkage into the address_space->i_mmap prio tree, or
 	 * linkage to the list of like vmas hanging off its node, or
 	 * linkage of vma in the address_space->i_mmap_nonlinear list.
+	 *
+	 * For private anonymous mappings, a pointer to a null terminated string
+	 * in the user process containing the name given to the vma, or NULL
+	 * if unnamed.
 	 */
 	union {
 		struct {
@@ -225,6 +229,7 @@
 		} vm_set;
 
 		struct raw_prio_tree_node prio_tree_node;
+		const char __user *anon_name;
 	} shared;
 
 	/*
@@ -392,4 +397,14 @@
 	return mm->cpu_vm_mask_var;
 }
 
+
+/* Return the name for an anonymous mapping or NULL for a file-backed mapping */
+static inline const char __user *vma_get_anon_name(struct vm_area_struct *vma)
+{
+	if (vma->vm_file)
+		return NULL;
+
+	return vma->shared.anon_name;
+}
+
 #endif /* _LINUX_MM_TYPES_H */
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index b295fcc..4be3260 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -221,6 +221,7 @@
 #define MDP_MEMORY_ID_TYPE_FB		0x00001000
 #define MDP_BWC_EN			0x00000400
 #define MDP_DECIMATION_EN		0x00000800
+#define MDP_SMP_FORCE_ALLOC            0x00200000
 #define MDP_TRANSP_NOP 0xffffffff
 #define MDP_ALPHA_NOP 0xff
 
diff --git a/include/linux/msm_thermal.h b/include/linux/msm_thermal.h
index 25b5363..2e3270d 100644
--- a/include/linux/msm_thermal.h
+++ b/include/linux/msm_thermal.h
@@ -36,6 +36,7 @@
 	int32_t psm_temp_hyst_degC;
 	int32_t ocr_temp_degC;
 	int32_t ocr_temp_hyst_degC;
+	int32_t therm_reset_temp_degC;
 };
 
 #ifdef CONFIG_THERMAL_MONITOR
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 0b95337..f712fba 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -2636,14 +2636,20 @@
  * @NL80211_BSS_BSSID: BSSID of the BSS (6 octets)
  * @NL80211_BSS_FREQUENCY: frequency in MHz (u32)
  * @NL80211_BSS_TSF: TSF of the received probe response/beacon (u64)
+ *	(if @NL80211_BSS_PRESP_DATA is present then this is known to be
+ *	from a probe response, otherwise it may be from the same beacon
+ *	that the NL80211_BSS_BEACON_TSF will be from)
  * @NL80211_BSS_BEACON_INTERVAL: beacon interval of the (I)BSS (u16)
  * @NL80211_BSS_CAPABILITY: capability field (CPU order, u16)
  * @NL80211_BSS_INFORMATION_ELEMENTS: binary attribute containing the
  *	raw information elements from the probe response/beacon (bin);
- *	if the %NL80211_BSS_BEACON_IES attribute is present, the IEs here are
- *	from a Probe Response frame; otherwise they are from a Beacon frame.
+ *	if the %NL80211_BSS_BEACON_IES attribute is present and the data is
+ *	different then the IEs here are from a Probe Response frame; otherwise
+ *	they are from a Beacon frame.
  *	However, if the driver does not indicate the source of the IEs, these
  *	IEs may be from either frame subtype.
+ *	If present, the @NL80211_BSS_PRESP_DATA attribute indicates that the
+ *	data here is known to be from a probe response, without any heuristics.
  * @NL80211_BSS_SIGNAL_MBM: signal strength of probe response/beacon
  *	in mBm (100 * dBm) (s32)
  * @NL80211_BSS_SIGNAL_UNSPEC: signal strength of the probe response/beacon
@@ -2653,6 +2659,12 @@
  * @NL80211_BSS_BEACON_IES: binary attribute containing the raw information
  *	elements from a Beacon frame (bin); not present if no Beacon frame has
  *	yet been received
+ * @NL80211_BSS_CHAN_WIDTH: channel width of the control channel
+ *	(u32, enum nl80211_bss_scan_width)
+ * @NL80211_BSS_BEACON_TSF: TSF of the last received beacon (u64)
+ *	(not present if no beacon frame has been received yet)
+ * @NL80211_BSS_PRESP_DATA: the data in @NL80211_BSS_INFORMATION_ELEMENTS and
+ *	@NL80211_BSS_TSF is known to be from a probe response (flag attribute)
  * @__NL80211_BSS_AFTER_LAST: internal
  * @NL80211_BSS_MAX: highest BSS attribute
  */
@@ -2669,6 +2681,9 @@
 	NL80211_BSS_STATUS,
 	NL80211_BSS_SEEN_MS_AGO,
 	NL80211_BSS_BEACON_IES,
+	NL80211_BSS_CHAN_WIDTH,
+	NL80211_BSS_BEACON_TSF,
+	NL80211_BSS_PRESP_DATA,
 
 	/* keep last */
 	__NL80211_BSS_AFTER_LAST,
diff --git a/include/linux/prctl.h b/include/linux/prctl.h
index e0cfec2..23728f0 100644
--- a/include/linux/prctl.h
+++ b/include/linux/prctl.h
@@ -124,4 +124,13 @@
 #define PR_SET_CHILD_SUBREAPER 36
 #define PR_GET_CHILD_SUBREAPER 37
 
+/* Sets the timerslack for arbitrary threads
+ * arg2 slack value, 0 means "use default"
+ * arg3 pid of the thread whose timer slack needs to be set
+ */
+#define PR_SET_TIMERSLACK_PID 41
+
+#define PR_SET_VMA		0x53564d41
+# define PR_SET_VMA_ANON_NAME		0
+
 #endif /* _LINUX_PRCTL_H */
diff --git a/include/linux/sync.h b/include/linux/sync.h
index f4ac10e..7fdd6a7 100644
--- a/include/linux/sync.h
+++ b/include/linux/sync.h
@@ -84,6 +84,9 @@
 
 	/* optional */
 	void (*pt_value_str)(struct sync_pt *pt, char *str, int size);
+
+	/* optional */
+	void (*pt_log)(struct sync_pt *pt);
 };
 
 /**
@@ -342,6 +345,15 @@
  */
 int sync_fence_wait(struct sync_fence *fence, long timeout);
 
+/**
+ * sync_fence_log() - log the details of the fence in the kernel log
+ * @fence:	fence to log
+ *
+ * Log the details of the fence and the associated sync points in the kernel
+ * log.
+ */
+void sync_fence_log(struct sync_fence *fence);
+
 #endif /* __KERNEL__ */
 
 /**
diff --git a/include/linux/wcnss_wlan.h b/include/linux/wcnss_wlan.h
index 56ba8ab..8bdcfd5 100644
--- a/include/linux/wcnss_wlan.h
+++ b/include/linux/wcnss_wlan.h
@@ -42,7 +42,6 @@
 #define HAVE_WCNSS_SUSPEND_RESUME_NOTIFY 1
 #define HAVE_WCNSS_RESET_INTR 1
 #define HAVE_WCNSS_CAL_DOWNLOAD 1
-#define HAVE_CBC_DONE 1
 #define HAVE_WCNSS_RX_BUFF_COUNT 1
 #define WLAN_MAC_ADDR_SIZE (6)
 
@@ -82,7 +81,6 @@
 void wcnss_pronto_log_debug_regs(void);
 int wcnss_is_hw_pronto_ver3(void);
 int wcnss_device_ready(void);
-int wcnss_cbc_complete(void);
 int wcnss_device_is_shutdown(void);
 void wcnss_riva_dump_pmic_regs(void);
 int wcnss_xo_auto_detect_enabled(void);
diff --git a/include/net/tcp.h b/include/net/tcp.h
index dce56a6..4f093b4 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -254,6 +254,7 @@
 extern int sysctl_tcp_cookie_size;
 extern int sysctl_tcp_thin_linear_timeouts;
 extern int sysctl_tcp_thin_dupack;
+extern int sysctl_tcp_default_init_rwnd;
 
 /* sysctl variables for controlling various tcp parameters */
 extern int sysctl_tcp_delack_seg;
diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h
index ec3038b..059916e 100644
--- a/include/sound/q6asm-v2.h
+++ b/include/sound/q6asm-v2.h
@@ -183,6 +183,7 @@
 	/* audio cache operations fptr*/
 	int (*fptr_cache_ops)(struct audio_buffer *abuff, int cache_op);
 	atomic_t               unmap_cb_success;
+	atomic_t               reset;
 };
 
 void q6asm_audio_client_free(struct audio_client *ac);
diff --git a/sound/soc/msm/qdsp6v2/q6core.h b/include/sound/q6core.h
similarity index 100%
rename from sound/soc/msm/qdsp6v2/q6core.h
rename to include/sound/q6core.h
diff --git a/include/uapi/linux/avtimer.h b/include/uapi/linux/avtimer.h
new file mode 100644
index 0000000..f688b38
--- /dev/null
+++ b/include/uapi/linux/avtimer.h
@@ -0,0 +1,19 @@
+#ifndef _UAPI_AVTIMER_H
+#define _UAPI_AVTIMER_H
+
+#include <linux/ioctl.h>
+
+#define MAJOR_NUM 100
+
+#define IOCTL_GET_AVTIMER_TICK _IOR(MAJOR_NUM, 0, char *)
+/*
+ * This IOCTL is used read the avtimer tick value.
+ * Avtimer is a 64 bit timer tick, hence the expected
+ * argument is of type uint64_t
+ */
+struct dev_avtimer_data {
+	uint32_t avtimer_msw_phy_addr;
+	uint32_t avtimer_lsw_phy_addr;
+};
+
+#endif
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 1e5bfd8..780ac9b 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -1606,6 +1606,7 @@
 {
 	unsigned long flags;
 	int cpu, src_cpu, success = 0;
+	int notify = 0;
 
 	smp_wmb();
 	raw_spin_lock_irqsave(&p->pi_lock, flags);
@@ -1663,10 +1664,13 @@
 	ttwu_queue(p, cpu);
 stat:
 	ttwu_stat(p, cpu, wake_flags);
+
+	if (src_cpu != cpu && task_notify_on_migrate(p))
+		notify = 1;
 out:
 	raw_spin_unlock_irqrestore(&p->pi_lock, flags);
 
-	if (src_cpu != cpu && task_notify_on_migrate(p))
+	if (notify)
 		atomic_notifier_call_chain(&migration_notifier_head,
 					   cpu, (void *)src_cpu);
 	return success;
diff --git a/kernel/sys.c b/kernel/sys.c
index 39791be..2f95158 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -40,6 +40,9 @@
 #include <linux/syscore_ops.h>
 #include <linux/version.h>
 #include <linux/ctype.h>
+#include <linux/mm.h>
+#include <linux/mempolicy.h>
+#include <linux/sched.h>
 
 #include <linux/compat.h>
 #include <linux/syscalls.h>
@@ -1821,10 +1824,151 @@
 }
 #endif
 
+
+static int prctl_update_vma_anon_name(struct vm_area_struct *vma,
+		struct vm_area_struct **prev,
+		unsigned long start, unsigned long end,
+		const char __user *name_addr)
+{
+	struct mm_struct * mm = vma->vm_mm;
+	int error = 0;
+	pgoff_t pgoff;
+
+	if (name_addr == vma_get_anon_name(vma)) {
+		*prev = vma;
+		goto out;
+	}
+
+	pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
+	*prev = vma_merge(mm, *prev, start, end, vma->vm_flags, vma->anon_vma,
+				vma->vm_file, pgoff, vma_policy(vma),
+				name_addr);
+	if (*prev) {
+		vma = *prev;
+		goto success;
+	}
+
+	*prev = vma;
+
+	if (start != vma->vm_start) {
+		error = split_vma(mm, vma, start, 1);
+		if (error)
+			goto out;
+	}
+
+	if (end != vma->vm_end) {
+		error = split_vma(mm, vma, end, 0);
+		if (error)
+			goto out;
+	}
+
+success:
+	if (!vma->vm_file)
+		vma->shared.anon_name = name_addr;
+
+out:
+	if (error == -ENOMEM)
+		error = -EAGAIN;
+	return error;
+}
+
+static int prctl_set_vma_anon_name(unsigned long start, unsigned long end,
+			unsigned long arg)
+{
+	unsigned long tmp;
+	struct vm_area_struct * vma, *prev;
+	int unmapped_error = 0;
+	int error = -EINVAL;
+
+	/*
+	 * If the interval [start,end) covers some unmapped address
+	 * ranges, just ignore them, but return -ENOMEM at the end.
+	 * - this matches the handling in madvise.
+	 */
+	vma = find_vma_prev(current->mm, start, &prev);
+	if (vma && start > vma->vm_start)
+		prev = vma;
+
+	for (;;) {
+		/* Still start < end. */
+		error = -ENOMEM;
+		if (!vma)
+			return error;
+
+		/* Here start < (end|vma->vm_end). */
+		if (start < vma->vm_start) {
+			unmapped_error = -ENOMEM;
+			start = vma->vm_start;
+			if (start >= end)
+				return error;
+		}
+
+		/* Here vma->vm_start <= start < (end|vma->vm_end) */
+		tmp = vma->vm_end;
+		if (end < tmp)
+			tmp = end;
+
+		/* Here vma->vm_start <= start < tmp <= (end|vma->vm_end). */
+		error = prctl_update_vma_anon_name(vma, &prev, start, end,
+				(const char __user *)arg);
+		if (error)
+			return error;
+		start = tmp;
+		if (prev && start < prev->vm_end)
+			start = prev->vm_end;
+		error = unmapped_error;
+		if (start >= end)
+			return error;
+		if (prev)
+			vma = prev->vm_next;
+		else	/* madvise_remove dropped mmap_sem */
+			vma = find_vma(current->mm, start);
+	}
+}
+
+static int prctl_set_vma(unsigned long opt, unsigned long start,
+		unsigned long len_in, unsigned long arg)
+{
+	struct mm_struct *mm = current->mm;
+	int error;
+	unsigned long len;
+	unsigned long end;
+
+	if (start & ~PAGE_MASK)
+		return -EINVAL;
+	len = (len_in + ~PAGE_MASK) & PAGE_MASK;
+
+	/* Check to see whether len was rounded up from small -ve to zero */
+	if (len_in && !len)
+		return -EINVAL;
+
+	end = start + len;
+	if (end < start)
+		return -EINVAL;
+
+	if (end == start)
+		return 0;
+
+	down_write(&mm->mmap_sem);
+
+	switch (opt) {
+	case PR_SET_VMA_ANON_NAME:
+		error = prctl_set_vma_anon_name(start, end, arg);
+		break;
+	default:
+		error = -EINVAL;
+	}
+
+	up_write(&mm->mmap_sem);
+
+	return error;
+}
+
 SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
 		unsigned long, arg4, unsigned long, arg5)
 {
 	struct task_struct *me = current;
+	struct task_struct *tsk;
 	unsigned char comm[sizeof(me->comm)];
 	long error;
 
@@ -1981,6 +2125,29 @@
 			error = put_user(me->signal->is_child_subreaper,
 					 (int __user *) arg2);
 			break;
+		case PR_SET_VMA:
+			error = prctl_set_vma(arg2, arg3, arg4, arg5);
+			break;
+		case PR_SET_TIMERSLACK_PID:
+			if (current->pid != (pid_t)arg3 &&
+					!capable(CAP_SYS_NICE))
+				return -EPERM;
+			rcu_read_lock();
+			tsk = find_task_by_pid_ns((pid_t)arg3, &init_pid_ns);
+			if (tsk == NULL) {
+				rcu_read_unlock();
+				return -EINVAL;
+			}
+			get_task_struct(tsk);
+			rcu_read_unlock();
+			if (arg2 <= 0)
+				tsk->timer_slack_ns =
+					tsk->default_timer_slack_ns;
+			else
+				tsk->timer_slack_ns = arg2;
+			put_task_struct(tsk);
+			error = 0;
+			break;
 		default:
 			error = -EINVAL;
 			break;
diff --git a/mm/madvise.c b/mm/madvise.c
index 55f645c..b075d1d 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -93,7 +93,8 @@
 
 	pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
 	*prev = vma_merge(mm, *prev, start, end, new_flags, vma->anon_vma,
-				vma->vm_file, pgoff, vma_policy(vma));
+				vma->vm_file, pgoff, vma_policy(vma),
+				vma_get_anon_name(vma));
 	if (*prev) {
 		vma = *prev;
 		goto success;
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index b195691..a786980 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -660,7 +660,7 @@
 			((vmstart - vma->vm_start) >> PAGE_SHIFT);
 		prev = vma_merge(mm, prev, vmstart, vmend, vma->vm_flags,
 				  vma->anon_vma, vma->vm_file, pgoff,
-				  new_pol);
+				  new_pol, vma_get_anon_name(name));
 		if (prev) {
 			vma = prev;
 			next = vma->vm_next;
diff --git a/mm/mlock.c b/mm/mlock.c
index 38c77ab..029f234 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -333,7 +333,8 @@
 
 	pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
 	*prev = vma_merge(mm, *prev, start, end, newflags, vma->anon_vma,
-			  vma->vm_file, pgoff, vma_policy(vma));
+			  vma->vm_file, pgoff, vma_policy(vma),
+			  vma_get_anon_name(vma));
 	if (*prev) {
 		vma = *prev;
 		goto success;
diff --git a/mm/mmap.c b/mm/mmap.c
index 9932edb..964223d 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -649,7 +649,8 @@
  * per-vma resources, so we don't attempt to merge those.
  */
 static inline int is_mergeable_vma(struct vm_area_struct *vma,
-			struct file *file, unsigned long vm_flags)
+			struct file *file, unsigned long vm_flags,
+			const char __user *anon_name)
 {
 	/* VM_CAN_NONLINEAR may get set later by f_op->mmap() */
 	if ((vma->vm_flags ^ vm_flags) & ~VM_CAN_NONLINEAR)
@@ -658,6 +659,8 @@
 		return 0;
 	if (vma->vm_ops && vma->vm_ops->close)
 		return 0;
+	if (vma_get_anon_name(vma) != anon_name)
+		return 0;
 	return 1;
 }
 
@@ -688,9 +691,10 @@
  */
 static int
 can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
-	struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
+	struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff,
+	const char __user *anon_name)
 {
-	if (is_mergeable_vma(vma, file, vm_flags) &&
+	if (is_mergeable_vma(vma, file, vm_flags, anon_name) &&
 	    is_mergeable_anon_vma(anon_vma, vma->anon_vma, vma)) {
 		if (vma->vm_pgoff == vm_pgoff)
 			return 1;
@@ -707,9 +711,10 @@
  */
 static int
 can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
-	struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
+	struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff,
+	const char __user *anon_name)
 {
-	if (is_mergeable_vma(vma, file, vm_flags) &&
+	if (is_mergeable_vma(vma, file, vm_flags, anon_name) &&
 	    is_mergeable_anon_vma(anon_vma, vma->anon_vma, vma)) {
 		pgoff_t vm_pglen;
 		vm_pglen = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
@@ -720,9 +725,9 @@
 }
 
 /*
- * Given a mapping request (addr,end,vm_flags,file,pgoff), figure out
- * whether that can be merged with its predecessor or its successor.
- * Or both (it neatly fills a hole).
+ * Given a mapping request (addr,end,vm_flags,file,pgoff,anon_name),
+ * figure out whether that can be merged with its predecessor or its
+ * successor.  Or both (it neatly fills a hole).
  *
  * In most cases - when called for mmap, brk or mremap - [addr,end) is
  * certain not to be mapped by the time vma_merge is called; but when
@@ -752,7 +757,8 @@
 			struct vm_area_struct *prev, unsigned long addr,
 			unsigned long end, unsigned long vm_flags,
 		     	struct anon_vma *anon_vma, struct file *file,
-			pgoff_t pgoff, struct mempolicy *policy)
+			pgoff_t pgoff, struct mempolicy *policy,
+			const char __user *anon_name)
 {
 	pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
 	struct vm_area_struct *area, *next;
@@ -778,15 +784,15 @@
 	 */
 	if (prev && prev->vm_end == addr &&
   			mpol_equal(vma_policy(prev), policy) &&
-			can_vma_merge_after(prev, vm_flags,
-						anon_vma, file, pgoff)) {
+			can_vma_merge_after(prev, vm_flags, anon_vma,
+						file, pgoff, anon_name)) {
 		/*
 		 * OK, it can.  Can we now merge in the successor as well?
 		 */
 		if (next && end == next->vm_start &&
 				mpol_equal(policy, vma_policy(next)) &&
-				can_vma_merge_before(next, vm_flags,
-					anon_vma, file, pgoff+pglen) &&
+				can_vma_merge_before(next, vm_flags, anon_vma,
+						file, pgoff+pglen, anon_name) &&
 				is_mergeable_anon_vma(prev->anon_vma,
 						      next->anon_vma, NULL)) {
 							/* cases 1, 6 */
@@ -806,8 +812,8 @@
 	 */
 	if (next && end == next->vm_start &&
  			mpol_equal(policy, vma_policy(next)) &&
-			can_vma_merge_before(next, vm_flags,
-					anon_vma, file, pgoff+pglen)) {
+			can_vma_merge_before(next, vm_flags, anon_vma,
+					file, pgoff+pglen, anon_name)) {
 		if (prev && addr < prev->vm_end)	/* case 4 */
 			err = vma_adjust(prev, prev->vm_start,
 				addr, prev->vm_pgoff, NULL);
@@ -1282,7 +1288,8 @@
 	/*
 	 * Can we just expand an old mapping?
 	 */
-	vma = vma_merge(mm, prev, addr, addr + len, vm_flags, NULL, file, pgoff, NULL);
+	vma = vma_merge(mm, prev, addr, addr + len, vm_flags, NULL, file, pgoff,
+			NULL, NULL);
 	if (vma)
 		goto out;
 
@@ -2232,7 +2239,7 @@
 
 	/* Can we just expand an old private anonymous mapping? */
 	vma = vma_merge(mm, prev, addr, addr + len, flags,
-					NULL, NULL, pgoff, NULL);
+					NULL, NULL, pgoff, NULL, NULL);
 	if (vma)
 		goto out;
 
@@ -2382,7 +2389,8 @@
 
 	find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
 	new_vma = vma_merge(mm, prev, addr, addr + len, vma->vm_flags,
-			vma->anon_vma, vma->vm_file, pgoff, vma_policy(vma));
+			vma->anon_vma, vma->vm_file, pgoff, vma_policy(vma),
+			vma_get_anon_name(vma));
 	if (new_vma) {
 		/*
 		 * Source vma may have been merged into new_vma
diff --git a/mm/mprotect.c b/mm/mprotect.c
index a409926..10add6b 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -179,7 +179,8 @@
 	 */
 	pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
 	*pprev = vma_merge(mm, *pprev, start, end, newflags,
-			vma->anon_vma, vma->vm_file, pgoff, vma_policy(vma));
+			vma->anon_vma, vma->vm_file, pgoff, vma_policy(vma),
+			vma_get_anon_name(vma));
 	if (*pprev) {
 		vma = *pprev;
 		goto success;
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 7c81e3b..d615ac8 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -125,6 +125,21 @@
 	return ret;
 }
 
+/* Validate changes from /proc interface. */
+static int proc_tcp_default_init_rwnd(ctl_table *ctl, int write,
+				      void __user *buffer,
+				      size_t *lenp, loff_t *ppos)
+{
+	int old_value = *(int *)ctl->data;
+	int ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
+	int new_value = *(int *)ctl->data;
+
+	if (write && ret == 0 && (new_value < 3 || new_value > 100))
+		*(int *)ctl->data = old_value;
+
+	return ret;
+}
+
 static int proc_tcp_congestion_control(ctl_table *ctl, int write,
 				       void __user *buffer, size_t *lenp, loff_t *ppos)
 {
@@ -673,7 +688,7 @@
 		.mode           = 0644,
 		.proc_handler   = proc_dointvec
 	},
-        {
+	{
 		.procname       = "tcp_thin_dupack",
 		.data           = &sysctl_tcp_thin_dupack,
 		.maxlen         = sizeof(int),
@@ -681,6 +696,13 @@
 		.proc_handler   = proc_dointvec
 	},
 	{
+		.procname       = "tcp_default_init_rwnd",
+		.data           = &sysctl_tcp_default_init_rwnd,
+		.maxlen         = sizeof(int),
+		.mode           = 0644,
+		.proc_handler   = proc_tcp_default_init_rwnd
+	},
+	{
 		.procname	= "udp_mem",
 		.data		= &sysctl_udp_mem,
 		.maxlen		= sizeof(sysctl_udp_mem),
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 7c3612b..3b9c021 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -99,6 +99,7 @@
 
 int sysctl_tcp_moderate_rcvbuf __read_mostly = 1;
 int sysctl_tcp_abc __read_mostly;
+int sysctl_tcp_default_init_rwnd __read_mostly = TCP_DEFAULT_INIT_RCVWND;
 
 #define FLAG_DATA		0x01 /* Incoming frame contained data.		*/
 #define FLAG_WIN_UPDATE		0x02 /* Incoming ACK was a window update.	*/
@@ -348,14 +349,14 @@
 static void tcp_fixup_rcvbuf(struct sock *sk)
 {
 	u32 mss = tcp_sk(sk)->advmss;
-	u32 icwnd = TCP_DEFAULT_INIT_RCVWND;
+	u32 icwnd = sysctl_tcp_default_init_rwnd;
 	int rcvmem;
 
 	/* Limit to 10 segments if mss <= 1460,
 	 * or 14600/mss segments, with a minimum of two segments.
 	 */
 	if (mss > 1460)
-		icwnd = max_t(u32, (1460 * TCP_DEFAULT_INIT_RCVWND) / mss, 2);
+		icwnd = max_t(u32, (1460 * icwnd) / mss, 2);
 
 	rcvmem = SKB_TRUESIZE(mss + MAX_TCP_HEADER);
 	while (tcp_win_from_space(rcvmem) < mss)
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 7ac6423..08b49f8 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -229,14 +229,13 @@
 	}
 
 	/* Set initial window to a value enough for senders starting with
-	 * initial congestion window of TCP_DEFAULT_INIT_RCVWND. Place
+	 * initial congestion window of sysctl_tcp_default_init_rwnd. Place
 	 * a limit on the initial window when mss is larger than 1460.
 	 */
 	if (mss > (1 << *rcv_wscale)) {
-		int init_cwnd = TCP_DEFAULT_INIT_RCVWND;
+		int init_cwnd = sysctl_tcp_default_init_rwnd;
 		if (mss > 1460)
-			init_cwnd =
-			max_t(u32, (1460 * TCP_DEFAULT_INIT_RCVWND) / mss, 2);
+			init_cwnd = max_t(u32, (1460 * init_cwnd) / mss, 2);
 		/* when initializing use the value from init_rcv_wnd
 		 * rather than the default from above
 		 */
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index 1addd9f..efb0138 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -1348,7 +1348,7 @@
 	int err;
 
 	if (level != SOL_PPPOL2TP)
-		return udp_prot.setsockopt(sk, level, optname, optval, optlen);
+		return -EINVAL;
 
 	if (optlen < sizeof(int))
 		return -EINVAL;
@@ -1474,7 +1474,7 @@
 	struct pppol2tp_session *ps;
 
 	if (level != SOL_PPPOL2TP)
-		return udp_prot.getsockopt(sk, level, optname, optval, optlen);
+		return -EINVAL;
 
 	if (get_user(len, (int __user *) optlen))
 		return -EFAULT;
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index eb535cc..a3a7134 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -758,9 +758,10 @@
 	struct net *net = nf_ct_net(ct);
 
 	nf_ct_ext_destroy(ct);
-	atomic_dec(&net->ct.count);
 	nf_ct_ext_free(ct);
 	kmem_cache_free(net->ct.nf_conntrack_cachep, ct);
+	smp_mb__before_atomic_dec();
+	atomic_dec(&net->ct.count);
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_free);
 
diff --git a/net/wireless/db.txt b/net/wireless/db.txt
index 5f8b5c2..7fa1975 100644
--- a/net/wireless/db.txt
+++ b/net/wireless/db.txt
@@ -18,16 +18,28 @@
 
 country AE:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 80), (3, 17)
-	(5250 - 5330 @ 80), (3, 24), DFS
-	(5490 - 5730 @ 80), (3, 24), DFS
-	(5735 - 5835 @ 80), (3, 30)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
+
+country AF: DFS-ETSI
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
+
+country AI: DFS-ETSI
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
 
 country AL:
 	(2402 - 2482 @ 40), (N/A, 20)
 	(5150 - 5250 @ 80), (N/A, 20)
 	(5250 - 5350 @ 80), (N/A, 20), DFS
-	(5470 - 5725 @ 80), (N/A, 27), DFS
+	(5470 - 5710 @ 80), (N/A, 27), DFS
 
 country AM:
 	(2402 - 2482 @ 40), (N/A, 20)
@@ -42,17 +54,18 @@
 
 country AR:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 80), (3, 17)
-	(5250 - 5330 @ 80), (3, 24), DFS
-	(5490 - 5730 @ 80), (3, 24), DFS
-	(5735 - 5835 @ 80), (3, 30)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5590 @ 80), (6, 24), DFS
+	(5650 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
 
 country AS:
 	(2402 - 2472 @ 40), (N/A, 30)
-	(5150 - 5250 @ 80), (6, 17)
-	(5250 - 5350 @ 80), (6, 24), DFS
-	(5470 - 5725 @ 80), (6, 24), DFS
-	(5725 - 5850 @ 80), (6, 30)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5850 @ 80), (6, 30)
 
 country AT: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
@@ -64,16 +77,17 @@
 
 country AU:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 80), (3, 17)
-	(5250 - 5330 @ 80), (3, 24), DFS
-	(5490 - 5730 @ 80), (3, 24), DFS
-	(5735 - 5835 @ 80), (3, 30)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5590 @ 80), (6, 24), DFS
+	(5650 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
 
 country AW:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 40), (N/A, 20)
-	(5250 - 5330 @ 40), (N/A, 20), DFS
-	(5490 - 5710 @ 40), (N/A, 27), DFS
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
 
 country AZ:
 	(2402 - 2482 @ 40), (N/A, 20)
@@ -96,7 +110,7 @@
 
 country BD:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5725 - 5850 @ 80), (N/A, 30)
+	(5735 - 5835 @ 80), (N/A, 30)
 
 country BE: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
@@ -106,11 +120,18 @@
 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
 
+country BF:
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (3, 24)
+	(5250 - 5330 @ 80), (3, 24), DFS
+	(5490 - 5730 @ 80), (3, 24), DFS
+	(5735 - 5835 @ 80), (3, 30)
+
 country BG: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 80), (N/A, 23)
-	(5250 - 5290 @ 80), (N/A, 23), DFS
-	(5490 - 5710 @ 80), (N/A, 30), DFS
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
 
@@ -120,36 +141,49 @@
 	(5250 - 5330 @ 20), (N/A, 20), DFS
 	(5735 - 5835 @ 20), (N/A, 20)
 
+country BL:
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
+
 country BM:
 	(2402 - 2472 @ 40), (N/A, 30)
-	(5150 - 5250 @ 80), (6, 17)
-	(5250 - 5350 @ 80), (6, 24), DFS
-	(5470 - 5725 @ 80), (6, 24), DFS
-	(5725 - 5850 @ 80), (6, 30)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
 
 country BN:
 	(2402 - 2482 @ 40), (N/A, 20)
 	(5170 - 5250 @ 80), (N/A, 20)
 	(5250 - 5330 @ 80), (N/A, 20), DFS
-	(5735 - 5835 @ 80), (N/A, 30)
+	(5735 - 5835 @ 80), (N/A, 20)
 
 country BO:
-	(2402 - 2482 @ 40), (N/A, 30)
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 30), DFS
 	(5735 - 5835 @ 80), (N/A, 30)
 
 country BR:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 80), (3, 17)
-	(5250 - 5330 @ 80), (3, 24), DFS
-	(5490 - 5730 @ 80), (3, 24), DFS
-	(5735 - 5835 @ 80), (3, 30)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
 
 country BS:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5150 - 5250 @ 80), (6, 17)
-	(5250 - 5350 @ 80), (6, 24), DFS
-	(5470 - 5725 @ 80), (6, 24), DFS
-	(5725 - 5850 @ 80), (6, 30)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
+
+country BT: DFS-ETSI
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
 
 country BY:
 	(2402 - 2482 @ 40), (N/A, 20)
@@ -162,19 +196,32 @@
 	(5735 - 5835 @ 80), (N/A, 30)
 
 country CA:
-	(2402 - 2472 @ 40), (N/A, 27)
-	(5170 - 5250 @ 80), (3, 17)
-	(5250 - 5330 @ 80), (3, 24), DFS
-	(5490 - 5730 @ 80), (3, 24), DFS
-	(5735 - 5835 @ 80), (3, 30)
+	(2402 - 2472 @ 40), (N/A, 30)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5590 @ 80), (6, 24), DFS
+	(5650 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
 
-country CH: DFS-ETSI
+country CF:
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 40), (6, 24)
+	(5250 - 5330 @ 40), (6, 24), DFS
+	(5490 - 5730 @ 40), (6, 24), DFS
+	(5735 - 5835 @ 40), (6, 30)
+
+country CH:
 	(2402 - 2482 @ 40), (N/A, 20)
 	(5170 - 5250 @ 80), (N/A, 20)
 	(5250 - 5330 @ 80), (N/A, 20), DFS
 	(5490 - 5710 @ 80), (N/A, 27), DFS
-	# 60 gHz band channels 1-4, ref: Etsi En 302 567
-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
+
+country CI:
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
 
 country CL:
 	(2402 - 2482 @ 40), (N/A, 20)
@@ -184,10 +231,9 @@
 
 country CN:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5150 - 5250 @ 80), (6,	23)
-	(5250 - 5350 @ 80), (6,	23), DFS
-	(5725 - 5850 @ 80), (6,	30)
-	(5735 - 5835 @ 80), (N/A, 30)
+	(5170 - 5250 @ 80), (6, 23)
+	(5250 - 5330 @ 80), (6, 23), DFS
+	(5735 - 5835 @ 80), (6, 30)
 	# 60 gHz band channels 1,4: 28dBm, channels 2,3: 44dBm
 	# ref: http://www.miit.gov.cn/n11293472/n11505629/n11506593/n11960250/n11960606/n11960700/n12330791.files/n12330790.pdf
 	(57240 - 59400 @ 2160), (N/A, 28)
@@ -195,18 +241,25 @@
 	(63720 - 65880 @ 2160), (N/A, 28)
 
 country CO:
-	(2402 - 2472 @ 40), (N/A, 27)
-	(5170 - 5250 @ 80), (3, 17)
-	(5250 - 5330 @ 80), (3, 24), DFS
-	(5490 - 5730 @ 80), (3, 24), DFS
-	(5735 - 5835 @ 80), (3, 30)
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
 
 country CR:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 20), (3, 17)
-	(5250 - 5330 @ 20), (3, 24), DFS
-	(5490 - 5730 @ 20), (3, 24), DFS
-	(5735 - 5835 @ 20), (3, 30)
+	(5170 - 5250 @ 20), (6, 24)
+	(5250 - 5330 @ 20), (6, 24), DFS
+	(5490 - 5730 @ 20), (6, 24), DFS
+	(5735 - 5835 @ 20), (6, 30)
+
+country CX:
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
 
 country CY: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
@@ -221,10 +274,10 @@
 # Power at 5250 - 5350 MHz and 5470 - 5725 MHz can be doubled if TPC is
 # implemented.
 country CZ: DFS-ETSI
-	(2400 - 2483.5 @ 40), (N/A, 100 mW)
-	(5150 - 5250 @ 80), (N/A, 200 mW), NO-OUTDOOR
-	(5250 - 5350 @ 80), (N/A, 100 mW), NO-OUTDOOR, DFS
-	(5470 - 5725 @ 80), (N/A, 500 mW), DFS
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
 
@@ -242,13 +295,10 @@
 
 country DE: DFS-ETSI
 	# entries 279004 and 280006
-	(2400 - 2483.5 @ 40), (N/A, 100 mW)
-	# entry 303005
-	(5150 - 5250 @ 80), (N/A, 100 mW), NO-OUTDOOR
-	# entries 304002 and 305002
-	(5250 - 5350 @ 80), (N/A, 100 mW), NO-OUTDOOR, DFS
-	# entries 308002, 309001 and 310003
-	(5470 - 5725 @ 80), (N/A, 500 mW), DFS
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
 
@@ -260,24 +310,30 @@
 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
 
+country DM:
+	(2402 - 2472 @ 40), (N/A, 30)
+	(5170 - 5250 @ 80), (6, 17)
+	(5250 - 5330 @ 80), (6, 23), DFS
+	(5735 - 5835 @ 80), (6, 30)
+
 country DO:
-	(2402 - 2472 @ 40), (N/A, 27)
-	(5170 - 5250 @ 80), (3, 17)
-	(5250 - 5330 @ 80), (3, 23), DFS
-	(5735 - 5835 @ 80), (3, 30)
+	(2402 - 2472 @ 40), (N/A, 30)
+	(5170 - 5250 @ 80), (6, 17)
+	(5250 - 5330 @ 80), (6, 23), DFS
+	(5735 - 5835 @ 80), (6, 30)
 
 country DZ:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5150 - 5250 @ 80), (N/A, 23)
-	(5250 - 5350 @ 80), (N/A,23), DFS
-	(5470 - 5670 @ 80), (N/A, 20), DFS
+	(5170 - 5250 @ 80), (N/A, 23)
+	(5250 - 5330 @ 80), (N/A, 23), DFS
+	(5490 - 5670 @ 80), (N/A, 23), DFS
 
 country EC:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 20), (3, 17)
-	(5250 - 5330 @ 20), (3, 24), DFS
-	(5490 - 5730 @ 20), (3, 24), DFS
-	(5735 - 5835 @ 20), (3, 30)
+	(5170 - 5250 @ 20), (6, 24)
+	(5250 - 5330 @ 20), (6, 24), DFS
+	(5490 - 5730 @ 20), (6, 24), DFS
+	(5735 - 5835 @ 20), (6, 30)
 
 country EE: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
@@ -289,14 +345,14 @@
 
 country EG:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 20), (N/A, 20)
-	(5250 - 5330 @ 20), (N/A, 20), DFS
+	(5170 - 5250 @ 40), (N/A, 20)
+	(5250 - 5330 @ 40), (N/A, 20), DFS
 
 country ES: DFS-ETSI
-	(2400 - 2483.5 @ 40), (N/A, 100 mW)
-	(5150 - 5250 @ 80), (N/A, 100 mW), NO-OUTDOOR
-	(5250 - 5350 @ 80), (N/A, 100 mW), NO-OUTDOOR, DFS
-	(5470 - 5725 @ 80), (N/A, 500 mW), DFS
+	(2402 - 2482 @ 40),(N/A, 20)
+	(5170 - 5250 @ 80),(N/A, 20)
+	(5250 - 5330 @ 80),(N/A, 20), DFS
+	(5490 - 5710 @ 80),(N/A, 27), DFS
 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
 
@@ -314,6 +370,13 @@
 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
 
+country FM:
+	(2402 - 2472 @ 40), (3, 30)
+	(5170 - 5250 @ 80), (3, 24)
+	(5250 - 5330 @ 80), (3, 24), DFS
+	(5490 - 5730 @ 80), (3, 24), DFS
+	(5735 - 5835 @ 80), (3, 30)
+
 country FR: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
 	(5170 - 5250 @ 80), (N/A, 20)
@@ -322,19 +385,6 @@
 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
 
-country GF:
-	(2402 - 2482 @ 40), (N/A, 20)
-	(5150 - 5250 @ 80), (N/A, 20)
-	(5250 - 5350 @ 80), (N/A, 20), DFS
-        (5470 - 5725 @ 80), (N/A, 20), DFS
-
-country GE:
-	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 80), (N/A, 18)
-	(5250 - 5330 @ 80), (N/A, 18), DFS
-	# 60 gHz band channels 1-4, ref: Etsi En 302 567
-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
-
 country GB: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
 	(5170 - 5250 @ 80), (N/A, 20)
@@ -345,16 +395,42 @@
 
 country GD:
 	(2402 - 2472 @ 40), (3, 30)
-	(5170 - 5250 @ 80), (6, 17)
+	(5170 - 5250 @ 80), (6, 24)
 	(5250 - 5330 @ 80), (6, 24), DFS
 	(5490 - 5730 @ 80), (6, 24), DFS
 	(5735 - 5835 @ 80), (6, 30)
 
+country GE:
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 18)
+	(5250 - 5330 @ 80), (N/A, 18), DFS
+	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
+
+country GF:
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
+
+country GH:
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
+
+country GL: DFS-ETSI
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 20), (N/A, 20)
+	(5250 - 5330 @ 20), (N/A, 20), DFS
+	(5490 - 5710 @ 20), (N/A, 27), DFS
+
 country GP:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5150 - 5250 @ 80), (N/A, 20)
-	(5250 - 5350 @ 80), (N/A, 20), DFS
-        (5470 - 5725 @ 80), (N/A, 27), DFS
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
 
 country GR: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
@@ -364,35 +440,33 @@
 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
 
-country GL: DFS-ETSI
-	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 20), (N/A, 20)
-	(5250 - 5330 @ 20), (N/A, 20), DFS
-	(5490 - 5710 @ 20), (N/A, 27), DFS
-
 country GT:
-	(2402 - 2472 @ 40), (3, 30)
-	(5170 - 5250 @ 80), (6, 17)
-	(5250 - 5330 @ 80), (6, 23), DFS
-	(5735 - 5835 @ 80), (6, 30)
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
 
 country GU:
-	(2402 - 2472 @ 40), (3, 30)
-	(5170 - 5250 @ 20), (6, 17)
+	(2402 - 2472 @ 40), (N/A, 30)
+	(5170 - 5250 @ 20), (6, 24)
 	(5250 - 5330 @ 20), (6, 24), DFS
 	(5490 - 5730 @ 20), (6, 24), DFS
 	(5735 - 5835 @ 20), (6, 30)
 
-country HN:
+country GY:
+	(2402 - 2482 @ 40), (N/A, 30)
+	(5735 - 5835 @ 80), (N/A, 30)
+
+country HK:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 80), (6, 17)
+	(5170 - 5250 @ 80), (6, 24)
 	(5250 - 5330 @ 80), (6, 24), DFS
 	(5490 - 5730 @ 80), (6, 24), DFS
 	(5735 - 5835 @ 80), (6, 30)
 
-country HK:
+country HN:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 80), (6, 17)
+	(5170 - 5250 @ 80), (6, 24)
 	(5250 - 5330 @ 80), (6, 24), DFS
 	(5490 - 5730 @ 80), (6, 24), DFS
 	(5735 - 5835 @ 80), (6, 30)
@@ -406,10 +480,11 @@
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
 
 country HT:
-	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 80), (N/A, 20)
-	(5250 - 5330 @ 80), (N/A, 20), DFS
-	(5490 - 5710 @ 80), (N/A, 27), DFS
+	(2402 - 2472 @ 40), (N/A, 30)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
 
 country HU: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
@@ -421,8 +496,8 @@
 
 country ID:
 	# ref: http://www.postel.go.id/content/ID/regulasi/standardisasi/kepdir/bwa%205,8%20ghz.pdf
-	(2402 - 2482 @ 20), (N/A, 30)
-	(5735 - 5815 @ 20), (N/A, 30)
+	(2402 - 2482 @ 40), (N/A, 30)
+	(5735 - 5815 @ 80), (N/A, 30)
 
 country IE: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
@@ -434,7 +509,7 @@
 
 country IL:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5150 - 5250 @ 80), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
 	(5250 - 5330 @ 80), (N/A, 20), DFS
 
 country IN:
@@ -443,6 +518,10 @@
 	(5250 - 5330 @ 80), (N/A, 20), DFS
 	(5735 - 5835 @ 80), (N/A, 20)
 
+country IR:
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5735 - 5835 @ 80), (N/A, 30)
+
 country IS: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
 	(5170 - 5250 @ 80), (N/A, 20)
@@ -451,10 +530,6 @@
 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
 
-country IR:
-	(2402 - 2482 @ 40), (N/A, 20)
-	(5735 - 5835 @ 80), (N/A, 30)
-
 country IT: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
 	(5170 - 5250 @ 80), (N/A, 20)
@@ -465,30 +540,28 @@
 
 country JM:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 80), (6, 17)
+	(5170 - 5250 @ 80), (6, 24)
 	(5250 - 5330 @ 80), (6, 24), DFS
 	(5490 - 5730 @ 80), (6, 24), DFS
 	(5735 - 5835 @ 80), (6, 30)
 
+country JO:
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 23)
+	(5735 - 5835 @ 80), (N/A, 23)
+
 country JP:
 	(2402 - 2482 @ 40), (N/A, 20)
 	(2474 - 2494 @ 20), (N/A, 20), NO-OFDM
-	(4910 - 4990 @ 40), (N/A, 23)
-	(5030 - 5090 @ 40), (N/A, 23)
 	(5170 - 5250 @ 80), (N/A, 20)
 	(5250 - 5330 @ 80), (N/A, 20), DFS
-	(5490 - 5710 @ 160), (N/A, 23), DFS
-
-country JO:
-	(2402 - 2482 @ 40), (N/A, 20)
-	(5150 - 5250 @ 80), (N/A, 23)
-	(5725 - 5850 @ 80), (N/A, 23)
+	(5490 - 5710 @ 80), (N/A, 20), DFS
 
 country KE:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5150 - 5250 @ 80), (N/A, 23)
-        (5470 - 5570 @ 80), (N/A, 30), DFS
-        (5725 - 5775 @ 80), (N/A, 23)
+	(5170 - 5250 @ 80), (N/A, 23)
+	(5490 - 5570 @ 80), (N/A, 30), DFS
+	(5735 - 5775 @ 40), (N/A, 23)
 
 country KH:
 	(2402 - 2482 @ 40), (N/A, 20)
@@ -496,41 +569,48 @@
 	(5250 - 5330 @ 80), (N/A, 20), DFS
 	(5490 - 5710 @ 80), (N/A, 27), DFS
 
-country KY:
-        (2402 - 2472 @ 40), (N/A, 27)
-	(5170 - 5250 @ 80), (3, 17)
-	(5250 - 5330 @ 80), (3, 24), DFS
-	(5490 - 5730 @ 80), (3, 24), DFS
-	(5735 - 5835 @ 80), (3, 30)
-
-country KP:
-	(2402 - 2482 @ 20), (N/A, 20)
-	(5170 - 5330 @ 20), (6, 20)
-	(5160 - 5250 @ 20), (6, 20), DFS
-	(5490 - 5630 @ 20), (6, 30), DFS
-	(5735 - 5815 @ 20), (6, 30)
+country KN:
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (6, 20)
+	(5250 - 5330 @ 80), (6, 20), DFS
+	(5490 - 5710 @ 80), (6, 30), DFS
+	(5735 - 5815 @ 80), (6, 30)
 
 country KR:
-	(2402 - 2482 @ 20), (N/A, 20)
-	(5150 - 5250 @ 80), (6, 20)
-	(5250 - 5350 @ 80), (6, 20), DFS
-	(5470 - 5725 @ 80), (6, 30), DFS
-	(5725 - 5825 @ 80), (6, 30)
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (6, 20)
+	(5250 - 5330 @ 80), (6, 20), DFS
+	(5490 - 5630 @ 80), (6, 30), DFS
+	(5735 - 5815 @ 80), (6, 30)
 
 country KW:
 	(2402 - 2482 @ 40), (N/A, 20)
 	(5170 - 5250 @ 80), (N/A, 20)
 	(5250 - 5330 @ 80), (N/A, 20), DFS
 
+country KY:
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
+
 country KZ:
 	(2402 - 2482 @ 40), (N/A, 20)
 
 country LB:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5150 - 5250 @ 80), (6, 17)
-	(5250 - 5350 @ 80), (6, 24), DFS
-	(5470 - 5725 @ 80), (6, 24), DFS
-	(5725 - 5850 @ 80), (6, 30)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
+
+country LC:
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (6, 20)
+	(5250 - 5330 @ 80), (6, 20), DFS
+	(5490 - 5710 @ 80), (6, 30), DFS
+	(5735 - 5815 @ 80), (6, 30)
 
 country LI: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
@@ -540,10 +620,16 @@
 
 country LK:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 20), (3, 17)
-	(5250 - 5330 @ 20), (3, 20), DFS
-	(5490 - 5730 @ 20), (3, 20), DFS
-	(5735 - 5835 @ 20), (3, 30)
+	(5170 - 5250 @ 20), (6, 24)
+	(5250 - 5330 @ 20), (6, 24), DFS
+	(5490 - 5730 @ 20), (6, 24), DFS
+	(5735 - 5835 @ 20), (6, 30)
+
+country LS: DFS-ETSI
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
 
 country LT: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
@@ -569,101 +655,136 @@
 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
 
-country MC: DFS-ETSI
-	(2402 - 2482 @ 40), (N/A, 20)
-        (5150 - 5250 @ 80), (N/A, 20)
-        (5250 - 5350 @ 80), (N/A, 20), DFS
-        (5470 - 5725 @ 80), (N/A, 27), DFS
-
 country MA:
 	(2402 - 2482 @ 40), (N/A, 20)
 	(5170 - 5250 @ 80), (N/A, 20)
-	(5735 - 5835 @ 80), (N/A, 20), DFS
+	(5250 - 5330 @ 80), (N/A, 20), DFS
 
-country MO:
+country MC: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 40), (3, 23)
-	(5250 - 5330 @ 40), (3, 23), DFS
-	(5735 - 5835 @ 40), (3, 30)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
 
-country MP:
+country MD: DFS-ETSI
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
+
+country ME: DFS-ETSI
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
+
+country MF: DFS-ETSI
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
+
+country MH: DFS-FCC
 	(2402 - 2472 @ 40), (N/A, 30)
-        (5150 - 5250 @ 80), (6, 17)
-        (5250 - 5350 @ 80), (6, 24), DFS
-        (5470 - 5725 @ 80), (6,	24), DFS
-        (5725 - 5850 @ 80), (6, 30)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
 
 country MK: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 40), (N/A, 20)
-	(5250 - 5330 @ 40), (N/A, 20), DFS
-	(5490 - 5710 @ 40), (N/A, 27), DFS
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
 
 country MN:
 	(2402 - 2482 @ 40), (N/A, 20)
-        (5150 - 5250 @ 80), (6, 17)
-        (5250 - 5350 @ 80), (6, 24), DFS
-        (5470 - 5725 @ 80), (6, 24), DFS
-        (5725 - 5850 @ 80), (6,	30)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6,	30)
+
+country MO:
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5735 - 5835 @ 80), (N/A, 30)
+
+country MP:
+	(2402 - 2472 @ 40), (N/A, 30)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6,	24), DFS
+	(5735 - 5835 @ 80), (6, 30)
+
+country MQ: DFS-ETSI
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
+
+country MR: DFS-ETSI
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
 
 country MT: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 40), (N/A, 20)
-	(5250 - 5330 @ 40), (N/A, 20), DFS
-	(5490 - 5710 @ 40), (N/A, 27), DFS
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
 
-country MQ: DFS-ETSI
-        (2402 - 2482 @ 40), (N/A, 20)
-        (5150 - 5250 @ 80), (N/A, 20)
-	(5250 - 5350 @ 80), (N/A, 20), DFS
-	(5470 - 5725 @ 80), (N/A, 27), DFS
-
 country MU:
-        (2402 - 2482 @ 40), (N/A, 20)
-        (5150 - 5250 @ 80), (6, 17)
-        (5250 - 5350 @ 80), (6, 24), DFS
-        (5470 - 5725 @ 80), (6, 24), DFS
-        (5725 - 5850 @ 80), (6, 30)
-
-country MY:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 80), (N/A, 17)
-	(5250 - 5330 @ 80), (N/A, 23), DFS
-	(5735 - 5835 @ 80), (N/A, 30)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
 
-country MX:
-	(2402 - 2482 @ 40), (3, 20)
-	(5170 - 5250 @ 80), (3, 17)
-	(5250 - 5330 @ 80), (3, 24), DFS
-	(5490 - 5730 @ 80), (3, 24), DFS
-	(5735 - 5835 @ 80), (3, 30)
+country MV:
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5735 - 5835 @ 80), (N/A, 20)
 
 country MW:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5150 - 5250 @ 80), (N/A, 20)
-	(5250 - 5350 @ 80), (N/A, 20), DFS
-	(5470 - 5725 @ 80), (N/A, 27), DFS
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
+
+country MX:
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
+
+country MY:
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (6, 17)
+	(5250 - 5330 @ 80), (6, 23), DFS
+	(5735 - 5835 @ 80), (6, 30)
 
 country NG:
 	(2402 - 2482 @ 40), (N/A, 20)
-        (5250 - 5350 @ 80), (N/A, 30), DFS
-        (5725 - 5850 @ 80), (N/A, 30)
+	(5250 - 5330 @ 80), (N/A, 30), DFS
+	(5735 - 5835 @ 80), (N/A, 30)
 
 country NI:
 	(2402 - 2472 @ 40), (N/A, 30)
-        (5150 - 5250 @ 80), (6, 17)
-        (5250 - 5350 @ 80), (6, 24), DFS
-        (5470 - 5725 @ 80), (6,	24), DFS
-        (5725 - 5850 @ 80), (6, 30)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6,	24), DFS
+	(5735 - 5835 @ 80), (6, 30)
 
 country NL: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 80), (N/A, 20), NO-OUTDOOR
-	(5250 - 5330 @ 80), (N/A, 20), NO-OUTDOOR, DFS
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
 	(5490 - 5710 @ 80), (N/A, 27), DFS
 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
@@ -678,22 +799,22 @@
 
 country NP:
 	(2402 - 2482 @ 40), (N/A, 20)
-        (5150 - 5250 @ 80), (N/A, 20)
-        (5250 - 5350 @ 80), (N/A, 20), DFS
-        (5725 - 5850 @ 80), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5735 - 5835 @ 80), (N/A, 20)
 
 country NZ:
 	(2402 - 2482 @ 40), (N/A, 30)
-	(5170 - 5250 @ 80), (6, 17)
+	(5170 - 5250 @ 80), (6, 24)
 	(5250 - 5330 @ 80), (6, 24), DFS
 	(5490 - 5730 @ 80), (6, 24), DFS
 	(5735 - 5835 @ 80), (6, 30)
 
 country OM:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5150 - 5250 @ 80), (N/A, 20)
-	(5250 - 5350 @ 80), (N/A, 20), DFS
-	(5470 - 5725 @ 80), (N/A, 27), DFS
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
 
 country PA:
 	(2402 - 2472 @ 40), (N/A, 30)
@@ -703,27 +824,27 @@
 
 country PE:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 80), (6, 20)
-	(5250 - 5330 @ 80), (6, 20), DFS
-	(5490 - 5730 @ 80), (6, 27), DFS
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
 	(5735 - 5835 @ 80), (6, 30)
 
 country PF:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5150 - 5250 @ 80), (N/A, 20)
-	(5250 - 5350 @ 80), (N/A, 20), DFS
-        (5470 - 5725 @ 80), (N/A, 27), DFS
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
 
 country PG:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5150 - 5250 @ 80), (6, 17)
-	(5250 - 5350 @ 80), (6, 24), DFS
-	(5470 - 5725 @ 80), (6, 24), DFS
-	(5725 - 5850 @ 80), (6, 30)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
 
 country PH:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 80), (6, 17)
+	(5170 - 5250 @ 80), (6, 24)
 	(5250 - 5330 @ 80), (6, 24), DFS
 	(5490 - 5730 @ 80), (6, 24), DFS
 	(5735 - 5835 @ 80), (6, 30)
@@ -740,6 +861,26 @@
 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
 
+country PM: DFS-ETSI
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
+
+country PR:
+	(2402 - 2472 @ 40), (N/A, 30)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
+
+# Public Safety FCCA, FCC4
+#  27dBm [4.9GHz 1/4 rate], 30dBm [1/2 rate], 33dBm [full rate], and 5GHz same as FCC1
+#  db.txt cannot express the limitation on 5G so disable all 5G channels for FCC4
+country PS:
+	(2402 - 2472 @ 40), (N/A, 30)
+	(4940 - 4990 @ 40), (6, 33)
+
 country PT: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
 	(5170 - 5250 @ 80), (N/A, 20)
@@ -748,19 +889,19 @@
 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
 
-country PR:
-	(2402 - 2472 @ 40), (3, 30)
-	(5170 - 5250 @ 80), (6, 17)
+country PW:
+	(2402 - 2472 @ 40), (N/A, 30)
+	(5170 - 5250 @ 80), (6, 24)
 	(5250 - 5330 @ 80), (6, 24), DFS
 	(5490 - 5730 @ 80), (6, 24), DFS
 	(5735 - 5835 @ 80), (6, 30)
 
 country PY:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5150 - 5250 @ 80), (6, 17)
-	(5250 - 5350 @ 80), (6, 24), DFS
-	(5470 - 5725 @ 80), (6, 24), DFS
-	(5725 - 5850 @ 80), (6, 30)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
 
 country QA:
 	(2402 - 2482 @ 40), (N/A, 20)
@@ -768,9 +909,9 @@
 
 country RE:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5150 - 5250 @ 80), (N/A, 20)
-	(5250 - 5350 @ 80), (N/A, 20), DFS
-	(5470 - 5725 @ 80), (N/A, 27), DFS
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
 
 country RO: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
@@ -780,37 +921,35 @@
 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
 
-
 # Source:
 # http://www.ratel.rs/upload/documents/Plan_namene/Plan_namene-sl_glasnik.pdf
 country RS:
-	(2400 - 2483.5 @ 40), (N/A, 100 mW)
-	(5150 - 5250 @ 80), (N/A, 200 mW), NO-OUTDOOR
-        (5250 - 5350 @ 80), (N/A, 200 mW), DFS
-	(5470 - 5725 @ 80), (3, 1000 mW), DFS
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
+        (5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (3, 27), DFS
 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
 
 country RU:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5150 - 5250 @ 40), (N/A, 20)
-	(5250 - 5350 @ 40), (N/A, 20), DFS
-	(5650 - 5725 @ 40), (N/A, 30), DFS
-	(5725 - 5825 @ 40), (N/A, 30)
+	(5170 - 5250 @ 40), (N/A, 20)
+	(5250 - 5330 @ 40), (N/A, 20), DFS
+	(5650 - 5710 @ 40), (N/A, 30), DFS
+	(5735 - 5835 @ 40), (N/A, 30)
 
 country RW:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5150 - 5250 @ 80), (6, 17)
+	(5170 - 5250 @ 80), (6, 24)
 	(5250 - 5330 @ 80), (6, 24), DFS
-	(5470 - 5725 @ 80), (6, 24), DFS
-	(5725 - 5835 @ 80), (6, 30)
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
 
 country SA:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 80), (3, 17)
-	(5250 - 5330 @ 80), (3, 24), DFS
-	(5490 - 5710 @ 80), (3, 24), DFS
-	(5735 - 5835 @ 80), (3, 30)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
 
 country SE: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
@@ -822,7 +961,7 @@
 
 country SG:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 80), (6, 17)
+	(5170 - 5250 @ 80), (6, 24)
 	(5250 - 5330 @ 80), (6, 24), DFS
 	(5490 - 5730 @ 80), (6, 24), DFS
 	(5735 - 5835 @ 80), (6, 30)
@@ -843,11 +982,18 @@
 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
 
+country SN:
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
+
 country SR: DFS-ETSI
-	(2400 - 2483.5 @ 40), (N/A, 100 mW)
-	(5150 - 5250 @ 80), (N/A, 100 mW), NO-OUTDOOR
-	(5250 - 5350 @ 80), (N/A, 100 mW), NO-OUTDOOR, DFS
-	(5470 - 5725 @ 80), (N/A, 500 mW), DFS
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
 
 country SV:
 	(2402 - 2482 @ 40), (N/A, 20)
@@ -858,31 +1004,36 @@
 country SY:
 	(2402 - 2482 @ 40), (N/A, 20)
 
-country TW:
-	(2402 - 2472 @ 40), (3, 30)
-	(5270 - 5330 @ 40), (6, 17)
-	(5490 - 5590 @ 80), (6, 30), DFS
-	(5650 - 5730 @ 80), (6, 30), DFS
-	(5735 - 5815 @ 80), (6, 30)
+country TC:
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
+
+country TD:
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
+
+country TG: DFS-ETSI
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 40), (N/A, 20)
+	(5250 - 5330 @ 40), (N/A, 20), DFS
+	(5490 - 5710 @ 40), (N/A, 27), DFS
 
 country TH:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 80), (3, 17)
-	(5250 - 5330 @ 80), (3, 24), DFS
-	(5490 - 5730 @ 80), (3, 24), DFS
-	(5735 - 5835 @ 80), (3, 30)
-
-country TT:
-	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 40), (3, 17)
-	(5250 - 5330 @ 40), (3, 20), DFS
-	(5490 - 5730 @ 40), (3, 20), DFS
-	(5735 - 5835 @ 40), (3, 30)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
 
 country TN:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 20), (N/A, 20)
-	(5250 - 5330 @ 20), (N/A, 20), DFS
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
 
 country TR: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
@@ -891,7 +1042,25 @@
 	(5490 - 5710 @ 80), (N/A, 27), DFS
 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
- 
+
+country TT:
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
+
+country TW:
+	(2402 - 2472 @ 40), (N/A, 30)
+	(5270 - 5330 @ 40), (6, 17)
+	(5490 - 5590 @ 80), (6, 17), DFS
+	(5650 - 5730 @ 80), (6, 30), DFS
+	(5735 - 5835 @ 80), (6, 30)
+
+country TZ:
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5735 - 5835 @ 80), (N/A, 30)
+
 # Source:
 # #914 / 06 Sep 2007: http://www.ucrf.gov.ua/uk/doc/nkrz/1196068874
 # #1174 / 23 Oct 2008: http://www.nkrz.gov.ua/uk/activities/ruling/1225269361
@@ -900,102 +1069,108 @@
 # rules in the referenced laws. Such a range is used because of
 # disputable definitions there.
 country UA:
-	(2400 - 2483.5 @ 40), (N/A, 20), NO-OUTDOOR
-	(5150 - 5250 @ 40), (N/A, 20), NO-OUTDOOR
-	(5250 - 5350 @ 40), (N/A, 20), NO-OUTDOOR, DFS
-	(5470 - 5670 @ 40), (N/A, 20), DFS
-	(5725 - 5850 @ 40), (N/A, 20)
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 40), (N/A, 20)
+	(5250 - 5330 @ 40), (N/A, 20), DFS
+	(5490 - 5670 @ 40), (N/A, 30), DFS
+	(5735 - 5835 @ 40), (N/A, 30)
 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
 
 country UG:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5150 - 5250 @ 80), (6, 20)
-	(5250 - 5350 @ 80), (6, 20), DFS
-        (5470 - 5725 @ 80), (6, 20), DFS
-        (5725 - 5825 @ 80), (6, 20)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+        (5490 - 5730 @ 80), (6, 24), DFS
+        (5735 - 5835 @ 80), (6, 30)
 
 country US: DFS-FCC
-	(2402 - 2472 @ 40), (3, 27)
-	(5170 - 5250 @ 80), (3, 17)
-	(5250 - 5330 @ 80), (3, 24), DFS
-	(5490 - 5600 @ 80), (3, 24), DFS
-	(5650 - 5730 @ 40), (3, 24), DFS
-	(5735 - 5835 @ 80), (3, 30)
+	(2402 - 2472 @ 40), (N/A, 30)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
 	# 60g band
 	# reference: http://cfr.regstoday.com/47cfr15.aspx#47_CFR_15p255
 	# channels 1,2,3, EIRP=40dBm(43dBm peak)
 	(57240 - 63720 @ 2160), (N/A, 40)
 
-# Public Safety FCCA, FCC4
-#  27dBm [4.9GHz 1/4 rate], 30dBm [1/2 rate], 33dBm [full rate], and 5GHz same as FCC1
-#  db.txt cannot express the limitation on 5G so disable all 5G channels for FCC4
-country PS:
-	(2402 - 2472 @ 40), (N/A, 30)
-	#(4940 - 4990 @ 40), (6, 27)
-	#(5150 - 5250 @ 80), (6, 30)
-	#(5250 - 5350 @ 80), (6, 30), DFS
-	#(5725 - 5850 @ 80), (6, 33)
-
 country UY:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 40), (3, 17)
-	(5250 - 5330 @ 40), (3, 20), DFS
-	(5490 - 5730 @ 40), (3, 20), DFS
-	(5735 - 5835 @ 40), (3, 30)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
 
 country UZ:
-	(2402 - 2472 @ 40), (3, 27)
-	(5170 - 5250 @ 40), (3, 17)
-	(5250 - 5330 @ 40), (3, 20), DFS
-	(5490 - 5730 @ 40), (3, 20), DFS
-	(5735 - 5835 @ 40), (3, 30)
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+
+country VC: DFS-ETSI
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
 
 country VE:
-	(2402 - 2482 @ 40), (N/A, 20)
-      (5150 - 5250 @ 80), (6, 17)
-      (5250 - 5350 @ 80), (6, 23), DFS
-      (5725 - 5850 @ 80), (6, 30)
-
-
-country VN:
-	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 80), (3, 17)
-	(5250 - 5330 @ 80), (3, 24), DFS
-	(5490 - 5730 @ 80), (3, 24), DFS
-	(5735 - 5835 @ 80), (3, 30)
+	(2402 - 2482 @ 40), (N/A, 30)
+	(5170 - 5250 @ 80), (6, 23)
+        (5250 - 5330 @ 80), (6, 23), DFS
+	(5735 - 5835 @ 80), (6, 30)
 
 country VI:
 	(2402 - 2472 @ 40), (N/A, 30)
-	(5150 - 5250 @ 80), (6, 17)
-	(5250 - 5350 @ 80), (6, 24), DFS
-	(5470 - 5725 @ 80), (6, 24), DFS
-	(5725 - 5850 @ 80), (6, 30)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
+
+country VN:
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
+
+country VU:
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+	(5735 - 5835 @ 80), (6, 30)
+
+country WF: DFS-ETSI
+	(2402 - 2482 @ 40), (N/A, 20)
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
 
 country WS: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 20), (3, 17)
-	(5250 - 5330 @ 80), (3, 24), DFS
-	(5490 - 5710 @ 80), (3, 24), DFS
+	(5170 - 5250 @ 40), (N/A, 20)
+	(5250 - 5330 @ 40), (N/A, 20), DFS
+	(5490 - 5710 @ 40), (N/A, 27), DFS
 
 country YE:
 	(2402 - 2482 @ 40), (N/A, 20)
 
 country YT: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
-        (5150 - 5250 @ 80), (N/A, 20)
-        (5250 - 5350 @ 80), (N/A, 20), DFS
-        (5470 - 5725 @ 80), (N/A, 27), DFS
+        (5170 - 5250 @ 80), (N/A, 20)
+        (5250 - 5330 @ 80), (N/A, 20), DFS
+        (5490 - 5710 @ 80), (N/A, 27), DFS
 
 country ZA:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 80), (3, 20)
-	(5250 - 5330 @ 80), (3, 20), DFS
-	(5490 - 5710 @ 80), (3, 27), DFS
+	(5170 - 5250 @ 80), (6, 24)
+	(5250 - 5330 @ 80), (6, 24), DFS
+	(5490 - 5730 @ 80), (6, 24), DFS
+        (5735 - 5835 @ 80), (6, 30)
 
 country ZW:
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5150 - 5250 @ 80), (N/A, 20)
-	(5250 - 5350 @ 80), (N/A, 20), DFS
-	(5470 - 5725 @ 80), (N/A, 27), DFS
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
 
diff --git a/scripts/dtc/libfdt/fdt.c b/scripts/dtc/libfdt/fdt.c
index e56833a..e591c54 100644
--- a/scripts/dtc/libfdt/fdt.c
+++ b/scripts/dtc/libfdt/fdt.c
@@ -71,6 +71,20 @@
 		return -FDT_ERR_BADMAGIC;
 	}
 
+	if (fdt_off_dt_struct(fdt) > (UINT_MAX - fdt_size_dt_struct(fdt)))
+		return FDT_ERR_BADOFFSET;
+
+	if (fdt_off_dt_strings(fdt) > (UINT_MAX -  fdt_size_dt_strings(fdt)))
+		return FDT_ERR_BADOFFSET;
+
+	if ((fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt))
+	    > fdt_totalsize(fdt))
+		return FDT_ERR_BADOFFSET;
+
+	if ((fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt))
+	    > fdt_totalsize(fdt))
+		return FDT_ERR_BADOFFSET;
+
 	return 0;
 }
 
diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c
index 24437df..d7d09fe 100644
--- a/scripts/dtc/libfdt/fdt_rw.c
+++ b/scripts/dtc/libfdt/fdt_rw.c
@@ -394,7 +394,7 @@
 static void _fdt_packblocks(const char *old, char *new,
 			    int mem_rsv_size, int struct_size)
 {
-	int mem_rsv_off, struct_off, strings_off;
+	uint32_t mem_rsv_off, struct_off, strings_off;
 
 	mem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8);
 	struct_off = mem_rsv_off + mem_rsv_size;
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
index f8e9d7a..240ce66 100644
--- a/sound/core/compress_offload.c
+++ b/sound/core/compress_offload.c
@@ -156,9 +156,12 @@
 static int snd_compr_update_tstamp(struct snd_compr_stream *stream,
 		struct snd_compr_tstamp *tstamp)
 {
+	int err = 0;
 	if (!stream->ops->pointer)
 		return -ENOTSUPP;
-	stream->ops->pointer(stream, tstamp);
+	err = stream->ops->pointer(stream, tstamp);
+	if (err)
+		return err;
 	pr_debug("dsp consumed till %d total %d bytes\n",
 		tstamp->byte_offset, tstamp->copied_total);
 	if (stream->direction == SND_COMPRESS_PLAYBACK)
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index f174685..58d377c 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -1216,8 +1216,11 @@
 	list_del_init(&pcm->list);
 	for (cidx = 0; cidx < 2; cidx++)
 		for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
-			if (substream->runtime)
+			if (substream->runtime) {
 				substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED;
+                                wake_up(&substream->runtime->sleep);
+                                wake_up(&substream->runtime->tsleep);
+                        }
 	list_for_each_entry(notify, &snd_pcm_notify_list, list) {
 		notify->n_disconnect(pcm);
 	}
diff --git a/sound/soc/codecs/msm8x10-wcd.c b/sound/soc/codecs/msm8x10-wcd.c
index bbe1ac7..a2f6811 100644
--- a/sound/soc/codecs/msm8x10-wcd.c
+++ b/sound/soc/codecs/msm8x10-wcd.c
@@ -35,10 +35,10 @@
 #include <sound/tlv.h>
 #include <mach/qdsp6v2/apr.h>
 #include <mach/subsystem_notif.h>
+#include <sound/q6core.h>
 #include "msm8x10-wcd.h"
 #include "wcd9xxx-resmgr.h"
 #include "msm8x10_wcd_registers.h"
-#include "../msm/qdsp6v2/q6core.h"
 #include "wcd9xxx-common.h"
 
 #define MSM8X10_WCD_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
diff --git a/sound/soc/codecs/wcd9306.c b/sound/soc/codecs/wcd9306.c
index b35f7fb..b29d81c 100644
--- a/sound/soc/codecs/wcd9306.c
+++ b/sound/soc/codecs/wcd9306.c
@@ -291,6 +291,9 @@
 	u32 anc_slot;
 	bool anc_func;
 
+	/*track adie loopback mode*/
+	bool lb_mode;
+
 	/*track tapan interface type*/
 	u8 intf_type;
 
@@ -306,6 +309,8 @@
 	u8 aux_l_gain;
 	u8 aux_r_gain;
 
+	bool dec_active[NUM_DECIMATORS];
+
 	bool spkr_pa_widget_on;
 
 	struct afe_param_cdc_slimbus_slave_cfg slimbus_slave_cfg;
@@ -512,6 +517,43 @@
 	return 0;
 }
 
+static int tapan_loopback_mode_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
+
+	ucontrol->value.integer.value[0] = tapan->lb_mode;
+	dev_dbg(codec->dev, "%s: lb_mode = %d\n",
+		__func__, tapan->lb_mode);
+
+	return 0;
+}
+
+static int tapan_loopback_mode_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
+
+	dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
+		__func__, ucontrol->value.integer.value[0]);
+
+	switch (ucontrol->value.integer.value[0]) {
+	case 0:
+		tapan->lb_mode = false;
+		break;
+	case 1:
+		tapan->lb_mode = true;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+
 static int tapan_pa_gain_get(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
@@ -1036,6 +1078,13 @@
 	return 0;
 }
 
+static const char * const tapan_loopback_mode_ctrl_text[] = {
+		"DISABLE", "ENABLE"};
+static const struct soc_enum tapan_loopback_mode_ctl_enum[] = {
+		SOC_ENUM_SINGLE_EXT(2, tapan_loopback_mode_ctrl_text),
+};
+
+
 static const char * const tapan_ear_pa_gain_text[] = {"POS_6_DB", "POS_4P5_DB",
 						      "POS_3_DB", "POS_1P5_DB",
 						      "POS_0_DB", "NEG_2P5_DB",
@@ -1112,6 +1161,9 @@
 	SOC_ENUM_EXT("EAR PA Gain", tapan_ear_pa_gain_enum[0],
 		tapan_pa_gain_get, tapan_pa_gain_put),
 
+	SOC_ENUM_EXT("LOOPBACK Mode", tapan_loopback_mode_ctl_enum[0],
+		tapan_loopback_mode_get, tapan_loopback_mode_put),
+
 	SOC_SINGLE_TLV("HPHL Volume", TAPAN_A_RX_HPH_L_GAIN, 0, 20, 1,
 		line_gain),
 	SOC_SINGLE_TLV("HPHR Volume", TAPAN_A_RX_HPH_R_GAIN, 0, 20, 1,
@@ -1959,7 +2011,7 @@
 				1 << init_bit_shift);
 		break;
 	case SND_SOC_DAPM_POST_PMU:
-
+		usleep_range(2000, 2010);
 		snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift, 0x00);
 
 		break;
@@ -2398,6 +2450,7 @@
 	dev_dbg(codec->dev, "%s(): decimator %u hpf_cut_of_freq 0x%x\n",
 		 __func__, hpf_work->decimator, (unsigned int)hpf_cut_of_freq);
 
+	snd_soc_update_bits(codec, TAPAN_A_TX_1_2_TXFE_CLKDIV, 0x55, 0x55);
 	snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30, hpf_cut_of_freq << 4);
 }
 
@@ -2411,10 +2464,11 @@
 {
 	struct snd_soc_codec *codec = w->codec;
 	unsigned int decimator;
+	struct tapan_priv *tapan_p = snd_soc_codec_get_drvdata(codec);
 	char *dec_name = NULL;
 	char *widget_name = NULL;
 	char *temp;
-	int ret = 0;
+	int ret = 0, i;
 	u16 dec_reset_reg, tx_vol_ctl_reg, tx_mux_ctl_reg;
 	u8 dec_hpf_cut_of_freq;
 	int offset;
@@ -2466,6 +2520,10 @@
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
+		for (i = 0; i < NUM_DECIMATORS; i++) {
+			if (decimator == i + 1)
+				tapan_p->dec_active[i] = true;
+		}
 
 		/* Enableable TX digital mute */
 		snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
@@ -2490,13 +2548,17 @@
 
 		/* enable HPF */
 		snd_soc_update_bits(codec, tx_mux_ctl_reg , 0x08, 0x00);
-
+		snd_soc_update_bits(codec, TAPAN_A_TX_1_2_TXFE_CLKDIV,
+				0x55, 0x44);
 		break;
 
 	case SND_SOC_DAPM_POST_PMU:
 
-		/* Disable TX digital mute */
-		snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00);
+		if (tapan_p->lb_mode) {
+			pr_debug("%s: loopback mode unmute the DEC\n",
+							__func__);
+			snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00);
+		}
 
 		if (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq !=
 				CF_MIN_3DB_150HZ) {
@@ -2525,7 +2587,10 @@
 		snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x08);
 		snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30,
 			(tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq) << 4);
-
+		for (i = 0; i < NUM_DECIMATORS; i++) {
+			if (decimator == i + 1)
+				tapan_p->dec_active[i] = false;
+		}
 		break;
 	}
 out:
@@ -4026,6 +4091,53 @@
 	return 0;
 }
 
+int tapan_digital_mute(struct snd_soc_dai *dai, int mute)
+{
+	struct snd_soc_codec *codec = NULL;
+	u16 tx_vol_ctl_reg = 0;
+	u8 decimator = 0, i;
+	struct tapan_priv *tapan_p;
+
+	pr_debug("%s: Digital Mute val = %d\n", __func__, mute);
+
+	if (!dai || !dai->codec) {
+		pr_err("%s: Invalid params\n", __func__);
+		return -EINVAL;
+	}
+	codec = dai->codec;
+	tapan_p = snd_soc_codec_get_drvdata(codec);
+
+	if (dai->id != AIF1_CAP) {
+		dev_dbg(codec->dev, "%s: Not capture use case skip\n",
+		__func__);
+		return 0;
+	}
+
+	mute = (mute) ? 1 : 0;
+	if (!mute) {
+		/*
+		 * 5 ms is an emperical value for the mute time
+		 * that was arrived by checking the pop level
+		 * to be inaudible
+		 */
+		usleep_range(5000, 5010);
+	}
+
+	for (i = 0; i < NUM_DECIMATORS; i++) {
+		if (tapan_p->dec_active[i])
+			decimator = i + 1;
+		if (decimator && decimator <= NUM_DECIMATORS) {
+			pr_debug("%s: Mute = %d Decimator = %d", __func__,
+					mute, decimator);
+			tx_vol_ctl_reg = TAPAN_A_CDC_TX1_VOL_CTL_CFG +
+				8 * (decimator - 1);
+			snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, mute);
+		}
+		decimator = 0;
+	}
+	return 0;
+}
+
 static struct snd_soc_dai_ops tapan_dai_ops = {
 	.startup = tapan_startup,
 	.shutdown = tapan_shutdown,
@@ -4034,6 +4146,7 @@
 	.set_fmt = tapan_set_dai_fmt,
 	.set_channel_map = tapan_set_channel_map,
 	.get_channel_map = tapan_get_channel_map,
+	.digital_mute = tapan_digital_mute,
 };
 
 static struct snd_soc_dai_driver tapan9302_dai[] = {
@@ -6223,6 +6336,7 @@
 	tapan->aux_r_gain = 0x1F;
 	tapan->ldo_h_users = 0;
 	tapan->micb_2_users = 0;
+	tapan->lb_mode = false;
 	tapan_update_reg_defaults(codec);
 	tapan_update_reg_mclk_rate(wcd9xxx);
 	tapan_codec_init_reg(codec);
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index 4b8d5bd..1dfd72b 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -6946,6 +6946,18 @@
 
 	mutex_lock(&codec->mutex);
 
+        if (codec->reg_def_copy) {
+            pr_debug("%s: Update ASOC cache", __func__);
+            kfree(codec->reg_cache);
+            codec->reg_cache = kmemdup(codec->reg_def_copy,
+                                            codec->reg_size, GFP_KERNEL);
+            if (!codec->reg_cache) {
+                pr_err("%s: Cache update failed!\n", __func__);
+                mutex_unlock(&codec->mutex);
+                return -ENOMEM;
+            }
+        }
+
 	taiko_update_reg_defaults(codec);
 	if (wcd9xxx->mclk_rate == TAIKO_MCLK_CLK_12P288MHZ)
 		snd_soc_update_bits(codec, TAIKO_A_CHIP_CTL, 0x06, 0x0);
diff --git a/sound/soc/msm/apq8074.c b/sound/soc/msm/apq8074.c
index 3a143aa..f997e44 100644
--- a/sound/soc/msm/apq8074.c
+++ b/sound/soc/msm/apq8074.c
@@ -26,13 +26,13 @@
 #include <sound/pcm.h>
 #include <sound/jack.h>
 #include <sound/q6afe-v2.h>
+#include <sound/q6core.h>
 #include <sound/pcm_params.h>
 #include <asm/mach-types.h>
 #include <mach/subsystem_notif.h>
 #include <mach/socinfo.h>
 
 #include "qdsp6v2/msm-pcm-routing-v2.h"
-#include "qdsp6v2/q6core.h"
 #include "../codecs/wcd9xxx-common.h"
 #include "../codecs/wcd9320.h"
 
diff --git a/sound/soc/msm/msm8226.c b/sound/soc/msm/msm8226.c
index cc27fc0..bf33208 100644
--- a/sound/soc/msm/msm8226.c
+++ b/sound/soc/msm/msm8226.c
@@ -27,8 +27,9 @@
 #include <asm/mach-types.h>
 #include <mach/socinfo.h>
 #include <mach/subsystem_notif.h>
+#include <sound/q6core.h>
+
 #include <qdsp6v2/msm-pcm-routing-v2.h>
-#include "qdsp6v2/q6core.h"
 #include "../codecs/wcd9xxx-common.h"
 #include "../codecs/wcd9306.h"
 
@@ -58,7 +59,7 @@
 #define LO_1_SPK_AMP   0x1
 #define LO_2_SPK_AMP   0x2
 
-#define ADSP_STATE_READY_TIMEOUT_MS 3000
+#define ADSP_STATE_READY_TIMEOUT_MS 50
 
 static void *adsp_state_notifier;
 
diff --git a/sound/soc/msm/msm8974.c b/sound/soc/msm/msm8974.c
index 23ed60a..c74f8dc 100644
--- a/sound/soc/msm/msm8974.c
+++ b/sound/soc/msm/msm8974.c
@@ -26,11 +26,11 @@
 #include <sound/pcm.h>
 #include <sound/jack.h>
 #include <sound/q6afe-v2.h>
+#include <sound/q6core.h>
 #include <sound/pcm_params.h>
 #include <asm/mach-types.h>
 #include <mach/subsystem_notif.h>
 #include "qdsp6v2/msm-pcm-routing-v2.h"
-#include "qdsp6v2/q6core.h"
 #include "../codecs/wcd9xxx-common.h"
 #include "../codecs/wcd9320.h"
 
@@ -80,7 +80,7 @@
 
 static void *adsp_state_notifier;
 
-#define ADSP_STATE_READY_TIMEOUT_MS 3000
+#define ADSP_STATE_READY_TIMEOUT_MS 50
 
 static inline int param_is_mask(int p)
 {
diff --git a/sound/soc/msm/qdsp6v2/audio_ocmem.c b/sound/soc/msm/qdsp6v2/audio_ocmem.c
index 5be880d..8432067 100644
--- a/sound/soc/msm/qdsp6v2/audio_ocmem.c
+++ b/sound/soc/msm/qdsp6v2/audio_ocmem.c
@@ -31,7 +31,7 @@
 #include <mach/subsystem_restart.h>
 #include <mach/msm_memtypes.h>
 #include <mach/ramdump.h>
-#include "q6core.h"
+#include <sound/q6core.h>
 #include "audio_ocmem.h"
 
 
diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
index 3bc6abe..4ca5764 100644
--- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
@@ -480,6 +480,7 @@
 		snd_compr_fragment_elapsed(cstream);
 		prtd->copied_total = prtd->bytes_received;
 		atomic_set(&prtd->error, 1);
+		wake_up(&prtd->drain_wait);
 		spin_unlock(&prtd->lock);
 		break;
 	default:
@@ -931,14 +932,19 @@
 	rc = wait_event_interruptible(prtd->drain_wait,
 					prtd->drain_ready ||
 					prtd->cmd_interrupt ||
-					atomic_read(&prtd->xrun));
-	pr_debug("%s: out of buffer drain wait\n", __func__);
+					atomic_read(&prtd->xrun) ||
+					atomic_read(&prtd->error));
+	pr_debug("%s: out of buffer drain wait with ret %d\n", __func__, rc);
 	spin_lock_irqsave(&prtd->lock, *flags);
 	if (prtd->cmd_interrupt) {
 		pr_debug("%s: buffer drain interrupted by flush)\n", __func__);
 		rc = -EINTR;
 		prtd->cmd_interrupt = 0;
 	}
+	if (atomic_read(&prtd->error)) {
+		pr_err("%s: Got RESET EVENTS notification, return\n", __func__);
+		rc = -ENETRESET;
+	}
 	return rc;
 }
 
@@ -1404,13 +1410,12 @@
 	tstamp.byte_offset = prtd->byte_offset;
 	tstamp.copied_total = prtd->copied_total;
 	first_buffer = prtd->first_buffer;
-
 	if (atomic_read(&prtd->error)) {
 		pr_err("%s Got RESET EVENTS notification, return error", __func__);
 		tstamp.pcm_io_frames = 0;
 		memcpy(arg, &tstamp, sizeof(struct snd_compr_tstamp));
 		spin_unlock_irqrestore(&prtd->lock, flags);
-		return -EINVAL;
+		return -ENETRESET;
 	}
 
 	spin_unlock_irqrestore(&prtd->lock, flags);
@@ -1424,7 +1429,10 @@
 		if (rc < 0) {
 			pr_err("%s: Get Session Time return value =%lld\n",
 				__func__, timestamp);
-			return -EAGAIN;
+			if (atomic_read(&prtd->error))
+				return -ENETRESET;
+			else
+				return -EAGAIN;
 		}
 	} else {
 		timestamp = prtd->marker_timestamp;
@@ -1507,7 +1515,7 @@
 	if (atomic_read(&prtd->error)) {
 		pr_err("%s Got RESET EVENTS notification", __func__);
 		spin_unlock_irqrestore(&prtd->lock, flags);
-		return -EINVAL;
+		return -ENETRESET;
 	}
 	spin_unlock_irqrestore(&prtd->lock, flags);
 
diff --git a/sound/soc/msm/qdsp6v2/msm-multi-ch-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-multi-ch-pcm-q6-v2.c
index 39e6934..2fb2a00 100644
--- a/sound/soc/msm/qdsp6v2/msm-multi-ch-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-multi-ch-pcm-q6-v2.c
@@ -28,6 +28,7 @@
 #include <sound/pcm.h>
 #include <sound/initval.h>
 #include <sound/control.h>
+#include <sound/timer.h>
 
 #include "msm-pcm-q6-v2.h"
 #include "msm-pcm-routing-v2.h"
@@ -199,6 +200,18 @@
 		}
 	}
 	break;
+	case RESET_EVENTS:
+		pr_debug("%s RESET_EVENTS\n", __func__);
+		atomic_inc(&prtd->out_count);
+		prtd->reset_event = true;
+		if (atomic_read(&prtd->start))
+			snd_pcm_period_elapsed(substream);
+		else if (substream->timer_running)
+			snd_timer_interrupt(substream->timer, 1);
+		wake_up(&the_locks.eos_wait);
+		wake_up(&the_locks.write_wait);
+		wake_up(&the_locks.read_wait);
+		break;
 	default:
 		pr_debug("Not Supported Event opcode[0x%x]\n", opcode);
 		break;
@@ -453,12 +466,22 @@
 	fbytes = frames_to_bytes(runtime, frames);
 	pr_debug("%s: prtd->out_count = %d\n",
 				__func__, atomic_read(&prtd->out_count));
+	if (prtd->reset_event == true) {
+		pr_err("%s: In SSR return ENETRESET before wait\n", __func__);
+		return -ENETRESET;
+	}
+
 	ret = wait_event_timeout(the_locks.write_wait,
 			(atomic_read(&prtd->out_count)), 5 * HZ);
 	if (!ret) {
 		pr_err("%s: wait_event_timeout failed\n", __func__);
 		goto fail;
 	}
+	if (prtd->reset_event == true) {
+		pr_err("%s: In SSR return ENETRESET after wait\n", __func__);
+		return -ENETRESET;
+	}
+
 
 	if (!atomic_read(&prtd->out_count)) {
 		pr_err("%s: pcm stopped out_count 0\n", __func__);
@@ -547,12 +570,22 @@
 	pr_debug("hw_ptr %d\n", (int)runtime->status->hw_ptr);
 	pr_debug("avail_min %d\n", (int)runtime->control->avail_min);
 
+	if (prtd->reset_event == true) {
+		pr_err("%s: In SSR return ENETRESET before wait\n", __func__);
+		return -ENETRESET;
+	}
+
 	ret = wait_event_timeout(the_locks.read_wait,
 			(atomic_read(&prtd->in_count)), 5 * HZ);
 	if (!ret) {
 		pr_debug("%s: wait_event_timeout failed\n", __func__);
 		goto fail;
 	}
+	if (prtd->reset_event == true) {
+		pr_err("%s: In SSR return ENETRESET after wait\n", __func__);
+		return -ENETRESET;
+	}
+
 	if (!atomic_read(&prtd->in_count)) {
 		pr_debug("%s: pcm stopped in_count 0\n", __func__);
 		return 0;
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
index d80ca19..e2e488f 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
@@ -35,12 +35,12 @@
 
 #define MIN_PLAYBACK_PERIOD_SIZE (128 * 2)
 #define MAX_PLAYBACK_PERIOD_SIZE (128 * 2 * 2 * 6)
-#define MIN_PLAYBACK_NUM_PERIODS (64)
+#define MIN_PLAYBACK_NUM_PERIODS (4)
 #define MAX_PLAYBACK_NUM_PERIODS (768)
 
 #define MIN_CAPTURE_PERIOD_SIZE (128 * 2 * 4)
 #define MAX_CAPTURE_PERIOD_SIZE (128 * 2 * 2 * 6 * 4)
-#define MIN_CAPTURE_NUM_PERIODS (32)
+#define MIN_CAPTURE_NUM_PERIODS (4)
 #define MAX_CAPTURE_NUM_PERIODS (384)
 
 static struct snd_pcm_hardware msm_afe_hardware_playback = {
@@ -58,7 +58,7 @@
 	.channels_min =         1,
 	.channels_max =         6,
 	.buffer_bytes_max =     MAX_PLAYBACK_PERIOD_SIZE *
-				MIN_PLAYBACK_NUM_PERIODS,
+				MAX_PLAYBACK_NUM_PERIODS,
 	.period_bytes_min =     MIN_PLAYBACK_PERIOD_SIZE,
 	.period_bytes_max =     MAX_PLAYBACK_PERIOD_SIZE,
 	.periods_min =          MIN_PLAYBACK_NUM_PERIODS,
@@ -81,7 +81,7 @@
 	.channels_min =         1,
 	.channels_max =         6,
 	.buffer_bytes_max =     MAX_CAPTURE_PERIOD_SIZE *
-				MIN_CAPTURE_NUM_PERIODS,
+				MAX_CAPTURE_NUM_PERIODS,
 	.period_bytes_min =     MIN_CAPTURE_PERIOD_SIZE,
 	.period_bytes_max =     MAX_CAPTURE_PERIOD_SIZE,
 	.periods_min =          MIN_CAPTURE_NUM_PERIODS,
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
index b49ce46..7d36fff 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
@@ -26,6 +26,7 @@
 #include <sound/initval.h>
 #include <sound/control.h>
 #include <sound/q6audio-v2.h>
+#include <sound/timer.h>
 #include <asm/dma.h>
 #include <linux/dma-mapping.h>
 #include <linux/msm_audio_ion.h>
@@ -240,6 +241,18 @@
 		}
 	}
 	break;
+	case RESET_EVENTS:
+		pr_err("%s RESET_EVENTS\n", __func__);
+		prtd->pcm_irq_pos += prtd->pcm_count;
+		atomic_inc(&prtd->out_count);
+		atomic_inc(&prtd->in_count);
+		prtd->reset_event = true;
+		if (atomic_read(&prtd->start))
+			snd_pcm_period_elapsed(substream);
+		wake_up(&the_locks.eos_wait);
+		wake_up(&the_locks.write_wait);
+		wake_up(&the_locks.read_wait);
+		break;
 	default:
 		pr_debug("Not Supported Event opcode[0x%x]\n", opcode);
 		break;
@@ -450,6 +463,7 @@
 
 	prtd->dsp_cnt = 0;
 	prtd->set_channel_map = false;
+	prtd->reset_event = false;
 	runtime->private_data = prtd;
 
 	return 0;
@@ -472,6 +486,12 @@
 	fbytes = frames_to_bytes(runtime, frames);
 	pr_debug("%s: prtd->out_count = %d\n",
 				__func__, atomic_read(&prtd->out_count));
+
+	if (prtd->reset_event) {
+		pr_err("%s: In SSR return ENETRESET before wait\n", __func__);
+		return -ENETRESET;
+	}
+
 	ret = wait_event_timeout(the_locks.write_wait,
 			(atomic_read(&prtd->out_count)), 5 * HZ);
 	if (!ret) {
@@ -479,6 +499,11 @@
 		goto fail;
 	}
 
+	if (prtd->reset_event) {
+		pr_err("%s: In SSR return ENETRESET after wait\n", __func__);
+		return -ENETRESET;
+	}
+
 	if (!atomic_read(&prtd->out_count)) {
 		pr_err("%s: pcm stopped out_count 0\n", __func__);
 		return 0;
@@ -569,12 +594,20 @@
 	pr_debug("hw_ptr %d\n", (int)runtime->status->hw_ptr);
 	pr_debug("avail_min %d\n", (int)runtime->control->avail_min);
 
+	if (prtd->reset_event) {
+		pr_err("%s: In SSR return ENETRESET before wait\n", __func__);
+		return -ENETRESET;
+	}
 	ret = wait_event_timeout(the_locks.read_wait,
 			(atomic_read(&prtd->in_count)), 5 * HZ);
 	if (!ret) {
 		pr_debug("%s: wait_event_timeout failed\n", __func__);
 		goto fail;
 	}
+	if (prtd->reset_event) {
+		pr_err("%s: In SSR return ENETRESET after wait\n", __func__);
+		return -ENETRESET;
+	}
 	if (!atomic_read(&prtd->in_count)) {
 		pr_debug("%s: pcm stopped in_count 0\n", __func__);
 		return 0;
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h
index 5d5c995..da2a919 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h
@@ -69,6 +69,7 @@
 
 	int abort; /* set when error, like sample rate mismatch */
 
+        bool reset_event;
 	int enabled;
 	int close_ack;
 	int cmd_ack;
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index e973d10..c8ff41d 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -30,12 +30,12 @@
 #include <sound/tlv.h>
 #include <sound/asound.h>
 #include <sound/pcm_params.h>
+#include <sound/q6core.h>
 #include <linux/slab.h>
 
 #include "msm-pcm-routing-v2.h"
 #include "msm-dolby-dap-config.h"
 #include "q6voice.h"
-#include "q6core.h"
 
 struct msm_pcm_routing_bdai_data {
 	u16 port_id; /* AFE port ID */
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c
index 6b32064..4fe2459 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c
@@ -144,6 +144,7 @@
 	spinlock_t dsp_lock;
 	spinlock_t dsp_ul_lock;
 
+	bool voip_reset;
 	uint32_t mode;
 	uint32_t rate_type;
 	uint32_t rate;
@@ -317,6 +318,34 @@
 /* sample rate supported */
 static unsigned int supported_sample_rates[] = {8000, 16000};
 
+static void voip_ssr_cb_fn(uint32_t opcode, void *private_data)
+{
+
+	/* Notify ASoC to send next playback/Capture to unblock write/read */
+	struct voip_drv_info *prtd = private_data;
+
+	if (opcode == 0xFFFFFFFF) {
+
+		prtd->voip_reset = true;
+		pr_debug("%s: Notify ASoC to send next playback/Capture\n",
+			__func__);
+
+		prtd->pcm_playback_irq_pos += prtd->pcm_count;
+		if (prtd->state == VOIP_STARTED)
+			snd_pcm_period_elapsed(prtd->playback_substream);
+		wake_up(&prtd->out_wait);
+
+		prtd->pcm_capture_irq_pos += prtd->pcm_capture_count;
+		if (prtd->state == VOIP_STARTED)
+			snd_pcm_period_elapsed(prtd->capture_substream);
+		wake_up(&prtd->in_wait);
+
+	} else {
+		pr_err("%s: Invalid opcode during reset : %d\n",
+			__func__, opcode);
+	}
+}
+
 /* capture path */
 static void voip_process_ul_pkt(uint8_t *voc_pkt,
 				uint32_t pkt_len,
@@ -754,10 +783,20 @@
 	int count = frames_to_bytes(runtime, frames);
 	pr_debug("%s: count = %d, frames=%d\n", __func__, count, (int)frames);
 
+	if (prtd->voip_reset) {
+		pr_debug("%s: RESET event happened during VoIP\n", __func__);
+		return -ENETRESET;
+	}
+
 	ret = wait_event_interruptible_timeout(prtd->in_wait,
 				(!list_empty(&prtd->free_in_queue) ||
 				prtd->state == VOIP_STOPPED),
 				1 * HZ);
+	if (prtd->voip_reset) {
+		pr_debug("%s: RESET event happened during VoIP\n", __func__);
+		return -ENETRESET;
+	}
+
 	if (ret > 0) {
 		if (count <= VOIP_MAX_VOC_PKT_SIZE) {
 			spin_lock_irqsave(&prtd->dsp_lock, dsp_flags);
@@ -807,11 +846,21 @@
 
 	pr_debug("%s: count = %d\n", __func__, count);
 
+	if (prtd->voip_reset) {
+		pr_debug("%s: RESET event happened during VoIP\n", __func__);
+		return -ENETRESET;
+	}
+
 	ret = wait_event_interruptible_timeout(prtd->out_wait,
 				(!list_empty(&prtd->out_queue) ||
 				prtd->state == VOIP_STOPPED),
 				1 * HZ);
 
+	if (prtd->voip_reset) {
+		pr_debug("%s: RESET event happened during VoIP\n", __func__);
+		return -ENETRESET;
+	}
+
 	if (ret > 0) {
 
 		if (count <= VOIP_MAX_VOC_PKT_SIZE) {
@@ -842,7 +891,6 @@
 			list_add_tail(&buf_node->list,
 						&prtd->free_out_queue);
 			spin_unlock_irqrestore(&prtd->dsp_ul_lock, dsp_flags);
-
 		} else {
 			pr_err("%s: Read count %d > VOIP_MAX_VOC_PKT_SIZE\n",
 				__func__, count);
@@ -902,10 +950,11 @@
 
 	if (!prtd->playback_instance && !prtd->capture_instance) {
 		if (prtd->state == VOIP_STARTED) {
+			prtd->voip_reset = false;
 			prtd->state = VOIP_STOPPED;
 			voc_end_voice_call(
 					voc_get_session_id(VOIP_SESSION_NAME));
-			voc_register_mvs_cb(NULL, NULL, prtd);
+			voc_register_mvs_cb(NULL, NULL, NULL, prtd);
 		}
 		/* release all buffer */
 		/* release in_queue and free_in_queue */
@@ -1131,8 +1180,10 @@
 			goto done;
 		}
 
+		/* Initialaizing cb variables */
 		voc_register_mvs_cb(voip_process_ul_pkt,
-				    voip_process_dl_pkt, prtd);
+				    voip_process_dl_pkt,
+				    voip_ssr_cb_fn, prtd);
 
 		ret = voc_start_voice_call(
 				voc_get_session_id(VOIP_SESSION_NAME));
diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c
index a7a5d1e..f619b67 100644
--- a/sound/soc/msm/qdsp6v2/q6afe.c
+++ b/sound/soc/msm/qdsp6v2/q6afe.c
@@ -53,6 +53,7 @@
 	u16 dtmf_gen_rx_portid;
 	struct afe_spkr_prot_calib_get_resp calib_data;
 	int vi_tx_port;
+	int vi_rx_port;
 	uint32_t afe_sample_rates[AFE_MAX_PORTS];
 	struct aanc_data aanc_info;
 };
@@ -500,7 +501,7 @@
 	return result;
 }
 
-static int afe_spk_prot_prepare(int port, int param_id,
+static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id,
 		union afe_spkr_prot_config *prot_config)
 {
 	int ret = -EINVAL;
@@ -512,17 +513,28 @@
 		pr_err("%s Invalid params\n", __func__);
 		goto fail_cmd;
 	}
-	if ((q6audio_validate_port(port) < 0)) {
-		pr_err("%s invalid port %d", __func__, port);
+	ret = q6audio_validate_port(src_port);
+	if (ret < 0) {
+		pr_err("%s: Invalid src port 0x%x ret %d",
+				__func__, src_port, ret);
+		ret = -EINVAL;
 		goto fail_cmd;
 	}
-	index = q6audio_get_port_index(port);
+	ret = q6audio_validate_port(dst_port);
+	if (ret < 0) {
+		pr_err("%s: Invalid dst port 0x%x ret %d", __func__,
+				dst_port, ret);
+		ret = -EINVAL;
+		goto fail_cmd;
+	}
+	index = q6audio_get_port_index(src_port);
 	switch (param_id) {
 	case AFE_PARAM_ID_FBSP_MODE_RX_CFG:
 		config.pdata.module_id = AFE_MODULE_FB_SPKR_PROT_RX;
 		break;
 	case AFE_PARAM_ID_FEEDBACK_PATH_CFG:
-		this_afe.vi_tx_port = port;
+		this_afe.vi_tx_port = src_port;
+		this_afe.vi_rx_port = dst_port;
 	case AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG:
 	case AFE_PARAM_ID_MODE_VI_PROC_CFG:
 		config.pdata.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC;
@@ -540,7 +552,7 @@
 	config.hdr.token = index;
 
 	config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
-	config.param.port_id = q6audio_get_port_id(port);
+	config.param.port_id = q6audio_get_port_id(src_port);
 	config.param.payload_size = sizeof(config) - sizeof(config.hdr)
 		- sizeof(config.param);
 	config.pdata.param_id = param_id;
@@ -549,8 +561,8 @@
 	atomic_set(&this_afe.state, 1);
 	ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config);
 	if (ret < 0) {
-		pr_err("%s: Setting param for port %d param[0x%x]failed\n",
-		 __func__, port, param_id);
+		pr_err("%s: port = 0x%x param = 0x%x failed %d\n",
+		__func__, src_port, param_id, ret);
 		goto fail_cmd;
 	}
 	ret = wait_event_timeout(this_afe.wait[index],
@@ -568,8 +580,8 @@
 	}
 	ret = 0;
 fail_cmd:
-	pr_debug("%s config.pdata.param_id %x status %d\n",
-	__func__, config.pdata.param_id, ret);
+	pr_debug("%s: config.pdata.param_id 0x%x status %d 0x%x\n",
+	__func__, config.pdata.param_id, ret, src_port);
 	return ret;
 }
 
@@ -590,7 +602,7 @@
 		else
 			afe_spk_config.mode_rx_cfg.mode =
 			Q6AFE_MSM_SPKR_PROCESSING;
-		if (afe_spk_prot_prepare(port_id,
+		if (afe_spk_prot_prepare(port_id, 0,
 			AFE_PARAM_ID_MODE_VI_PROC_CFG,
 			&afe_spk_config))
 			pr_err("%s TX VI_PROC_CFG failed\n", __func__);
@@ -600,7 +612,7 @@
 			(uint32_t) prot_cfg.r0;
 			afe_spk_config.vi_proc_cfg.t0_cali_q6 =
 			(uint32_t) prot_cfg.t0;
-			if (afe_spk_prot_prepare(port_id,
+			if (afe_spk_prot_prepare(port_id, 0,
 				AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG,
 				&afe_spk_config))
 				pr_err("%s SPKR_CALIB_VI_PROC_CFG failed\n",
@@ -617,7 +629,8 @@
 	/*Get spkr protection cfg data*/
 	get_spk_protection_cfg(&prot_cfg);
 
-	if (prot_cfg.mode != MSM_SPKR_PROT_DISABLED) {
+	if ((prot_cfg.mode != MSM_SPKR_PROT_DISABLED) &&
+		(this_afe.vi_rx_port == port_id)) {
 		if (prot_cfg.mode == MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS)
 			afe_spk_config.mode_rx_cfg.mode =
 			Q6AFE_MSM_SPKR_CALIBRATION;
@@ -625,7 +638,7 @@
 			afe_spk_config.mode_rx_cfg.mode =
 			Q6AFE_MSM_SPKR_PROCESSING;
 		afe_spk_config.mode_rx_cfg.minor_version = 1;
-		if (afe_spk_prot_prepare(port_id,
+		if (afe_spk_prot_prepare(port_id, 0,
 			AFE_PARAM_ID_FBSP_MODE_RX_CFG,
 			&afe_spk_config))
 			pr_err("%s RX MODE_VI_PROC_CFG failed\n",
@@ -701,7 +714,7 @@
 
 void afe_send_cal(u16 port_id)
 {
-	pr_debug("%s\n", __func__);
+	pr_debug("%s: port_id=0x%x\n", __func__, port_id);
 
 	if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_TX) {
 		afe_send_cal_spkr_prot_tx(port_id);
@@ -1488,6 +1501,7 @@
 	case SLIMBUS_2_RX: return IDX_SLIMBUS_2_RX;
 	case SLIMBUS_2_TX: return IDX_SLIMBUS_2_TX;
 	case SLIMBUS_3_RX: return IDX_SLIMBUS_3_RX;
+	case SLIMBUS_3_TX: return IDX_SLIMBUS_3_TX;
 	case INT_BT_SCO_RX: return IDX_INT_BT_SCO_RX;
 	case INT_BT_SCO_TX: return IDX_INT_BT_SCO_TX;
 	case INT_BT_A2DP_RX: return IDX_INT_BT_A2DP_RX;
@@ -3220,6 +3234,7 @@
 	if (!enable) {
 		pr_debug("%s Disable Feedback tx path", __func__);
 		this_afe.vi_tx_port = -1;
+		this_afe.vi_rx_port = -1;
 		return 0;
 	}
 
@@ -3248,7 +3263,7 @@
 	}
 	prot_config.feedback_path_cfg.num_channels = index;
 	prot_config.feedback_path_cfg.minor_version = 1;
-	ret = afe_spk_prot_prepare(src_port,
+	ret = afe_spk_prot_prepare(src_port, dst_port,
 			AFE_PARAM_ID_FEEDBACK_PATH_CFG, &prot_config);
 fail_cmd:
 	return ret;
@@ -3264,6 +3279,7 @@
 	this_afe.dtmf_gen_rx_portid = -1;
 	this_afe.mmap_handle = 0;
 	this_afe.vi_tx_port = -1;
+	this_afe.vi_rx_port = -1;
 	for (i = 0; i < AFE_MAX_PORTS; i++)
 		init_waitqueue_head(&this_afe.wait[i]);
 
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 9a3cb87..6796378 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -676,7 +676,7 @@
 
 		while (cnt >= 0) {
 			if (port->buf[cnt].data) {
-				if (!rc)
+				if (!rc || atomic_read(&ac->reset))
 					msm_audio_ion_free(
 						port->buf[cnt].client,
 						port->buf[cnt].handle);
@@ -726,7 +726,7 @@
 			(void *)&port->buf[0].phys,
 			(void *)port->buf[0].client,
 			(void *)port->buf[0].handle);
-		if (!rc)
+		if (!rc || atomic_read(&ac->reset))
 			msm_audio_ion_free(port->buf[0].client,
 					   port->buf[0].handle);
 		port->buf[0].client = NULL;
@@ -886,6 +886,7 @@
 	init_waitqueue_head(&ac->time_wait);
 	init_waitqueue_head(&ac->mem_wait);
 	atomic_set(&ac->time_flag, 1);
+	atomic_set(&ac->reset, 0);
 	INIT_LIST_HEAD(&ac->port[0].mem_map_handle);
 	INIT_LIST_HEAD(&ac->port[1].mem_map_handle);
 	pr_debug("%s: mem_map_handle list init'ed\n", __func__);
@@ -1124,11 +1125,7 @@
 	payload = data->payload;
 
 	if (data->opcode == RESET_EVENTS) {
-		struct audio_client *ac_mmap = (struct audio_client *)priv;
-		if (ac_mmap == NULL) {
-			pr_err("%s ac or priv NULL\n", __func__);
-			return -EINVAL;
-		}
+
 		pr_debug("%s: Reset event is received: %d %d apr[%p]\n",
 				__func__,
 				data->reset_event,
@@ -1137,7 +1134,6 @@
 		atomic_set(&this_mmap.ref_cnt, 0);
 		apr_reset(this_mmap.apr);
 		this_mmap.apr = NULL;
-		ac_mmap->mmap_apr = NULL;
 		for (; i <= OUT; i++) {
 			list_for_each_safe(ptr, next,
 				&common_client.port[i].mem_map_handle) {
@@ -1287,16 +1283,20 @@
 	}
 
 	if (data->opcode == RESET_EVENTS) {
-		if(ac->apr == NULL) {
-		    ac->apr = ac->apr2;
-		}
+		atomic_set(&ac->reset, 1);
+		if (ac->apr == NULL)
+			ac->apr = ac->apr2;
 		pr_debug("q6asm_callback: Reset event is received: %d %d apr[%p]\n",
 				data->reset_event, data->reset_proc, ac->apr);
-			if (ac->cb)
-				ac->cb(data->opcode, data->token,
-					(uint32_t *)data->payload, ac->priv);
+		if (ac->cb)
+			ac->cb(data->opcode, data->token,
+				(uint32_t *)data->payload, ac->priv);
 		apr_reset(ac->apr);
 		ac->apr = NULL;
+		atomic_set(&ac->time_flag, 0);
+		atomic_set(&ac->cmd_state, 0);
+		wake_up(&ac->time_wait);
+		wake_up(&ac->cmd_wait);
 		return 0;
 	}
 
diff --git a/sound/soc/msm/qdsp6v2/q6core.c b/sound/soc/msm/qdsp6v2/q6core.c
index 496a5ef..ba237c1 100644
--- a/sound/soc/msm/qdsp6v2/q6core.c
+++ b/sound/soc/msm/qdsp6v2/q6core.c
@@ -20,10 +20,11 @@
 #include <linux/slab.h>
 #include <mach/msm_smd.h>
 #include <mach/qdsp6v2/apr.h>
-#include "q6core.h"
 #include <mach/ocmem.h>
+#include <sound/q6core.h>
 
 #define TIMEOUT_MS 1000
+#define Q6_READY_TIMEOUT_MS 100
 
 struct q6core_str {
 	struct apr_svc *core_handle_q;
@@ -237,7 +238,7 @@
 
 	rc = wait_event_timeout(q6core_lcl.bus_bw_req_wait,
 				(q6core_lcl.bus_bw_resp_received == 1),
-				msecs_to_jiffies(TIMEOUT_MS));
+				msecs_to_jiffies(Q6_READY_TIMEOUT_MS));
 	if (rc > 0 && q6core_lcl.bus_bw_resp_received) {
 		/* ensure to read updated param by callback thread */
 		rmb();
diff --git a/sound/soc/msm/qdsp6v2/q6lsm.c b/sound/soc/msm/qdsp6v2/q6lsm.c
index 61222fe..051c4c2 100644
--- a/sound/soc/msm/qdsp6v2/q6lsm.c
+++ b/sound/soc/msm/qdsp6v2/q6lsm.c
@@ -26,12 +26,12 @@
 #include <linux/atomic.h>
 #include <sound/apr_audio-v2.h>
 #include <sound/lsm_params.h>
+#include <sound/q6core.h>
 #include <sound/q6lsm.h>
 #include <asm/ioctls.h>
 #include <mach/memory.h>
 #include <mach/debug_mm.h>
 #include "audio_acdb.h"
-#include "q6core.h"
 
 #define APR_TIMEOUT	(5 * HZ)
 #define LSM_CAL_SIZE	4096
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index 475a0eb..b165664 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -5206,10 +5206,12 @@
 
 void voc_register_mvs_cb(ul_cb_fn ul_cb,
 			   dl_cb_fn dl_cb,
+			   voip_ssr_cb ssr_cb,
 			   void *private_data)
 {
 	common.mvs_info.ul_cb = ul_cb;
 	common.mvs_info.dl_cb = dl_cb;
+	common.mvs_info.ssr_cb = ssr_cb;
 	common.mvs_info.private_data = private_data;
 }
 
@@ -5260,6 +5262,14 @@
 		} else {
 			pr_debug("%s: Reset event received in Voice service\n",
 				__func__);
+
+			if (common.mvs_info.ssr_cb) {
+				pr_debug("%s: Informing reset event to VoIP\n",
+					__func__);
+				common.mvs_info.ssr_cb(data->opcode,
+						common.mvs_info.private_data);
+			}
+
 			apr_reset(c->apr_q6_mvm);
 			c->apr_q6_mvm = NULL;
 
diff --git a/sound/soc/msm/qdsp6v2/q6voice.h b/sound/soc/msm/qdsp6v2/q6voice.h
index c6f3482..58cdfc3 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.h
+++ b/sound/soc/msm/qdsp6v2/q6voice.h
@@ -1226,6 +1226,9 @@
 				  char *session,
 				  void *private_data);
 
+typedef void (*voip_ssr_cb) (uint32_t opcode,
+				void *private_data);
+
 struct mvs_driver_info {
 	uint32_t media_type;
 	uint32_t rate;
@@ -1233,6 +1236,7 @@
 	uint32_t dtx_mode;
 	ul_cb_fn ul_cb;
 	dl_cb_fn dl_cb;
+	voip_ssr_cb ssr_cb;
 	void *private_data;
 	uint32_t evrc_min_rate;
 	uint32_t evrc_max_rate;
@@ -1365,6 +1369,7 @@
 
 void voc_register_mvs_cb(ul_cb_fn ul_cb,
 			dl_cb_fn dl_cb,
+			voip_ssr_cb ssr_cb,
 			void *private_data);
 
 void voc_register_dtmf_rx_detection_cb(dtmf_rx_det_cb_fn dtmf_rx_ul_cb,
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index 4792719..fb4eed1 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -599,14 +599,15 @@
 {
 	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
 	struct snd_soc_platform *platform = rtd->platform;
+	int ret = 0;
 
 	mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
 
 	if (platform->driver->compr_ops && platform->driver->compr_ops->pointer)
-		 platform->driver->compr_ops->pointer(cstream, tstamp);
+		ret = platform->driver->compr_ops->pointer(cstream, tstamp);
 
 	mutex_unlock(&rtd->pcm_mutex);
-	return 0;
+	return ret;
 }
 
 static int soc_compr_copy(struct snd_compr_stream *cstream,
diff --git a/sound/usb/card.c b/sound/usb/card.c
index d419e2f..69c9ebc 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -48,7 +48,6 @@
 #include <linux/usb/audio.h>
 #include <linux/usb/audio-v2.h>
 #include <linux/module.h>
-#include <linux/switch.h>
 
 #include <sound/control.h>
 #include <sound/core.h>
@@ -87,7 +86,6 @@
 static bool async_unlink = 1;
 static int device_setup[SNDRV_CARDS]; /* device parameter for this card */
 static bool ignore_ctl_error;
-struct switch_dev *usbaudiosdev;
 
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for the USB audio adapter.");
@@ -277,7 +275,6 @@
 		break;
 	}
 	}
-	switch_set_state(usbaudiosdev, 1);
 	return 0;
 }
 
@@ -595,7 +592,6 @@
 		mutex_unlock(&chip->shutdown_mutex);
 		mutex_unlock(&register_mutex);
 	}
-	switch_set_state(usbaudiosdev, 0);
 }
 
 /*
@@ -728,32 +724,17 @@
 
 static int __init snd_usb_audio_init(void)
 {
-	int err;
 	if (nrpacks < 1 || nrpacks > MAX_PACKS) {
 		printk(KERN_WARNING "invalid nrpacks value.\n");
 		return -EINVAL;
 	}
 
-	usbaudiosdev = kzalloc(sizeof(*usbaudiosdev), GFP_KERNEL);
-	if (!usbaudiosdev) {
-		pr_err("Usb audio device memory allocation failed.\n");
-		return -ENOMEM;
-	}
-
-	usbaudiosdev->name = "usb_audio";
-
-	err = switch_dev_register(usbaudiosdev);
-	if (err)
-		pr_err("Usb-audio switch registration failed\n");
-	else
-		pr_debug("usb hs_detected\n");
 	return usb_register(&usb_audio_driver);
 }
 
 static void __exit snd_usb_audio_cleanup(void)
 {
 	usb_deregister(&usb_audio_driver);
-	kfree(usbaudiosdev);
 }
 
 module_init(snd_usb_audio_init);