Merge "msm: Add RPM stats read support for 8960." into msm-3.0
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index f379b04..2f8bf62 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -348,8 +348,8 @@
  *  r13 = *virtual* address to jump to upon completion
  */
 __enable_mmu:
-#ifdef CONFIG_ALIGNMENT_TRAP
-	orr	r0, r0, #CR_A
+#if defined(CONFIG_ALIGNMENT_TRAP) && __LINUX_ARM_ARCH__ < 6
+      orr     r0, r0, #CR_A
 #else
 	bic	r0, r0, #CR_A
 #endif
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index 0cd8a6e..d82a6bf 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -948,16 +948,10 @@
 
 static void vote_dfab(void)
 {
-	int rc;
-
-	rc = clk_enable(dfab_clk);
-	if (rc)
-		pr_err("bam_dmux vote for dfab failed rc = %d\n", rc);
 }
 
 static void unvote_dfab(void)
 {
-	clk_disable(dfab_clk);
 }
 
 static int restart_notifier_cb(struct notifier_block *this,
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index 1b6497d..1c91d94 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -24,6 +24,7 @@
 #include <mach/board.h>
 #include <media/msm_camera.h>
 #include <mach/msm_subsystem_map.h>
+#include <linux/ion.h>
 
 #define CONFIG_MSM_CAMERA_DEBUG
 #ifdef CONFIG_MSM_CAMERA_DEBUG
@@ -474,6 +475,7 @@
 	struct msm_pmem_info info;
 	struct msm_mapped_buffer *msm_buffer;
 	int subsys_id;
+	struct ion_handle *handle;
 };
 
 struct axidata {
diff --git a/arch/arm/mach-msm/include/mach/msm_smsm.h b/arch/arm/mach-msm/include/mach/msm_smsm.h
index 4641479..0c2cd4b 100644
--- a/arch/arm/mach-msm/include/mach/msm_smsm.h
+++ b/arch/arm/mach-msm/include/mach/msm_smsm.h
@@ -82,6 +82,8 @@
 #define SMSM_WKUP_REASON_TIMER	0x00000008
 #define SMSM_WKUP_REASON_ALARM	0x00000010
 #define SMSM_WKUP_REASON_RESET	0x00000020
+#define SMSM_A2_FORCE_SHUTDOWN 0x00002000
+#define SMSM_A2_RESET_BAM      0x00004000
 
 #define SMSM_VENDOR             0x00020000
 
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h b/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h
index fb6e22e..1f8ce68 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h
@@ -523,6 +523,10 @@
 /* Media types */
 #define VSS_MEDIA_ID_EVRC_MODEM		0x00010FC2
 /* 80-VF690-47 CDMA enhanced variable rate vocoder modem format. */
+#define VSS_MEDIA_ID_4GV_NB_MODEM  0x00010FC3
+/* 4GV Narrowband modem format */
+#define VSS_MEDIA_ID_4GV_WB_MODEM  0x00010FC4
+/* 4GV Wideband modem format */
 #define VSS_MEDIA_ID_AMR_NB_MODEM	0x00010FC6
 /* 80-VF690-47 UMTS AMR-NB vocoder modem format. */
 #define VSS_MEDIA_ID_AMR_WB_MODEM	0x00010FC7
@@ -652,12 +656,17 @@
 			 uint32_t *pkt_len,
 			 void *private_data);
 
+struct q_min_max_rate {
+	uint32_t min_rate;
+	uint32_t max_rate;
+};
 
 struct mvs_driver_info {
 	uint32_t media_type;
 	uint32_t rate;
 	uint32_t network_type;
 	uint32_t dtx_mode;
+	struct q_min_max_rate q_min_max_rate;
 	ul_cb_fn ul_cb;
 	dl_cb_fn dl_cb;
 	void *private_data;
@@ -750,7 +759,8 @@
 void voice_config_vocoder(uint32_t media_type,
 			  uint32_t rate,
 			  uint32_t network_type,
-			  uint32_t dtx_mode);
+			  uint32_t dtx_mode,
+			  struct q_min_max_rate q_min_max_rate);
 
 int voice_start_record(uint32_t rec_mode, uint32_t set);
 
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_mvs.c b/arch/arm/mach-msm/qdsp6v2/audio_mvs.c
index 2dae9a8..0b4997c 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_mvs.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_mvs.c
@@ -38,7 +38,7 @@
 
 struct audio_mvs_buf_node {
 	struct list_head list;
-	struct msm_audio_mvs_frame frame;
+	struct q6_msm_audio_mvs_frame frame;
 };
 
 struct audio_mvs_info_type {
@@ -47,6 +47,7 @@
 	uint32_t mvs_mode;
 	uint32_t rate_type;
 	uint32_t dtx_mode;
+	struct q_min_max_rate min_max_rate;
 
 	struct list_head in_queue;
 	struct list_head free_in_queue;
@@ -110,7 +111,8 @@
 			 * Bits 0-3: Frame rate
 			 * Bits 4-7: Frame type
 			 */
-			buf_node->frame.frame_type = ((*voc_pkt) & 0xF0) >> 4;
+			buf_node->frame.header.frame_type =
+						((*voc_pkt) & 0xF0) >> 4;
 			voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 			buf_node->frame.len = pkt_len - DSP_FRAME_HDR_LEN;
@@ -124,7 +126,7 @@
 		}
 
 		case MVS_MODE_IS127: {
-			buf_node->frame.frame_type = 0;
+			buf_node->frame.header.packet_rate = (*voc_pkt) & 0x0F;
 			voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 			buf_node->frame.len = pkt_len - DSP_FRAME_HDR_LEN;
@@ -147,7 +149,7 @@
 			 * Header format:
 			 * Bits 0-1: Frame type
 			 */
-			buf_node->frame.frame_type = (*voc_pkt) & 0x03;
+			buf_node->frame.header.frame_type = (*voc_pkt) & 0x03;
 			voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 			/* There are two frames in the buffer. Length of the
@@ -177,7 +179,8 @@
 				 * Header format:
 				 * Bits 0-1: Frame type
 				 */
-				buf_node->frame.frame_type = (*voc_pkt) & 0x03;
+				buf_node->frame.header.frame_type =
+							(*voc_pkt) & 0x03;
 				voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 				/* There are two frames in the buffer. Length
@@ -213,7 +216,7 @@
 			 * Bits 0-1: Frame type
 			 * Bits 2-3: Frame rate
 			 */
-			buf_node->frame.frame_type = (*voc_pkt) & 0x03;
+			buf_node->frame.header.frame_type = (*voc_pkt) & 0x03;
 			voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 			/* There are two frames in the buffer. Length of the
@@ -244,7 +247,8 @@
 				 * Bits 0-1: Frame type
 				 * Bits 2-3: Frame rate
 				 */
-				buf_node->frame.frame_type = (*voc_pkt) & 0x03;
+				buf_node->frame.header.frame_type =
+							(*voc_pkt) & 0x03;
 				voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 				/* There are two frames in the buffer. Length
@@ -267,8 +271,25 @@
 			break;
 		}
 
+		case MVS_MODE_4GV_NB:
+		case MVS_MODE_4GV_WB: {
+			/* Remove the DSP frame info header.
+			 * Header format:
+			 * Bits 0-3: frame rate
+			 */
+			buf_node->frame.header.packet_rate = (*voc_pkt) & 0x0F;
+			voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
+			buf_node->frame.len = pkt_len - DSP_FRAME_HDR_LEN;
+
+			memcpy(&buf_node->frame.voc_pkt[0],
+				voc_pkt,
+				buf_node->frame.len);
+			list_add_tail(&buf_node->list, &audio->out_queue);
+			break;
+		}
+
 		default: {
-			buf_node->frame.frame_type = 0;
+			buf_node->frame.header.frame_type = 0;
 
 			buf_node->frame.len = pkt_len;
 
@@ -314,8 +335,9 @@
 			 * Bits 0-3: Frame rate
 			 * Bits 4-7: Frame type
 			 */
-			*voc_pkt = ((buf_node->frame.frame_type & 0x0F) << 4) |
-				   (rate_type & 0x0F);
+			*voc_pkt =
+			    ((buf_node->frame.header.frame_type & 0x0F) << 4) |
+			    (rate_type & 0x0F);
 			voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 			*pkt_len = buf_node->frame.len + DSP_FRAME_HDR_LEN;
@@ -333,7 +355,7 @@
 			 * Bits 0-3: Frame rate
 			 * Bits 4-7: Frame type
 			 */
-			*voc_pkt = rate_type & 0x0F;
+			*voc_pkt = buf_node->frame.header.packet_rate & 0x0F;
 			voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 			*pkt_len = buf_node->frame.len + DSP_FRAME_HDR_LEN;
@@ -353,7 +375,7 @@
 			/* Add the first DSP frame info header. Header format:
 			 * Bits 0-1: Frame type
 			 */
-			*voc_pkt = buf_node->frame.frame_type & 0x03;
+			*voc_pkt = buf_node->frame.header.frame_type & 0x03;
 			voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 			*pkt_len = buf_node->frame.len + DSP_FRAME_HDR_LEN;
@@ -376,7 +398,8 @@
 				 * Header format:
 				 * Bits 0-1: Frame type
 				 */
-				*voc_pkt = buf_node->frame.frame_type & 0x03;
+				*voc_pkt = buf_node->frame.header.frame_type
+						& 0x03;
 				voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 				*pkt_len = *pkt_len +
@@ -409,7 +432,7 @@
 			 * Bits 2-3: Frame rate
 			 */
 			*voc_pkt = ((rate_type & 0x0F) << 2) |
-				   (buf_node->frame.frame_type & 0x03);
+				   (buf_node->frame.header.frame_type & 0x03);
 			voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 			*pkt_len = buf_node->frame.len + DSP_FRAME_HDR_LEN;
@@ -434,7 +457,7 @@
 				 * Bits 2-3: Frame rate
 				 */
 				*voc_pkt = ((rate_type & 0x0F) << 2) |
-					   (buf_node->frame.frame_type & 0x03);
+				     (buf_node->frame.header.frame_type & 0x03);
 				voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 				*pkt_len = *pkt_len +
@@ -458,6 +481,23 @@
 			break;
 		}
 
+		case MVS_MODE_4GV_NB:
+		case MVS_MODE_4GV_WB: {
+			/* Add the DSP frame info header. Header format:
+			 * Bits 0-3 : Frame rate
+			*/
+			*voc_pkt = buf_node->frame.header.packet_rate & 0x0F;
+			voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
+			*pkt_len = buf_node->frame.len + DSP_FRAME_HDR_LEN;
+
+			memcpy(voc_pkt,
+				&buf_node->frame.voc_pkt[0],
+				buf_node->frame.len);
+
+			list_add_tail(&buf_node->list, &audio->free_in_queue);
+			break;
+		}
+
 		default: {
 			*pkt_len = buf_node->frame.len;
 
@@ -487,6 +527,14 @@
 		media_type = VSS_MEDIA_ID_EVRC_MODEM;
 		break;
 
+	case MVS_MODE_4GV_NB:
+		media_type = VSS_MEDIA_ID_4GV_NB_MODEM;
+		break;
+
+	case MVS_MODE_4GV_WB:
+		media_type = VSS_MEDIA_ID_4GV_WB_MODEM;
+		break;
+
 	case MVS_MODE_AMR:
 		media_type = VSS_MEDIA_ID_AMR_NB_MODEM;
 		break;
@@ -533,6 +581,7 @@
 
 	switch (mvs_mode) {
 	case MVS_MODE_IS127:
+	case MVS_MODE_4GV_NB:
 	case MVS_MODE_AMR:
 	case MVS_MODE_LINEAR_PCM:
 	case MVS_MODE_PCM:
@@ -541,6 +590,7 @@
 		network_type = VSS_NETWORK_ID_VOIP_NB;
 		break;
 
+	case MVS_MODE_4GV_WB:
 	case MVS_MODE_AMR_WB:
 	case MVS_MODE_PCM_WB:
 		network_type = VSS_NETWORK_ID_VOIP_WB;
@@ -576,7 +626,8 @@
 		    audio_mvs_get_media_type(audio->mvs_mode, audio->rate_type),
 		    audio_mvs_get_rate(audio->mvs_mode, audio->rate_type),
 		    audio_mvs_get_network_type(audio->mvs_mode),
-		    audio->dtx_mode);
+		    audio->dtx_mode,
+		    audio->min_max_rate);
 
 		audio->state = AUDIO_MVS_STARTED;
 	} else {
@@ -729,7 +780,7 @@
 		if ((audio->state == AUDIO_MVS_STARTED) &&
 		    (!list_empty(&audio->out_queue))) {
 
-			if (count >= sizeof(struct msm_audio_mvs_frame)) {
+			if (count >= sizeof(struct q6_msm_audio_mvs_frame)) {
 				buf_node = list_first_entry(&audio->out_queue,
 						struct audio_mvs_buf_node,
 						list);
@@ -737,11 +788,11 @@
 
 				rc = copy_to_user(buf,
 					&buf_node->frame,
-					sizeof(struct msm_audio_mvs_frame));
+					sizeof(struct q6_msm_audio_mvs_frame));
 
 				if (rc == 0) {
 					rc = buf_node->frame.len +
-					    sizeof(buf_node->frame.frame_type) +
+					    sizeof(buf_node->frame.header) +
 					    sizeof(buf_node->frame.len);
 				} else {
 					pr_err("%s: Copy to user retuned %d",
@@ -755,7 +806,7 @@
 			} else {
 				pr_err("%s: Read count %d < sizeof(frame) %d",
 				       __func__, count,
-				       sizeof(struct msm_audio_mvs_frame));
+				       sizeof(struct q6_msm_audio_mvs_frame));
 
 				rc = -ENOMEM;
 			}
@@ -799,7 +850,7 @@
 		mutex_lock(&audio->in_lock);
 
 		if (audio->state == AUDIO_MVS_STARTED) {
-			if (count <= sizeof(struct msm_audio_mvs_frame)) {
+			if (count <= sizeof(struct q6_msm_audio_mvs_frame)) {
 				if (!list_empty(&audio->free_in_queue)) {
 					buf_node =
 					list_first_entry(&audio->free_in_queue,
@@ -818,7 +869,7 @@
 			} else {
 				pr_err("%s: Write count %d < sizeof(frame) %d",
 				       __func__, count,
-				       sizeof(struct msm_audio_mvs_frame));
+				       sizeof(struct q6_msm_audio_mvs_frame));
 
 				rc = -ENOMEM;
 			}
@@ -863,7 +914,8 @@
 		config.mvs_mode = audio->mvs_mode;
 		config.rate_type = audio->rate_type;
 		config.dtx_mode = audio->dtx_mode;
-
+		config.min_max_rate.min_rate = audio->min_max_rate.min_rate;
+		config.min_max_rate.max_rate = audio->min_max_rate.max_rate;
 		mutex_unlock(&audio->lock);
 
 		rc = copy_to_user((void *)arg, &config, sizeof(config));
@@ -888,6 +940,10 @@
 				audio->mvs_mode = config.mvs_mode;
 				audio->rate_type = config.rate_type;
 				audio->dtx_mode = config.dtx_mode;
+				audio->min_max_rate.min_rate =
+						config.min_max_rate.min_rate;
+				audio->min_max_rate.max_rate =
+						config.min_max_rate.max_rate;
 			} else {
 				pr_err("%s: Set confg called in state %d\n",
 				       __func__, audio->state);
diff --git a/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c b/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
index cd1fe4c..28e2962 100644
--- a/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
+++ b/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
@@ -28,7 +28,7 @@
 #include <sound/dai.h>
 #include "q6core.h"
 
-#define DMA_ALLOC_BUF_SZ		(SZ_4K * 6)
+#define DMA_ALLOC_BUF_SZ		(SZ_4K * 16)
 
 #define HDMI_AUDIO_FIFO_WATER_MARK	4
 
@@ -191,7 +191,7 @@
 			pr_debug("%s:failed to copy from user\n", __func__);
 			rc = -EFAULT;
 		}
-		if (lpa_if->dma_period_sz > DMA_ALLOC_BUF_SZ) {
+		if ((lpa_if->dma_period_sz * 2) > DMA_ALLOC_BUF_SZ) {
 			pr_err("Dma buffer size greater than allocated size\n");
 			return -EINVAL;
 		}
diff --git a/arch/arm/mach-msm/qdsp6v2/q6voice.c b/arch/arm/mach-msm/qdsp6v2/q6voice.c
index 7472849..1ab615a 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6voice.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6voice.c
@@ -1117,10 +1117,12 @@
 
 	/* Set encoder properties. */
 	switch (common.mvs_info.media_type) {
+	case VSS_MEDIA_ID_4GV_NB_MODEM:
+	case VSS_MEDIA_ID_4GV_WB_MODEM:
 	case VSS_MEDIA_ID_EVRC_MODEM: {
 		struct cvs_set_cdma_enc_minmax_rate_cmd cvs_set_cdma_rate;
 
-		pr_info("%s: Setting EVRC min-max rate\n", __func__);
+		pr_info("%s: Setting CDMA min-max rate\n", __func__);
 
 		cvs_set_cdma_rate.hdr.hdr_field =
 				APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
@@ -1133,14 +1135,16 @@
 		cvs_set_cdma_rate.hdr.token = 0;
 		cvs_set_cdma_rate.hdr.opcode =
 				VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE;
-		cvs_set_cdma_rate.cdma_rate.min_rate = common.mvs_info.rate;
-		cvs_set_cdma_rate.cdma_rate.max_rate = common.mvs_info.rate;
+		cvs_set_cdma_rate.cdma_rate.min_rate =
+				common.mvs_info.q_min_max_rate.min_rate;
+		cvs_set_cdma_rate.cdma_rate.max_rate =
+				common.mvs_info.q_min_max_rate.max_rate;
 
 		v->cvs_state = CMD_STATUS_FAIL;
 
 		ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_cdma_rate);
 		if (ret < 0) {
-			pr_err("%s: Error %d sending SET_EVRC_MINMAX_RATE\n",
+			pr_err("%s: Error %d sending CDMA_SET_ENC_MINMAX_RATE\n",
 			       __func__, ret);
 
 			goto done;
@@ -1156,6 +1160,10 @@
 			goto done;
 		}
 
+		if ((common.mvs_info.media_type == VSS_MEDIA_ID_4GV_NB_MODEM) ||
+		(common.mvs_info.media_type == VSS_MEDIA_ID_4GV_WB_MODEM))
+			ret = voice_set_dtx(v);
+
 		break;
 	}
 
@@ -2472,12 +2480,14 @@
 void voice_config_vocoder(uint32_t media_type,
 			  uint32_t rate,
 			  uint32_t network_type,
-			  uint32_t dtx_mode)
+			  uint32_t dtx_mode,
+			  struct q_min_max_rate q_min_max_rate)
 {
 	common.mvs_info.media_type = media_type;
 	common.mvs_info.rate = rate;
 	common.mvs_info.network_type = network_type;
 	common.mvs_info.dtx_mode = dtx_mode;
+	common.mvs_info.q_min_max_rate = q_min_max_rate;
 }
 
 static int32_t modem_mvm_callback(struct apr_client_data *data, void *priv)
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index d9488ec..febf77f 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -1015,6 +1015,7 @@
 	} else {
 		WARN_ON("Timer running on unknown hardware. Configure this! "
 			"Assuming default configuration.\n");
+		global_timer_offset = MSM_TMR0_BASE - MSM_TMR_BASE;
 		dgt->freq = 6750000;
 	}
 
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index 40a273a..4b4d235 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -1427,7 +1427,9 @@
 			mutex_unlock(&pcam->vid_lock);
 			return rc;
 		}
-
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+		pcam->mctl.client = msm_ion_client_create(-1, "camera");
+#endif
 		/* Should be set to sensor ops if any but right now its OK!! */
 		if (!pcam->mctl.mctl_open) {
 			D("%s: media contoller is not inited\n",
@@ -1603,7 +1605,9 @@
 			if (rc < 0)
 				pr_err("mctl_release fails %d\n", rc);
 		}
-
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+		ion_client_destroy(pcam->mctl.client);
+#endif
 		dma_release_declared_memory(&pcam->pdev->dev);
 	}
 	mutex_unlock(&pcam->vid_lock);
@@ -1903,13 +1907,13 @@
 	case MSM_CAM_IOCTL_REGISTER_PMEM:
 		return msm_register_pmem(
 			&config_cam->p_mctl->sync.pmem_stats,
-			(void __user *)arg);
+			(void __user *)arg, config_cam->p_mctl->client);
 		break;
 
 	case MSM_CAM_IOCTL_UNREGISTER_PMEM:
 		return msm_pmem_table_del(
 			&config_cam->p_mctl->sync.pmem_stats,
-			(void __user *)arg);
+			(void __user *)arg, config_cam->p_mctl->client);
 		break;
 	case VIDIOC_SUBSCRIBE_EVENT:
 		if (copy_from_user(&temp_sub,
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index 083fc57..f9cf5de 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -31,6 +31,7 @@
 #include <media/msm_isp.h>
 #include <mach/camera.h>
 #include <media/msm_isp.h>
+#include <linux/ion.h>
 
 #define MSM_V4L2_DIMENSION_SIZE 96
 #define MAX_DEV_NAME_LEN 50
@@ -219,6 +220,7 @@
 
 	struct pm_qos_request_list pm_qos_req_list;
 	struct msm_mctl_pp_info pp_info;
+	struct ion_client *client;
 };
 
 /* abstract camera device represents a VFE and connected sensor */
@@ -402,8 +404,10 @@
 int msm_mctl_release_free_buf(struct msm_cam_media_controller *pmctl,
 				int path, struct msm_free_buf *free_buf);
 /*Memory(PMEM) functions*/
-int msm_register_pmem(struct hlist_head *ptype, void __user *arg);
-int msm_pmem_table_del(struct hlist_head *ptype, void __user *arg);
+int msm_register_pmem(struct hlist_head *ptype, void __user *arg,
+				struct ion_client *client);
+int msm_pmem_table_del(struct hlist_head *ptype, void __user *arg,
+				struct ion_client *client);
 int msm_pmem_region_get_phy_addr(struct hlist_head *ptype,
 	struct msm_mem_map_info *mem_map, int32_t *phyaddr);
 uint8_t msm_pmem_region_lookup(struct hlist_head *ptype,
diff --git a/drivers/media/video/msm/msm_mctl_buf.c b/drivers/media/video/msm/msm_mctl_buf.c
index 1bbb029..f7e5479 100644
--- a/drivers/media/video/msm/msm_mctl_buf.c
+++ b/drivers/media/video/msm/msm_mctl_buf.c
@@ -115,7 +115,7 @@
 			rc = videobuf2_pmem_contig_user_get(mem, &offset,
 				buf_type,
 				pcam_inst->buf_offset[buf_idx][i].addr_offset,
-				pcam_inst->path);
+				pcam_inst->path, pcam->mctl.client);
 		else
 			rc = videobuf2_pmem_contig_mmap_get(mem, &offset,
 				buf_type, pcam_inst->path);
@@ -241,7 +241,7 @@
 	}
 	for (i = 0; i < vb->num_planes; i++) {
 		mem = vb2_plane_cookie(vb, i);
-		videobuf2_pmem_contig_user_put(mem);
+		videobuf2_pmem_contig_user_put(mem, pcam->mctl.client);
 	}
 	buf->state = MSM_BUFFER_STATE_UNUSED;
 }
diff --git a/drivers/media/video/msm/msm_mem.c b/drivers/media/video/msm/msm_mem.c
index 5c64e01..b6dbe87 100644
--- a/drivers/media/video/msm/msm_mem.c
+++ b/drivers/media/video/msm/msm_mem.c
@@ -124,49 +124,57 @@
 }
 
 static int msm_pmem_table_add(struct hlist_head *ptype,
-	struct msm_pmem_info *info)
+	struct msm_pmem_info *info, struct ion_client *client)
 {
-	struct file *file;
 	unsigned long paddr;
 	unsigned int flags;
-#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 	unsigned long kvstart;
-	int rc;
+	struct file *file;
 #endif
+	int rc = -ENOMEM;
+
 	unsigned long len;
 	struct msm_pmem_region *region;
-#ifdef CONFIG_ANDROID_PMEM
+
+	region = kmalloc(sizeof(struct msm_pmem_region), GFP_KERNEL);
+	if (!region)
+		goto out;
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	region->handle = ion_import_fd(client, info->fd);
+	if (IS_ERR_OR_NULL(region->handle))
+		goto OUT1;
+	ion_phys(client, region->handle, &paddr, (size_t *)&len);
+#elif CONFIG_ANDROID_PMEM
 	rc = get_pmem_file(info->fd, &paddr, &kvstart, &len, &file);
 	if (rc < 0) {
 		pr_err("%s: get_pmem_file fd %d error %d\n",
-						__func__,
-						info->fd, rc);
-		return rc;
+				__func__, info->fd, rc);
+		goto out1;
 	}
-	if (!info->len)
-		info->len = len;
-
-	rc = check_pmem_info(info, len);
-	if (rc < 0)
-		return rc;
+	region->file = file;
 #else
 	paddr = 0;
 	file = NULL;
+	kvstart = 0;
 #endif
+	if (!info->len)
+		info->len = len;
+	rc = check_pmem_info(info, len);
+	if (rc < 0)
+		goto out2;
 	paddr += info->offset;
 	len = info->len;
 
-	if (check_overlap(ptype, paddr, len) < 0)
-		return -EINVAL;
+	if (check_overlap(ptype, paddr, len) < 0) {
+		rc = -EINVAL;
+		goto out2;
+	}
 
 	CDBG("%s: type %d, active flag %d, paddr 0x%lx, vaddr 0x%lx\n",
 		__func__, info->type, info->active, paddr,
 		(unsigned long)info->vaddr);
 
-	region = kmalloc(sizeof(struct msm_pmem_region), GFP_KERNEL);
-	if (!region)
-		return -ENOMEM;
-
 	INIT_HLIST_NODE(&region->list);
 	flags = MSM_SUBSYSTEM_MAP_IOVA;
 	region->subsys_id = MSM_SUBSYSTEM_CAMERA;
@@ -174,13 +182,12 @@
 					flags, &(region->subsys_id), 1);
 	if (IS_ERR((void *)region->msm_buffer)) {
 		pr_err("%s: msm_subsystem_map_buffer failed\n", __func__);
-		kfree(region);
-		put_pmem_file(file);
-		return PTR_ERR((void *)region->msm_buffer);
+		rc = PTR_ERR((void *)region->msm_buffer);
+		goto out2;
 	}
-	region->paddr = region->msm_buffer->iova[0];
+	paddr = region->msm_buffer->iova[0];
+	region->paddr = paddr;
 	region->len = len;
-	region->file = file;
 	memcpy(&region->info, info, sizeof(region->info));
 	D("%s Adding region to list with type %d\n", __func__,
 						region->info.type);
@@ -188,10 +195,20 @@
 	hlist_add_head(&(region->list), ptype);
 
 	return 0;
+out2:
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	ion_free(client, region->handle);
+#elif CONFIG_ANDROID_PMEM
+	put_pmem_file(region->file);
+#endif
+out1:
+	kfree(region);
+out:
+	return rc;
 }
 
 static int __msm_register_pmem(struct hlist_head *ptype,
-			struct msm_pmem_info *pinfo)
+			struct msm_pmem_info *pinfo, struct ion_client *client)
 {
 	int rc = 0;
 
@@ -203,7 +220,7 @@
 	case MSM_PMEM_CS:
 	case MSM_PMEM_IHIST:
 	case MSM_PMEM_SKIN:
-		rc = msm_pmem_table_add(ptype, pinfo);
+		rc = msm_pmem_table_add(ptype, pinfo, client);
 		break;
 
 	default:
@@ -215,7 +232,7 @@
 }
 
 static int __msm_pmem_table_del(struct hlist_head *ptype,
-			struct msm_pmem_info *pinfo)
+			struct msm_pmem_info *pinfo, struct ion_client *client)
 {
 	int rc = 0;
 	struct msm_pmem_region *region;
@@ -235,16 +252,16 @@
 			if (pinfo->type == region->info.type &&
 				pinfo->vaddr == region->info.vaddr &&
 				pinfo->fd == region->info.fd) {
+				hlist_del(node);
 				if (msm_subsystem_unmap_buffer
 					(region->msm_buffer) < 0)
 					pr_err(
 					"%s: unmapped stat memory\n",
-					__func__);
-				hlist_del(node);
-#ifdef CONFIG_ANDROID_PMEM
-				put_pmem_file(region->file);
+				__func__);
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+				ion_free(client, region->handle);
 #else
-
+				put_pmem_file(region->file);
 #endif
 				kfree(region);
 			}
@@ -381,7 +398,8 @@
 	return 0;
 }
 
-int msm_register_pmem(struct hlist_head *ptype, void __user *arg)
+int msm_register_pmem(struct hlist_head *ptype, void __user *arg,
+					  struct ion_client *client)
 {
 	struct msm_pmem_info info;
 
@@ -390,11 +408,12 @@
 			return -EFAULT;
 	}
 
-	return __msm_register_pmem(ptype, &info);
+	return __msm_register_pmem(ptype, &info, client);
 }
 EXPORT_SYMBOL(msm_register_pmem);
 
-int msm_pmem_table_del(struct hlist_head *ptype, void __user *arg)
+int msm_pmem_table_del(struct hlist_head *ptype, void __user *arg,
+					   struct ion_client *client)
 {
 	struct msm_pmem_info info;
 
@@ -403,6 +422,6 @@
 		return -EFAULT;
 	}
 
-	return __msm_pmem_table_del(ptype, &info);
+	return __msm_pmem_table_del(ptype, &info, client);
 }
 EXPORT_SYMBOL(msm_pmem_table_del);
diff --git a/drivers/media/video/videobuf2-msm-mem.c b/drivers/media/video/videobuf2-msm-mem.c
index d765244..fa7e3fd 100644
--- a/drivers/media/video/videobuf2-msm-mem.c
+++ b/drivers/media/video/videobuf2-msm-mem.c
@@ -151,16 +151,27 @@
 int videobuf2_pmem_contig_user_get(struct videobuf2_contig_pmem *mem,
 					struct videobuf2_msm_offset *offset,
 					enum videobuf2_buffer_type buffer_type,
-					uint32_t addr_offset, int path)
+					uint32_t addr_offset, int path,
+					struct ion_client *client)
 {
-	unsigned long kvstart;
 	unsigned long len;
-	int rc;
+	int rc = 0;
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
+	unsigned long kvstart;
+#endif
 	unsigned int flags = 0;
-
+	unsigned long paddr = 0;
 	if (mem->phyaddr != 0)
 		return 0;
-
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	mem->ion_handle = ion_import_fd(client, (int)mem->vaddr);
+	if (IS_ERR_OR_NULL(mem->ion_handle)) {
+		pr_err("%s ION import failed\n", __func__);
+		return PTR_ERR(mem->ion_handle);
+	}
+	rc = ion_phys(client, mem->ion_handle, (ion_phys_addr_t *)&mem->phyaddr,
+			 (size_t *)&len);
+#elif CONFIG_ANDROID_PMEM
 	rc = get_pmem_file((int)mem->vaddr, (unsigned long *)&mem->phyaddr,
 					&kvstart, &len, &mem->file);
 	if (rc < 0) {
@@ -168,32 +179,48 @@
 					__func__, (int)mem->vaddr, rc);
 		return rc;
 	}
+#else
+	paddr = 0;
+	kvstart = 0;
+#endif
 	if (offset)
 		mem->offset = *offset;
 	else
 		memset(&mem->offset, 0, sizeof(struct videobuf2_msm_offset));
 	mem->path = path;
 	mem->buffer_type = buffer_type;
+	paddr = mem->phyaddr;
 	flags = MSM_SUBSYSTEM_MAP_IOVA;
 	mem->subsys_id = MSM_SUBSYSTEM_CAMERA;
 	mem->msm_buffer = msm_subsystem_map_buffer(mem->phyaddr, len,
 					flags, &(mem->subsys_id), 1);
 	if (IS_ERR((void *)mem->msm_buffer)) {
 		pr_err("%s: msm_subsystem_map_buffer failed\n", __func__);
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+		ion_free(client, mem->ion_handle);
+#elif CONFIG_ANDROID_PMEM
 		put_pmem_file(mem->file);
+#endif
 		return PTR_ERR((void *)mem->msm_buffer);
 	}
-	mem->mapped_phyaddr = mem->msm_buffer->iova[0] + addr_offset;
+	paddr = mem->msm_buffer->iova[0];
+	mem->mapped_phyaddr = paddr + addr_offset;
 	return rc;
 }
 EXPORT_SYMBOL_GPL(videobuf2_pmem_contig_user_get);
 
-void videobuf2_pmem_contig_user_put(struct videobuf2_contig_pmem *mem)
+void videobuf2_pmem_contig_user_put(struct videobuf2_contig_pmem *mem,
+					struct ion_client *client)
 {
 	if (msm_subsystem_unmap_buffer(mem->msm_buffer) < 0)
 		D("%s unmapped memory\n", __func__);
-	if (mem->is_userptr)
+	if (mem->is_userptr) {
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+		ion_free(client, mem->ion_handle);
+#elif CONFIG_ANDROID_PMEM
 		put_pmem_file(mem->file);
+#endif
+	}
 	mem->is_userptr = 0;
 	mem->phyaddr = 0;
 	mem->size = 0;
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index 303dd99..b96c288 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -2329,6 +2329,9 @@
 		pm8xxx_writeb(chip->dev->parent, PSI_CONFIG_STATUS, 0x0C);
 	}
 
+	/* Disable EOC FSM processing */
+	pm8xxx_writeb(chip->dev->parent, CHG_BUCK_CTRL_TEST3, 0x91);
+
 	rc = pm_chg_charge_dis(chip, charging_disabled);
 	if (rc) {
 		pr_err("Failed to disable CHG_CHARGE_DIS bit rc=%d\n", rc);
diff --git a/include/linux/msm_audio_mvs.h b/include/linux/msm_audio_mvs.h
index 37a6ee7..c934aee 100644
--- a/include/linux/msm_audio_mvs.h
+++ b/include/linux/msm_audio_mvs.h
@@ -94,14 +94,30 @@
 	MVS_G729A_ERASURE
 };
 
+struct min_max_rate {
+	uint32_t min_rate;
+	uint32_t max_rate;
+};
+
 struct msm_audio_mvs_config {
 	uint32_t mvs_mode;
 	uint32_t rate_type;
+	struct min_max_rate min_max_rate;
 	uint32_t dtx_mode;
 };
 
 #define MVS_MAX_VOC_PKT_SIZE 640
 
+struct q6_msm_audio_mvs_frame {
+	union {
+	uint32_t frame_type;
+	uint32_t packet_rate;
+	} header;
+	uint32_t len;
+	uint8_t voc_pkt[MVS_MAX_VOC_PKT_SIZE];
+
+};
+
 struct msm_audio_mvs_frame {
 	uint32_t frame_type;
 	uint32_t len;
diff --git a/include/media/videobuf2-msm-mem.h b/include/media/videobuf2-msm-mem.h
index ac1575b..916c458 100644
--- a/include/media/videobuf2-msm-mem.h
+++ b/include/media/videobuf2-msm-mem.h
@@ -17,6 +17,7 @@
 
 #include <media/videobuf2-core.h>
 #include <mach/msm_subsystem_map.h>
+#include <linux/ion.h>
 
 struct videobuf2_mapping {
 	unsigned int count;
@@ -58,6 +59,7 @@
 	struct msm_mapped_buffer *msm_buffer;
 	int subsys_id;
 	unsigned long mapped_phyaddr;
+	struct ion_handle *ion_handle;
 };
 void videobuf2_queue_pmem_contig_init(struct vb2_queue *q,
 					enum v4l2_buf_type type,
@@ -70,8 +72,10 @@
 int videobuf2_pmem_contig_user_get(struct videobuf2_contig_pmem *mem,
 					struct videobuf2_msm_offset *offset,
 					enum videobuf2_buffer_type,
-					uint32_t addr_offset, int path);
-void videobuf2_pmem_contig_user_put(struct videobuf2_contig_pmem *mem);
+					uint32_t addr_offset, int path,
+					struct ion_client *client);
+void videobuf2_pmem_contig_user_put(struct videobuf2_contig_pmem *mem,
+					struct ion_client *client);
 unsigned long videobuf2_to_pmem_contig(struct vb2_buffer *buf,
 					unsigned int plane_no);
 
diff --git a/include/sound/q6asm.h b/include/sound/q6asm.h
index f146684..16439e8 100644
--- a/include/sound/q6asm.h
+++ b/include/sound/q6asm.h
@@ -147,6 +147,8 @@
 
 struct audio_client *q6asm_audio_client_alloc(app_cb cb, void *priv);
 
+struct audio_client *q6asm_get_audio_client(int session_id);
+
 int q6asm_audio_client_buf_alloc(unsigned int dir/* 1:Out,0:In */,
 				struct audio_client *ac,
 				unsigned int bufsz,
diff --git a/kernel/power/wakelock.c b/kernel/power/wakelock.c
index b257424..e9f49b5 100644
--- a/kernel/power/wakelock.c
+++ b/kernel/power/wakelock.c
@@ -19,7 +19,6 @@
 #include <linux/suspend.h>
 #include <linux/syscalls.h> /* sys_sync */
 #include <linux/wakelock.h>
-#include <linux/syscore_ops.h>
 #ifdef CONFIG_WAKELOCK_STAT
 #include <linux/proc_fs.h>
 #endif
@@ -392,8 +391,15 @@
 	return ret;
 }
 
+static int power_resume_early(struct device *dev)
+{
+	msm_suspend_check_done = 0;
+	return 0;
+}
+
 static struct dev_pm_ops power_driver_pm_ops = {
 	.suspend_noirq = power_suspend_late,
+	.resume_noirq = power_resume_early,
 };
 
 static struct platform_driver power_driver = {
@@ -404,14 +410,6 @@
 	.name = "power",
 };
 
-static void power_resume_early(void)
-{
-	msm_suspend_check_done = 0;
-}
-static struct syscore_ops wakelock_syscore_ops = {
-	.resume = power_resume_early,
-};
-
 void wake_lock_init(struct wake_lock *lock, int type, const char *name)
 {
 	unsigned long irqflags = 0;
@@ -663,7 +661,6 @@
 	proc_create("wakelocks", S_IRUGO, NULL, &wakelock_stats_fops);
 #endif
 
-	register_syscore_ops(&wakelock_syscore_ops);
 	return 0;
 
 err_suspend_work_queue:
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index eb55f77..268d2e5 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -440,6 +440,23 @@
 	return NULL;
 }
 
+struct audio_client *q6asm_get_audio_client(int session_id)
+{
+	if ((session_id <= 0) || (session_id > SESSION_MAX)) {
+		pr_err("%s: invalid session: %d\n", __func__, session_id);
+		goto err;
+	}
+
+	if (!session[session_id]) {
+		pr_err("%s: session not active: %d\n", __func__, session_id);
+		goto err;
+	}
+
+	return session[session_id];
+err:
+	return NULL;
+}
+
 int q6asm_audio_client_buf_alloc(unsigned int dir,
 			struct audio_client *ac,
 			unsigned int bufsz,