Merge "msm: camera: Convert CSIPHY into platform device" into msm-3.0
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index be98991..ce15b0d 100755
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -336,6 +336,7 @@
 CONFIG_USB_SERIAL=y
 CONFIG_USB_SERIAL_QUALCOMM=y
 CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_USB_QCOM_DIAG_BRIDGE=y
 CONFIG_USB_QCOM_DUN_BRIDGE=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_DEBUG_FILES=y
diff --git a/arch/arm/mach-msm/board-apq8064-regulator.c b/arch/arm/mach-msm/board-apq8064-regulator.c
index f8984f8..8448600 100644
--- a/arch/arm/mach-msm/board-apq8064-regulator.c
+++ b/arch/arm/mach-msm/board-apq8064-regulator.c
@@ -158,6 +158,12 @@
 VREG_CONSUMERS(NCP) = {
 	REGULATOR_SUPPLY("8921_ncp",		NULL),
 };
+VREG_CONSUMERS(8821_S0) = {
+	REGULATOR_SUPPLY("8821_s0",		NULL),
+};
+VREG_CONSUMERS(8821_S1) = {
+	REGULATOR_SUPPLY("8821_s1",		NULL),
+};
 
 #define PM8921_VREG_INIT(_id, _min_uV, _max_uV, _modes, _ops, _apply_uV, \
 			 _pull_down, _always_on, _supply_regulator, \
@@ -262,11 +268,17 @@
 	}
 
 /* SAW regulator constraints */
-struct regulator_init_data msm8064_saw_regulator_pdata_s5 =
+struct regulator_init_data msm8064_saw_regulator_pdata_8921_s5 =
 	/*	      ID  vreg_name	       min_uV   max_uV */
-	SAW_VREG_INIT(S5, "8921_s5",	       1050000, 1150000);
-struct regulator_init_data msm8064_saw_regulator_pdata_s6 =
-	SAW_VREG_INIT(S6, "8921_s6",	       1050000, 1150000);
+	SAW_VREG_INIT(S5, "8921_s5",	       950000, 1150000);
+struct regulator_init_data msm8064_saw_regulator_pdata_8921_s6 =
+	SAW_VREG_INIT(S6, "8921_s6",	       950000, 1150000);
+
+struct regulator_init_data msm8064_saw_regulator_pdata_8821_s0 =
+	/*	      ID       vreg_name	min_uV  max_uV */
+	SAW_VREG_INIT(8821_S0, "8821_s0",       950000, 1150000);
+struct regulator_init_data msm8064_saw_regulator_pdata_8821_s1 =
+	SAW_VREG_INIT(8821_S1, "8821_s1",       950000, 1150000);
 
 /* PM8921 regulator constraints */
 struct pm8921_regulator_platform_data
diff --git a/arch/arm/mach-msm/board-apq8064.c b/arch/arm/mach-msm/board-apq8064.c
index 153fce8..5ae388f 100644
--- a/arch/arm/mach-msm/board-apq8064.c
+++ b/arch/arm/mach-msm/board-apq8064.c
@@ -481,6 +481,38 @@
 	}
 }
 
+static struct platform_device msm8064_device_saw_regulator_core0 = {
+	.name	= "saw-regulator",
+	.id	= 0,
+	.dev	= {
+		.platform_data = &msm8064_saw_regulator_pdata_8921_s5,
+	},
+};
+
+static struct platform_device msm8064_device_saw_regulator_core1 = {
+	.name	= "saw-regulator",
+	.id	= 1,
+	.dev	= {
+		.platform_data = &msm8064_saw_regulator_pdata_8921_s6,
+	},
+};
+
+static struct platform_device msm8064_device_saw_regulator_core2 = {
+	.name	= "saw-regulator",
+	.id	= 2,
+	.dev	= {
+		.platform_data = &msm8064_saw_regulator_pdata_8821_s0,
+	},
+};
+
+static struct platform_device msm8064_device_saw_regulator_core3 = {
+	.name	= "saw-regulator",
+	.id	= 3,
+	.dev	= {
+		.platform_data = &msm8064_saw_regulator_pdata_8821_s1,
+	},
+};
+
 static struct platform_device *common_devices[] __initdata = {
 	&apq8064_device_dmov,
 	&apq8064_device_qup_i2c_gsbi4,
@@ -496,6 +528,10 @@
 	&android_pmem_adsp_device,
 	&android_pmem_audio_device,
 	&msm8064_device_watchdog,
+	&msm8064_device_saw_regulator_core0,
+	&msm8064_device_saw_regulator_core1,
+	&msm8064_device_saw_regulator_core2,
+	&msm8064_device_saw_regulator_core3,
 };
 
 static struct platform_device *sim_devices[] __initdata = {
diff --git a/arch/arm/mach-msm/board-apq8064.h b/arch/arm/mach-msm/board-apq8064.h
index 1d2109a..0928a58 100644
--- a/arch/arm/mach-msm/board-apq8064.h
+++ b/arch/arm/mach-msm/board-apq8064.h
@@ -32,6 +32,11 @@
 
 extern int msm8064_pm8921_regulator_pdata_len __devinitdata;
 
+extern struct regulator_init_data msm8064_saw_regulator_pdata_8921_s5;
+extern struct regulator_init_data msm8064_saw_regulator_pdata_8921_s6;
+extern struct regulator_init_data msm8064_saw_regulator_pdata_8821_s0;
+extern struct regulator_init_data msm8064_saw_regulator_pdata_8821_s1;
+
 struct mmc_platform_data;
 int __init apq8064_add_sdcc(unsigned int controller,
 		struct mmc_platform_data *plat);
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index 38c9e85..1745f26 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -42,7 +42,7 @@
 #define NUM_AUTOFOCUS_MULTI_WINDOW_GRIDS 16
 #define NUM_STAT_OUTPUT_BUFFERS      3
 #define NUM_AF_STAT_OUTPUT_BUFFERS      3
-#define max_control_command_size 260
+#define max_control_command_size 512
 #define CROP_LEN 36
 
 enum vfe_mode_of_operation{
diff --git a/arch/arm/mach-msm/ramdump.c b/arch/arm/mach-msm/ramdump.c
index 962371b..53128ad 100644
--- a/arch/arm/mach-msm/ramdump.c
+++ b/arch/arm/mach-msm/ramdump.c
@@ -198,8 +198,8 @@
 		return NULL;
 	}
 
-	strncpy(rd_dev->name, "ramdump_", 256);
-	strncat(rd_dev->name, dev_name, 256);
+	snprintf(rd_dev->name, ARRAY_SIZE(rd_dev->name), "ramdump_%s",
+		 dev_name);
 
 	init_completion(&rd_dev->ramdump_complete);
 
diff --git a/arch/arm/mach-msm/subsystem_restart.c b/arch/arm/mach-msm/subsystem_restart.c
index ff699e2..54607d0 100644
--- a/arch/arm/mach-msm/subsystem_restart.c
+++ b/arch/arm/mach-msm/subsystem_restart.c
@@ -252,6 +252,8 @@
 		goto out;
 
 	r_log = kmalloc(sizeof(struct restart_log), GFP_KERNEL);
+	if (!r_log)
+		goto out;
 	r_log->subsys = subsys;
 	do_gettimeofday(&r_log->time);
 	curr_time = &r_log->time;
diff --git a/drivers/bluetooth/hci_smd.c b/drivers/bluetooth/hci_smd.c
index 77f9c79..118bbb3 100644
--- a/drivers/bluetooth/hci_smd.c
+++ b/drivers/bluetooth/hci_smd.c
@@ -443,6 +443,9 @@
 	smd_close(hs.event_channel);
 	smd_close(hs.data_channel);
 
+	if (wake_lock_active(&hs.wake_lock_rx))
+		wake_unlock(&hs.wake_lock_rx);
+
 	/*Destroy the timer used to monitor the Rx queue for emptiness */
 	del_timer_sync(&hs.rx_q_timer);
 	tasklet_kill(&hs.hci_event_task);
diff --git a/drivers/hwmon/pm8xxx-adc-scale.c b/drivers/hwmon/pm8xxx-adc-scale.c
index 40ade69..7b27f72 100644
--- a/drivers/hwmon/pm8xxx-adc-scale.c
+++ b/drivers/hwmon/pm8xxx-adc-scale.c
@@ -34,81 +34,89 @@
 };
 
 static const struct pm8xxx_adc_map_pt adcmap_btm_threshold[] = {
-	{-30,	41001},
-	{-20,	40017},
-	{-10,	38721},
-	{0,	37186},
-	{10,	35554},
-	{11,	35392},
-	{12,	35230},
-	{13,	35070},
-	{14,	34910},
-	{15,	34751},
-	{16,	34594},
-	{17,	34438},
-	{18,	34284},
-	{19,	34131},
-	{20,	33980},
-	{21,	33830},
-	{22,	33683},
-	{23,	33538},
-	{24,	33394},
-	{25,	33253},
-	{26,	33114},
-	{27,	32977},
-	{28,	32842},
-	{29,	32710},
-	{30,	32580},
-	{31,	32452},
-	{32,	32327},
-	{33,	32204},
-	{34,	32084},
-	{35,	31966},
-	{36,	31850},
-	{37,	31737},
-	{38,	31627},
-	{39,	31518},
-	{40,	31412},
-	{41,	31309},
-	{42,	31208},
-	{43,	31109},
-	{44,	31013},
-	{45,	30918},
-	{46,	30827},
-	{47,	30737},
-	{48,	30649},
-	{49,	30564},
-	{50,	30481},
-	{51,	30400},
-	{52,	30321},
-	{53,	30244},
-	{54,	30169},
-	{55,	30096},
-	{56,	30025},
-	{57,	29956},
-	{58,	29889},
-	{59,	29823},
-	{60,	29759},
-	{61,	29697},
-	{62,	29637},
-	{63,	29578},
-	{64,	29521},
-	{65,	29465},
-	{66,	29411},
-	{67,	29359},
-	{68,	29308},
-	{69,	29258},
-	{70,	29209},
-	{71,	29162},
-	{72,	29117},
-	{73,	29072},
-	{74,	29029},
-	{75,	28987},
-	{76,	28946},
-	{77,	28906},
-	{78,	28868},
-	{79,	28830},
-	{80,	28794}
+	{-30,	1642},
+	{-20,	1544},
+	{-10,	1414},
+	{0,	1260},
+	{1,	1244},
+	{2,	1228},
+	{3,	1212},
+	{4,	1195},
+	{5,	1179},
+	{6,	1162},
+	{7,	1146},
+	{8,	1129},
+	{9,	1113},
+	{10,	1097},
+	{11,	1080},
+	{12,	1064},
+	{13,	1048},
+	{14,	1032},
+	{15,	1016},
+	{16,	1000},
+	{17,	985},
+	{18,	969},
+	{19,	954},
+	{20,	939},
+	{21,	924},
+	{22,	909},
+	{23,	894},
+	{24,	880},
+	{25,	866},
+	{26,	852},
+	{27,	838},
+	{28,	824},
+	{29,	811},
+	{30,	798},
+	{31,	785},
+	{32,	773},
+	{33,	760},
+	{34,	748},
+	{35,	736},
+	{36,	725},
+	{37,	713},
+	{38,	702},
+	{39,	691},
+	{40,	681},
+	{41,	670},
+	{42,	660},
+	{43,	650},
+	{44,	640},
+	{45,	631},
+	{46,	622},
+	{47,	613},
+	{48,	604},
+	{49,	595},
+	{50,	587},
+	{51,	579},
+	{52,	571},
+	{53,	563},
+	{54,	556},
+	{55,	548},
+	{56,	541},
+	{57,	534},
+	{58,	527},
+	{59,	521},
+	{60,	514},
+	{61,	508},
+	{62,	502},
+	{63,	496},
+	{64,	490},
+	{65,	485},
+	{66,	281},
+	{67,	274},
+	{68,	267},
+	{69,	260},
+	{70,	254},
+	{71,	247},
+	{72,	241},
+	{73,	235},
+	{74,	229},
+	{75,	224},
+	{76,	218},
+	{77,	213},
+	{78,	208},
+	{79,	203}
 };
 
 static const struct pm8xxx_adc_map_pt adcmap_pa_therm[] = {
@@ -597,7 +605,9 @@
 }
 EXPORT_SYMBOL_GPL(pm8xxx_adc_tdkntcg_therm);
 
-int32_t pm8xxx_adc_batt_scaler(struct pm8xxx_adc_arb_btm_param *btm_param)
+int32_t pm8xxx_adc_batt_scaler(struct pm8xxx_adc_arb_btm_param *btm_param,
+		const struct pm8xxx_adc_properties *adc_properties,
+		const struct pm8xxx_adc_chan_properties *chan_properties)
 {
 	int rc;
 
@@ -606,14 +616,29 @@
 		ARRAY_SIZE(adcmap_btm_threshold),
 		btm_param->low_thr_temp,
 		&btm_param->low_thr_voltage);
+	if (rc)
+		return rc;
 
-	if (!rc) {
-		rc = pm8xxx_adc_map_linear(
-			adcmap_btm_threshold,
-			ARRAY_SIZE(adcmap_btm_threshold),
-			btm_param->high_thr_temp,
-			&btm_param->high_thr_voltage);
-	}
+	btm_param->low_thr_voltage *=
+		chan_properties->adc_graph[ADC_CALIB_RATIOMETRIC].dy;
+	do_div(btm_param->low_thr_voltage, adc_properties->adc_vdd_reference);
+	btm_param->low_thr_voltage +=
+		chan_properties->adc_graph[ADC_CALIB_RATIOMETRIC].adc_gnd;
+
+	rc = pm8xxx_adc_map_linear(
+		adcmap_btm_threshold,
+		ARRAY_SIZE(adcmap_btm_threshold),
+		btm_param->high_thr_temp,
+		&btm_param->high_thr_voltage);
+	if (rc)
+		return rc;
+
+	btm_param->high_thr_voltage *=
+		chan_properties->adc_graph[ADC_CALIB_RATIOMETRIC].dy;
+	do_div(btm_param->high_thr_voltage, adc_properties->adc_vdd_reference);
+	btm_param->high_thr_voltage +=
+		chan_properties->adc_graph[ADC_CALIB_RATIOMETRIC].adc_gnd;
+
 
 	return rc;
 }
diff --git a/drivers/hwmon/pm8xxx-adc.c b/drivers/hwmon/pm8xxx-adc.c
index 152eb40..5da80d9 100644
--- a/drivers/hwmon/pm8xxx-adc.c
+++ b/drivers/hwmon/pm8xxx-adc.c
@@ -121,6 +121,7 @@
 #define PM8XXX_ADC_PA_THERM_VREG_UV_MIN			1800000
 #define PM8XXX_ADC_PA_THERM_VREG_UV_MAX			1800000
 #define PM8XXX_ADC_PA_THERM_VREG_UA_LOAD		100000
+#define PM8XXX_ADC_HWMON_NAME_LENGTH			32
 
 struct pm8xxx_adc {
 	struct device				*dev;
@@ -654,6 +655,10 @@
 					(calib_read_1 - calib_read_2);
 	adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_RATIOMETRIC].dx =
 					adc_pmic->adc_prop->adc_vdd_reference;
+	adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_RATIOMETRIC].adc_vref =
+					calib_read_1;
+	adc_pmic->conv->chan_prop->adc_graph[ADC_CALIB_RATIOMETRIC].adc_gnd =
+					calib_read_2;
 calib_fail:
 	rc = pm8xxx_adc_arb_cntrl(0, CHANNEL_NONE);
 	if (rc < 0) {
@@ -694,11 +699,12 @@
 	if (channel < PM8XXX_CHANNEL_MPP_SCALE1_IDX) {
 		mpp_scale = PREMUX_MPP_SCALE_0;
 		adc_pmic->conv->amux_channel = channel;
-	} else if (channel >= PM8XXX_CHANNEL_MPP_SCALE1_IDX) {
+	} else if (channel >= PM8XXX_CHANNEL_MPP_SCALE1_IDX &&
+			channel < PM8XXX_CHANNEL_MPP_SCALE3_IDX) {
 		mpp_scale = PREMUX_MPP_SCALE_1;
 		adc_pmic->conv->amux_channel = channel %
 				PM8XXX_CHANNEL_MPP_SCALE1_IDX;
-	} else if (channel >= PM8XXX_CHANNEL_MPP_SCALE3_IDX) {
+	} else {
 		mpp_scale = PREMUX_MPP_SCALE_1_DIV3;
 		adc_pmic->conv->amux_channel = channel %
 				PM8XXX_CHANNEL_MPP_SCALE3_IDX;
@@ -830,7 +836,8 @@
 		return -EINVAL;
 	}
 
-	rc = pm8xxx_adc_batt_scaler(btm_param);
+	rc = pm8xxx_adc_batt_scaler(btm_param, adc_pmic->adc_prop,
+					adc_pmic->conv->chan_prop);
 	if (rc < 0) {
 		pr_err("Failed to lookup the BTM thresholds\n");
 		return rc;
@@ -1014,9 +1021,8 @@
 	if (rc)
 		return 0;
 
-	return snprintf(buf, sizeof(struct pm8xxx_adc_chan_result),
-				"Result:%lld Raw:%d\n",
-				result.physical, result.adc_code);
+	return snprintf(buf, PM8XXX_ADC_HWMON_NAME_LENGTH,
+		"Result:%lld Raw:%d\n", result.physical, result.adc_code);
 }
 
 static int get_adc(void *data, u64 *val)
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index 4b4d235..8ef0de9 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -774,11 +774,21 @@
 	}
 	if (!pb->count) {
 		/* Deallocation. free buf_offset array */
-		D("%s freeing buffer offsets array ", __func__);
+		D("%s Inst %p freeing buffer offsets array",
+			__func__, pcam_inst);
 		for (j = 0 ; j < pcam_inst->buf_count ; j++)
 			kfree(pcam_inst->buf_offset[j]);
 		kfree(pcam_inst->buf_offset);
+		pcam_inst->buf_offset = NULL;
+		/* If the userspace has deallocated all the
+		 * buffers, then release the vb2 queue */
+		if (pcam_inst->vbqueue_initialized) {
+			vb2_queue_release(&pcam_inst->vid_bufq);
+			pcam_inst->vbqueue_initialized = 0;
+		}
 	} else {
+		D("%s Inst %p Allocating buf_offset array",
+			__func__, pcam_inst);
 		/* Allocation. allocate buf_offset array */
 		pcam_inst->buf_offset = (struct msm_cam_buf_offset **)
 			kzalloc(pb->count * sizeof(struct msm_cam_buf_offset *),
@@ -796,6 +806,7 @@
 				for (j = i-1 ; j >= 0; j--)
 					kfree(pcam_inst->buf_offset[j]);
 				kfree(pcam_inst->buf_offset);
+				pcam_inst->buf_offset = NULL;
 				return -ENOMEM;
 			}
 		}
@@ -828,7 +839,18 @@
 
 	D("%s Inst = %p\n", __func__, pcam_inst);
 	WARN_ON(pctx != f->private_data);
+
+	if (!pcam_inst->buf_offset) {
+		pr_err("%s Buffer is already released. Returning. ", __func__);
+		return -EINVAL;
+	}
+
 	if (pb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		/* Reject the buffer if planes array was not allocated */
+		if (pb->m.planes == NULL) {
+			pr_err("%s Planes array is null ", __func__);
+			return -EINVAL;
+		}
 		for (i = 0; i < pcam_inst->plane_info.num_planes; i++) {
 			D("%s stored offsets for plane %d as"
 				"addr offset %d, data offset %d",
@@ -1093,7 +1115,7 @@
 	pcam_inst = container_of(f->private_data,
 			struct msm_cam_v4l2_dev_inst, eventHandle);
 
-	D("%s\n", __func__);
+	D("%s Inst %p\n", __func__, pcam_inst);
 	WARN_ON(pctx != f->private_data);
 
 	if (!pcam_inst->vbqueue_initialized) {
diff --git a/drivers/media/video/msm/msm_mctl_buf.c b/drivers/media/video/msm/msm_mctl_buf.c
index f7e5479..aed70bc 100644
--- a/drivers/media/video/msm/msm_mctl_buf.c
+++ b/drivers/media/video/msm/msm_mctl_buf.c
@@ -100,7 +100,7 @@
 	buf_type = (vb->num_planes == 1) ? VIDEOBUF2_SINGLE_PLANE
 					: VIDEOBUF2_MULTIPLE_PLANES;
 	if (buf_type == VIDEOBUF2_SINGLE_PLANE) {
-		offset.sp_off.y_off = 0;
+		offset.sp_off.y_off = pcam_inst->plane_info.sp_y_offset;
 		offset.sp_off.cbcr_off =
 			pcam_inst->plane_info.plane[0].offset;
 	}
diff --git a/drivers/mfd/pm8xxx-misc.c b/drivers/mfd/pm8xxx-misc.c
index 439cefe..ce6a016 100644
--- a/drivers/mfd/pm8xxx-misc.c
+++ b/drivers/mfd/pm8xxx-misc.c
@@ -16,14 +16,13 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
+#include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/pm8xxx/core.h>
 #include <linux/mfd/pm8xxx/misc.h>
 
 /* PON CTRL 1 register */
-#define REG_PM8058_PON_CTRL_1			0x01C
-#define REG_PM8921_PON_CTRL_1			0x01C
-#define REG_PM8018_PON_CTRL_1			0x01C
+#define REG_PM8XXX_PON_CTRL_1			0x01C
 
 #define PON_CTRL_1_PULL_UP_MASK			0xE0
 #define PON_CTRL_1_USB_PWR_EN			0x10
@@ -83,6 +82,10 @@
 #define SLEEP_CTRL_SMPL_EN_RESET		0x04
 #define SLEEP_CTRL_SMPL_EN_PWR_OFF		0x00
 
+#define SLEEP_CTRL_SMPL_SEL_MASK		0x03
+#define SLEEP_CTRL_SMPL_SEL_MIN			0
+#define SLEEP_CTRL_SMPL_SEL_MAX			3
+
 /* FTS regulator PMR registers */
 #define REG_PM8901_REGULATOR_S1_PMR		0xA7
 #define REG_PM8901_REGULATOR_S2_PMR		0xA8
@@ -92,6 +95,13 @@
 #define PM8901_REGULATOR_PMR_STATE_MASK		0x60
 #define PM8901_REGULATOR_PMR_STATE_OFF		0x20
 
+/* COINCELL CHG registers */
+#define REG_PM8058_COIN_CHG			0x02F
+#define REG_PM8921_COIN_CHG			0x09C
+#define REG_PM8018_COIN_CHG			0x09C
+
+#define COINCELL_RESISTOR_SHIFT			0x2
+
 /* GPIO UART MUX CTRL registers */
 #define REG_PM8XXX_GPIO_MUX_CTRL		0x1CC
 
@@ -103,6 +113,7 @@
 	struct pm8xxx_misc_platform_data	pdata;
 	struct device				*dev;
 	enum pm8xxx_version			version;
+	u64					osc_halt_count;
 };
 
 static LIST_HEAD(pm8xxx_misc_chips);
@@ -294,7 +305,7 @@
 	 * Also ensure that KPD, CBL0, and CBL1 pull ups are enabled and that
 	 * USB charging is enabled.
 	 */
-	rc = pm8xxx_misc_masked_write(chip, REG_PM8018_PON_CTRL_1,
+	rc = pm8xxx_misc_masked_write(chip, REG_PM8XXX_PON_CTRL_1,
 		PON_CTRL_1_PULL_UP_MASK | PON_CTRL_1_USB_PWR_EN
 		| PON_CTRL_1_WD_EN_MASK,
 		PON_CTRL_1_PULL_UP_MASK | PON_CTRL_1_USB_PWR_EN
@@ -351,7 +362,7 @@
 	 * Also ensure that KPD, CBL0, and CBL1 pull ups are enabled and that
 	 * USB charging is enabled.
 	 */
-	rc = pm8xxx_misc_masked_write(chip, REG_PM8058_PON_CTRL_1,
+	rc = pm8xxx_misc_masked_write(chip, REG_PM8XXX_PON_CTRL_1,
 		PON_CTRL_1_PULL_UP_MASK | PON_CTRL_1_USB_PWR_EN
 		| PON_CTRL_1_WD_EN_MASK,
 		PON_CTRL_1_PULL_UP_MASK | PON_CTRL_1_USB_PWR_EN
@@ -411,7 +422,7 @@
 	 * Also ensure that KPD, CBL0, and CBL1 pull ups are enabled and that
 	 * USB charging is enabled.
 	 */
-	rc = pm8xxx_misc_masked_write(chip, REG_PM8921_PON_CTRL_1,
+	rc = pm8xxx_misc_masked_write(chip, REG_PM8XXX_PON_CTRL_1,
 		PON_CTRL_1_PULL_UP_MASK | PON_CTRL_1_USB_PWR_EN
 		| PON_CTRL_1_WD_EN_MASK,
 		PON_CTRL_1_PULL_UP_MASK | PON_CTRL_1_USB_PWR_EN
@@ -472,6 +483,262 @@
 EXPORT_SYMBOL_GPL(pm8xxx_reset_pwr_off);
 
 /**
+ * pm8xxx_smpl_control - enables/disables SMPL detection
+ * @enable: 0 = shutdown PMIC on power loss, 1 = reset PMIC on power loss
+ *
+ * This function enables or disables the Sudden Momentary Power Loss detection
+ * module.  If SMPL detection is enabled, then when a sufficiently long power
+ * loss event occurs, the PMIC will automatically reset itself.  If SMPL
+ * detection is disabled, then the PMIC will shutdown when power loss occurs.
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_smpl_control(int enable)
+{
+	struct pm8xxx_misc_chip *chip;
+	unsigned long flags;
+	int rc = 0;
+
+	spin_lock_irqsave(&pm8xxx_misc_chips_lock, flags);
+
+	/* Loop over all attached PMICs and call specific functions for them. */
+	list_for_each_entry(chip, &pm8xxx_misc_chips, link) {
+		switch (chip->version) {
+		case PM8XXX_VERSION_8018:
+			rc = pm8xxx_misc_masked_write(chip,
+				REG_PM8018_SLEEP_CTRL, SLEEP_CTRL_SMPL_EN_MASK,
+				(enable ? SLEEP_CTRL_SMPL_EN_PWR_OFF
+					   : SLEEP_CTRL_SMPL_EN_PWR_OFF));
+			break;
+		case PM8XXX_VERSION_8058:
+			rc = pm8xxx_misc_masked_write(chip,
+				REG_PM8058_SLEEP_CTRL, SLEEP_CTRL_SMPL_EN_MASK,
+				(enable ? SLEEP_CTRL_SMPL_EN_RESET
+					   : SLEEP_CTRL_SMPL_EN_PWR_OFF));
+			break;
+		case PM8XXX_VERSION_8921:
+			rc = pm8xxx_misc_masked_write(chip,
+				REG_PM8921_SLEEP_CTRL, SLEEP_CTRL_SMPL_EN_MASK,
+				(enable ? SLEEP_CTRL_SMPL_EN_PWR_OFF
+					   : SLEEP_CTRL_SMPL_EN_PWR_OFF));
+			break;
+		default:
+			/* PMIC doesn't have reset_pwr_off; do nothing. */
+			break;
+		}
+		if (rc) {
+			pr_err("setting smpl control failed, rc=%d\n", rc);
+			break;
+		}
+	}
+
+	spin_unlock_irqrestore(&pm8xxx_misc_chips_lock, flags);
+
+	return rc;
+}
+EXPORT_SYMBOL(pm8xxx_smpl_control);
+
+
+/**
+ * pm8xxx_smpl_set_delay - sets the SMPL detection time delay
+ * @delay: enum value corresponding to delay time
+ *
+ * This function sets the time delay of the SMPL detection module.  If power
+ * is reapplied within this interval, then the PMIC reset automatically.  The
+ * SMPL detection module must be enabled for this delay time to take effect.
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_smpl_set_delay(enum pm8xxx_smpl_delay delay)
+{
+	struct pm8xxx_misc_chip *chip;
+	unsigned long flags;
+	int rc = 0;
+
+	if (delay < SLEEP_CTRL_SMPL_SEL_MIN
+	    || delay > SLEEP_CTRL_SMPL_SEL_MAX) {
+		pr_err("%s: invalid delay specified: %d\n", __func__, delay);
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&pm8xxx_misc_chips_lock, flags);
+
+	/* Loop over all attached PMICs and call specific functions for them. */
+	list_for_each_entry(chip, &pm8xxx_misc_chips, link) {
+		switch (chip->version) {
+		case PM8XXX_VERSION_8018:
+			rc = pm8xxx_misc_masked_write(chip,
+				REG_PM8018_SLEEP_CTRL, SLEEP_CTRL_SMPL_SEL_MASK,
+				delay);
+			break;
+		case PM8XXX_VERSION_8058:
+			rc = pm8xxx_misc_masked_write(chip,
+				REG_PM8058_SLEEP_CTRL, SLEEP_CTRL_SMPL_SEL_MASK,
+				delay);
+			break;
+		case PM8XXX_VERSION_8921:
+			rc = pm8xxx_misc_masked_write(chip,
+				REG_PM8921_SLEEP_CTRL, SLEEP_CTRL_SMPL_SEL_MASK,
+				delay);
+			break;
+		default:
+			/* PMIC doesn't have reset_pwr_off; do nothing. */
+			break;
+		}
+		if (rc) {
+			pr_err("setting smpl delay failed, rc=%d\n", rc);
+			break;
+		}
+	}
+
+	spin_unlock_irqrestore(&pm8xxx_misc_chips_lock, flags);
+
+	return rc;
+}
+EXPORT_SYMBOL(pm8xxx_smpl_set_delay);
+
+/**
+ * pm8xxx_coincell_chg_config - Disables or enables the coincell charger, and
+ *				configures its voltage and resistor settings.
+ * @chg_config:			Holds both voltage and resistor values, and a
+ *				switch to change the state of charger.
+ *				If state is to disable the charger then
+ *				both voltage and resistor are disregarded.
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_coincell_chg_config(struct pm8xxx_coincell_chg *chg_config)
+{
+	struct pm8xxx_misc_chip *chip;
+	unsigned long flags;
+	u8 reg = 0, voltage, resistor;
+	int rc = 0;
+
+	if (chg_config == NULL) {
+		pr_err("chg_config is NULL\n");
+		return -EINVAL;
+	}
+
+	voltage = chg_config->voltage;
+	resistor = chg_config->resistor;
+
+	if (resistor < PM8XXX_COINCELL_RESISTOR_2100_OHMS ||
+			resistor > PM8XXX_COINCELL_RESISTOR_800_OHMS) {
+		pr_err("Invalid resistor value provided\n");
+		return -EINVAL;
+	}
+
+	if (voltage < PM8XXX_COINCELL_VOLTAGE_3p2V ||
+		(voltage > PM8XXX_COINCELL_VOLTAGE_3p0V &&
+			voltage != PM8XXX_COINCELL_VOLTAGE_2p5V)) {
+		pr_err("Invalid voltage value provided\n");
+		return -EINVAL;
+	}
+
+	if (chg_config->state == PM8XXX_COINCELL_CHG_DISABLE) {
+		reg = 0;
+	} else {
+		reg |= voltage;
+		reg |= (resistor << COINCELL_RESISTOR_SHIFT);
+	}
+
+	spin_lock_irqsave(&pm8xxx_misc_chips_lock, flags);
+
+	/* Loop over all attached PMICs and call specific functions for them. */
+	list_for_each_entry(chip, &pm8xxx_misc_chips, link) {
+		switch (chip->version) {
+		case PM8XXX_VERSION_8018:
+			rc = pm8xxx_writeb(chip->dev->parent,
+					REG_PM8018_COIN_CHG, reg);
+			break;
+		case PM8XXX_VERSION_8058:
+			rc = pm8xxx_writeb(chip->dev->parent,
+					REG_PM8058_COIN_CHG, reg);
+			break;
+		case PM8XXX_VERSION_8921:
+			rc = pm8xxx_writeb(chip->dev->parent,
+					REG_PM8921_COIN_CHG, reg);
+			break;
+		default:
+			/* PMIC doesn't have reset_pwr_off; do nothing. */
+			break;
+		}
+		if (rc) {
+			pr_err("coincell chg. config failed, rc=%d\n", rc);
+			break;
+		}
+	}
+
+	spin_unlock_irqrestore(&pm8xxx_misc_chips_lock, flags);
+
+	return rc;
+}
+EXPORT_SYMBOL(pm8xxx_coincell_chg_config);
+
+/**
+ * pm8xxx_watchdog_reset_control - enables/disables watchdog reset detection
+ * @enable: 0 = shutdown when PS_HOLD goes low, 1 = reset when PS_HOLD goes low
+ *
+ * This function enables or disables the PMIC watchdog reset detection feature.
+ * If watchdog reset detection is enabled, then the PMIC will reset itself
+ * when PS_HOLD goes low.  If it is not enabled, then the PMIC will shutdown
+ * when PS_HOLD goes low.
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_watchdog_reset_control(int enable)
+{
+	struct pm8xxx_misc_chip *chip;
+	unsigned long flags;
+	int rc = 0;
+
+	spin_lock_irqsave(&pm8xxx_misc_chips_lock, flags);
+
+	/* Loop over all attached PMICs and call specific functions for them. */
+	list_for_each_entry(chip, &pm8xxx_misc_chips, link) {
+		switch (chip->version) {
+		case PM8XXX_VERSION_8018:
+		case PM8XXX_VERSION_8058:
+		case PM8XXX_VERSION_8921:
+			rc = pm8xxx_misc_masked_write(chip,
+				REG_PM8XXX_PON_CTRL_1, PON_CTRL_1_WD_EN_MASK,
+				(enable ? PON_CTRL_1_WD_EN_RESET
+					   : PON_CTRL_1_WD_EN_PWR_OFF));
+			break;
+		default:
+			/* WD reset control not supported */
+			break;
+		}
+		if (rc) {
+			pr_err("setting WD reset control failed, rc=%d\n", rc);
+			break;
+		}
+	}
+
+	spin_unlock_irqrestore(&pm8xxx_misc_chips_lock, flags);
+
+	return rc;
+}
+EXPORT_SYMBOL(pm8xxx_watchdog_reset_control);
+
+/* Handle the OSC_HALT interrupt: 32 kHz XTAL oscillator has stopped. */
+static irqreturn_t pm8xxx_osc_halt_isr(int irq, void *data)
+{
+	struct pm8xxx_misc_chip *chip = data;
+	u64 count = 0;
+
+	if (chip) {
+		chip->osc_halt_count++;
+		count = chip->osc_halt_count;
+	}
+
+	pr_crit("%s: OSC_HALT interrupt has triggered, 32 kHz XTAL oscillator"
+				" has halted (%llu)!\n", __func__, count);
+
+	return IRQ_HANDLED;
+}
+
+/**
  * pm8xxx_uart_gpio_mux_ctrl - Mux configuration to select the UART
  *
  * @uart_path_sel: Input argument to select either UART1/2/3
@@ -519,7 +786,7 @@
 	struct pm8xxx_misc_chip *sibling;
 	struct list_head *prev;
 	unsigned long flags;
-	int rc = 0;
+	int rc = 0, irq;
 
 	if (!pdata) {
 		pr_err("missing platform data\n");
@@ -537,6 +804,18 @@
 	chip->version = pm8xxx_get_version(chip->dev->parent);
 	memcpy(&(chip->pdata), pdata, sizeof(struct pm8xxx_misc_platform_data));
 
+	irq = platform_get_irq_byname(pdev, "pm8xxx_osc_halt_irq");
+	if (irq > 0) {
+		rc = request_any_context_irq(irq, pm8xxx_osc_halt_isr,
+				 IRQF_TRIGGER_RISING | IRQF_DISABLED,
+				 "pm8xxx_osc_halt_irq", chip);
+		if (rc < 0) {
+			pr_err("%s: request_any_context_irq(%d) FAIL: %d\n",
+							 __func__, irq, rc);
+			goto fail_irq;
+		}
+	}
+
 	/* Insert PMICs in priority order (lowest value first). */
 	spin_lock_irqsave(&pm8xxx_misc_chips_lock, flags);
 	prev = &pm8xxx_misc_chips;
@@ -552,12 +831,20 @@
 	platform_set_drvdata(pdev, chip);
 
 	return rc;
+
+fail_irq:
+	platform_set_drvdata(pdev, NULL);
+	kfree(chip);
+	return rc;
 }
 
 static int __devexit pm8xxx_misc_remove(struct platform_device *pdev)
 {
 	struct pm8xxx_misc_chip *chip = platform_get_drvdata(pdev);
 	unsigned long flags;
+	int irq = platform_get_irq_byname(pdev, "pm8xxx_osc_halt_irq");
+	if (irq > 0)
+		free_irq(irq, chip);
 
 	spin_lock_irqsave(&pm8xxx_misc_chips_lock, flags);
 	list_del(&chip->link);
diff --git a/drivers/net/msm_rmnet_bam.c b/drivers/net/msm_rmnet_bam.c
index e617aa5..3b3758e 100644
--- a/drivers/net/msm_rmnet_bam.c
+++ b/drivers/net/msm_rmnet_bam.c
@@ -374,8 +374,11 @@
 	if (!p->device_up) {
 		r = msm_bam_dmux_open(p->ch_id, dev, bam_notify);
 
-		if (r < 0)
+		if (r < 0) {
+			DBG0("%s: ch=%d failed with rc %d\n",
+					__func__, p->ch_id, r);
 			return -ENODEV;
+		}
 	}
 
 	p->device_up = DEVICE_ACTIVE;
@@ -688,8 +691,10 @@
 		dev = alloc_netdev(sizeof(struct rmnet_private),
 				   "rmnet%d", rmnet_setup);
 
-		if (!dev)
+		if (!dev) {
+			pr_err("%s: no memory for netdev %d\n", __func__, n);
 			return -ENOMEM;
+		}
 
 		netdevs[n] = dev;
 		d = &(dev->dev);
@@ -707,6 +712,8 @@
 
 		ret = register_netdev(dev);
 		if (ret) {
+			pr_err("%s: unable to register netdev"
+				   " %d rc=%d\n", __func__, n, ret);
 			free_netdev(dev);
 			return ret;
 		}
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 3a5af71..d16fcda 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -74,7 +74,7 @@
 #define USB_PHY_1P8_HPM_LOAD	50000	/* uA */
 #define USB_PHY_1P8_LPM_LOAD	4000	/* uA */
 
-#define USB_PHY_VDD_DIG_VOL_MIN	945000 /* uV */
+#define USB_PHY_VDD_DIG_VOL_MIN	1045000 /* uV */
 #define USB_PHY_VDD_DIG_VOL_MAX	1320000 /* uV */
 
 static struct msm_otg *the_msm_otg;
diff --git a/include/linux/mfd/pm8xxx/misc.h b/include/linux/mfd/pm8xxx/misc.h
index 2374d11..2bd2850 100644
--- a/include/linux/mfd/pm8xxx/misc.h
+++ b/include/linux/mfd/pm8xxx/misc.h
@@ -35,6 +35,38 @@
 	UART_TX3_RX3,
 };
 
+enum pm8xxx_coincell_chg_voltage {
+	PM8XXX_COINCELL_VOLTAGE_3p2V = 1,
+	PM8XXX_COINCELL_VOLTAGE_3p1V,
+	PM8XXX_COINCELL_VOLTAGE_3p0V,
+	PM8XXX_COINCELL_VOLTAGE_2p5V = 16
+};
+
+enum pm8xxx_coincell_chg_resistor {
+	PM8XXX_COINCELL_RESISTOR_2100_OHMS,
+	PM8XXX_COINCELL_RESISTOR_1700_OHMS,
+	PM8XXX_COINCELL_RESISTOR_1200_OHMS,
+	PM8XXX_COINCELL_RESISTOR_800_OHMS
+};
+
+enum pm8xxx_coincell_chg_state {
+	PM8XXX_COINCELL_CHG_DISABLE,
+	PM8XXX_COINCELL_CHG_ENABLE
+};
+
+struct pm8xxx_coincell_chg {
+	enum pm8xxx_coincell_chg_state		state;
+	enum pm8xxx_coincell_chg_voltage	voltage;
+	enum pm8xxx_coincell_chg_resistor	resistor;
+};
+
+enum pm8xxx_smpl_delay {
+	PM8XXX_SMPL_DELAY_0p5,
+	PM8XXX_SMPL_DELAY_1p0,
+	PM8XXX_SMPL_DELAY_1p5,
+	PM8XXX_SMPL_DELAY_2p0,
+};
+
 #if defined(CONFIG_MFD_PM8XXX_MISC) || defined(CONFIG_MFD_PM8XXX_MISC_MODULE)
 
 /**
@@ -48,18 +80,84 @@
 
 int pm8xxx_uart_gpio_mux_ctrl(enum pm8xxx_uart_path_sel uart_path_sel);
 
+/**
+ * pm8xxx_coincell_chg_config - Disables or enables the coincell charger, and
+ *				configures its voltage and resistor settings.
+ * @chg_config:			Holds both voltage and resistor values, and a
+ *				switch to change the state of charger.
+ *				If state is to disable the charger then
+ *				both voltage and resistor are disregarded.
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_coincell_chg_config(struct pm8xxx_coincell_chg *chg_config);
+
+/**
+ * pm8xxx_smpl_control - enables/disables SMPL detection
+ * @enable: 0 = shutdown PMIC on power loss, 1 = reset PMIC on power loss
+ *
+ * This function enables or disables the Sudden Momentary Power Loss detection
+ * module.  If SMPL detection is enabled, then when a sufficiently long power
+ * loss event occurs, the PMIC will automatically reset itself.  If SMPL
+ * detection is disabled, then the PMIC will shutdown when power loss occurs.
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_smpl_control(int enable);
+
+/**
+ * pm8xxx_smpl_set_delay - sets the SMPL detection time delay
+ * @delay: enum value corresponding to delay time
+ *
+ * This function sets the time delay of the SMPL detection module.  If power
+ * is reapplied within this interval, then the PMIC reset automatically.  The
+ * SMPL detection module must be enabled for this delay time to take effect.
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_smpl_set_delay(enum pm8xxx_smpl_delay delay);
+
+/**
+ * pm8xxx_watchdog_reset_control - enables/disables watchdog reset detection
+ * @enable: 0 = shutdown when PS_HOLD goes low, 1 = reset when PS_HOLD goes low
+ *
+ * This function enables or disables the PMIC watchdog reset detection feature.
+ * If watchdog reset detection is enabled, then the PMIC will reset itself
+ * when PS_HOLD goes low.  If it is not enabled, then the PMIC will shutdown
+ * when PS_HOLD goes low.
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_watchdog_reset_control(int enable);
+
 #else
 
 static inline int pm8xxx_reset_pwr_off(int reset)
 {
 	return -ENODEV;
 }
-
 static inline int
 pm8xxx_uart_gpio_mux_ctrl(enum pm8xxx_uart_path_sel uart_path_sel)
 {
 	return -ENODEV;
 }
+static inline int
+pm8xxx_coincell_chg_config(struct pm8xxx_coincell_chg *chg_config)
+{
+	return -ENODEV;
+}
+static inline int pm8xxx_smpl_set_delay(enum pm8xxx_smpl_delay delay)
+{
+	return -ENODEV;
+}
+static inline int pm8xxx_smpl_control(int enable)
+{
+	return -ENODEV;
+}
+static inline int pm8xxx_watchdog_reset_control(int enable)
+{
+	return -ENODEV;
+}
 
 #endif
 
diff --git a/include/linux/mfd/pm8xxx/pm8xxx-adc.h b/include/linux/mfd/pm8xxx/pm8xxx-adc.h
index aa642cc..ba4b29c 100644
--- a/include/linux/mfd/pm8xxx/pm8xxx-adc.h
+++ b/include/linux/mfd/pm8xxx/pm8xxx-adc.h
@@ -221,6 +221,8 @@
  * @offset: Offset with respect to the actual curve
  * @dy: Numerator slope to calculate the gain
  * @dx: Denominator slope to calculate the gain
+ * @adc_vref: A/D word of the voltage reference used for the channel
+ * @adc_gnd: A/D word of the ground reference used for the channel
  *
  * Each ADC device has different offset and gain parameters which are computed
  * to calibrate the device.
@@ -229,6 +231,8 @@
 	int32_t offset;
 	int32_t dy;
 	int32_t dx;
+	int32_t adc_vref;
+	int32_t adc_gnd;
 };
 
 /**
@@ -453,8 +457,8 @@
  * levels once the thresholds are reached
  */
 struct pm8xxx_adc_arb_btm_param {
-	uint32_t	low_thr_temp;
-	uint32_t	high_thr_temp;
+	int32_t		low_thr_temp;
+	int32_t		high_thr_temp;
 	uint64_t	low_thr_voltage;
 	uint64_t	high_thr_voltage;
 	int32_t		interval;
@@ -462,8 +466,9 @@
 	void		(*btm_cool_fn) (bool);
 };
 
-int32_t pm8xxx_adc_batt_scaler(struct pm8xxx_adc_arb_btm_param *);
-
+int32_t pm8xxx_adc_batt_scaler(struct pm8xxx_adc_arb_btm_param *,
+			const struct pm8xxx_adc_properties *adc_prop,
+			const struct pm8xxx_adc_chan_properties *chan_prop);
 /**
  * struct pm8xxx_adc_platform_data - PM8XXX ADC platform data
  * @adc_prop: ADC specific parameters, voltage and channel setup
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index fa19613..384c3ca 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -1094,6 +1094,7 @@
 	uint32_t ext_mode;
 	uint8_t num_planes;
 	struct plane_data plane[MAX_PLANES];
+	uint32_t sp_y_offset;
 	uint8_t vpe_can_use;
 };